[Bf-blender-cvs] [9468425524d] tmp-eevee-shadowmap-refactor: Eevee: Shadow: Refactor / Cleanup of shadow update

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


Commit: 9468425524d7e885f88d2663a661503e2a2de4c3
Author: Clément Foucault
Date:   Sat Aug 31 21:47:08 2019 +0200
Branches: tmp-eevee-shadowmap-refactor
https://developer.blender.org/rB9468425524d7e885f88d2663a661503e2a2de4c3

Eevee: Shadow: Refactor / Cleanup of shadow update

- Replace EEVEE_lightbits by BLI_bitmap
- Replace EEVEE_BoundSphere by BoundSphere
- Support for dupli light shadows
- Detect unecessary update of soft shadows (i.e: moving the view)
- Remove Object references

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

M	source/blender/draw/engines/eevee/eevee_data.c
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/effect_translucency_frag.glsl
M	source/blender/draw/engines/eevee/shaders/lights_lib.glsl

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

diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index 8d8019d1e19..dd70ee1bd4b 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -35,7 +35,6 @@ void EEVEE_view_layer_data_free(void *storage)
   MEM_SAFE_FREE(sldata->lights);
   DRW_UBO_FREE_SAFE(sldata->light_ubo);
   DRW_UBO_FREE_SAFE(sldata->shadow_ubo);
-  DRW_UBO_FREE_SAFE(sldata->shadow_render_ubo);
   GPU_FRAMEBUFFER_FREE_SAFE(sldata->shadow_fb);
   DRW_TEXTURE_FREE_SAFE(sldata->shadow_cube_pool);
   DRW_TEXTURE_FREE_SAFE(sldata->shadow_cascade_pool);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 6414da749ea..7ca9790bda6 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -49,6 +49,7 @@ extern char datatoc_common_view_lib_glsl[];
 
 /* Prototypes */
 static void eevee_light_setup(Object *ob, EEVEE_Light *evli);
+static void eevee_contact_shadow_setup(const Light *la, EEVEE_Shadow *evsh);
 static float light_attenuation_radius_get(Light *la, float light_threshold);
 
 /* *********** FUNCTIONS *********** */
@@ -74,7 +75,6 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
     sldata->lights = MEM_callocN(sizeof(EEVEE_LightsInfo), "EEVEE_LightsInfo");
     sldata->light_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL);
     sldata->shadow_ubo = DRW_uniformbuffer_create(shadow_ubo_size, NULL);
-    sldata->shadow_render_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_ShadowRender), NULL);
 
     for (int i = 0; i < 2; ++i) {
       sldata->shcasters_buffers[i].bbox = MEM_callocN(
@@ -130,11 +130,7 @@ void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
   linfo->num_light = 0;
   linfo->num_cube_layer = 0;
   linfo->num_cascade_layer = 0;
-  linfo->gpu_cube_len = linfo->gpu_cascade_len = linfo->gpu_shadow_len = 0;
-  linfo->cpu_cube_len = linfo->cpu_cascade_len = 0;
-  memset(linfo->light_ref, 0, sizeof(linfo->light_ref));
-  memset(linfo->shadow_cube_ref, 0, sizeof(linfo->shadow_cube_ref));
-  memset(linfo->shadow_cascade_ref, 0, sizeof(linfo->shadow_cascade_ref));
+  linfo->cube_len = linfo->cascade_len = linfo->shadow_len = 0;
 
   /* Shadow Casters: Reset flags. */
   BLI_bitmap_set_all(backbuffer->update, true, backbuffer->alloc_count);
@@ -160,14 +156,12 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
 {
   EEVEE_LightsInfo *linfo = sldata->lights;
 
-  const DRWContextState *draw_ctx = DRW_context_state_get();
-  const float threshold = draw_ctx->scene->eevee.light_threshold;
   /* Step 1 find all lights in the scene and setup them */
   if (linfo->num_light >= MAX_LIGHT) {
     printf("Too many lights in the scene !!!\n");
   }
   else {
-    Light *la = (Light *)ob->data;
+    const Light *la = (Light *)ob->data;
 
     /* Early out if light has no power. */
     if (la->energy == 0.0f || is_zero_v3(&la->r)) {
@@ -177,68 +171,65 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
     EEVEE_Light *evli = linfo->light_data + linfo->num_light;
     eevee_light_setup(ob, evli);
 
-    /* We do not support shadowmaps for dupli lights. */
-    if ((ob->base_flag & BASE_FROM_DUPLI) != 0) {
-      linfo->num_light++;
-      return;
-    }
-
-    EEVEE_LightEngineData *led = EEVEE_light_data_ensure(ob);
-
-    /* Default light without shadows */
-    led->data.ld.shadow_id = -1;
-
     if (la->mode & LA_SHADOW) {
       if (la->type == LA_SUN) {
-        int cascade_nbr = la->cascade_count;
+        if (linfo->cascade_len < MAX_SHADOW_CASCADE) {
+          EEVEE_Shadow *sh_data = linfo->shadow_data + linfo->shadow_len;
+          EEVEE_ShadowCascade *csm_data = linfo->shadow_cascade_data + linfo->cascade_len;
+          EEVEE_ShadowCascadeRender *csm_render = linfo->shadow_cascade_render +
+                                                  linfo->cascade_len;
+
+          eevee_contact_shadow_setup(la, sh_data);
+
+          linfo->shadow_cascade_light_indices[linfo->cascade_len] = linfo->num_light;
+          evli->shadow_id = linfo->shadow_len++;
+          sh_data->type_data_id = linfo->cascade_len++;
+          csm_data->tex_id = linfo->num_cascade_layer;
+          csm_render->cascade_fade = la->cascade_fade;
+          csm_render->cascade_count = la->cascade_count;
+          csm_render->cascade_exponent = la->cascade_exponent;
+          csm_render->cascade_max_dist = la->cascade_max_dist;
+
+          linfo->num_cascade_layer += la->cascade_count;
+        }
+      }
+      else if (ELEM(la->type, LA_SPOT, LA_LOCAL, LA_AREA)) {
+        if (linfo->cube_len < MAX_SHADOW_CUBE) {
+          EEVEE_Shadow *sh_data = linfo->shadow_data + linfo->shadow_len;
+
+          /* Always update dupli lights as EEVEE_LightEngineData is not saved.
+           * Same issue with dupli shadow casters. */
+          bool update = (ob->base_flag & BASE_FROM_DUPLI) != 0;
+          if (!update) {
+            EEVEE_LightEngineData *led = EEVEE_light_data_ensure(ob);
+            if (led->need_update) {
+              update = true;
+              led->need_update = false;
+            }
+          }
 
-        if ((linfo->gpu_cascade_len + 1) <= MAX_SHADOW_CASCADE) {
-          /* Save Light object. */
-          linfo->shadow_cascade_ref[linfo->cpu_cascade_len] = ob;
+          if (update) {
+            BLI_BITMAP_ENABLE(&linfo->sh_cube_update[0], linfo->cube_len);
+          }
 
-          /* Store indices. */
-          EEVEE_ShadowCascadeData *data = &led->data.scad;
-          data->shadow_id = linfo->gpu_shadow_len;
-          data->cascade_id = linfo->gpu_cascade_len;
-          data->layer_id = linfo->num_cascade_layer;
+          sh_data->near = max_ff(la->clipsta, 1e-8f);
+          eevee_contact_shadow_setup(la, sh_data);
 
-          /* Increment indices. */
-          linfo->gpu_shadow_len += 1;
-          linfo->gpu_cascade_len += 1;
-          linfo->num_cascade_layer += cascade_nbr;
+          /* Saving light bounds for later. */
+          BoundSphere *cube_bound = linfo->shadow_bounds + linfo->cube_len;
+          copy_v3_v3(cube_bound->center, evli->position);
+          cube_bound->radius = sqrt(1.0f / evli->invsqrdist);
 
-          linfo->cpu_cascade_len += 1;
-        }
-      }
-      else if (la->type == LA_SPOT || la->type == LA_LOCAL || la->type == LA_AREA) {
-        if ((linfo->gpu_cube_len + 1) <= MAX_SHADOW_CUBE) {
-          /* Save Light object. */
-          linfo->shadow_cube_ref[linfo->cpu_cube_len] = ob;
+          linfo->shadow_cube_light_indices[linfo->cube_len] = linfo->num_light;
+          evli->shadow_id = linfo->shadow_len++;
+          sh_data->type_data_id = linfo->cube_len++;
 
-          /* Saving light bounds for later. */
-          BLI_assert(linfo->cpu_cube_len >= 0 && linfo->cpu_cube_len < MAX_LIGHT);
-          copy_v3_v3(linfo->shadow_bounds[linfo->cpu_cube_len].center, ob->obmat[3]);
-          linfo->shadow_bounds[linfo->cpu_cube_len].radius = light_attenuation_radius_get(
-              la, threshold);
-
-          EEVEE_ShadowCubeData *data = &led->data.scd;
-          /* Store indices. */
-          data->shadow_id = linfo->gpu_shadow_len;
-          data->cube_id = linfo->gpu_cube_len;
-          data->layer_id = linfo->num_cube_layer;
-
-          /* Increment indices. */
-          linfo->gpu_shadow_len += 1;
-          linfo->gpu_cube_len += 1;
-          linfo->num_cube_layer += 1;
-
-          linfo->cpu_cube_len += 1;
+          /* Same as linfo->cube_len, no need to save. */
+          linfo->num_cube_layer++;
         }
       }
     }
 
-    led->data.ld.light_id = linfo->num_light;
-    linfo->light_ref[linfo->num_light] = ob;
     linfo->num_light++;
   }
 }
@@ -395,6 +386,14 @@ void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
   EEVEE_lights_update(sldata, vedata);
 }
 
+void eevee_contact_shadow_setup(const Light *la, EEVEE_Shadow *evsh)
+{
+  evsh->contact_dist = (la->mode & LA_SHAD_CONTACT) ? la->contact_dist : 0.0f;
+  evsh->contact_bias = 0.05f * la->contact_bias;
+  evsh->contact_spread = la->contact_spread;
+  evsh->contact_thickness = la->contact_thickness;
+}
+
 float light_attenuation_radius_get(Light *la, float light_threshold)
 {
   if (la->mode & LA_CUSTOM_ATTENUATION) {
@@ -521,7 +520,7 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
   mul_v3_fl(evli->color, power * la->energy);
 
   /* No shadow by default */
-  evli->shadowid = -1.0f;
+  evli->shadow_id = -1.0f;
 }
 
 /**
@@ -590,7 +589,6 @@ static void sample_ellipse(
 }
 
 static void shadow_cube_random_position_set(EEVEE_Light *evli,
-                                            Light *la,
                                             int sample_ofs,
                                             float ws_sample_pos[3])
 {
@@ -601,14 +599,12 @@ static void shadow_cube_random_position_set(EEVEE_Light *evli,
 #else
   for (int i = 0; i <= sample_ofs; ++i) {
 #endif
-  switch (la->type) {
+  switch ((int)evli->light_type) {
     case LA_AREA:
-      if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_SQUARE)) {
-        sample_rectangle(i, evli->rightvec, evli->upvec, evli->sizex, evli->sizey, jitter);
-      }
-      else {
-        sample_ellipse(i, evli->rightvec, evli->upvec, evli->sizex, evli->sizey, jitter);
-      }
+      sample_rectangle(i, evli->rightvec, evli->upvec, evli->sizex, evli->sizey, jitter);
+      break;
+    case (int)LAMPTYPE_AREA_ELLIPSE:
+      sample_ellipse(i, evli->rightvec, evli->upvec, evli->sizex, evli->sizey, jitter);
       break;
     default:
       sample_ball(i, evli->radius, jitter);
@@ -622,40 +618,34 @@ static void shadow_cube_random_position_set(EEVEE_Light *evli,
 add_v3_v3(ws_sample_pos, jitter);
 }
 
-static void eevee_shadow_cube_setup(Object *ob,
-                                    EEVEE_LightsInfo *linfo,
-                                    EEVEE_LightEngineData *led,
-                                    int sample_ofs)
+/* Return true if sample has changed and light needs to be updated. */
+static bool eevee_shadow_cube_setup(

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list