bevyengine / bevyengine/bevy

Change Detection Logic Bug in Point/Spot Light Frustra Update

Open
#14,959 4 comments 0 reactions 0 assignees View on GitHub
A-Rendering C-Bug D-Straightforward S-Ready-For-Implementation
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.