Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Objective
add
RenderLayers
awareness to lights. lights default toRenderLayers::layer(0)
, and must intersect the camera entity'sRenderLayers
in order to affect the camera's output.note that lights already use renderlayers to filter meshes for shadow casting. this adds filtering lights per view based on intersection of camera layers and light layers.
fixes #3462
Solution
PointLights and SpotLights are assigned to individual views in
assign_lights_to_clusters
, so we simply cull the lights which don't match the view layers in that function.DirectionalLights are global, so we
DirectionalLight
structViewUniform
structapply_pbr_lighting
potential issue: when mesh/light layers are smaller than the view layers weird results can occur. e.g:
camera = layers 1+2
light = layers 1
mesh = layers 2
the mesh does not cast shadows wrt the light as (1 & 2) == 0.
the light affects the view as (1+2 & 1) != 0.
the view renders the mesh as (1+2 & 2) != 0.
so the mesh is rendered and lit, but does not cast a shadow.
this could be fixed (so that the light would not affect the mesh in that view) by adding the light layers to the point and spot light structs, but i think the setup is pretty unusual, and space is at a premium in those structs (adding 4 bytes more would reduce the webgl point+spot light max count to 240 from 256).
I think typical usage is for cameras to have a single layer, and meshes/lights to maybe have multiple layers to render to e.g. minimaps as well as primary views.
if there is a good use case for the above setup and we should support it, please let me know.
Migration Guide
Lights no longer affect all
RenderLayers
by default, now like cameras and meshes they default toRenderLayers::layer(0)
. To recover the previous behaviour and have all lights affect all views, add aRenderLayers::all()
component to the light entity.