diff --git a/crates/bevy_pbr/src/render/shadows.wgsl b/crates/bevy_pbr/src/render/shadows.wgsl index 0e539f0009..ef2f73e968 100644 --- a/crates/bevy_pbr/src/render/shadows.wgsl +++ b/crates/bevy_pbr/src/render/shadows.wgsl @@ -62,6 +62,22 @@ fn fetch_point_shadow(light_id: u32, frag_position: vec4, surface_normal: v return sample_shadow_cubemap(frag_ls * flip_z, distance_to_light, depth, light_id); } +// this method of constructing a basis from a vec3 is used by glam::Vec3::any_orthonormal_pair +// so we reproduce it here to avoid a mismatch if glam changes. we also switch the handedness +// the construction of the orthonormal basis up and right vectors needs to precisely mirror the code +// in bevy_light/spot_light.rs:spot_light_world_from_view +fn spot_light_world_from_view(fwd: vec3) -> mat3x3 { + var sign = -1.0; + if (fwd.z >= 0.0) { + sign = 1.0; + } + let a = -1.0 / (fwd.z + sign); + let b = fwd.x * fwd.y * a; + let up_dir = vec3(1.0 + sign * fwd.x * fwd.x * a, sign * b, -sign * fwd.x); + let right_dir = vec3(-b, -sign - fwd.y * fwd.y * a, fwd.y); + return mat3x3(right_dir, up_dir, fwd); +} + fn fetch_spot_shadow( light_id: u32, frag_position: vec4, @@ -88,17 +104,7 @@ fn fetch_spot_shadow( + ((*light).shadow_depth_bias * normalize(surface_to_light)) + (surface_normal.xyz * (*light).shadow_normal_bias) * distance_to_light; - // the construction of the up and right vectors needs to precisely mirror the code - // in render/light.rs:spot_light_view_matrix - var sign = -1.0; - if (fwd.z >= 0.0) { - sign = 1.0; - } - let a = -1.0 / (fwd.z + sign); - let b = fwd.x * fwd.y * a; - let up_dir = vec3(1.0 + sign * fwd.x * fwd.x * a, sign * b, -sign * fwd.x); - let right_dir = vec3(-b, -sign - fwd.y * fwd.y * a, fwd.y); - let light_inv_rot = mat3x3(right_dir, up_dir, fwd); + let light_inv_rot = spot_light_world_from_view(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.