Commit: 1eab858dbc8455d48eebcb896310efa583526207
Author: Clément Foucault
Date: Wed Aug 12 17:02:28 2020 +0200
Branches: blender-v2.90-release
https://developer.blender.org/rB1eab858dbc8455d48eebcb896310efa583526207
EEVEE: Rework deformation motion blur
This change how motion data are indexed inside the ghash.
We follow cycles closely now and use evaluated ID pointers.
By removing the hack, it fixes T78561 (No Motion Blur on linked objects)
===================================================================
M source/blender/draw/engines/eevee/eevee_data.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 b7db6fef918..564e985b601 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -29,6 +29,7 @@
#include "BKE_duplilist.h"
#include "BKE_modifier.h"
+#include "BKE_object.h"
#include "DEG_depsgraph_query.h"
@@ -42,15 +43,20 @@
static void eevee_motion_blur_mesh_data_free(void *val)
{
EEVEE_GeometryMotionData *geom_mb = (EEVEE_GeometryMotionData *)val;
+ EEVEE_HairMotionData *hair_mb = (EEVEE_HairMotionData *)val;
switch (geom_mb->type) {
- case EEVEE_HAIR_GEOM_MOTION_DATA:
- for (int i = 0; i < ARRAY_SIZE(geom_mb->vbo); i++) {
- GPU_VERTBUF_DISCARD_SAFE(geom_mb->hair_pos[i]);
- DRW_TEXTURE_FREE_SAFE(geom_mb->hair_pos_tx[i]);
+ case EEVEE_MOTION_DATA_HAIR:
+ for (int j = 0; j < hair_mb->psys_len; j++) {
+ for (int i = 0; i < ARRAY_SIZE(hair_mb->psys[0].hair_pos); i++) {
+ GPU_VERTBUF_DISCARD_SAFE(hair_mb->psys[j].hair_pos[i]);
+ }
+ for (int i = 0; i < ARRAY_SIZE(hair_mb->psys[0].hair_pos); i++) {
+ DRW_TEXTURE_FREE_SAFE(hair_mb->psys[j].hair_pos_tx[i]);
+ }
}
break;
- case EEVEE_MESH_GEOM_MOTION_DATA:
+ case EEVEE_MOTION_DATA_MESH:
for (int i = 0; i < ARRAY_SIZE(geom_mb->vbo); i++) {
GPU_VERTBUF_DISCARD_SAFE(geom_mb->vbo[i]);
}
@@ -148,9 +154,7 @@ EEVEE_ObjectMotionData
*EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *
return ob_step;
}
-static EEVEE_GeometryMotionData
*motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb,
- Object *ob,
- bool hair)
+static void *motion_blur_deform_data_get(EEVEE_MotionBlurData *mb, Object *ob,
bool hair)
{
if (mb->geom == NULL) {
return NULL;
@@ -161,13 +165,29 @@ static EEVEE_GeometryMotionData
*motion_blur_geometry_data_get(EEVEE_MotionBlurD
key = dup->ob;
}
else {
+ key = ob;
+ }
+ /* Only use data for object that have no modifiers. */
+ if (!BKE_object_is_modified(DRW_context_state_get()->scene, ob)) {
key = ob->data;
}
key = (char *)key + (int)hair;
EEVEE_GeometryMotionData *geom_step = BLI_ghash_lookup(mb->geom, key);
if (geom_step == NULL) {
- geom_step = MEM_callocN(sizeof(EEVEE_GeometryMotionData), __func__);
- geom_step->type = hair ? EEVEE_HAIR_GEOM_MOTION_DATA :
EEVEE_MESH_GEOM_MOTION_DATA;
+ if (hair) {
+ EEVEE_HairMotionData *hair_step;
+ /* Ugly, we allocate for each modifiers and just fill based on modifier
index in the list. */
+ int psys_len = (ob->type != OB_HAIR) ?
BLI_listbase_count(&ob->modifiers) : 1;
+ hair_step = MEM_callocN(sizeof(EEVEE_HairMotionData) +
sizeof(hair_step->psys[0]) * psys_len,
+ __func__);
+ hair_step->psys_len = psys_len;
+ geom_step = (EEVEE_GeometryMotionData *)hair_step;
+ geom_step->type = EEVEE_MOTION_DATA_HAIR;
+ }
+ else {
+ geom_step = MEM_callocN(sizeof(EEVEE_GeometryMotionData), __func__);
+ geom_step->type = EEVEE_MOTION_DATA_MESH;
+ }
BLI_ghash_insert(mb->geom, key, geom_step);
}
return geom_step;
@@ -175,12 +195,12 @@ static EEVEE_GeometryMotionData
*motion_blur_geometry_data_get(EEVEE_MotionBlurD
EEVEE_GeometryMotionData
*EEVEE_motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb, Object *ob)
{
- return motion_blur_geometry_data_get(mb, ob, false);
+ return motion_blur_deform_data_get(mb, ob, false);
}
-EEVEE_GeometryMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_MotionBlurData
*mb, Object *ob)
+EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_MotionBlurData
*mb, Object *ob)
{
- return motion_blur_geometry_data_get(mb, ob, true);
+ return motion_blur_deform_data_get(mb, ob, true);
}
/* View Layer data. */
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c
b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index e3dd4252018..a02007fede9 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -289,7 +289,14 @@ void
EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
/* Store transform */
DRW_hair_duplimat_get(ob, psys, md, mb_data->obmat[mb_step]);
- EEVEE_GeometryMotionData *mb_geom =
EEVEE_motion_blur_hair_data_get(&effects->motion_blur, ob);
+ EEVEE_HairMotionData *mb_hair =
EEVEE_motion_blur_hair_data_get(&effects->motion_blur, ob);
+ int psys_id = (md != NULL) ? BLI_findindex(&ob->modifiers, md) : 0;
+
+ if (psys_id >= mb_hair->psys_len) {
+ /* This should never happen. It means the modifier list was changed by
frame evaluation. */
+ BLI_assert(0);
+ return;
+ }
if (mb_step == MB_CURR) {
/* Fill missing matrices if the object was hidden in previous or next
frame. */
@@ -300,18 +307,21 @@ void
EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
copy_m4_m4(mb_data->obmat[MB_NEXT], mb_data->obmat[MB_CURR]);
}
+ GPUTexture *tex_prev = mb_hair->psys[psys_id].hair_pos_tx[MB_PREV];
+ GPUTexture *tex_next = mb_hair->psys[psys_id].hair_pos_tx[MB_NEXT];
+
grp = DRW_shgroup_hair_create_sub(ob, psys, md,
effects->motion_blur.hair_grp);
DRW_shgroup_uniform_mat4(grp, "prevModelMatrix",
mb_data->obmat[MB_PREV]);
DRW_shgroup_uniform_mat4(grp, "currModelMatrix",
mb_data->obmat[MB_CURR]);
DRW_shgroup_uniform_mat4(grp, "nextModelMatrix",
mb_data->obmat[MB_NEXT]);
- DRW_shgroup_uniform_texture(grp, "prvBuffer",
mb_geom->hair_pos_tx[MB_PREV]);
- DRW_shgroup_uniform_texture(grp, "nxtBuffer",
mb_geom->hair_pos_tx[MB_NEXT]);
- DRW_shgroup_uniform_bool(grp, "useDeform", &mb_geom->use_deform, 1);
+ DRW_shgroup_uniform_texture(grp, "prvBuffer", tex_prev);
+ DRW_shgroup_uniform_texture(grp, "nxtBuffer", tex_next);
+ DRW_shgroup_uniform_bool(grp, "useDeform", &mb_hair->use_deform, 1);
}
else {
/* Store vertex position buffer. */
- mb_geom->hair_pos[mb_step] = DRW_hair_pos_buffer_get(ob, psys, md);
- mb_geom->use_deform = true;
+ mb_hair->psys[psys_id].hair_pos[mb_step] = DRW_hair_pos_buffer_get(ob,
psys, md);
+ mb_hair->use_deform = true;
}
}
}
@@ -375,17 +385,6 @@ void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData
*UNUSED(sldata),
}
if (mb_geom->use_deform) {
- EEVEE_ObjectEngineData *oedata = EEVEE_object_data_ensure(ob);
- if (!oedata->geom_update) {
- /* FIXME(fclem) There can be false positive where the actual mesh is
not updated.
- * This avoids a crash but removes the motion blur from some object.
- * Maybe an issue with depsgraph tagging. */
- mb_geom->use_deform = false;
- oedata->geom_update = false;
-
- GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_PREV]);
- GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_NEXT]);
- }
/* Keep to modify later (after init). */
mb_geom->batch = batch;
}
@@ -445,29 +444,36 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata)
BLI_ghashIterator_done(&ghi) == false;
BLI_ghashIterator_step(&ghi)) {
EEVEE_GeometryMotionData *mb_geom = BLI_ghashIterator_getValue(&ghi);
+ EEVEE_HairMotionData *mb_hair = (EEVEE_HairMotionData *)mb_geom;
if (!mb_geom->use_deform) {
continue;
}
switch (mb_geom->type) {
- case EEVEE_HAIR_GEOM_MOTION_DATA:
+ case EEVEE_MOTION_DATA_HAIR:
if (mb_step == MB_CURR) {
/* TODO(fclem) Check if vertex count mismatch. */
- mb_geom->use_deform = true;
+ mb_hair->use_deform = true;
}
else {
- mb_geom->hair_pos[mb_step] =
GPU_vertbuf_duplicate(mb_geom->hair_pos[mb_step]);
+ for (int i = 0; i < mb_hair->psys_len; i++) {
+ if (mb_hair->psys[i].hair_pos[mb_step] == NULL) {
+ continue;
+ }
+ mb_hair->psys[i].hair_pos[mb_step] = GPU_vertbuf_duplicate(
+ mb_hair->psys[i].hair_pos[mb_step]);
- /* Create vbo immediately to bind to texture buffer. */
- GPU_vertbuf_use(mb_geom->hair_pos[mb_step]);
+ /* Create vbo immediately to bind to texture buffer. */
+ GPU_vertbuf_use(mb_hair->psys[i].hair_pos[mb_step]);
- mb_geom->hair_pos_tx[mb_step] = GPU_texture_create_from_vertbuf(
- mb_geom->hair_pos[mb_step]);
+ mb_hair->psys[i].hair_pos_tx[mb_step] =
GPU_texture_create_from_vertbuf(
+ mb_hair->psys[i].hair_pos[mb_step]);
+ }
}
break;
- case EEVEE_MESH_GEOM_MOTION_DATA:
+ case EEVEE_MOTION_DATA_MESH:
if (mb_step == MB_CURR) {
/* Modify batch to have data from adjacent frames. */
GPUBatch *batch = mb_geom->batch;
@@ -549,16 +555,19 @@ void EEVEE_motion_blur_swap_data(EEVEE_Data *vedata)
BLI_ghashIterator_done(&ghi) == false;
BLI_ghashIterator_step(&ghi)) {
EEVEE_GeometryMotionData *mb_geom = BLI_ghashIterator_getValue(&ghi);
+ EEVEE_HairMotionData *mb_hair = (EEVEE_HairMotionData *)mb_geom;
switch (mb_geom->type) {
- case EEVEE_HAIR_GEOM_MOTION_DATA:
- GPU_VERTBUF_DISCARD_SAFE(mb_geom->hair_pos[MB_PREV]);
- DRW_TEXTURE_FREE_SAFE(mb_geom->hair_pos_tx[MB_PREV]);
- mb_geom->hair_pos[MB_PREV] = mb_geom->hair_pos[MB_NEXT];
- mb_geom->hair_pos_tx[MB_PREV] = mb_geom->hair_pos_tx[MB_NEXT];
+ case EEVEE_MOTION_DATA_HAIR:
+ for (int i = 0; i < mb_hair->psys_len; i++) {
+ GPU_VERTBUF_DISCARD_SAFE(mb_hair->psys[i].hair_pos[MB_PREV]);
+ DRW_TEXTURE_FREE_SAFE(mb_hair->psys[i].hair_pos_tx[MB_PREV]);
+ mb_hair->psys[i].hair_pos[MB_PREV] =
mb_hair->psys[i].hair_pos[MB_NEXT];
+ mb_hair->psys[i].hair_pos_tx[MB_PREV] =
mb_hair->psys[i].hair_pos_tx[MB_NEXT];
+ }
break;
- case EEVEE_MESH_GEOM_MOTION_DATA:
+ case E
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs