Skip to content

Make shadows respect render layers #18747

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

Adriigbs
Copy link

@Adriigbs Adriigbs commented Apr 7, 2025

Fix #18000: Shadows do not respect render layers

Shadows of objects are still rendered even when camera is rendering a different render layer.

Objective

Solution

  • Export RenderLayers of Mesh from the world.
  • In queue_shadows(), add filter that checks if RenderLayers of the Mesh match the current rendered layer of the Camera.
  • Skip that mesh if the render layers don't match.

Testing


Showcase

ShowCase.mp4

Fix bevyengine#18000: Shadows do not respect render layers

Shadows of objects are still rendered even when camera is rendering a
different render layer.

This happens because `queue_shadows` does not use the camera render
layers when filtering visible entities.

To fix it, i just exported the Mesh render layers and filtered them
according to the camera render layers.
Copy link
Contributor

github-actions bot commented Apr 7, 2025

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

Copy link
Contributor

github-actions bot commented Apr 7, 2025

Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke!
You can review it at https://pixel-eagle.com/project/B04F67C0-C054-4A6F-92EC-F599FEC2FD1D?filter=PR-18747

If it's expected, please add the M-Deliberate-Rendering-Change label.

If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it.

@alice-i-cecile alice-i-cecile added this to the 0.16 milestone Apr 7, 2025
@alice-i-cecile alice-i-cecile changed the title Signed-off-by: Adrian Graur <adrian.graur@tecnico.ulisboa.pt> Make shadows respect render layers Apr 7, 2025
@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior A-Rendering Drawing game state to the screen labels Apr 7, 2025
@alice-i-cecile alice-i-cecile added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Apr 7, 2025
@alice-i-cecile alice-i-cecile modified the milestones: 0.16, 0.17 Apr 7, 2025
Adriigbs and others added 4 commits April 22, 2025 18:47
Filter was removing shadows of objects without any layers.
Changed code to just filter if mesh has RenderLayers assigned.

Signed-off-by: Adrian Graur <adrian.graur@tecnico.ulisboa.pt>
Signed-off-by: Adrian Graur <adrian.graur@tecnico.ulisboa.pt>
Signed-off-by: Adrian Graur <adrian.graur@tecnico.ulisboa.pt>
@Adriigbs
Copy link
Author

Fixed the visual difference, the original fix was filtering shadows by layers even when layers were not assigned. I'm sorry for the multiple commits but i wasn't able to run the CI tests locally for some reason. Ready to be reviewed when possible.

) -> RenderVisibleMeshEntities {
RenderVisibleMeshEntities {
entities: visible_entities
.iter()
.map(|e| {
let render_entity = mapper.get(*e).unwrap_or(Entity::PLACEHOLDER);
(render_entity, MainEntity::from(*e))

// Extract RenderLayers from the mesh entity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very hot path and I'm not sure it makes sense to store this information here, particularly because it will duplicate the the mesh instance render layers for every view light in which the entity appears, which will increase memory and hurt locality. I'm not 100% sure that filtering in the queue method is correct, but if we are going to do so, we should probably store the mesh render layers on RenderMeshInstanceShared, which is currently looked up in the queue system anyway and will ensure that they're only stored once per instance.

@alice-i-cecile alice-i-cecile added S-Needs-Design This issue requires design work to think about how it would best be accomplished and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 5, 2025
Adriigbs and others added 4 commits May 6, 2025 23:31
@Adriigbs
Copy link
Author

Adriigbs commented May 6, 2025

I changed the render layers location to RenderMeshInstanceShared. As for the filtering, i think it's a design choice and is not up to me.

Copy link
Contributor

@tychedelia tychedelia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just a few changes. I'm still agnostic on whether the queue is the right place to do this check but it seems convenient.

}
}

// Skip the entity if it's cached in a bin and up to date.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you move this on purpose?

let mesh_layers = mesh_instance.shared.render_layers.as_ref();

// Skip the entity if it's not in the camera render layers.
if let (Some(camera_layers), Some(layers)) = (camera_layers, mesh_layers) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically the way we do this is to call unwrap_or_default on each of the respective layers, since a non-specified layer counts as layer 0. See check_point_light_mesh_visibility for example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior S-Needs-Design This issue requires design work to think about how it would best be accomplished
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

Shadows do not respect render layers
3 participants