When using 2D and 3D cameras, moving the 2D UI camera to a nondefault render layer makes shadows flicker
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
## Bevy version
0.16.0
## Relevant system information
```ignore
AdapterInfo { name: "AMD Radeon RX 7900 XTX (RADV NAVI31)", vendor: 4098, device: 29772, device_type: DiscreteGpu, driver: "radv", driver_info: "Mesa 25.0.3", backend: Vulkan }
```
## What you did
I have the following "concepts":
```rust
enum CameraOrder {
World,
ViewModel,
Ui,
}
impl From for isize {
fn from(order: CameraOrder) -> Self {
order as isize
}
}
bitflags! {
struct RenderLayer: u32 {
const DEFAULT = 0b00000001;
const VIEW_MODEL = 0b00000010;
const PARTICLES = 0b00000100;
const GIZMO3 = 0b0001000;
const UI = 0b0010000;
}
}
impl From for RenderLayers {
fn from(layer: RenderLayer) -> Self {
RenderLayers::from_iter(layer.iter().map(|l| (l.bits() >> 1) as usize))
}
}
```
Using these terms, my hierarchy is as follows:
- UI camera
- Player camera parent
- World model camera
- View model camera
where the relevant code look like this:
UI Camera
Full code: https://github.com/janhohenheim/foxtrot/blob/nondefault-ui-cam/src/ui_camera.rs#L18-L32
```rust
(
Name::new("UI Camera"),
Camera2d,
IsDefaultUiCamera,
Camera {
// The UI camera order is the highest.
order: CameraOrder::Ui.into(),
..default()
},
)
```
World Model Camera
Full code: https://github.com/janhohenheim/foxtrot/blob/nondefault-ui-cam/src/gameplay/player/camera.rs#L98-L125
```rust
(
Name::new("World Model Camera"),
Camera3d::default(),
Camera {
order: CameraOrder::World.into(),
hdr: true,
..default()
},
RenderLayers::from(
RenderLayer::DEFAULT | RenderLayer::PARTICLES,
),
Bloom::NATURAL,
#[cfg(feature = "native")]
(
Msaa::Off,
ScreenSpaceAmbientOcclusion::default(),
TemporalAntiAliasing::default(),
NormalPrepass,
ShadowFilteringMethod::Temporal,
),
)
```
View Model Camera
Full code: https://github.com/janhohenheim/foxtrot/blob/nondefault-ui-cam/src/gameplay/player/camera.rs#L128-L148
```rust
(
Name::new("View Model Camera"),
Camera3d::default(),
Camera {
// Bump the order to render on top of the world model.
order: CameraOrder::ViewModel.into(),
hdr: true,
..default()
},
// Only render objects belonging to the view model.
RenderLayers::from(RenderLayer::VIEW_MODEL),
)
```
The lights all belong to `RenderLayer::DEFAULT | RenderLayer::VIEW_MODEL`:
Light setup
Full code: https://github.com/janhohenheim/foxtrot/blob/nondefault-ui-cam/src/gameplay/player/camera.rs#L248-L270
```rust
fn add_render_layers_to_point_light(trigger: Trigger, mut commands: Commands) {
let entity = trigger.target();
commands.entity(entity).insert(RenderLayers::from(
RenderLayer::DEFAULT | RenderLayer::VIEW_MODEL,
));
}
fn add_render_layers_to_spot_light(trigger: Trigger, mut commands: Commands) {
let entity = trigger.target();
commands.entity(entity).insert(RenderLayers::from(
RenderLayer::DEFAULT | RenderLayer::VIEW_MODEL,
));
}
fn add_render_layers_to_directional_light(
trigger: Trigger,
mut commands: Commands,
) {
let entity = trigger.target();
commands.entity(entity).insert(RenderLayers::from(
RenderLayer::DEFAULT | RenderLayer::VIEW_MODEL,
));
}
```
This all works fine. Now let's do one little change by moving the UI camera to a nondefault render layer:
```rust
fn spawn_ui_camera(mut commands: Commands) {
commands.spawn((
Name::new("UI Camera"),
UiCamera,
IsDefaultUiCamera,
Camera {
order: CameraOrder::Ui.into(),
..default()
},
// This line causes the issue
RenderLayers::from(RenderLayer::UI),
));
}
```
## What went wrong
The lights flicker uncontrollably (warning for flashing lights!)
https://github.com/user-attachments/assets/450ef9f5-e5a1-4c7d-8bf3-2f30d2d468af
Interestingly, this only happens when moving close to my spot lights
https://github.com/user-attachments/assets/2c31d0a0-2ef5-46ad-b74e-428891ddb3e2
## Additional information
To see this in action, clone https://github.com/janhohenheim/foxtrot/tree/nondefault-ui-cam (note the branch) and run `bevy run`.
This has only happened on native, but it's hard to test this on Wasm since there, the lights ignore most of the obstacles in their way anyways:

Instead, I get #19167 on web
Contributor guide
Assessment
This issue has not been assessed yet.