Skip to content

Fix: Use the auxiliary entity (associated camera view)’s position via ViewUniform for gpu visibility range culling #24133

Closed
kfc35 wants to merge 4 commits into
bevyengine:mainfrom
kfc35:23991_cpu_culling_fix_2
Closed

Fix: Use the auxiliary entity (associated camera view)’s position via ViewUniform for gpu visibility range culling #24133
kfc35 wants to merge 4 commits into
bevyengine:mainfrom
kfc35:23991_cpu_culling_fix_2

Conversation

@kfc35

@kfc35 kfc35 commented May 5, 2026

Copy link
Copy Markdown
Contributor

Note: a newer alternate PR using immediates is here: #24197. Decisions made between the two PR’s can be mixed and matched, just let me know.

Objective

Solution

  • Store the render entity for the auxiliary entity (represents a regular viewing camera for directional lights). Use it to query for the auxiliary entity’s world position when it’s time to build the ViewUniform, which will be used for visibility range culling.
  • Added bitflags to the ViewUniform to ensure that ExtractedViews for entities that aren’t also ExtractedCameras and do not have auxiliary entities are not used for visibility range culling. Such ExtractedViews should only be Point and Spot lights.

Note

As a consequence, if meshes have NoCpuCulling, have a VisibilityRange defined, and are being illuminated by a Point or Spot light, their shadows currently won’t disappear if an ExtractedCamera goes outside the meshes visibility range! I am looking for guidance on what to do in this case…

  • Note: Regular cameras have their position data duplicated in both world_position and primary_world_position.

I actually do not know if this is the best way to send information to the gpu; I just tacked stuff onto ViewUniform. If there is a different, more preferred way to do this work, you’ll have to give me some guidance as I’m not too experienced with rendering!

NOTE: There’s also code that touches calculating the dithering level that I haven’t touched in the wgsl. Let me know if that should be changed too….

If anyone wants text on me explaining what the concrete changes are and why I did them, or just a different wording: https://discord.com/channels/691052431525675048/743663924229963868/1501630877082325062

Testing

  • cargo run --example visibility_range -- --no-cpu-culling works as desired without shadows popping in and out
  • cargo run --example visibility_range works as desired without shadows popping in and out
  • checked cargo run --example spotlight and cargo run --example async_channel_pattern for regressions; they seem fine.

@kfc35 kfc35 added this to the 0.19 milestone May 5, 2026
@kfc35 kfc35 added C-Bug An unexpected or incorrect behavior A-Rendering Drawing game state to the screen D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 5, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Rendering May 5, 2026
@kfc35 kfc35 changed the title Fix: Use auxiliary cameras for visibility range culling if defined Fix: Use auxiliary entity (reg view camera) for visibility range culling if defined May 5, 2026
@kfc35 kfc35 requested a review from JMS55 May 5, 2026 05:41
@kfc35 kfc35 changed the title Fix: Use auxiliary entity (reg view camera) for visibility range culling if defined Fix: Use auxiliary entity (reg view camera) for gpu visibility range culling if defined May 5, 2026
@Br3nnabee

Copy link
Copy Markdown
Contributor

Just a learning question if you wouldn't mind: Why do directional light shadow views need to cull based on the camera's world position rather than the light's position?

@kfc35

kfc35 commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

Just a learning question if you wouldn't mind: Why do directional light shadow views need to cull based on the camera's world position rather than the light's position?

I don’t mind at all!

As far as I understand, visibility ranges are only meant to define distances at which meshes start to fade out from view / fade into view when viewed from a user defined camera, as opposed to a shadow camera. This is specifically about visibility range culling as opposed to the more general frustum culling, even though the logic is in the same block in the wgsl file.

In the specific example for visibility_rangeon main, you can observe the results of the existing behavior (where it doesn’t use the user defined camera). When the user moves their camera at certain angles at distances, the shadow starts to cull even though the object hasn’t. I don’t know much about shadow cameras (I’ve really only dove into this part of the code within the past few weeks!), but I assume it’s because the distance from the shadow camera is not within the visibility range of the shadow, which shows up as premature fading on the user camera. The mesh and its shadow also end up using two different cameras to do visibility range culling instead of the same user camera, which means the mesh and shadow could end up disappearing/reappearing at different times.

@kfc35 kfc35 requested review from pcwalton May 6, 2026 23:12
@kfc35

kfc35 commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

@pcwalton just review requesting you since i think you might be most familiar with the things this code is touching / have strong opinions. please look whenever most convenient for you!

@kfc35 kfc35 added the S-Needs-Help The author needs help finishing this PR. label May 7, 2026
@kfc35

kfc35 commented May 8, 2026

Copy link
Copy Markdown
Contributor Author

I opened an alternate solution to the bug as #24197

@kfc35 kfc35 changed the title Fix: Use auxiliary entity (reg view camera) for gpu visibility range culling if defined Fix: Use the auxiliary entity (associated camera view)’s position via ViewUniform for gpu visibility range culling May 10, 2026
@kfc35

kfc35 commented May 13, 2026

Copy link
Copy Markdown
Contributor Author

closing this since we will most likely go the way of the revert

people also weren’t really fond of this option anyway!

@kfc35 kfc35 closed this May 13, 2026
@github-project-automation github-project-automation Bot moved this from Needs SME Triage to Done in Rendering May 13, 2026
github-merge-queue Bot pushed a commit that referenced this pull request May 13, 2026
…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
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 D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Help The author needs help finishing this PR. S-Needs-Review Needs reviewer attention (from anyone!) to move forward

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Shadows disappear abruptly in visibility range example

3 participants