[Bf-blender-cvs] [a77301289dd] tmp-eevee-shadowmap-refactor: Eevee: Shadow: Remove receiver plane bias and use hardware filtering

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


Commit: a77301289ddee926fb34ee03a12dfe6300a5c704
Author: Clément Foucault
Date:   Wed Aug 28 17:42:53 2019 +0200
Branches: tmp-eevee-shadowmap-refactor
https://developer.blender.org/rBa77301289ddee926fb34ee03a12dfe6300a5c704

Eevee: Shadow: Remove receiver plane bias and use hardware filtering

In an attempt to simplify the shadowing in eevee, we remove the bias and
filtering option.

Now the shadowmap always get the minimum constant and slope bias and we
only do a bilinear shadow filtering. This means the shadow is as sharper
and exact as the shadow map format allows (bitdepth and size).

Only the lamp size can change the shadow softness.

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

M	source/blender/draw/engines/eevee/eevee_lights.c
M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/engines/eevee/eevee_subsurface.c
M	source/blender/draw/engines/eevee/shaders/lights_lib.glsl
M	source/blender/draw/intern/draw_manager_exec.c

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

diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 10da80ece54..1cf5650205d 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -428,7 +428,7 @@ void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
                                                            linfo->shadow_cube_size,
                                                            max_ii(1, linfo->num_cube_layer * 6),
                                                            shadow_pool_format,
-                                                           DRW_TEX_FILTER,
+                                                           DRW_TEX_FILTER | DRW_TEX_COMPARE,
                                                            NULL);
   }
 
@@ -437,7 +437,7 @@ void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
                                                               linfo->shadow_cascade_size,
                                                               max_ii(1, linfo->num_cascade_layer),
                                                               shadow_pool_format,
-                                                              DRW_TEX_FILTER,
+                                                              DRW_TEX_FILTER | DRW_TEX_COMPARE,
                                                               NULL);
   }
 
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index af9e2bc67f4..41df16ab22d 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1753,6 +1753,15 @@ void EEVEE_materials_free(void)
 
 void EEVEE_materials_draw_opaque(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
 {
+  /* We sample the shadowmaps using shadow sampler. We need to enable Comparison mode.
+   * TODO(fclem) avoid this by using sampler objects.*/
+  GPU_texture_bind(sldata->shadow_cube_pool, 0);
+  GPU_texture_compare_mode(sldata->shadow_cube_pool, true);
+  GPU_texture_unbind(sldata->shadow_cube_pool);
+  GPU_texture_bind(sldata->shadow_cascade_pool, 0);
+  GPU_texture_compare_mode(sldata->shadow_cascade_pool, true);
+  GPU_texture_unbind(sldata->shadow_cascade_pool);
+
   for (int i = 0; i < VAR_MAT_MAX; ++i) {
     if (psl->default_pass[i]) {
       DRW_draw_pass(psl->default_pass[i]);
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index b31925e8eff..4d29e597dae 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -333,7 +333,7 @@ void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
   }
 }
 
-void EEVEE_subsurface_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
 {
   EEVEE_PassList *psl = vedata->psl;
   EEVEE_StorageList *stl = vedata->stl;
@@ -356,6 +356,15 @@ void EEVEE_subsurface_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
     }
 
     if (!DRW_pass_is_empty(psl->sss_translucency_ps)) {
+      /* We sample the shadowmaps using normal sampler. We need to disable Comparison mode.
+       * TODO(fclem) avoid this by using sampler objects.*/
+      GPU_texture_bind(sldata->shadow_cube_pool, 0);
+      GPU_texture_compare_mode(sldata->shadow_cube_pool, false);
+      GPU_texture_unbind(sldata->shadow_cube_pool);
+      GPU_texture_bind(sldata->shadow_cascade_pool, 0);
+      GPU_texture_compare_mode(sldata->shadow_cascade_pool, false);
+      GPU_texture_unbind(sldata->shadow_cascade_pool);
+
       GPU_framebuffer_bind(fbl->sss_translucency_fb);
       DRW_draw_pass(psl->sss_translucency_ps);
     }
diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
index 5558e2ef074..23bf8b59648 100644
--- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
@@ -1,6 +1,6 @@
 
-uniform sampler2DArray shadowCubeTexture;
-uniform sampler2DArray shadowCascadeTexture;
+uniform sampler2DArrayShadow shadowCubeTexture;
+uniform sampler2DArrayShadow shadowCascadeTexture;
 
 #define LAMPS_LIB
 
@@ -51,19 +51,6 @@ vec2 cubeFaceCoordEEVEE(vec3 P, float face)
   }
 }
 
-float cubeFaceDepthEEVEE(vec3 P, float face)
-{
-  if (face < 2.0) {
-    return abs(P.x);
-  }
-  else if (face < 4.0) {
-    return abs(P.y);
-  }
-  else {
-    return abs(P.z);
-  }
-}
-
 vec4 sample_cube(sampler2DArray tex, vec3 cubevec, float cube)
 {
   /* Manual Shadow Cube Layer indexing. */
@@ -78,168 +65,25 @@ vec4 sample_cascade(sampler2DArray tex, vec2 co, float cascade_id)
   return texture(tex, vec3(co, cascade_id));
 }
 
-/** Convert screenspace derivatives to texture space derivatives.
- * As described by John R. Isidoro in GDC 2006 presentation "Shadow Mapping: GPU-based Tips and
- *Techniques". https://developer.amd.com/wordpress/media/2012/10/Isidoro-ShadowMapping.pdf
- **/
-vec2 texture_space_derivatives(vec3 duvfdx, vec3 duvfdy)
-{
-  /* Invert texture Jacobian and use chain rule to compute ddist/du and ddist/dv
-   *  |ddist/du| = |du/dx  du/dy|-T  * |ddist/dx|
-   *  |ddist/dv|   |dv/dx  dv/dy|      |ddist/dy| */
-
-  /* // Multiply ddist/dx and ddist/dy by inverse transpose of Jacobian
-   * float invDet = 1 / ((duvdist_dx.x * duvdist_dy.y) - (duvdist_dx.y * duvdist_dy.x));
-   * // Top row of 2x2
-   * ddist_duv.x = duvdist_dy.y * duvdist_dx.w;  // invJtrans[0][0] * ddist_dx
-   * ddist_duv.x -= duvdist_dx.y * duvdist_dy.w; // invJtrans[0][1] * ddist_dy
-   * // Bottom row of 2x2
-   * ddist_duv.y = duvdist_dx.x * duvdist_dy.w;  // invJtrans[1][1] * ddist_dy
-   * ddist_duv.y -= duvdist_dy.x * duvdist_dx.w; // invJtrans[1][0] * ddist_dx
-   * ddist_duv *= invDet;
-   **/
-
-  /* Optimized version. */
-  vec2 a = duvfdx.xy * duvfdy.yx;
-  vec4 b = duvfdy.yzzx * duvfdx.zyxz;
-  return (b.xz - b.yw) / (a.x - a.y);
-}
-
-/** Returns Receiver Plane Depth Bias
- * As described by John R. Isidoro in GDC 2006 presentation "Shadow Mapping: GPU-based Tips and
- * Techniques". https://developer.amd.com/wordpress/media/2012/10/Isidoro-ShadowMapping.pdf
- */
-float shadowmap_bias(vec2 co, vec2 tap_co, vec2 dwduv)
-{
-  return dot(tap_co - co, dwduv);
-}
-
-/**
- * Parameters:
- * shadow_tx : shadowmap to sample.
- * co        : the original sample position.
- * ref       : the original depth to test (Depth of the surface in shadowmap space).
- * co_ofs    : the actual offseted sample position.
- * dwduv     : result of texture_space_derivatives().
- **/
-float filtered_and_biased_shadow_test(sampler2DArray shadow_tx,
-                                      vec2 co,
-                                      float layer,
-                                      float ref,
-                                      float max_bias,
-                                      vec2 co_ofs,
-                                      vec2 dwduv)
-{
-  vec4 biases, depths;
-  vec2 texture_size = vec2(textureSize(shadow_tx, 0).xy);
-  vec3 texel_size = vec3(1.0 / texture_size, 0.0);
-  /* Center texel coordinate to match hardware filtering */
-  vec2 texel_uv = co_ofs * texture_size.xy - 0.5;
-  vec2 texel_fract = fract(texel_uv);
-  vec2 texel_floor = (floor(texel_uv) + 0.5) * texel_size.xy;
-  /* Calc bias for each sample */
-  biases.x = shadowmap_bias(co, texel_floor + texel_size.zy, dwduv);
-  biases.y = shadowmap_bias(co, texel_floor + texel_size.xy, dwduv);
-  biases.z = shadowmap_bias(co, texel_floor + texel_size.xz, dwduv);
-  biases.w = shadowmap_bias(co, texel_floor + texel_size.zz, dwduv);
-  /* Gather samples */
-#ifdef GPU_ARB_texture_gather
-  /* Note: To make sure that we get the exact same result we use texel center.
-   * This is because Anisotropic filtering is offsetting the coordinate. */
-  depths = textureGather(shadow_tx, vec3(texel_floor + texel_size.xy * 0.5, layer));
-#else
-  depths.x = texture(shadow_tx, vec3(texel_floor + texel_size.zy, layer)).x;
-  depths.y = texture(shadow_tx, vec3(texel_floor + texel_size.xy, layer)).x;
-  depths.z = texture(shadow_tx, vec3(texel_floor + texel_size.xz, layer)).x;
-  depths.w = texture(shadow_tx, vec3(texel_floor + texel_size.zz, layer)).x;
-#endif
-  /* Take absolute of bias to avoid overshadowing in proximity area.
-   * Also limit the bias in case the geom is almost perpendicular to the shadow source
-   * to avoid light leaking. */
-  vec4 refs = saturate(ref - min(vec4(max_bias), abs(biases)));
-  /* Bilinear PCF. */
-  vec4 tests = step(refs, depths);
-  tests.xy = mix(tests.wz, tests.xy, texel_fract.y);
-  return saturate(mix(tests.x, tests.y, texel_fract.x));
-}
-
-float shadow_cubemap(ShadowData sd, ShadowCubeData scd, float texid, vec3 W)
+float sample_cube_shadow(ShadowData sd, ShadowCubeData scd, float texid, vec3 W)
 {
   vec3 cubevec = W - scd.position.xyz;
 
-#ifndef VOLUMETRICS
-  vec3 rand = texelfetch_noise_tex(gl_FragCoord.xy).zwy;
-  float ofs_len = fast_sqrt(rand.z) * sd.sh_blur * 0.1;
-  vec3 cubevec_nor = normalize(cubevec);
-  vec3 T, B;
-  make_orthonormal_basis(cubevec_nor, T, B);
-  vec3 cubevec_ofs = cubevec_nor + (T * rand.x + B * rand.y) * ofs_len;
-  /* Use face of the offseted cubevec. */
-  float face_id = cubeFaceIndexEEVEE(cubevec_ofs);
-  vec2 uv_ofs = cubeFaceCoordEEVEE(cubevec_ofs, face_id);
-
-  /* To avoid derivatives discontinuity, we compute derivatives
-   * on a smooth linear function (unormalized cubevec),
-   * and manually do the derivative of the uv coords. */
-  vec3 duvwdx, duvwdy;
-  vec3 dPdx = cubevec + dFdx(cubevec);
-  vec3 dPdy = cubevec + dFdy(cubevec);
-  vec2 uv = cubeFaceCoordEEVEE(cubevec, face_id);
-  duvwdx.xy = cubeFaceCoordEEVEE(dPdx, face_id) - uv;
-  duvwdy.xy = cubeFaceCoordEEVEE(dPdy, face_id) - uv;
-
-  float dist = cubeFaceDepthEEVEE(cubevec, face_id);
-  duvwdx.z = cubeFaceDepthEEVEE(dPdx, face_id);
-  duvwdy.z = cubeFaceDepthEEVEE(dPdy, face_id);
-
-  dist = buffer_depth(tru

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list