fix(shadow): correct comparison sampler from GreaterEqual to LessEqual

With the shadow map cleared to 1.0 (farthest depth from light) and the
shadow pass writing smaller depths for surfaces closer to the light,
the fragment-to-light distance must be <= the stored surface depth for
lit pixels. GreaterEqual was inverted — everything appeared lit with no
shadows rendered.
This commit is contained in:
Jérôme Bousquié
2026-09-19 12:05:57 +02:00
parent c2cbd7fadb
commit 39167ee05f
2 changed files with 5 additions and 4 deletions
+4 -3
View File
@@ -162,9 +162,10 @@ impl Renderer {
min_filter: wgpu::FilterMode::Linear,
mipmap_filter: wgpu::MipmapFilterMode::Nearest,
// Comparison sampler : `textureSampleCompare` returns 1 when the sampled depth passes
// this test against the reference, 0 otherwise (D5). GreaterEqual = lit when nothing
// closer than the fragment has been written into the shadow map.
compare: Some(wgpu::CompareFunction::GreaterEqual),
// this test against the reference, 0 otherwise (D5). LessEqual = lit when the fragment
// is no farther from the light than the surface recorded in the shadow map (the map is
// cleared to 1.0 = far, so open un-blocked texels pass and surfaces behind a blocker fail).
compare: Some(wgpu::CompareFunction::LessEqual),
..Default::default()
});
let shadow_map_layout = create_shadow_map_bind_group_layout(&device);
+1 -1
View File
@@ -207,7 +207,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
// Étape 14 (DRAFT 3.2, D5) : PCF shadow factor for this fragment. Reprojects the world position
// into the shadow light's clip space, converts to depth-map UVs + normalized depth, then averages
// a 3×3 `textureSampleCompare` neighborhood using the comparison sampler (GreaterEqual). Returns
// a 3×3 `textureSampleCompare` neighborhood using the comparison sampler (LessEqual). Returns
// 1.0 when fully lit (or shadows disabled), 0.0 when fully in shadow. The reference depth is
// pulled toward the viewer by `frame.shadow_params.y` (bias) to suppress acne.
fn compute_shadow(world_pos: vec3<f32>) -> f32 {