Fix: Send CurrentView/ PointAndSpotLightShadowPrimaryCamera ’s world position via Immediates for gpu vis range culling#24197
Conversation
JMS55
left a comment
There was a problem hiding this comment.
Note: With this PR, we lose out on PreprocessingOnly support for WebGPU, until immediates are added to the spec and wgpu supports it.
|
I will add a marker component for the camera to use for gpu vis culling spot and point lights shadows, that should be ready to review in a few hours |
34ad77f to
3a800cd
Compare
|
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! 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. |
a767075 to
3f8e38b
Compare
3f8e38b to
ac87f8e
Compare
CurrentView/ an ExtractedCamera’s world position via immediates for gpu vis range cullingCurrentView/ PointAndSpotLightShadowPrimaryCamera ’s world position via Immediates for gpu vis range culling
|
I'm not sure if PointAndSpotLightShadowPrimaryCamera is correct. The original implementation #12916 says:
|
|
Thanks for finding that @beicause My thoughts given that information:
I’ll get to implementing this logic in about 18 hours unless there are any objections (and may work on it sooner if I get some timely affirmations) |
|
IMO we should consider reverting #23115. This may introduce extra overhead on GPU and regression on WebGPU before immediates is supported.
bevy/crates/bevy_light/src/lib.rs Line 429 in 2002a18 |
Seems seems quite expensive 😬 . Also I don't know what that would even look like, I feel like the shadows would be all weird. |
I agree that it would look weird 😢 I’m not sure how to interpret the original intent for visibility ranges in this context then...
Reverting is definitely an option at this point… I’ll just keep this PR as is for now. Thanks for the quick input! |
| } else { | ||
| // There is no single designated primary camera to use for vis range culling of the shadows. | ||
| // Do not render them. | ||
| continue; |
There was a problem hiding this comment.
Doesn't this continue skip the entire preprocess dispatch for the view?
There was a problem hiding this comment.
For the PointLight/SpotLight shadow view, yes
But I would consider that a user configuration error at this point, so the shadows just wouldn’t be rendered.
(However we do not need to continue this conversation because I will close this PR! It seems the consensus is converging on reverting the offending PR)
…CpuCulling` is specified. (#23115) (#24252) This reverts commit ebfbc3f. # Objective - A third PR that fixes #23991 ## Solution - Reverts the commit that causes the issue. - This can be considered if the other solutions (#24197 & #24133) I’ve put up are not satisfactory, and we need more time to come up with a good solution (i.e. post 0.19 rc) that: - Implements PointLight and SpotLight shadow view behavior for gpu vis range culling that is agreed upon and looks good - Finalizes an appropriate way of sending this camera view world position data to the gpu (Immediates vs ViewUniformBuffer or other Uniform) - Note: Meshes that are tagged with `NoCpuCulling` will **not** undergo cpu visibility range culling. That was implemented in a separate PR: https://github.com/bevyengine/bevy/pull/23107/changes#diff-fec33d34072b7b4be336571ceecf2c10fc9bafd8366c1b29531089b7e3ef621cL745-L748. If you want to use `VisibilityRange` culling, you will still need to have CPU culling enabled for the mesh. ## Testing - `cargo run --example visibility_range` works normal now. - Tested some other 3d examples make sure the pipeline is ok — atmosphere, pccm
Right now, visibility ranges are always resolved relative to the view. This is incorrect for shadow maps in two ways: 1. Visibility ranges for meshes in directional light shadow maps should be resolved relative to the camera that the cascades are associated with. 2. Visibility ranges for meshes in point and spot light shadow maps should be resolved relative to *some* camera. To properly solve (2), this commit introduces the notion of a *primary camera*. The primary camera is the one that visibility ranges are relative to, when rendering views not associated with any camera. Point and spot light shadow maps are currently not associated with a camera, and therefore we need this extra notion in order to properly evaluate visibility ranges. (As a follow-up, we should introduce the notion of *own shadow maps*, which will allow each camera to have separate shadow maps for point and spot lights. That feature is however out of scope for *this* patch, which simply seeks to make the existing semantics consistent.) A new component, `PrimaryCamera`, has been added, which allows the developer to customize which camera is primary. In the absence of this component, this PR implements a simple heuristic to determine the primary camera: to prefer cameras that render to a window. This heuristic should suffice in the vast majority of cases, so developers will rarely have to manually use the `PrimaryCamera` component. A new field, `lod_view_world_position`, has been added to `View` to supply the position of the primary camera to the GPU. This is much simpler than introducing a new uniform or using immediates, as bevyengine#24197 tried to do. This commit is the proper fix for bevyengine#23991. PR bevyengine#24252 attempted to fix this problem by reverting bevyengine#23115. However, this didn't actually fix the issue, because the semantics were still inconsistent. This commit constitutes the correct fix for the issue. I verified that, after un-reverting bevyengine#23115 on top of this patch and modifying it to use the new `lod_view_world_position`, that the issue reported in bevyengine#23991 disappears.
Right now, visibility ranges are always resolved relative to the view. This is incorrect for shadow maps in two ways: 1. Visibility ranges for meshes in directional light shadow maps should be resolved relative to the camera that the cascades are associated with. 2. Visibility ranges for meshes in point and spot light shadow maps should be resolved relative to *some* camera. To properly solve (2), this commit introduces the notion of a *shadow LOD origin*. The shadow LOD origin is the point that visibility ranges are relative to, when rendering views not associated with any camera. Point and spot light shadow maps are currently not associated with a camera, and therefore we need this extra notion in order to properly evaluate visibility ranges. (As a follow-up, we should introduce the notion of *own shadow maps*, which will allow each camera to have separate shadow maps for point and spot lights. That feature is however out of scope for *this* patch, which simply seeks to make the existing semantics consistent.) A new component, `ShadowLodOrigin`, has been added, which allows the developer to customize the shadow LOD origin. In the absence of this component, this PR implements a simple heuristic to determine the shadow LOD origin: to prefer an origin that coincides with cameras that render to a window. This heuristic should suffice in the vast majority of cases, so developers will rarely have to manually use the `ShadowLodOrigin` component. A new field, `lod_view_world_position`, has been added to `View` to supply the position of the shadow LOD origin to the GPU. This is much simpler than introducing a new uniform or using immediates, as bevyengine#24197 tried to do. This commit is the proper fix for bevyengine#23991. PR bevyengine#24252 attempted to fix this problem by reverting bevyengine#23115. However, this didn't actually fix the issue, because the semantics were still inconsistent. This commit constitutes the correct fix for the issue. I verified that, after un-reverting bevyengine#23115 on top of this patch and modifying it to use the new `lod_view_world_position`, that the issue reported in bevyengine#23991 disappears.
Right now, visibility ranges are always resolved relative to the view. This is incorrect for shadow maps in two ways: 1. Visibility ranges for meshes in directional light shadow maps should be resolved relative to the camera that the cascades are associated with. 2. Visibility ranges for meshes in point and spot light shadow maps should be resolved relative to *some* camera. To properly solve (2), this commit introduces the notion of a *shadow LOD origin*. The shadow LOD origin is the point that visibility ranges are relative to, when rendering views not associated with any camera. Point and spot light shadow maps are currently not associated with a camera, and therefore we need this extra notion in order to properly evaluate visibility ranges. (As a follow-up, we should introduce the notion of *own shadow maps*, which will allow each camera to have separate shadow maps for point and spot lights. That feature is however out of scope for *this* patch, which simply seeks to make the existing semantics consistent.) A new component, `ShadowLodOrigin`, has been added, which allows the developer to customize the shadow LOD origin. In the absence of this component, this PR implements a simple heuristic to determine the shadow LOD origin: to prefer an origin that coincides with cameras that render to a window. This heuristic should suffice in the vast majority of cases, so developers will rarely have to manually use the `ShadowLodOrigin` component. A new field, `lod_view_world_position`, has been added to `View` to supply the position of the shadow LOD origin to the GPU. This is much simpler than introducing a new uniform or using immediates, as bevyengine#24197 tried to do. This commit is the proper fix for bevyengine#23991. PR bevyengine#24252 attempted to fix this problem by reverting bevyengine#23115. However, this didn't actually fix the issue, because the semantics were still inconsistent. This commit constitutes the correct fix for the issue. I verified that, after un-reverting bevyengine#23115 on top of this patch and modifying it to use the new `lod_view_world_position`, that the issue reported in bevyengine#23991 disappears.
Right now, visibility ranges are always resolved relative to the view. This is incorrect for shadow maps in two ways: 1. Visibility ranges for meshes in directional light shadow maps should be resolved relative to the camera that the cascades are associated with. 2. Visibility ranges for meshes in point and spot light shadow maps should be resolved relative to *some* camera. To properly solve (2), this commit introduces the notion of a *shadow LOD origin*. The shadow LOD origin is the point that visibility ranges are relative to, when rendering views not associated with any camera. Point and spot light shadow maps are currently not associated with a camera, and therefore we need this extra notion in order to properly evaluate visibility ranges. (As a follow-up, we should introduce the notion of *own shadow maps*, which will allow each camera to have separate shadow maps for point and spot lights. That feature is however out of scope for *this* patch, which simply seeks to make the existing semantics consistent.) A new component, `ShadowLodOrigin`, has been added, which allows the developer to customize the shadow LOD origin. In the absence of this component, this PR implements a simple heuristic to determine the shadow LOD origin: to prefer an origin that coincides with cameras that render to a window. This heuristic should suffice in the vast majority of cases, so developers will rarely have to manually use the `ShadowLodOrigin` component. A new field, `lod_view_world_position`, has been added to `View` to supply the position of the shadow LOD origin to the GPU. This is much simpler than introducing a new uniform or using immediates, as #24197 tried to do. This commit is the proper fix for #23991. PR #24252 attempted to fix this problem by reverting #23115. However, this didn't actually fix the issue, because the semantics were still inconsistent. This commit constitutes the correct fix for the issue. I verified that, after un-reverting #23115 on top of this patch and modifying it to use the new `lod_view_world_position`, that the issue reported in #23991 disappears.
Objective
ViewUniformfor gpu visibility range culling #24133 . Decisions made can be mixed and matched between the two, just let me knowImmediatesto avoid bloatingViewUniforms. There was also a concern about usingRetainedViewEntityto pass information about what camera to use along. This is that alternate implementation path.Solution
CurrentViewmechanism to get the current view’s world position, used when preprocessing directional light shadow views. This will be used for gpu vis range culling dir light shadows.RootNonCameraViews), a marker component has been added to denote the camera to use:PointAndSpotLightShadowPrimaryCamera. There must only be one camera with this component. This camera’s position will be used for gpu vis range culling point/spotlight shadows.PointAndSpotLightShadowPrimaryCameracomponent, we can revertac87f8e — the previous logic just queried for extracted cameras and took the world position of the first one returned by the query.
Note
Copying this comment from @JMS55:
With this PR, we lose out on PreprocessingOnly support for WebGPU, until immediates are added to the spec and wgpu supports it.
Testing
cargo run --example visibility_range -- --no-cpu-cullingworks with a directional light as desiredvisibility_rangeexample to be a Spot or PointLight like so:And added the
PointAndSpotLightShadowPrimaryCamerato theCamera3din the example, and then ran the example. The shadows of spot and point lights also look normal.