Commit: 36a3a40033298227cfc55f59580e03863c09699d
Author: Clément Foucault
Date:   Sun Nov 11 17:45:29 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB36a3a40033298227cfc55f59580e03863c09699d

Eevee: Fix ESM not working after a certain distance

This was caused by overflow caused by the background and precision during
filtering.

===================================================================

M       source/blender/draw/engines/eevee/eevee_lights.c
M       source/blender/draw/engines/eevee/eevee_private.h
M       source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl
M       source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl

===================================================================

diff --git a/source/blender/draw/engines/eevee/eevee_lights.c 
b/source/blender/draw/engines/eevee/eevee_lights.c
index 83fd1bf68cc..02667bf7087 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -1241,6 +1241,7 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, 
EEVEE_Data *vedata)
                copy_v3_v3(srd->position, cube_data->position);
 
                srd->stored_texel_size = 1.0 / 
(float)linfo->shadow_cube_store_size;
+               srd->exponent = la->bleedexp;
 
                DRW_uniformbuffer_update(sldata->shadow_render_ubo, srd);
 
diff --git a/source/blender/draw/engines/eevee/eevee_private.h 
b/source/blender/draw/engines/eevee/eevee_private.h
index 1c04dc81aad..a07f6f05f45 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -384,6 +384,7 @@ typedef struct EEVEE_ShadowRender {
        float clip_far;
        int shadow_samples_len;
        float shadow_samples_len_inv;
+       float exponent;
 } EEVEE_ShadowRender;
 
 /* This is just a really long bitflag with special function to access it. */
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl 
b/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl
index 4ae22b480f1..3ac214bfde2 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl
@@ -9,6 +9,7 @@ layout(std140) uniform shadow_render_block {
        float farClip;
        int shadowSampleCount;
        float shadowInvSampleCount;
+       float exponent;
 };
 
 #ifdef CSM
@@ -22,40 +23,28 @@ uniform float shadowFilterSize;
 
 out vec4 FragColor;
 
-float linear_depth(float z)
-{
-       return (nearClip  * farClip) / (z * (nearClip - farClip) + farClip);
-}
+#define linear_depth(z) ((nearClip  * farClip) / (clamp(z, 0.0, 0.999999) * 
(nearClip - farClip) + farClip))
 
-vec4 linear_depth(vec4 z)
-{
-       return (nearClip  * farClip) / (z * (nearClip - farClip) + farClip);
-}
+/* add bias so background filtering does not bleed into shadow map */
+#define BACKGROUND_BIAS 0.05
 
 #ifdef CSM
 vec4 get_world_distance(vec4 depths, vec3 cos[4])
 {
-       /* Background case */
-       vec4 is_background = step(vec4(0.99999), depths);
-       depths *= abs(farClip - nearClip); /* Same factor as in 
shadow_cascade(). */
-       depths += 1e1 * is_background;
-       return depths;
+       depths += step(vec4(0.9999), depths) * BACKGROUND_BIAS;
+       return clamp(depths * abs(farClip - nearClip), 0.0, 1e10); /* Same 
factor as in shadow_cascade(). */
 }
 
 float get_world_distance(float depth, vec3 cos)
 {
-       /* Background case */
-       float is_background = step(0.9999, depth);
-       depth *= abs(farClip - nearClip); /* Same factor as in 
shadow_cascade(). */
-       depth += 1e1 * is_background;
-       return depth;
+       depth += step(0.9999, depth) * BACKGROUND_BIAS;
+       return clamp(depth * abs(farClip - nearClip), 0.0, 1e10); /* Same 
factor as in shadow_cascade(). */
 }
+
 #else /* CUBEMAP */
 vec4 get_world_distance(vec4 depths, vec3 cos[4])
 {
-       vec4 is_background = step(vec4(1.0), depths);
        depths = linear_depth(depths);
-       depths += vec4(1e1) * is_background;
        cos[0] = normalize(abs(cos[0]));
        cos[1] = normalize(abs(cos[1]));
        cos[2] = normalize(abs(cos[2]));
@@ -70,9 +59,7 @@ vec4 get_world_distance(vec4 depths, vec3 cos[4])
 
 float get_world_distance(float depth, vec3 cos)
 {
-       float is_background = step(1.0, depth);
        depth = linear_depth(depth);
-       depth += 1e1 * is_background;
        cos = normalize(abs(cos));
        float cos_vec = max(cos.x, max(cos.y, cos.z));
        return depth / cos_vec;
@@ -80,23 +67,18 @@ float get_world_distance(float depth, vec3 cos)
 #endif
 
 /* 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));
-}
+#define ln_space_prefilter_step(ref, sample) exp(sample - ref)
+#define ln_space_prefilter_finalize(ref, sum) (ref + log(SAMPLE_WEIGHT * sum))
 
 #define SAMPLE_WEIGHT 0.11111
 
 #ifdef ESM
-void prefilter(vec4 depths, inout float accum)
+void prefilter(vec4 depths, float ref, inout float accum)
 {
-       accum = ln_space_prefilter(1.0, accum, SAMPLE_WEIGHT, depths.x);
-       accum = ln_space_prefilter(1.0, accum, SAMPLE_WEIGHT, depths.y);
-       accum = ln_space_prefilter(1.0, accum, SAMPLE_WEIGHT, depths.z);
-       accum = ln_space_prefilter(1.0, accum, SAMPLE_WEIGHT, depths.w);
+       accum += dot(ln_space_prefilter_step(ref, depths), vec4(1.0));
 }
 #else /* VSM */
-void prefilter(vec4 depths, inout vec2 accum)
+void prefilter(vec4 depths, float ref, inout vec2 accum)
 {
        vec4 depths_sqr = depths * depths;
        accum += vec2(dot(vec4(1.0), depths), dot(vec4(1.0), depths_sqr)) * 
SAMPLE_WEIGHT;
@@ -168,8 +150,10 @@ void main() {
        }
 
 #ifdef ESM
-       float accum = ln_space_prefilter(0.0, 0.0, SAMPLE_WEIGHT, depth);
+       float accum = 1.0;
+       float ref = depth;
 #else /* VSM */
+       float ref = 0.0; /* UNUSED */
        vec2 accum = vec2(depth, depth * depth) * SAMPLE_WEIGHT;
 #endif
 
@@ -191,7 +175,7 @@ void main() {
        depths.z = texture(shadowTexture, cos[2]).r;
        depths.w = texture(shadowTexture, cos[3]).r;
        depths = get_world_distance(depths, cos);
-       prefilter(depths, accum);
+       prefilter(depths, ref, accum);
 
        cos[0] = get_texco(uvs, ofs.xy);
        cos[1] = get_texco(uvs, ofs.zx);
@@ -202,7 +186,11 @@ void main() {
        depths.z = texture(shadowTexture, cos[2]).r;
        depths.w = texture(shadowTexture, cos[3]).r;
        depths = get_world_distance(depths, cos);
-       prefilter(depths, accum);
+       prefilter(depths, ref, accum);
+
+#ifdef ESM
+       accum = ln_space_prefilter_finalize(ref, accum);
+#endif
 
        FragColor = vec2(accum).xyxy;
 }
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 d5ac821c3fa..cb7b2b0312a 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
@@ -7,6 +7,7 @@ layout(std140) uniform shadow_render_block {
        float farClip;
        int shadowSampleCount;
        float shadowInvSampleCount;
+       float exponent;
 };
 
 #ifdef CSM
@@ -34,15 +35,9 @@ vec3 octahedral_to_cubemap_proj(vec2 co)
 }
 
 /* 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));
-}
-
-vec4 ln_space_prefilter(float w0, vec4 x, float w1, vec4 y)
-{
-    return x + log(w0 + w1 * exp(y - x));
-}
+/* 
http://advances.realtimerendering.com/s2009/SIGGRAPH%202009%20-%20Lighting%20Research%20at%20Bungie.pdf
 Slide 55*/
+#define ln_space_prefilter_step(ref, sample) exp(sample - ref)
+#define ln_space_prefilter_finalize(ref, sum) (ref + log(shadowInvSampleCount 
* sum))
 
 #ifdef CSM
 vec3 get_texco(vec3 cos, const vec2 ofs)
@@ -73,6 +68,7 @@ vec3 get_texco(vec3 cos, const vec2 ofs)
 void grouped_samples_accum(
                vec3 cos,
                const vec2 co1, const vec2 co2, const vec2 co3, const vec2 co4,
+               float ref,
                inout vec4 accum)
 {
        vec4 depths;
@@ -81,12 +77,13 @@ void grouped_samples_accum(
        depths.z = texture(shadowTexture, get_texco(cos, co3)).r;
        depths.w = texture(shadowTexture, get_texco(cos, co4)).r;
 
-       accum = ln_space_prefilter(1.0, accum, shadowInvSampleCount, depths);
+       accum += ln_space_prefilter_step(ref, depths);
 }
 #else /* VSM */
 void grouped_samples_accum(
                vec3 cos,
                const vec2 co1, const vec2 co2, const vec2 co3, const vec2 co4,
+               float ref,
                inout vec2 accum)
 {
        vec4 depths1, depths2;
@@ -134,17 +131,18 @@ void main() {
 
 #ifdef ESM
        /* disc blur in log space. */
-       vec4 accum = vec4(0.0);
        vec4 depths;
        depths.x = texture(shadowTexture, get_texco(cos, concentric[0])).r;
        depths.y = texture(shadowTexture, get_texco(cos, concentric[1])).r;
        depths.z = texture(shadowTexture, get_texco(cos, concentric[2])).r;
        depths.w = texture(shadowTexture, get_texco(cos, concentric[3])).r;
-       accum = ln_space_prefilter(0.0, accum, shadowInvSampleCount, depths);
+       float ref = depths.x;
+       vec4 accum = ln_space_prefilter_step(ref, depths);
 
 #else /* VSM */
+       float ref = 0.0; /* UNUSED */
        vec2 accum = vec2(0.0);
-       grouped_samples_accum(cos, concentric[0], concentric[1], concentric[2], 
concentric[3], accum);
+       grouped_samples_accum(cos, concentric[0], concentric[1], concentric[2], 
concentric[3], ref, accum);
 #endif
 
        /**
@@ -154,89 +152,88 @@ void main() {
         * The solution is to use constant indices to access the array.
         */
        if (shadowSampleCount > 4) {
-               grouped_samples_accum(cos, concentric[4], concentric[5], 
concentric[6], concentric[7], accum);
-               grouped_samples_accum(cos, concentric[8], concentric[9], 
concentric[10], concentric[11], accum);
-               grouped_samples_accum(cos, concentric[12], concentric[13], 
concentric[14], concentric[15], accum);
+               grouped_samples_accum(cos, concentric[4], concentric[5], 
concentric[6], concentric[7], ref, accum);
+               grouped_samples_accum(cos, concentric[8], concentric[9], 
concentric[10], concentric[11], ref, accum);
+               grouped_samples_accum(cos, concentric[12], concentric[13], 
concentric[14], concentric[15], ref, accum);
        }
        if (shadowSampleCount > 16) {
-               grouped_samples_accum(cos, concentric[16], concentric[17], 
concentric[18], concentric[19], accum);
-               grouped_samples_accum(cos, concentric[20], concentric[21], 
concentric[22], concentric[23], accum);
-               grouped_samples_accum(cos, concentric[24], concentric[25], 
concentric[26], concentric[27], accum);
-               grouped_samples_accum(cos, concentric[28], concentric[29], 
concentric[30], concentric[31], accum);
-               grouped_samples_accum(cos, concentric[32], concentric[33], 
concentric[34], concentric[35], accum);
+               grouped_samples_accum(cos, concentric[16], concentric[17], 
concentric[18], concentric[19], ref, accum);
+               grouped_samples_accum(cos, concentric[20], concentric[21], 
concentric[22], concentric[23], ref, accum);
+               grouped_samples_accum(cos, concentric[24], concentric[25], 
concentric[26], concentric[27], ref, accum);
+               grouped_samples_accum(cos, concentric[28], concentric[29], 
concentric[30], concentric[31], ref, accum);
+               grouped_samples_accum(cos, concentric[32], concentric[33], 
concentric[34], concentric[35], ref,

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to