diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-06-02 21:50:04 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-06-03 01:54:01 +0300 |
commit | 0d52f8daea3b6603db83f41aa97fb137b4c97bcc (patch) | |
tree | e67899497e222d332e7fd96eea8dccfb1496ac32 /source/blender/draw/engines/eevee/shaders | |
parent | 4bd2de2030f5c655256c9108eef53b536768d9be (diff) |
Eevee: Polishing of Exponential Shadow mapping
Added exponent parameter to tweak light bleeding.
Added depth bias to the shadow test.
Added better blurring using 32 samples.
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders')
6 files changed, 66 insertions, 14 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index a9be6ca5478..8963ad2b93e 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -36,13 +36,14 @@ struct LightData { struct ShadowCubeData { - vec4 near_far_bias; + vec4 near_far_bias_exp; }; /* convenience aliases */ -#define sh_cube_near near_far_bias.x -#define sh_cube_far near_far_bias.y -#define sh_cube_bias near_far_bias.z +#define sh_cube_near near_far_bias_exp.x +#define sh_cube_far near_far_bias_exp.y +#define sh_cube_bias near_far_bias_exp.z +#define sh_cube_exp near_far_bias_exp.w struct ShadowMapData { diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index 92069dc37e4..953b087bcd7 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -176,11 +176,11 @@ void light_visibility(LightData ld, ShadingData sd, out float vis) ShadowCubeData scd = shadows_cube_data[int(shid)]; vec3 cubevec = sd.W - ld.l_position; - float dist = length(cubevec); + float dist = length(cubevec) - scd.sh_cube_bias; float z = texture_octahedron(shadowCubes, vec4(cubevec, shid)).r; - float esm_test = min(1.0, exp(-5.0 * dist) * z); + float esm_test = saturate(exp(scd.sh_cube_exp * (z - dist))); float sh_test = step(0, z - dist); vis *= esm_test; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl index 7a8b06e3430..3fc3c146c66 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl @@ -3,6 +3,7 @@ layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; vec4 lampPosition; int layer; + float exponent; }; in vec3 worldPosition; @@ -11,5 +12,5 @@ out vec4 FragColor; void main() { float dist = distance(lampPosition.xyz, worldPosition.xyz); - FragColor = vec4(exp(5.0 * dist), 0.0, 0.0, 1.0); + FragColor = vec4(dist, 0.0, 0.0, 1.0); } diff --git a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl index 4bd2999787b..afc78c4a8f8 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl @@ -3,6 +3,7 @@ layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; vec4 lampPosition; int layer; + float exponent; }; layout(triangles) in; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl index 67bee97fade..40b980b3904 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl @@ -1,4 +1,11 @@ +layout(std140) uniform shadow_render_block { + mat4 ShadowMatrix[6]; + vec4 lampPosition; + int layer; + float exponent; +}; + uniform samplerCube shadowCube; out vec4 FragColor; @@ -24,6 +31,35 @@ void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B) B = cross(N, T); } +#define NUM_SAMPLE 32 +vec2 poisson_disc[32] = vec2[32]( + vec2( 0.476, 0.854), vec2(-0.659, -0.670), + vec2( 0.905, -0.270), vec2( 0.215, -0.133), + vec2(-0.595, 0.242), vec2(-0.146, 0.519), + vec2( 0.108, -0.930), vec2( 0.807, 0.449), + + vec2(-0.476, -0.854), vec2( 0.659, 0.670), + vec2(-0.905, 0.270), vec2(-0.215, 0.133), + vec2( 0.595, -0.242), vec2( 0.146, -0.519), + vec2(-0.108, 0.930), vec2(-0.807, -0.449), + + vec2(-0.854, 0.476), vec2( 0.670, -0.659), + vec2( 0.270, 0.905), vec2( 0.133, 0.215), + vec2(-0.242, -0.595), vec2(-0.519, -0.146), + vec2( 0.930, 0.108), vec2(-0.449, 0.807), + + vec2( 0.854, -0.476), vec2(-0.670, 0.659), + vec2(-0.270, -0.905), vec2(-0.133, -0.215), + vec2( 0.242, 0.595), vec2( 0.519, 0.146), + vec2(-0.930, -0.108), vec2( 0.449, -0.807) +); + +/* Marco Salvi's GDC 2008 presentation about shadow maps pre-filtering techniques slide 24 */ +float ln_space_prefilter(float w0, float x, float w1, float y) +{ + return x + log(w0 + w1 * exp(y - x)); +} + void main() { const vec2 texelSize = vec2(1.0 / 512.0); @@ -52,13 +88,25 @@ void main() { vec3 T, B; make_orthonormal_basis(cubevec, T, B); - vec2 offsetvec = texelSize.xy * vec2(-1.0, 1.0); /* Totally arbitrary */ - /* get cubemap shadow value */ - FragColor = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.x * B).rrrr; - FragColor += texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).rrrr; - FragColor += texture(shadowCube, cubevec + offsetvec.y * T + offsetvec.x * B).rrrr; - FragColor += texture(shadowCube, cubevec + offsetvec.y * T + offsetvec.y * B).rrrr; + const float blur_radius = 5.0 / 512.0; /* Totally arbitrary */ + const float weight = 1.0 / float(NUM_SAMPLE); + float accum = 0.0; + + /* Poisson disc blur in log space. */ + vec2 offsetvec = poisson_disc[0].xy * blur_radius; + float depth1 = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).r; + + offsetvec = poisson_disc[1].xy * blur_radius; + float depth2 = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).r; + + accum = ln_space_prefilter(weight, depth1, weight, depth2); + + for (int i = 2; i < NUM_SAMPLE; ++i) { + vec2 offsetvec = poisson_disc[i].xy * blur_radius; + depth1 = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).r; + accum = ln_space_prefilter(1.0, accum, weight, depth1); + } - FragColor /= 4.0; + FragColor = vec4(accum, accum, accum, 1.0); }
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl index f14354ad4cd..1d456095e02 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl @@ -3,6 +3,7 @@ layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; vec4 lampPosition; int layer; + float exponent; }; layout(triangles) in; |