[Bf-blender-cvs] [8cd42410c5d] eevee-motionblur-object: EEVEE: Motion Blur: Rework object motion vector rendering

Clément Foucault noreply at git.blender.org
Tue Apr 14 19:09:13 CEST 2020


Commit: 8cd42410c5ded12f3b170549ddb983c88126589e
Author: Clément Foucault
Date:   Sat Apr 4 00:03:00 2020 +0200
Branches: eevee-motionblur-object
https://developer.blender.org/rB8cd42410c5ded12f3b170549ddb983c88126589e

EEVEE: Motion Blur: Rework object motion vector rendering

Object matrices are now stored in a GHash per object, similar to cycles.
The objects surfaces are not split per material anymore.

This approach is not supported for viewport.

This approach is much cleaner and will be able to easily support deforming
motion blur.

This approach also supports instances

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

M	source/blender/draw/engines/eevee/eevee_data.c
M	source/blender/draw/engines/eevee/eevee_engine.c
M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/engines/eevee/eevee_motion_blur.c
M	source/blender/draw/engines/eevee/eevee_private.h

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

diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index 0cdc2de953b..e0fbd04833f 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -24,9 +24,108 @@
 
 #include "DRW_render.h"
 
+#include "BLI_ghash.h"
+
+#include "BKE_anim.h"
+
 #include "eevee_lightcache.h"
 #include "eevee_private.h"
 
+/* Motion Blur data. */
+
+static void eevee_motion_blur_mesh_data_free(void *val)
+{
+  MEM_freeN(val);
+}
+
+static uint eevee_object_key_hash(const void *key)
+{
+  EEVEE_ObjectKey *ob_key = (EEVEE_ObjectKey *)key;
+  uint hash = BLI_ghashutil_ptrhash(ob_key->ob);
+  hash = BLI_ghashutil_combine_hash(hash, BLI_ghashutil_ptrhash(ob_key->parent));
+  for (int i = 0; i < 16; i++) {
+    if (ob_key->id[i] != 0) {
+      hash = BLI_ghashutil_combine_hash(hash, BLI_ghashutil_inthash(ob_key->id[i]));
+    }
+    else {
+      break;
+    }
+  }
+  return hash;
+}
+
+/* Return false if equal. */
+static bool eevee_object_key_cmp(const void *a, const void *b)
+{
+  EEVEE_ObjectKey *key_a = (EEVEE_ObjectKey *)a;
+  EEVEE_ObjectKey *key_b = (EEVEE_ObjectKey *)b;
+
+  if (key_a->ob != key_b->ob) {
+    return true;
+  }
+  if (key_a->parent != key_b->parent) {
+    return true;
+  }
+  if (memcmp(key_a->id, key_b->id, sizeof(key_a->id)) != 0) {
+    return true;
+  }
+  return false;
+}
+
+void EEVEE_motion_blur_data_init(EEVEE_MotionBlurData *mb)
+{
+  if (mb->object == NULL) {
+    mb->object = BLI_ghash_new(eevee_object_key_hash, eevee_object_key_cmp, "EEVEE Object Motion");
+  }
+  if (mb->geom == NULL) {
+    mb->geom = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EEVEE Mesh Motion");
+  }
+}
+
+void EEVEE_motion_blur_data_free(EEVEE_MotionBlurData *mb)
+{
+  if (mb->object) {
+    BLI_ghash_free(mb->object, MEM_freeN, MEM_freeN);
+    mb->object = NULL;
+  }
+  if (mb->geom) {
+    BLI_ghash_free(mb->geom, NULL, eevee_motion_blur_mesh_data_free);
+    mb->geom = NULL;
+  }
+}
+
+EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, Object *ob)
+{
+  if (mb->object == NULL) {
+    return NULL;
+  }
+
+  EEVEE_ObjectKey key, *key_p;
+  key.ob = ob;
+  DupliObject *dup = DRW_object_get_dupli(ob);
+  if (dup) {
+    key.parent = DRW_object_get_dupli_parent(ob);
+    memcpy(key.id, dup->persistent_id, sizeof(key.id));
+  }
+  else {
+    key.parent = key.ob;
+    memset(key.id, 0, sizeof(key.id));
+  }
+
+  EEVEE_ObjectMotionData *ob_step = BLI_ghash_lookup(mb->object, &key);
+  if (ob_step == NULL) {
+    key_p = MEM_mallocN(sizeof(*key_p), __func__);
+    memcpy(key_p, &key, sizeof(*key_p));
+
+    ob_step = MEM_callocN(sizeof(EEVEE_ObjectMotionData), __func__);
+
+    BLI_ghash_insert(mb->object, key_p, ob_step);
+  }
+  return ob_step;
+}
+
+/* View Layer data. */
+
 void EEVEE_view_layer_data_free(void *storage)
 {
   EEVEE_ViewLayerData *sldata = (EEVEE_ViewLayerData *)storage;
@@ -94,8 +193,6 @@ static void eevee_object_data_init(DrawData *dd)
 {
   EEVEE_ObjectEngineData *eevee_data = (EEVEE_ObjectEngineData *)dd;
   eevee_data->shadow_caster_id = -1;
-  eevee_data->curr_time = INT_MIN;
-  eevee_data->prev_time = INT_MIN;
 }
 
 EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob)
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 0e8d25eb554..e68c515e2d8 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -438,6 +438,8 @@ static void eevee_render_to_image(void *vedata,
       return;
     }
 
+    EEVEE_motion_blur_step_set(ved, 0);
+
     DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, EEVEE_render_cache);
 
     RE_engine_frame_set(engine, time, 0.0f);
@@ -457,12 +459,15 @@ static void eevee_render_to_image(void *vedata,
     return;
   }
 
+  EEVEE_motion_blur_step_set(ved, 1);
+
   DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, EEVEE_render_cache);
 
   /* Actually do the rendering. */
   EEVEE_render_draw(vedata, engine, render_layer, rect);
 
   EEVEE_volumes_free_smoke_textures();
+  EEVEE_motion_blur_data_free(&ved->stl->effects->motion_blur);
 }
 
 static void eevee_engine_free(void)
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 98a2c097f19..9bf1bb7e8d2 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -2142,9 +2142,6 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
                 shgrps->material_accum_grp[renderpass_index], ob, mat_geom[i], oedata);
           }
 
-          /* Motion Blur Vectors. */
-          EEVEE_motion_blur_cache_populate(vedata, ob, oedata, mat_geom[i]);
-
           /* Shadow Pass */
           struct GPUMaterial *gpumat;
           const bool use_gpumat = (ma_array[i]->use_nodes && ma_array[i]->nodetree);
@@ -2171,6 +2168,9 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
           }
         }
       }
+
+      /* Motion Blur Vectors. */
+      EEVEE_motion_blur_cache_populate(sldata, vedata, ob);
     }
 
     /* Volumetrics */
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index 982ca3a2e06..13c9198d18f 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -33,6 +33,7 @@
 
 #include "DNA_anim_types.h"
 #include "DNA_camera_types.h"
+#include "DNA_mesh_types.h"
 #include "DNA_screen_types.h"
 
 #include "ED_screen.h"
@@ -94,11 +95,13 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
   const DRWContextState *draw_ctx = DRW_context_state_get();
   Scene *scene = draw_ctx->scene;
 
-  /* Viewport support is experimental. */
-  if (!DRW_state_is_scene_render() && !U.experimental.use_viewport_motion_blur) {
+  /* Viewport not supported for now. */
+  if (!DRW_state_is_scene_render()) {
     return 0;
   }
 
+  effects->motion_blur_step = 0;
+
   if (scene->eevee.flag & SCE_EEVEE_MOTION_BLUR_ENABLED) {
     float ctime = DEG_get_ctime(draw_ctx->depsgraph);
 
@@ -159,6 +162,13 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
   return 0;
 }
 
+void EEVEE_motion_blur_step_set(EEVEE_Data *vedata, int step)
+{
+  /* This might do more things in the future. */
+  BLI_assert(step < MAX_MB_DATA_STEP);
+  vedata->stl->effects->motion_blur_step = step;
+}
+
 void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
 {
   EEVEE_PassList *psl = vedata->psl;
@@ -193,6 +203,8 @@ void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
       DRW_shgroup_uniform_mat4(grp, "currViewProjectionMatrix", effects->current_world_to_ndc);
       DRW_shgroup_uniform_float_copy(grp, "deltaTimeInv", 1.0f / delta_time);
     }
+
+    EEVEE_motion_blur_data_init(&effects->motion_blur);
   }
   else {
     psl->motion_blur = NULL;
@@ -200,43 +212,32 @@ void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
   }
 }
 
-void EEVEE_motion_blur_cache_populate(EEVEE_Data *vedata,
-                                      Object *ob,
-                                      EEVEE_ObjectEngineData *oedata,
-                                      struct GPUBatch *geom)
+void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
+                                      EEVEE_Data *vedata,
+                                      Object *ob)
 {
   EEVEE_PassList *psl = vedata->psl;
   EEVEE_StorageList *stl = vedata->stl;
   EEVEE_EffectsInfo *effects = stl->effects;
   DRWShadingGroup *grp = NULL;
 
-  if ((effects->enabled_effects & EFFECT_MOTION_BLUR) && oedata) {
-    if (oedata->curr_time != effects->current_time) {
-      copy_m4_m4(oedata->prev_matrix, oedata->curr_matrix);
-      oedata->prev_time = oedata->curr_time;
-    }
-    copy_m4_m4(oedata->curr_matrix, ob->obmat);
-    oedata->curr_time = effects->current_time;
-
-    if (oedata->motion_mats_init == false) {
-      /* Disable motion blur if not initialized. */
-      copy_m4_m4(oedata->prev_matrix, oedata->curr_matrix);
-      oedata->prev_time = oedata->curr_time;
-      oedata->motion_mats_init = true;
-    }
+  EEVEE_ObjectMotionData *mbdata = EEVEE_motion_blur_object_data_get(&effects->motion_blur, ob);
+
+  if (mbdata) {
+    /* Store transform  */
+    copy_m4_m4(mbdata->obmat[effects->motion_blur_step], ob->obmat);
+
+    struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
+    /* TODO(fclem) Copy pos vbo and store it in geometry motion steps. */
 
-    float delta_time = oedata->curr_time - oedata->prev_time;
-    if (delta_time != 0.0f) {
+    if (geom && effects->motion_blur_step == MAX_MB_DATA_STEP - 1) {
       grp = DRW_shgroup_create(e_data.motion_blur_object_sh, psl->velocity_object);
-      DRW_shgroup_uniform_mat4(grp, "prevModelMatrix", oedata->prev_matrix);
-      DRW_shgroup_uniform_mat4(grp, "currModelMatrix", oedata->curr_matrix);
-      DRW_shgroup_uniform_float_copy(grp, "deltaTimeInv", 1.0f / delta_time);
+      DRW_shgroup_uniform_mat4(grp, "prevModelMatrix", mbdata->obmat[0]);
+      DRW_shgroup_uniform_mat4(grp, "currModelMatrix", mbdata->obmat[1]);
+
       DRW_shgroup_call(grp, geom, ob);
     }
   }
-  else if (oedata) {
-    oedata->motion_mats_init = false;
-  }
 }
 
 void EEVEE_motion_blur_draw(EEVEE_Data *vedata)
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 81280d1c285..d3f6eaecf28 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -553,6 +553,33 @@ enum {
   PROBE_UPDATE_ALL = 0xFFFFFF,
 };
 
+/* ************** MOTION BLUR ************ */
+
+#define MAX_MB_DATA_STEP 2
+
+typedef struct EEVEE_MotionBlurData {
+  struct GHash *object;
+  struct GHash *geom;
+} EEVEE_MotionBlurData;
+
+typedef struct EEVEE_ObjectKey {
+  /** Object or source object for duplis */
+  struct Object *ob;
+  /** Parent object for

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list