Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions crates/bevy_light/src/spot_light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,19 +171,15 @@ pub fn orthonormalize(z_basis: Dir3) -> Mat3 {
let y_basis = Vec3::new(b, sign + z_basis.y * z_basis.y * a, -z_basis.y);
Mat3::from_cols(x_basis, y_basis, z_basis.into())
}
/// Constructs a left-handed orthonormal basis with translation, using only the forward direction and translation of a given [`GlobalTransform`].
/// Constructs a right-handed orthonormal basis with translation, using only the forward direction and translation of a given [`GlobalTransform`].
///
/// This is a handedness-inverted version of [`orthonormalize`] which also includes translation.
/// we mirror this construction in the fragment shader and need our implementations to match exactly.
// See bevy_pbr/shadows.wgsl:spot_light_world_from_view
/// This is a version of [`orthonormalize`] which also includes translation.
pub fn spot_light_world_from_view(transform: &GlobalTransform) -> Mat4 {
// the matrix z_local (opposite of transform.forward())
let fwd_dir = transform.back();

let basis = orthonormalize(fwd_dir);
let mut mat = Mat4::from_mat3(basis);
// handedness flip
mat.x_axis = -mat.x_axis;
mat.w_axis = transform.translation().extend(1.0);
mat
}
Expand Down
17 changes: 1 addition & 16 deletions crates/bevy_pbr/src/render/shadows.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,6 @@ fn fetch_point_shadow(light_id: u32, frag_position: vec4<f32>, surface_normal: v
return sample_shadow_cubemap(frag_ls * flip_z, distance_to_light, depth, light_id);
}

// Constructs a left-handed orthonormal basis from a given unit Z vector.
//
// NOTE: requires unit-length (normalized) input to function properly.
//
// this method of constructing a basis from a vec3 is used by glam::Vec3::any_orthonormal_pair
// the construction of the orthonormal basis up and right vectors here needs to precisely mirror the code
// in bevy_light/spot_light.rs:spot_light_world_from_view
// so we use `bevy_math::orthonormalize` which matches the rust impl, but we also invert the handedness
fn spot_light_world_from_view(z_basis: vec3<f32>) -> mat3x3<f32> {
var basis = orthonormalize(z_basis);
// handedness flip
basis[0] = -basis[0];
return basis;
}

fn fetch_spot_shadow(
light_id: u32,
frag_position: vec4<f32>,
Expand All @@ -103,7 +88,7 @@ fn fetch_spot_shadow(
+ ((*light).shadow_depth_bias * normalize(surface_to_light))
+ (surface_normal.xyz * (*light).shadow_normal_bias) * distance_to_light;

let light_inv_rot = spot_light_world_from_view(fwd);
let light_inv_rot = orthonormalize(fwd);

// because the matrix is a pure rotation matrix, the inverse is just the transpose, and to calculate
// the product of the transpose with a vector we can just post-multiply instead of pre-multiplying.
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_render/src/maths.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ fn copysign(a: f32, b: f32) -> f32 {
//
// https://jcgt.org/published/0006/01/01/paper.pdf
// this method of constructing a basis from a vec3 is also used by `glam::Vec3::any_orthonormal_pair`
// the construction of the orthonormal basis up and right vectors here needs to precisely match the rust
// implementation in bevy_light/spot_light.rs:spot_light_world_from_view
fn orthonormalize(z_basis: vec3<f32>) -> mat3x3<f32> {
let sign = copysign(1.0, z_basis.z);
let a = -1.0 / (sign + z_basis.z);
Expand Down
Loading