mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 00:49:19 +02:00
use textureGather for shadow PCF
This commit is contained in:
@@ -51,7 +51,6 @@ float calc_shadow()
|
||||
|
||||
|
||||
|
||||
float shadow = 0.0;
|
||||
float bias = 0.00005f * float(cascade + 1U);
|
||||
vec2 texel = vec2(1.0) / vec2(textureSize(shadowmap, 0));
|
||||
//float radius = 1.0; f_light_pos[cascade].w; //0.5 + 2.0 * max(abs(2.0 * coords.x - 1.0), abs(2.0 * coords.y - 1.0));
|
||||
@@ -63,13 +62,43 @@ float calc_shadow()
|
||||
radius = mix(minradius, f_light_pos[cascade+1U].w/f_light_pos[cascade].w, dist_casc);
|
||||
else
|
||||
radius = 0.5;
|
||||
|
||||
|
||||
#if defined(GL_ARB_gpu_shader5) || defined(GL_EXT_gpu_shader5) || __VERSION__ >= 400
|
||||
// Fast path -- replace the original 4x4 grid of individual hardware-PCF
|
||||
// lookups with 4 textureGather() calls. Each gather returns the 4 raw
|
||||
// shadow comparisons of a 2x2 texel footprint, so 4 gathers laid out at
|
||||
// (+-1, +-1) * radius * texel from the sample center cover the same 4x4
|
||||
// sample area as the original kernel; summing all 16 comparisons and
|
||||
// dividing by 16 reproduces the original loop's averaging. The cost on
|
||||
// the TMUs drops from 16 hardware-PCF samples to 4 gathers (the gather
|
||||
// path returns 4 values per fetch where the original needed 4 fetches),
|
||||
// roughly a 4x reduction in shadow-sample work. The only thing dropped
|
||||
// vs. the hardware-PCF path is the implicit bilinear blending inside
|
||||
// each 2x2 footprint -- effectively turning a tent-weighted kernel into
|
||||
// a box-weighted one of the same extent, which is imperceptible in
|
||||
// motion. calc_shadow() is by far the heaviest piece of the lighting
|
||||
// shader, so this is a measurable GPU saving on every shaded fragment.
|
||||
float refz = coords.z + bias;
|
||||
float layer = float(cascade);
|
||||
vec2 off = radius * texel;
|
||||
vec4 g0 = textureGather(shadowmap, vec3(coords.xy + vec2(-off.x, -off.y), layer), refz);
|
||||
vec4 g1 = textureGather(shadowmap, vec3(coords.xy + vec2( off.x, -off.y), layer), refz);
|
||||
vec4 g2 = textureGather(shadowmap, vec3(coords.xy + vec2(-off.x, off.y), layer), refz);
|
||||
vec4 g3 = textureGather(shadowmap, vec3(coords.xy + vec2( off.x, off.y), layer), refz);
|
||||
float shadow = dot(g0 + g1 + g2 + g3, vec4(1.0 / 16.0));
|
||||
return shadow;
|
||||
#else
|
||||
// Fallback for drivers without textureGather on shadow samplers
|
||||
// (notably GLES 3.0 and any 3.3 desktop driver that doesn't expose
|
||||
// GL_ARB_texture_gather). Identical to the previous implementation.
|
||||
float shadow = 0.0;
|
||||
for (float y = -1.5; y <= 1.5; y += 1.0)
|
||||
for (float x = -1.5; x <= 1.5; x += 1.0)
|
||||
shadow += texture(shadowmap, vec4(coords.xy + vec2(x, y) * radius * texel, cascade, coords.z + bias) );
|
||||
shadow /= 16.0;
|
||||
|
||||
return shadow;
|
||||
#endif
|
||||
#else
|
||||
return 0.0;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user