Refactor shadowmap sampling in shaders
This commit is contained in:
parent
90ba17a9a9
commit
17fd7a5ec4
3 changed files with 35 additions and 63 deletions
|
@ -107,40 +107,12 @@ fn fs_main(vert: FogVertexOutput) -> @location(0) vec4<f32> {
|
||||||
let fog_density = dd.x;
|
let fog_density = dd.x;
|
||||||
let fog_depth = dd.y;
|
let fog_depth = dd.y;
|
||||||
|
|
||||||
var in_light = 0.0;
|
|
||||||
if (global_uniforms.use_shadowmaps > 0u) {
|
|
||||||
for (var i: i32 = 0; i < 6; i++) {
|
|
||||||
let light_coords = light.matrices[i] * vert.world_position;
|
|
||||||
let light_dir = normalize(light_coords.xyz);
|
|
||||||
let bias = 0.01;
|
|
||||||
// z can never be smaller than this inside 90 degree frustum
|
|
||||||
if (light_dir.z < INV_SQRT_3 - bias) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// x and y can never be larger than this inside frustum
|
|
||||||
if (abs(light_dir.y) > INV_SQRT_2 + bias) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (abs(light_dir.x) > INV_SQRT_2 + bias) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
in_light = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
var base_color = vec3<f32>(mix(0.5, 0.1, fog_density));
|
var base_color = vec3<f32>(mix(0.5, 0.1, fog_density));
|
||||||
let ambient_strength = 0.04;
|
let ambient_strength = 0.04;
|
||||||
let ambient_color = base_color * ambient_strength;
|
let ambient_color = base_color * ambient_strength;
|
||||||
|
|
||||||
var radiance = vec3<f32>(0.0);
|
var radiance = vec3<f32>(0.0);
|
||||||
|
let in_light = sample_direct_light(vert.world_position);
|
||||||
if (in_light > 0.0) {
|
if (in_light > 0.0) {
|
||||||
// attenuation
|
// attenuation
|
||||||
let fog_position = vert.world_position.xyz + direction * fog_depth;
|
let fog_position = vert.world_position.xyz + direction * fog_depth;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
fn sample_direct_light(index: i32, light_coords: vec4<f32>) -> f32 {
|
fn sample_direct_light_index(index: i32, light_coords: vec4<f32>) -> f32 {
|
||||||
if (light_coords.w <= 0.0) {
|
if (light_coords.w <= 0.0) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
@ -27,3 +27,35 @@ fn sample_direct_light(index: i32, light_coords: vec4<f32>) -> f32 {
|
||||||
|
|
||||||
return total_sample;
|
return total_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sample_direct_light(world_position: vec4<f32>) -> f32 {
|
||||||
|
var in_light = 0.0;
|
||||||
|
if (global_uniforms.use_shadowmaps > 0u) {
|
||||||
|
for (var i: i32 = 0; i < 6; i++) {
|
||||||
|
let light_coords = light.matrices[i] * world_position;
|
||||||
|
let light_dir = normalize(light_coords.xyz);
|
||||||
|
let bias = 0.01;
|
||||||
|
// z can never be smaller than this inside 90 degree frustum
|
||||||
|
if (light_dir.z < INV_SQRT_3 - bias) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// x and y can never be larger than this inside frustum
|
||||||
|
if (abs(light_dir.y) > INV_SQRT_2 + bias) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (abs(light_dir.x) > INV_SQRT_2 + bias) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
in_light = sample_direct_light_index(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) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
in_light = 1.0;
|
||||||
|
}
|
||||||
|
return in_light;
|
||||||
|
}
|
||||||
|
|
|
@ -82,39 +82,7 @@ fn fs_main(vert: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
|
|
||||||
var total_radiance: vec3<f32>;
|
var total_radiance: vec3<f32>;
|
||||||
|
|
||||||
var in_light = 0.0;
|
let in_light = sample_direct_light(vert.world_position);
|
||||||
|
|
||||||
// Depth sampling is broken in WebGL...
|
|
||||||
// TODO: remove once WebGPU
|
|
||||||
if (global_uniforms.use_shadowmaps > 0u) {
|
|
||||||
for (var i: i32 = 0; i < 6; i++) {
|
|
||||||
let light_coords = light.matrices[i] * vert.world_position;
|
|
||||||
|
|
||||||
let light_dir = normalize(light_coords.xyz);
|
|
||||||
let bias = 0.01;
|
|
||||||
// z can never be smaller than this inside 90 degree frustum
|
|
||||||
if (light_dir.z < INV_SQRT_3 - bias) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// x and y can never be larger than this inside frustum
|
|
||||||
if (abs(light_dir.y) > INV_SQRT_2 + bias) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (abs(light_dir.x) > INV_SQRT_2 + bias) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
in_light = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_light > 0.0) {
|
if (in_light > 0.0) {
|
||||||
// lighting vecs
|
// lighting vecs
|
||||||
let normal_dir = object_normal.xyz * 2.0 - 1.0;
|
let normal_dir = object_normal.xyz * 2.0 - 1.0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue