bugfix(frustra of point lights were not recalculated when a camera changes) (#18519)
# Objective - Fixes https://github.com/bevyengine/bevy/issues/11682 ## Solution - https://github.com/bevyengine/bevy/pull/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: https://github.com/bevyengine/bevy/issues/11682#issuecomment-2746287416 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>
This commit is contained in:
parent
6a981aaa6f
commit
a58a8bde2b
@ -563,9 +563,13 @@ pub fn update_directional_light_frusta(
|
||||
// NOTE: Run this after assign_lights_to_clusters!
|
||||
pub fn update_point_light_frusta(
|
||||
global_lights: Res<GlobalVisibleClusterableObjects>,
|
||||
mut views: Query<
|
||||
(Entity, &GlobalTransform, &PointLight, &mut CubemapFrusta),
|
||||
Or<(Changed<GlobalTransform>, Changed<PointLight>)>,
|
||||
mut views: Query<(Entity, &GlobalTransform, &PointLight, &mut CubemapFrusta)>,
|
||||
changed_lights: Query<
|
||||
Entity,
|
||||
(
|
||||
With<PointLight>,
|
||||
Or<(Changed<GlobalTransform>, Changed<PointLight>)>,
|
||||
),
|
||||
>,
|
||||
) {
|
||||
let view_rotations = CUBE_MAP_FACES
|
||||
@ -574,6 +578,12 @@ pub fn update_point_light_frusta(
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for (entity, transform, point_light, mut cubemap_frusta) in &mut views {
|
||||
// If this light hasn't changed, and neither has the set of global_lights,
|
||||
// then we can skip this calculation.
|
||||
if !global_lights.is_changed() && !changed_lights.contains(entity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The frusta are used for culling meshes to the light for shadow mapping
|
||||
// so if shadow mapping is disabled for this light, then the frusta are
|
||||
// not needed.
|
||||
|
Loading…
Reference in New Issue
Block a user