Skip to content

Fix shadow panic when a camera is despawned before extraction#24877

Open
mgi388 wants to merge 1 commit into
bevyengine:mainfrom
mgi388:light-unwrap-panic
Open

Fix shadow panic when a camera is despawned before extraction#24877
mgi388 wants to merge 1 commit into
bevyengine:mainfrom
mgi388:light-unwrap-panic

Conversation

@mgi388

@mgi388 mgi388 commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Objective

thread 'Compute Task Pool (2)' (54205291) panicked at /me/bevy/crates/bevy_pbr/src/render/light.rs:1508:18:
called `Option::unwrap()` on a `None` value                                                                                                                                                                                                    stack backtrace:
   0:        0x10b3f042c - std[7d7552da0923e8b2]::backtrace_rs::backtrace::libunwind::trace
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/../../backtrace/src/backtrace/libunwind.rs:117:9
   1:        0x10b3f042c - std[7d7552da0923e8b2]::backtrace_rs::backtrace::trace_unsynchronized::<std[7d7552da0923e8b2]::sys::backtrace::_print_fmt::{closure#1}>       
  • At the time I couldn't really work out what the bug was, so I reordered my own code and managed to work around it.

Solution

  • After working backwards from the panic at the unwrap() site, I discovered (what I think) is the bug: the for loop over the extracted cascades insertion was incorrectly breaking when it came across an unmapped entity, rather than continuing.
  • This meant it dropped entries for other valid cameras.
  • Note the fix is a change from else { break; } to else { continue; } which is pointless, hence why I just removed it.

Testing

  • See below for a runnable repro for this. It's an example, so reviewers can copy this into your local repo and run the example before and after the fix. The example is actually pretty tiny in the end and so it should be clear it's a valid example.
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, spawn_throwaway_cameras)
        .add_systems(Last, despawn_throwaway_cameras)
        .run();
}

fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    commands.spawn((
        Mesh3d(meshes.add(Cuboid::new(10.0, 0.1, 10.0))),
        MeshMaterial3d(materials.add(Color::WHITE)),
        Transform::from_xyz(0.0, -0.05, 0.0),
    ));

    commands.spawn((
        Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
        MeshMaterial3d(materials.add(Color::srgb(0.4, 0.5, 0.9))),
        Transform::from_xyz(0.0, 0.5, 0.0),
    ));

    // Directional light. This is the light whose per-camera cascade map ends up
    // missing the main camera's entry.
    commands.spawn((
        DirectionalLight {
            shadow_maps_enabled: true,
            ..default()
        },
        Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
    ));

    // Main camera.
    commands.spawn((
        Camera3d::default(),
        Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
    ));
}

#[derive(Component)]
struct Throwaway;

const THROWAWAY_CAMERAS_PER_FRAME: usize = 64;

fn spawn_throwaway_cameras(mut commands: Commands) {
    for _ in 0..THROWAWAY_CAMERAS_PER_FRAME {
        commands.spawn((Camera3d::default(), Throwaway));
    }
}

fn despawn_throwaway_cameras(mut commands: Commands, query: Query<Entity, With<Throwaway>>) {
    for entity in query.iter() {
        commands.entity(entity).despawn();
    }
}

@mgi388 mgi388 added C-Bug An unexpected or incorrect behavior A-Rendering Drawing game state to the screen D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jul 5, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Rendering Jul 5, 2026
@mgi388 mgi388 added this to the 0.19.1 milestone Jul 5, 2026
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-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

1 participant