[Bf-blender-cvs] [585eaa5b0a5] tmp-eevee-shadowmap-refactor: Eevee: Shadows: Improve contact shadows

Clément Foucault noreply at git.blender.org
Mon Sep 2 16:53:26 CEST 2019


Commit: 585eaa5b0a5165d2fba7aed56a05b2b72450873c
Author: Clément Foucault
Date:   Thu Aug 29 19:23:08 2019 +0200
Branches: tmp-eevee-shadowmap-refactor
https://developer.blender.org/rB585eaa5b0a5165d2fba7aed56a05b2b72450873c

Eevee: Shadows: Improve contact shadows

Contact shadows now follow the shadowmap direction. This means it matches
the shadowmap blur that is proportional to the light radius.

Moreover this adds a more efficient bias for most contact shadows.

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

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/bsdf_common_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lights_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
M	source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl

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

diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 1cf5650205d..777cda4c00e 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -817,6 +817,8 @@ static void eevee_shadow_cascade_setup(Object *ob,
   copy_m4_m4(sh_data->viewinv, viewmat);
   invert_m4(viewmat);
 
+  copy_v3_v3(cascade_data->shadow_vec, sh_data->viewinv[2]);
+
   /* Compute near and far value based on all shadow casters cumulated AABBs. */
   float sh_near = -1.0e30f, sh_far = 1.0e30f;
   BoundBox shcaster_bounds;
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index ce0c4033987..a7fe5a7a9b9 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -388,6 +388,7 @@ typedef struct EEVEE_ShadowCascade {
   float shadowmat[MAX_CASCADE_NUM][4][4];
   float split_start[4];
   float split_end[4];
+  float shadow_vec[3], _pad[1];
 } EEVEE_ShadowCascade;
 
 typedef struct EEVEE_ShadowRender {
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 c3169f4635f..f6a4fabe883 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -69,6 +69,7 @@ struct ShadowCascadeData {
   mat4 shadowmat[MAX_CASCADE_NUM];
   vec4 split_start_distances;
   vec4 split_end_distances;
+  vec4 shadow_vec;
 };
 
 /* convenience aliases */
diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
index 9c1038cee6a..4ce3266f634 100644
--- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
@@ -152,7 +152,9 @@ float light_visibility(LightData ld,
                        vec3 W,
 #ifndef VOLUMETRICS
                        vec3 viewPosition,
-                       vec3 vN,
+                       float tracing_depth,
+                       vec3 true_normal,
+                       float rand_x,
 #endif
                        vec4 l_vector)
 {
@@ -174,52 +176,35 @@ float light_visibility(LightData ld,
 #  ifndef VOLUMETRICS
     /* Only compute if not already in shadow. */
     if (data.sh_contact_dist > 0.0) {
-      vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0);
-      float trace_distance = (ld.l_type != SUN) ? min(data.sh_contact_dist, l_vector.w) :
-                                                  data.sh_contact_dist;
+      /* Contact Shadows. */
+      vec3 ray_ori, ray_dir;
+      float trace_distance;
 
-      vec3 T, B;
-      make_orthonormal_basis(L.xyz / L.w, T, B);
-
-      vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
-      rand.zw *= fast_sqrt(rand.y) * data.sh_contact_spread;
-
-      /* We use the full l_vector.xyz so that the spread is minimize
-       * if the shading point is further away from the light source */
-      vec3 ray_dir = L.xyz + T * rand.z + B * rand.w;
-      ray_dir = transform_direction(ViewMatrix, ray_dir);
-      ray_dir = normalize(ray_dir);
-
-      vec3 ray_ori = viewPosition;
-
-      /* Fix translucency shadowed by contact shadows. */
-      vN = (gl_FrontFacing) ? vN : -vN;
-
-      if (dot(vN, ray_dir) <= 0.0) {
-        return vis;
+      if (ld.l_type == SUN) {
+        trace_distance = data.sh_contact_dist;
+        ray_dir = shadows_cascade_data[int(data.sh_data_start)].shadow_vec.xyz * trace_distance;
+      }
+      else {
+        ray_dir = shadows_cube_data[int(data.sh_data_start)].position.xyz - W;
+        float len = length(ray_dir);
+        trace_distance = min(data.sh_contact_dist, len);
+        ray_dir *= trace_distance / len;
       }
 
-      float bias = 0.5;                    /* Constant Bias */
-      bias += 1.0 - abs(dot(vN, ray_dir)); /* Angle dependent bias */
-      bias *= gl_FrontFacing ? data.sh_contact_offset : -data.sh_contact_offset;
-
-      vec3 nor_bias = vN * bias;
-      ray_ori += nor_bias;
-
-      ray_dir *= trace_distance;
-      ray_dir -= nor_bias;
+      ray_dir = transform_direction(ViewMatrix, ray_dir);
+      ray_ori = vec3(viewPosition.xy, tracing_depth) + true_normal * data.sh_contact_offset;
 
       vec3 hit_pos = raycast(
-          -1, ray_ori, ray_dir, data.sh_contact_thickness, rand.x, 0.1, 0.001, false);
+          -1, ray_ori, ray_dir, data.sh_contact_thickness, rand_x, 0.1, 0.001, false);
 
       if (hit_pos.z > 0.0) {
         hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z);
         float hit_dist = distance(viewPosition, hit_pos);
         float dist_ratio = hit_dist / trace_distance;
-        return vis * saturate(dist_ratio * dist_ratio * dist_ratio);
+        return vis * saturate(dist_ratio * 3.0 - 2.0);
       }
     }
-#  endif
+#  endif /* VOLUMETRICS */
   }
 #endif
 
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 b2bccb5d24b..7c0c4cf8fa0 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -222,6 +222,16 @@ void CLOSURE_NAME(vec3 N
   vec3 out_spec_clear = vec3(0.0);
 #  endif
 
+  float tracing_depth = gl_FragCoord.z;
+  /* Constant bias (due to depth buffer precision) */
+  /* Magic numbers for 24bits of precision.
+   * From http://terathon.com/gdc07_lengyel.pdf (slide 26) */
+  tracing_depth -= mix(2.4e-7, 4.8e-7, gl_FragCoord.z);
+  /* Convert to view Z. */
+  tracing_depth = get_view_z_from_depth(tracing_depth);
+
+  vec3 true_normal = normalize(cross(dFdx(viewPosition), dFdy(viewPosition)));
+
   for (int i = 0; i < MAX_LIGHT && i < laNumLight; ++i) {
     LightData ld = lights_data[i];
 
@@ -229,7 +239,8 @@ void CLOSURE_NAME(vec3 N
     l_vector.xyz = ld.l_position - worldPosition;
     l_vector.w = length(l_vector.xyz);
 
-    float l_vis = light_visibility(ld, worldPosition, viewPosition, viewNormal, l_vector);
+    float l_vis = light_visibility(
+        ld, worldPosition, viewPosition, tracing_depth, true_normal, rand.x, l_vector);
 
     if (l_vis < 1e-8) {
       continue;
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index 14e0c947b47..f88cfdf3787 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -120,7 +120,8 @@ void prepare_raycast(vec3 ray_origin,
   ss_ray = ss_start * m.xyyy + 0.5;
   ss_step *= m.xyyy;
 
-  ss_ray.xy += m * ssrPixelSize * 2.0; /* take the center of the texel. * 2 because halfres. */
+  /* take the center of the texel. */
+  // ss_ray.xy += sign(ss_ray.xy) * m * ssrPixelSize * (1.0 + hizMipOffset);
 }
 
 /* See times_and_deltas. */



More information about the Bf-blender-cvs mailing list