Skip to content

Commit a58a8bd

Browse files
HugoPeters1024alice-i-cecileJMS55
authored
bugfix(frustra of point lights were not recalculated when a camera changes) (#18519)
# Objective - Fixes #11682 ## Solution - #4086 introduced an optimization to not do redundant calculations, but did not take into account changes to the resource `global_lights`. I believe that my patch includes the optimization benefit but adds the required nuance to fix said bug. ## Testing The example originally given by [@kirillsurkov](https://github.com/kirillsurkov) and then updated by me to bevy 15.3 here: #11682 (comment) will not have shadows without this patch: ```rust use bevy::prelude::*; #[derive(Resource)] struct State { x: f32, } fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, update) .insert_resource(State { x: -40.0 }) .run(); } fn setup( mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<StandardMaterial>>, ) { commands.spawn(( Mesh3d(meshes.add(Circle::new(4.0))), MeshMaterial3d(materials.add(Color::WHITE)), )); commands.spawn(( Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))), MeshMaterial3d(materials.add(Color::linear_rgb(0.0, 1.0, 0.0))), )); commands.spawn(( PointLight { shadows_enabled: true, ..default() }, Transform::from_xyz(4.0, 8.0, 4.0), )); commands.spawn(Camera3d::default()); } fn update(mut state: ResMut<State>, mut camera: Query<&mut Transform, With<Camera3d>>) { let mut camera = camera.single_mut().unwrap(); let t = Vec3::new(state.x, 0.0, 10.0); camera.translation = t; camera.look_at(t - Vec3::Z, Vec3::Y); state.x = 0.0; } ``` --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
1 parent 6a981aa commit a58a8bd

File tree

1 file changed

+13
-3
lines changed
  • crates/bevy_pbr/src/light

1 file changed

+13
-3
lines changed

crates/bevy_pbr/src/light/mod.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -563,9 +563,13 @@ pub fn update_directional_light_frusta(
563563
// NOTE: Run this after assign_lights_to_clusters!
564564
pub fn update_point_light_frusta(
565565
global_lights: Res<GlobalVisibleClusterableObjects>,
566-
mut views: Query<
567-
(Entity, &GlobalTransform, &PointLight, &mut CubemapFrusta),
568-
Or<(Changed<GlobalTransform>, Changed<PointLight>)>,
566+
mut views: Query<(Entity, &GlobalTransform, &PointLight, &mut CubemapFrusta)>,
567+
changed_lights: Query<
568+
Entity,
569+
(
570+
With<PointLight>,
571+
Or<(Changed<GlobalTransform>, Changed<PointLight>)>,
572+
),
569573
>,
570574
) {
571575
let view_rotations = CUBE_MAP_FACES
@@ -574,6 +578,12 @@ pub fn update_point_light_frusta(
574578
.collect::<Vec<_>>();
575579

576580
for (entity, transform, point_light, mut cubemap_frusta) in &mut views {
581+
// If this light hasn't changed, and neither has the set of global_lights,
582+
// then we can skip this calculation.
583+
if !global_lights.is_changed() && !changed_lights.contains(entity) {
584+
continue;
585+
}
586+
577587
// The frusta are used for culling meshes to the light for shadow mapping
578588
// so if shadow mapping is disabled for this light, then the frusta are
579589
// not needed.

0 commit comments

Comments
 (0)