Skip to content

Commit

Permalink
bevy_pbr2: Do manual shadow map depth comparisons for more flexibility
Browse files Browse the repository at this point in the history
  • Loading branch information
superdump committed Jul 13, 2021
1 parent f7315cc commit 7df1bab
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 17 deletions.
4 changes: 2 additions & 2 deletions pipelined/bevy_pbr2/src/render/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ impl FromWorld for ShadowShaders {
mag_filter: FilterMode::Nearest,
min_filter: FilterMode::Nearest,
mipmap_filter: FilterMode::Nearest,
compare: Some(CompareFunction::LessEqual),
compare: None,
..Default::default()
}),
directional_light_sampler: render_device.create_sampler(&SamplerDescriptor {
Expand All @@ -210,7 +210,7 @@ impl FromWorld for ShadowShaders {
mag_filter: FilterMode::Nearest,
min_filter: FilterMode::Nearest,
mipmap_filter: FilterMode::Nearest,
compare: Some(CompareFunction::LessEqual),
compare: None,
..Default::default()
}),
}
Expand Down
4 changes: 2 additions & 2 deletions pipelined/bevy_pbr2/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl FromWorld for PbrShaders {
binding: 3,
visibility: ShaderStage::FRAGMENT,
ty: BindingType::Sampler {
comparison: true,
comparison: false,
filtering: false,
},
count: None,
Expand All @@ -109,7 +109,7 @@ impl FromWorld for PbrShaders {
binding: 5,
visibility: ShaderStage::FRAGMENT,
ty: BindingType::Sampler {
comparison: true,
comparison: false,
filtering: false,
},
count: None,
Expand Down
33 changes: 20 additions & 13 deletions pipelined/bevy_pbr2/src/render/pbr.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ var lights: Lights;
[[group(0), binding(2)]]
var point_shadow_textures: texture_depth_cube_array;
[[group(0), binding(3)]]
var point_shadow_textures_sampler: sampler_comparison;
var point_shadow_textures_sampler: sampler;
[[group(0), binding(4)]]
var directional_shadow_textures: texture_depth_2d_array;
[[group(0), binding(5)]]
var directional_shadow_textures_sampler: sampler_comparison;
var directional_shadow_textures_sampler: sampler;

[[group(2), binding(0)]]
var material: StandardMaterial;
Expand Down Expand Up @@ -398,13 +398,14 @@ fn fetch_point_shadow(light_id: i32, frag_position: vec4<f32>) -> f32 {
let w = major_axis_magnitude;
let depth = z / w;

// do the lookup, using HW PCF and comparison
// NOTE: Due to the non-uniform control flow above, we must use the Level variant of
// textureSampleCompare to avoid undefined behaviour due to some of the fragments in
// a quad (2x2 fragments) being processed not being sampled, and this messing with
// mip-mapping functionality. The shadow maps have no mipmaps so Level just samples
// from LOD 0.
return textureSampleCompareLevel(point_shadow_textures, point_shadow_textures_sampler, frag_ls, i32(light_id), depth);
let shadow_map_depth = textureSampleLevel(point_shadow_textures, point_shadow_textures_sampler, frag_ls, i32(light_id), 0.0);
var shadow: f32;
if (depth < shadow_map_depth) {
shadow = 1.0;
} else {
shadow = 0.0;
}
return shadow;
}

fn fetch_directional_shadow(light_id: i32, frag_position: vec4<f32>) -> f32 {
Expand All @@ -418,10 +419,16 @@ fn fetch_directional_shadow(light_id: i32, frag_position: vec4<f32>) -> f32 {
let proj_correction = 1.0 / homogeneous_coords.w;
// compute texture coordinates for shadow lookup
let light_local = homogeneous_coords.xy * flip_correction * proj_correction + vec2<f32>(0.5, 0.5);
// do the lookup, using HW PCF and comparison
// NOTE: Due to non-uniform control flow above, we must use the level variant of the texture
// sampler to avoid use of implicit derivatives causing possible undefined behavior.
return textureSampleCompareLevel(directional_shadow_textures, directional_shadow_textures_sampler, light_local, i32(light_id), homogeneous_coords.z * proj_correction);
let depth = homogeneous_coords.z * proj_correction;

let shadow_map_depth = textureSampleLevel(directional_shadow_textures, directional_shadow_textures_sampler, light_local, i32(light_id), 0.0);
var shadow: f32;
if (depth < shadow_map_depth) {
shadow = 1.0;
} else {
shadow = 0.0;
}
return shadow;
}

struct FragmentInput {
Expand Down

0 comments on commit 7df1bab

Please sign in to comment.