[Bf-blender-cvs] [c584116e254] tmp-eevee-shadowmap-refactor: EEVEE: Shadow: Add temporal sampling to shadowmaps

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


Commit: c584116e2545453f44be1c9567e188a565639462
Author: Clément Foucault
Date:   Sun Sep 1 03:16:24 2019 +0200
Branches: tmp-eevee-shadowmap-refactor
https://developer.blender.org/rBc584116e2545453f44be1c9567e188a565639462

EEVEE: Shadow: Add temporal sampling to shadowmaps

If soft shadows is enabled, we randomize the shadowmap sample position
to reduce aliasing artifacts (jagged edge shadows).

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

M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/eevee_sampling.c
M	source/blender/draw/engines/eevee/eevee_shadows_cascade.c
M	source/blender/draw/engines/eevee/eevee_shadows_cube.c

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

diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 7919f4c1fda..613ceda14a7 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -897,6 +897,7 @@ void EEVEE_sample_ellipse(int sample_ofs,
                           float size_x,
                           float size_y,
                           float rsample[3]);
+void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4]);
 
 /* eevee_shaders.c */
 void EEVEE_shaders_lightprobe_shaders_init(void);
diff --git a/source/blender/draw/engines/eevee/eevee_sampling.c b/source/blender/draw/engines/eevee/eevee_sampling.c
index eecaef2c6bb..9d91e000562 100644
--- a/source/blender/draw/engines/eevee/eevee_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_sampling.c
@@ -95,4 +95,17 @@ void EEVEE_sample_ellipse(int sample_ofs,
   zero_v3(rsample);
   madd_v3_v3fl(rsample, x_axis, ht_point[0]);
   madd_v3_v3fl(rsample, y_axis, ht_point[1]);
+}
+
+void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4])
+{
+  double ht_point[3];
+  double ht_offset[3] = {0.0, 0.0, 0.0};
+  uint ht_primes[3] = {2, 3, 5};
+
+  BLI_halton_3d(ht_primes, ht_offset, sample_ofs, ht_point);
+
+  rotate_m4(r_mat, 'X', ht_point[0] * scale);
+  rotate_m4(r_mat, 'Y', ht_point[1] * scale);
+  rotate_m4(r_mat, 'Z', ht_point[2] * scale);
 }
\ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
index b7765901a61..58d3b0c44c0 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
@@ -27,6 +27,8 @@
 
 #include "eevee_private.h"
 
+#include "BLI_rand.h" /* needs to be after for some reason. */
+
 void EEVEE_shadows_cascade_add(EEVEE_LightsInfo *linfo, EEVEE_Light *evli, Object *ob)
 {
   if (linfo->cascade_len >= MAX_SHADOW_CASCADE) {
@@ -138,6 +140,17 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
   float cascade_max_dist = csm_render->cascade_max_dist;
   float cascade_exponent = csm_render->cascade_exponent;
 
+  float jitter_ofs[2];
+  double ht_point[2];
+  double ht_offset[2] = {0.0, 0.0};
+  uint ht_primes[2] = {2, 3};
+
+  BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point);
+
+  /* Not really sure why we need 4.0 factor here. */
+  jitter_ofs[0] = (ht_point[0] * 2.0 - 1.0) * 4.0 / linfo->shadow_cascade_size;
+  jitter_ofs[1] = (ht_point[1] * 2.0 - 1.0) * 4.0 / linfo->shadow_cascade_size;
+
   /* Camera Matrices */
   float persinv[4][4], vp_projmat[4][4];
   DRW_view_persmat_get(view, persinv, true);
@@ -352,6 +365,11 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
                     sh_near,
                     sh_far);
 
+    /* Anti-Aliasing */
+    if (linfo->soft_shadows) {
+      add_v2_v2(projmat[3], jitter_ofs);
+    }
+
     float viewprojmat[4][4];
     mul_m4_m4m4(viewprojmat, projmat, viewmat);
     mul_m4_m4m4(csm_data->shadowmat[c], texcomat, viewprojmat);
diff --git a/source/blender/draw/engines/eevee/eevee_shadows_cube.c b/source/blender/draw/engines/eevee/eevee_shadows_cube.c
index df74e38deb6..423a7cee52d 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows_cube.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows_cube.c
@@ -95,15 +95,16 @@ start:
 }
 
 /* Return true if sample has changed and light needs to be updated. */
-bool EEVEE_shadows_cube_setup(EEVEE_LightsInfo *linfo,
-                                     const EEVEE_Light *evli,
-                                     int sample_ofs)
+bool EEVEE_shadows_cube_setup(EEVEE_LightsInfo *linfo, const EEVEE_Light *evli, int sample_ofs)
 {
   EEVEE_Shadow *shdw_data = linfo->shadow_data + (int)evli->shadow_id;
   EEVEE_ShadowCube *cube_data = linfo->shadow_cube_data + (int)shdw_data->type_data_id;
 
   eevee_light_matrix_get(evli, cube_data->shadowmat);
 
+  shdw_data->far = max_ff(sqrt(1.0f / evli->invsqrdist), 3e-4);
+  shdw_data->near = min_ff(shdw_data->near, shdw_data->far - 1e-4);
+
   bool update = false;
 
   if (linfo->soft_shadows) {
@@ -111,14 +112,26 @@ bool EEVEE_shadows_cube_setup(EEVEE_LightsInfo *linfo,
     /* Update if position changes (avoid infinite update if soft shadows does not move).
      * Other changes are caught by depsgraph tagging. This one is for update between samples. */
     update = !compare_v3v3(cube_data->shadowmat[3], cube_data->position, 1e-10f);
+    /**
+     * Anti-Aliasing jitter: Add random rotation.
+     *
+     * The 2.0 factor is because texel angular size is not even across the cubemap,
+     * so we make the rotation range a bit bigger.
+     * This will not blur the shadow even if the spread is too big since we are just
+     * rotating the shadow cubemap.
+     * Note that this may be a rough approximation an may not converge to a perfectly
+     * smooth shadow (because sample distribution is quite non-uniform) but is enought
+     * in practice.
+     **/
+    /* NOTE: this has implication for spotlight rendering optimization
+     * (see EEVEE_shadows_draw_cubemap). */
+    float angular_texel_size = 2.0f * DEG2RADF(90) / (float)linfo->shadow_cube_size;
+    EEVEE_random_rotation_m4(sample_ofs, angular_texel_size, cube_data->shadowmat);
   }
 
   copy_v3_v3(cube_data->position, cube_data->shadowmat[3]);
   invert_m4(cube_data->shadowmat);
 
-  shdw_data->far = max_ff(sqrt(1.0f / evli->invsqrdist), 3e-4);
-  shdw_data->near = min_ff(shdw_data->near, shdw_data->far - 1e-4);
-
   return update;
 }
 
@@ -175,7 +188,7 @@ void EEVEE_shadows_draw_cubemap(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
   for (int j = 0; j < 6; j++) {
     /* Optimization: Only render the needed faces. */
     /* Skip all but -Z face. */
-    if (evli->light_type == LA_SPOT && j != 5 && evli->spotsize < cosf(DEG2RADF(90.0f) * 0.5f))
+    if (evli->light_type == LA_SPOT && j != 5 && evli->spotsize > cosf(DEG2RADF(90.0f) * 0.5f))
       continue;
     /* Skip +Z face. */
     if (evli->light_type != LA_LOCAL && j == 4)



More information about the Bf-blender-cvs mailing list