bevyengine / bevyengine/bevy

When using 2D and 3D cameras, moving the 2D UI camera to a nondefault render layer makes shadows flicker

Open
#19,166 3 comments 0 reactions 0 assignees View on GitHub
A-Rendering C-Bug
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:

![Image](https://github.com/user-attachments/assets/1c901388-fc42-4f5b-91e6-64d80814f06f)

Instead, I get #19167 on web

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.