From bdb39cf723a5076cac017c6cdc009aaa1b4ccac1 Mon Sep 17 00:00:00 2001 From: atlv Date: Sat, 5 Jul 2025 10:40:06 -0400 Subject: [PATCH] move spot light function into spot light file (#19956) # Objective - Make bevy_light possible ## Solution - Move some stuff it needs out of somewhere it cant depend on. Plus it makes sense, spotlight stuff goes in spotlight file. ## Testing - 3d_scene runs Note: no breaking changes thanks to re-exports --- crates/bevy_pbr/src/light/mod.rs | 1 + crates/bevy_pbr/src/light/spot_light.rs | 32 +++++++++++++++++++++++++ crates/bevy_pbr/src/render/light.rs | 32 ------------------------- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/crates/bevy_pbr/src/light/mod.rs b/crates/bevy_pbr/src/light/mod.rs index a93e3e4c58..004085fda6 100644 --- a/crates/bevy_pbr/src/light/mod.rs +++ b/crates/bevy_pbr/src/light/mod.rs @@ -20,6 +20,7 @@ use bevy_utils::Parallel; use core::{marker::PhantomData, ops::DerefMut}; use crate::*; +pub use light::spot_light::{spot_light_clip_from_view, spot_light_world_from_view}; mod ambient_light; pub use ambient_light::AmbientLight; diff --git a/crates/bevy_pbr/src/light/spot_light.rs b/crates/bevy_pbr/src/light/spot_light.rs index a7cfe1b817..7e0bd43f15 100644 --- a/crates/bevy_pbr/src/light/spot_light.rs +++ b/crates/bevy_pbr/src/light/spot_light.rs @@ -140,3 +140,35 @@ impl Default for SpotLight { } } } + +// this method of constructing a basis from a vec3 is used by glam::Vec3::any_orthonormal_pair +// we will also construct it in the fragment shader and need our implementations to match, +// so we reproduce it here to avoid a mismatch if glam changes. we also switch the handedness +// could move this onto transform but it's pretty niche +pub fn spot_light_world_from_view(transform: &GlobalTransform) -> Mat4 { + // the matrix z_local (opposite of transform.forward()) + let fwd_dir = transform.back().extend(0.0); + + let sign = 1f32.copysign(fwd_dir.z); + let a = -1.0 / (fwd_dir.z + sign); + let b = fwd_dir.x * fwd_dir.y * a; + let up_dir = Vec4::new( + 1.0 + sign * fwd_dir.x * fwd_dir.x * a, + sign * b, + -sign * fwd_dir.x, + 0.0, + ); + let right_dir = Vec4::new(-b, -sign - fwd_dir.y * fwd_dir.y * a, fwd_dir.y, 0.0); + + Mat4::from_cols( + right_dir, + up_dir, + fwd_dir, + transform.translation().extend(1.0), + ) +} + +pub fn spot_light_clip_from_view(angle: f32, near_z: f32) -> Mat4 { + // spot light projection FOV is 2x the angle from spot light center to outer edge + Mat4::perspective_infinite_reverse_rh(angle * 2.0, 1.0, near_z) +} diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 1a55eb0926..cee3d76e14 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -711,38 +711,6 @@ pub fn calculate_cluster_factors( } } -// this method of constructing a basis from a vec3 is used by glam::Vec3::any_orthonormal_pair -// we will also construct it in the fragment shader and need our implementations to match, -// so we reproduce it here to avoid a mismatch if glam changes. we also switch the handedness -// could move this onto transform but it's pretty niche -pub(crate) fn spot_light_world_from_view(transform: &GlobalTransform) -> Mat4 { - // the matrix z_local (opposite of transform.forward()) - let fwd_dir = transform.back().extend(0.0); - - let sign = 1f32.copysign(fwd_dir.z); - let a = -1.0 / (fwd_dir.z + sign); - let b = fwd_dir.x * fwd_dir.y * a; - let up_dir = Vec4::new( - 1.0 + sign * fwd_dir.x * fwd_dir.x * a, - sign * b, - -sign * fwd_dir.x, - 0.0, - ); - let right_dir = Vec4::new(-b, -sign - fwd_dir.y * fwd_dir.y * a, fwd_dir.y, 0.0); - - Mat4::from_cols( - right_dir, - up_dir, - fwd_dir, - transform.translation().extend(1.0), - ) -} - -pub(crate) fn spot_light_clip_from_view(angle: f32, near_z: f32) -> Mat4 { - // spot light projection FOV is 2x the angle from spot light center to outer edge - Mat4::perspective_infinite_reverse_rh(angle * 2.0, 1.0, near_z) -} - pub fn prepare_lights( mut commands: Commands, mut texture_cache: ResMut,