[Bf-blender-cvs] [84575936726] tmp-eevee-shadowmap-refactor: Eevee: Shadows: Add texel border on shadow cube for better edge filtering

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


Commit: 8457593672665e19a55f9fad3ca8958d4f42bbb8
Author: Clément Foucault
Date:   Fri Aug 30 13:08:58 2019 +0200
Branches: tmp-eevee-shadowmap-refactor
https://developer.blender.org/rB8457593672665e19a55f9fad3ca8958d4f42bbb8

Eevee: Shadows: Add texel border on shadow cube for better edge filtering

Unfortunately, this seems to be imprecise on lower cube resolution. But
the result is still most of the time more pleasant than no border filtering.

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

M	source/blender/draw/engines/eevee/eevee_lights.c
M	source/blender/draw/engines/eevee/shaders/lights_lib.glsl

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

diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 76e7340a20f..0f245d4fad7 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -424,8 +424,10 @@ void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
   }
 
   if (!sldata->shadow_cube_pool) {
-    sldata->shadow_cube_pool = DRW_texture_create_2d_array(linfo->shadow_cube_size,
-                                                           linfo->shadow_cube_size,
+    /* TODO shadowcube array. */
+    int cube_size = linfo->shadow_cube_size + ((true) ? 2 : 0);
+    sldata->shadow_cube_pool = DRW_texture_create_2d_array(cube_size,
+                                                           cube_size,
                                                            max_ii(1, linfo->num_cube_layer * 6),
                                                            shadow_pool_format,
                                                            DRW_TEX_FILTER | DRW_TEX_COMPARE,
@@ -1130,13 +1132,21 @@ void EEVEE_lights_update(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
   }
 }
 
-static void eevee_ensure_cube_views(float near,
-                                    float far,
-                                    const float viewmat[4][4],
-                                    DRWView *view[6])
+static void eevee_ensure_cube_views(
+    float near, float far, int cube_res, const float viewmat[4][4], DRWView *view[6])
 {
   float winmat[4][4];
-  perspective_m4(winmat, -near, near, -near, near, near, far);
+  float side = near;
+
+  /* TODO shadowcube array. */
+  if (true) {
+    /* This half texel offset is used to ensure correct filtering between faces. */
+    /* FIXME: This exhibit float precision issue with lower cube_res.
+     * But it seems to be caused by the perspective_m4. */
+    side *= ((float)cube_res + 1.0f) / (float)(cube_res);
+  }
+
+  perspective_m4(winmat, -side, side, -side, side, near, far);
 
   for (int i = 0; i < 6; i++) {
     float tmp[4][4];
@@ -1227,8 +1237,11 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRWView
     srd->clip_near = ubo_data->near;
     srd->clip_far = ubo_data->far;
 
-    eevee_ensure_cube_views(
-        srd->clip_near, srd->clip_far, cube_data->shadowmat, g_data->cube_views);
+    eevee_ensure_cube_views(srd->clip_near,
+                            srd->clip_far,
+                            linfo->shadow_cube_size,
+                            cube_data->shadowmat,
+                            g_data->cube_views);
 
     /* Render shadow cube */
     /* Render 6 faces separately: seems to be faster for the general case.
diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
index d1d01b1db9e..1d2c858d687 100644
--- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
@@ -38,25 +38,43 @@ float cubeFaceIndexEEVEE(vec3 P)
   }
 }
 
-vec2 cubeFaceCoordEEVEE(vec3 P, float face)
+vec2 cubeFaceCoordEEVEE(vec3 P, float face, float scale)
 {
   if (face < 2.0) {
-    return (P.zy / P.x) * vec2(-0.5, -sign(P.x) * 0.5) + 0.5;
+    return (P.zy / P.x) * scale * vec2(-0.5, -sign(P.x) * 0.5) + 0.5;
   }
   else if (face < 4.0) {
-    return (P.xz / P.y) * vec2(sign(P.y) * 0.5, 0.5) + 0.5;
+    return (P.xz / P.y) * scale * vec2(sign(P.y) * 0.5, 0.5) + 0.5;
   }
   else {
-    return (P.xy / P.z) * vec2(0.5, -sign(P.z) * 0.5) + 0.5;
+    return (P.xy / P.z) * scale * vec2(0.5, -sign(P.z) * 0.5) + 0.5;
   }
 }
 
+vec2 cubeFaceCoordEEVEE(vec3 P, float face, sampler2DArray tex)
+{
+  /* Scaling to compensate the 1px border around the face. */
+  float cube_res = float(textureSize(tex, 0).x);
+  float scale = (cube_res) / (cube_res + 1.0);
+  return cubeFaceCoordEEVEE(P, face, scale);
+}
+
+vec2 cubeFaceCoordEEVEE(vec3 P, float face, sampler2DArrayShadow tex)
+{
+  /* Scaling to compensate the 1px border around the face. */
+  float cube_res = float(textureSize(tex, 0).x);
+  float scale = (cube_res) / (cube_res + 1.0);
+  return cubeFaceCoordEEVEE(P, face, scale);
+}
+
 vec4 sample_cube(sampler2DArray tex, vec3 cubevec, float cube)
 {
   /* Manual Shadow Cube Layer indexing. */
   /* TODO Shadow Cube Array. */
   float face = cubeFaceIndexEEVEE(cubevec);
-  vec3 coord = vec3(cubeFaceCoordEEVEE(cubevec, face), cube * 6.0 + face);
+  vec2 uv = cubeFaceCoordEEVEE(cubevec, face, tex);
+
+  vec3 coord = vec3(uv, cube * 6.0 + face);
   return texture(tex, coord);
 }
 
@@ -75,7 +93,7 @@ float sample_cube_shadow(ShadowData sd, ShadowCubeData scd, float texid, vec3 W)
   /* Manual Shadow Cube Layer indexing. */
   /* TODO Shadow Cube Array. */
   float face = cubeFaceIndexEEVEE(cubevec);
-  vec2 coord = cubeFaceCoordEEVEE(cubevec, face);
+  vec2 coord = cubeFaceCoordEEVEE(cubevec, face, shadowCubeTexture);
 
   return texture(shadowCubeTexture, vec4(coord, texid * 6.0 + face, dist));
 }



More information about the Bf-blender-cvs mailing list