Add soft shadows

This commit is contained in:
Lauri Räsänen 2023-11-04 20:24:18 +02:00
parent 6c9fd76c42
commit 61e95cb550
3 changed files with 31 additions and 10 deletions

View file

@ -18,6 +18,8 @@ Controls:
- PBS - PBS
- glTF models - glTF models
- 1 realtime pointlight - 1 realtime pointlight
- Shadow mapping
- Soft shadows
- Simple wgsl preprocessor for includes - Simple wgsl preprocessor for includes
- Runs on WASM and native desktop - Runs on WASM and native desktop
- Tested on: - Tested on:
@ -27,7 +29,6 @@ Controls:
- `Chrome 109.0.5414.120` - `Chrome 109.0.5414.120`
TODO: TODO:
- Shadow mapping
- Transparency - Transparency
- Restructuring - Restructuring
- Simplify/abstract renderpasses; will be nice to have for PP and GI - Simplify/abstract renderpasses; will be nice to have for PP and GI

View file

@ -1,3 +1,6 @@
const PI = 3.14159; const PI = 3.14159;
const INV_SQRT_2 = 0.70710678118654752440; // 1 / sqrt(2) const INV_SQRT_2 = 0.70710678118654752440; // 1 / sqrt(2)
const INV_SQRT_3 = 0.57735026918962576451; // 1 / sqrt(3) const INV_SQRT_3 = 0.57735026918962576451; // 1 / sqrt(3)
const SHADOW_SAMPLES = 8;
const INV_SHADOW_SAMPLES = 1.0 / 8.0;
const SHADOW_SAMPLE_DIST = 0.001;

View file

@ -74,14 +74,29 @@ fn sample_direct_light(index: i32, light_coords: vec4<f32>) -> f32 {
let flip_correction = vec2<f32>(0.5, -0.5); let flip_correction = vec2<f32>(0.5, -0.5);
let proj_correction = 1.0 / light_coords.w; let proj_correction = 1.0 / light_coords.w;
let light_local = light_coords.xy * flip_correction * proj_correction + vec2<f32>(0.5, 0.5); let light_local = light_coords.xy * flip_correction * proj_correction + vec2<f32>(0.5, 0.5);
let reference_depth = light_coords.z * proj_correction;
return textureSampleCompareLevel( var total_sample = 0.0;
t_light_depth, for (var i: i32 = 0; i < SHADOW_SAMPLES; i++) {
s_light_depth, let phase = i % 4;
light_local, var offset = vec2<f32>(f32(i / 4) * SHADOW_SAMPLE_DIST);
index, if (phase == 1 || phase == 3) {
light_coords.z * proj_correction offset.x = -offset.x;
); }
if (phase == 2 || phase == 3) {
offset.y = -offset.y;
}
let s = textureSampleCompareLevel(
t_light_depth,
s_light_depth,
light_local + offset,
index,
reference_depth
);
total_sample += s * INV_SHADOW_SAMPLES;
}
return total_sample;
} }
@fragment @fragment
@ -118,6 +133,8 @@ fn fs_main(vert: VertexOutput) -> @location(0) vec4<f32> {
} }
in_light = sample_direct_light(i, light_coords); in_light = sample_direct_light(i, light_coords);
// TODO should break even if 0 since we're inside frustum.
// See if causes issues with bias overlap between directions.
if (in_light > 0.0) { if (in_light > 0.0) {
break; break;
} }
@ -138,7 +155,7 @@ fn fs_main(vert: VertexOutput) -> @location(0) vec4<f32> {
// radiance // radiance
let radiance_strength = max(dot(normal_dir, light_dir), 0.0); let radiance_strength = max(dot(normal_dir, light_dir), 0.0);
let radiance = radiance_strength * light.color.xyz * light.color.w * light_attenuation; let radiance = radiance_strength * light.color.xyz * light.color.w * light_attenuation * in_light;
// brdf shading // brdf shading
total_radiance += radiance * brdf( total_radiance += radiance * brdf(