Change Detection Logic Bug in Point/Spot Light Frustra Update
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## Bevy version
e4b740840f17d0ff3fa15d979d0ed2c65fa693c2
## What you did
Spawn point/spot lights with shadows enabled far away from the camera, and don't change their transform or light components. Move the camera closer to them.
## What went wrong
They will have no shadows, because their frustra isn't updated.
## Additional information
The issue is taking place here:
https://github.com/bevyengine/bevy/blob/36c6f29832ddeb2ce4880f2db90efde00f2609ee/crates/bevy_pbr/src/light/mod.rs#L565-L571
https://github.com/bevyengine/bevy/blob/36c6f29832ddeb2ce4880f2db90efde00f2609ee/crates/bevy_pbr/src/light/mod.rs#L609-L615
We rely on `Or, Changed` to update the frustra of only lights that changed. However, we bail early here if the lights are not in any clusters:
https://github.com/bevyengine/bevy/blob/36c6f29832ddeb2ce4880f2db90efde00f2609ee/crates/bevy_pbr/src/light/mod.rs#L585
https://github.com/bevyengine/bevy/blob/36c6f29832ddeb2ce4880f2db90efde00f2609ee/crates/bevy_pbr/src/light/mod.rs#L622
Once they're added to the clusters, they end up not getting their frustra updated until they either move or have the light component changed.
Relevant discord conversation: https://discord.com/channels/691052431525675048/743663924229963868/1277413598859100223
## Potential Solutions
1. Remove the `GlobalVisibleClusterableObjects` check entirely. This will result in some light frustra being updated needlessly, but doing so should be fast enough that it won't be a problem realistically.
2. Add a `GloballyClustered` component (or similar) that gets added/removed from the lights, and react to changes to that. This has performance implications due to archetype moves, and would go against the grain of moving rendering stuff out of components and into resources for perf.
3. Add a `ClusteringStatus` component that is updated with the lights (not added/removed), and react to changes to that. This should give us the benefit of not having false updated, without the drawbacks of false positives, but will also imply in an extra component laying around for all lights, regardless of clustering status.
Contributor guide
Research direction
Start in crates/bevy_pbr/src/light/mod.rs at the point-light and spot-light frustum update logic referenced by the issue. Reproduce the case with shadowed lights spawned far from the camera, then move the camera into range and inspect the GlobalVisibleClusterableObjects early exits. Done means the lights receive updated frusta and cast shadows after entering clusters without changing their transform or light components.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100