Merge branch 'blender-v3.1-release'
This commit is contained in:
commit
64293a277f
|
@ -27,25 +27,12 @@
|
|||
|
||||
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_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_MOTION_DATA_MESH:
|
||||
for (int i = 0; i < ARRAY_SIZE(geom_mb->vbo); i++) {
|
||||
GPU_VERTBUF_DISCARD_SAFE(geom_mb->vbo[i]);
|
||||
}
|
||||
break;
|
||||
EEVEE_ObjectMotionData *mb_data = (EEVEE_ObjectMotionData *)val;
|
||||
if (mb_data->hair_data != NULL) {
|
||||
MEM_freeN(mb_data->hair_data);
|
||||
}
|
||||
if (mb_data->geometry_data != NULL) {
|
||||
MEM_freeN(mb_data->geometry_data);
|
||||
}
|
||||
MEM_freeN(val);
|
||||
}
|
||||
|
@ -84,39 +71,57 @@ static bool eevee_object_key_cmp(const void *a, const void *b)
|
|||
return false;
|
||||
}
|
||||
|
||||
void EEVEE_motion_hair_step_free(EEVEE_HairMotionStepData *step_data)
|
||||
{
|
||||
GPU_vertbuf_discard(step_data->hair_pos);
|
||||
DRW_texture_free(step_data->hair_pos_tx);
|
||||
MEM_freeN(step_data);
|
||||
}
|
||||
|
||||
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");
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (mb->position_vbo_cache[i] == NULL) {
|
||||
mb->position_vbo_cache[i] = BLI_ghash_new(
|
||||
BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EEVEE duplicate vbo cache");
|
||||
}
|
||||
if (mb->hair_motion_step_cache[i] == NULL) {
|
||||
mb->hair_motion_step_cache[i] = BLI_ghash_new(
|
||||
BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EEVEE hair motion step cache");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EEVEE_motion_blur_data_free(EEVEE_MotionBlurData *mb)
|
||||
{
|
||||
if (mb->object) {
|
||||
BLI_ghash_free(mb->object, MEM_freeN, MEM_freeN);
|
||||
BLI_ghash_free(mb->object, MEM_freeN, eevee_motion_blur_mesh_data_free);
|
||||
mb->object = NULL;
|
||||
}
|
||||
if (mb->geom) {
|
||||
BLI_ghash_free(mb->geom, NULL, eevee_motion_blur_mesh_data_free);
|
||||
mb->geom = NULL;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (mb->position_vbo_cache[i]) {
|
||||
BLI_ghash_free(mb->position_vbo_cache[i], NULL, (GHashValFreeFP)GPU_vertbuf_discard);
|
||||
}
|
||||
if (mb->hair_motion_step_cache[i]) {
|
||||
BLI_ghash_free(
|
||||
mb->hair_motion_step_cache[i], NULL, (GHashValFreeFP)EEVEE_motion_hair_step_free);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb,
|
||||
Object *ob,
|
||||
bool hair)
|
||||
EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, Object *ob)
|
||||
{
|
||||
if (mb->object == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EEVEE_ObjectKey key, *key_p;
|
||||
/* Small hack to avoid another comparison. */
|
||||
key.ob = (Object *)((char *)ob + hair);
|
||||
/* Assumes that all instances have the same object pointer. This is currently the case because
|
||||
* instance objects are temporary objects on the stack. */
|
||||
key.ob = ob;
|
||||
DupliObject *dup = DRW_object_get_dupli(ob);
|
||||
if (dup) {
|
||||
key.parent = DRW_object_get_dupli_parent(ob);
|
||||
|
@ -139,53 +144,28 @@ EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *
|
|||
return ob_step;
|
||||
}
|
||||
|
||||
static void *motion_blur_deform_data_get(EEVEE_MotionBlurData *mb, Object *ob, bool hair)
|
||||
EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_ObjectMotionData *mb_data)
|
||||
{
|
||||
if (mb->geom == NULL) {
|
||||
return NULL;
|
||||
if (mb_data->geometry_data == NULL) {
|
||||
EEVEE_GeometryMotionData *geom_step = MEM_callocN(sizeof(EEVEE_GeometryMotionData), __func__);
|
||||
geom_step->type = EEVEE_MOTION_DATA_MESH;
|
||||
mb_data->geometry_data = geom_step;
|
||||
}
|
||||
DupliObject *dup = DRW_object_get_dupli(ob);
|
||||
void *key;
|
||||
if (dup) {
|
||||
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) {
|
||||
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_CURVES) ? 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;
|
||||
return mb_data->geometry_data;
|
||||
}
|
||||
|
||||
EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb, Object *ob)
|
||||
EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_ObjectMotionData *mb_data, Object *ob)
|
||||
{
|
||||
return motion_blur_deform_data_get(mb, ob, false);
|
||||
}
|
||||
|
||||
EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_MotionBlurData *mb, Object *ob)
|
||||
{
|
||||
return motion_blur_deform_data_get(mb, ob, true);
|
||||
if (mb_data->hair_data == NULL) {
|
||||
/* Ugly, we allocate for each modifiers and just fill based on modifier index in the list. */
|
||||
int psys_len = (ob->type != OB_CURVES) ? BLI_listbase_count(&ob->modifiers) : 1;
|
||||
EEVEE_HairMotionData *hair_step = MEM_callocN(
|
||||
sizeof(EEVEE_HairMotionData) + sizeof(hair_step->psys[0]) * psys_len, __func__);
|
||||
hair_step->psys_len = psys_len;
|
||||
hair_step->type = EEVEE_MOTION_DATA_HAIR;
|
||||
mb_data->hair_data = hair_step;
|
||||
}
|
||||
return mb_data->hair_data;
|
||||
}
|
||||
|
||||
/* View Layer data. */
|
||||
|
|
|
@ -226,15 +226,14 @@ void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
|
|||
}
|
||||
|
||||
/* For now we assume hair objects are always moving. */
|
||||
EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(
|
||||
&effects->motion_blur, ob, true);
|
||||
EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(&effects->motion_blur, ob);
|
||||
|
||||
if (mb_data) {
|
||||
int mb_step = effects->motion_blur_step;
|
||||
/* Store transform. */
|
||||
DRW_hair_duplimat_get(ob, psys, md, mb_data->obmat[mb_step]);
|
||||
|
||||
EEVEE_HairMotionData *mb_hair = EEVEE_motion_blur_hair_data_get(&effects->motion_blur, ob);
|
||||
EEVEE_HairMotionData *mb_hair = EEVEE_motion_blur_hair_data_get(mb_data, ob);
|
||||
int psys_id = (md != NULL) ? BLI_findindex(&ob->modifiers, md) : 0;
|
||||
|
||||
if (psys_id >= mb_hair->psys_len) {
|
||||
|
@ -252,8 +251,8 @@ 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];
|
||||
GPUTexture *tex_prev = mb_hair->psys[psys_id].step_data[MB_PREV].hair_pos_tx;
|
||||
GPUTexture *tex_next = mb_hair->psys[psys_id].step_data[MB_NEXT].hair_pos_tx;
|
||||
|
||||
grp = DRW_shgroup_hair_create_sub(ob, psys, md, effects->motion_blur.hair_grp, NULL);
|
||||
DRW_shgroup_uniform_mat4(grp, "prevModelMatrix", mb_data->obmat[MB_PREV]);
|
||||
|
@ -265,7 +264,7 @@ void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
|
|||
}
|
||||
else {
|
||||
/* Store vertex position buffer. */
|
||||
mb_hair->psys[psys_id].hair_pos[mb_step] = DRW_hair_pos_buffer_get(ob, psys, md);
|
||||
mb_hair->psys[psys_id].step_data[mb_step].hair_pos = DRW_hair_pos_buffer_get(ob, psys, md);
|
||||
mb_hair->use_deform = true;
|
||||
}
|
||||
}
|
||||
|
@ -304,24 +303,14 @@ void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
|
|||
return;
|
||||
}
|
||||
|
||||
const DupliObject *dup = DRW_object_get_dupli(ob);
|
||||
if (dup != NULL && dup->ob->data != dup->ob_data) {
|
||||
/* Geometry instances do not support motion blur correctly yet. The #key used in
|
||||
* #motion_blur_deform_data_get has to take ids of instances (#DupliObject.persistent_id) into
|
||||
* account. Otherwise it can't find matching geometry instances at different points in time. */
|
||||
return;
|
||||
}
|
||||
|
||||
EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(
|
||||
&effects->motion_blur, ob, false);
|
||||
EEVEE_ObjectMotionData *mb_data = EEVEE_motion_blur_object_data_get(&effects->motion_blur, ob);
|
||||
|
||||
if (mb_data) {
|
||||
int mb_step = effects->motion_blur_step;
|
||||
/* Store transform. */
|
||||
copy_m4_m4(mb_data->obmat[mb_step], ob->obmat);
|
||||
|
||||
EEVEE_GeometryMotionData *mb_geom = EEVEE_motion_blur_geometry_data_get(&effects->motion_blur,
|
||||
ob);
|
||||
EEVEE_GeometryMotionData *mb_geom = EEVEE_motion_blur_geometry_data_get(mb_data);
|
||||
|
||||
if (mb_step == MB_CURR) {
|
||||
GPUBatch *batch = DRW_cache_object_surface_get(ob);
|
||||
|
@ -407,86 +396,93 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata)
|
|||
DRW_cache_restart();
|
||||
}
|
||||
|
||||
for (BLI_ghashIterator_init(&ghi, effects->motion_blur.geom);
|
||||
for (BLI_ghashIterator_init(&ghi, effects->motion_blur.object);
|
||||
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_MOTION_DATA_HAIR:
|
||||
if (mb_step == MB_CURR) {
|
||||
/* TODO(fclem): Check if vertex count mismatch. */
|
||||
mb_hair->use_deform = true;
|
||||
}
|
||||
else {
|
||||
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_hair->psys[i].hair_pos[mb_step]);
|
||||
|
||||
mb_hair->psys[i].hair_pos_tx[mb_step] = GPU_texture_create_from_vertbuf(
|
||||
"hair_pos_motion_blur", mb_hair->psys[i].hair_pos[mb_step]);
|
||||
EEVEE_ObjectMotionData *mb_data = BLI_ghashIterator_getValue(&ghi);
|
||||
EEVEE_HairMotionData *mb_hair = mb_data->hair_data;
|
||||
EEVEE_GeometryMotionData *mb_geom = mb_data->geometry_data;
|
||||
if (mb_hair != NULL && mb_hair->use_deform) {
|
||||
if (mb_step == MB_CURR) {
|
||||
/* TODO(fclem): Check if vertex count mismatch. */
|
||||
mb_hair->use_deform = true;
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < mb_hair->psys_len; i++) {
|
||||
GPUVertBuf *vbo = mb_hair->psys[i].step_data[mb_step].hair_pos;
|
||||
if (vbo == NULL) {
|
||||
continue;
|
||||
}
|
||||
EEVEE_HairMotionStepData **step_data_cache_ptr;
|
||||
if (!BLI_ghash_ensure_p(effects->motion_blur.hair_motion_step_cache[mb_step],
|
||||
vbo,
|
||||
(void ***)&step_data_cache_ptr)) {
|
||||
EEVEE_HairMotionStepData *new_step_data = MEM_callocN(sizeof(EEVEE_HairMotionStepData),
|
||||
__func__);
|
||||
/* Duplicate the vbo, otherwise it would be lost when evaluating another frame. */
|
||||
new_step_data->hair_pos = GPU_vertbuf_duplicate(vbo);
|
||||
/* Create vbo immediately to bind to texture buffer. */
|
||||
GPU_vertbuf_use(new_step_data->hair_pos);
|
||||
new_step_data->hair_pos_tx = GPU_texture_create_from_vertbuf("hair_pos_motion_blur",
|
||||
new_step_data->hair_pos);
|
||||
*step_data_cache_ptr = new_step_data;
|
||||
}
|
||||
mb_hair->psys[i].step_data[mb_step] = **step_data_cache_ptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case EEVEE_MOTION_DATA_MESH:
|
||||
if (mb_step == MB_CURR) {
|
||||
/* Modify batch to have data from adjacent frames. */
|
||||
GPUBatch *batch = mb_geom->batch;
|
||||
for (int i = 0; i < MB_CURR; i++) {
|
||||
GPUVertBuf *vbo = mb_geom->vbo[i];
|
||||
if (vbo && batch) {
|
||||
if (GPU_vertbuf_get_vertex_len(vbo) != GPU_vertbuf_get_vertex_len(batch->verts[0])) {
|
||||
/* Vertex count mismatch, disable deform motion blur. */
|
||||
mb_geom->use_deform = false;
|
||||
}
|
||||
|
||||
if (mb_geom->use_deform == false) {
|
||||
motion_blur_remove_vbo_reference_from_batch(
|
||||
batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]);
|
||||
|
||||
GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_PREV]);
|
||||
GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_NEXT]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mb_geom != NULL && mb_geom->use_deform) {
|
||||
if (mb_step == MB_CURR) {
|
||||
/* Modify batch to have data from adjacent frames. */
|
||||
GPUBatch *batch = mb_geom->batch;
|
||||
for (int i = 0; i < MB_CURR; i++) {
|
||||
GPUVertBuf *vbo = mb_geom->vbo[i];
|
||||
if (vbo && batch) {
|
||||
if (GPU_vertbuf_get_vertex_len(vbo) != GPU_vertbuf_get_vertex_len(batch->verts[0])) {
|
||||
/* Vertex count mismatch, disable deform motion blur. */
|
||||
mb_geom->use_deform = false;
|
||||
}
|
||||
|
||||
if (mb_geom->use_deform == false) {
|
||||
motion_blur_remove_vbo_reference_from_batch(
|
||||
batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]);
|
||||
break;
|
||||
}
|
||||
/* Avoid adding the same vbo more than once when the batch is used by multiple
|
||||
* instances. */
|
||||
if (!GPU_batch_vertbuf_has(batch, vbo)) {
|
||||
/* Currently, the code assumes that all objects that share the same mesh in the
|
||||
* current frame also share the same mesh on other frames. */
|
||||
GPU_batch_vertbuf_add_ex(batch, vbo, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
GPUVertBuf *vbo = mb_geom->vbo[mb_step];
|
||||
if (vbo) {
|
||||
/* Use the vbo to perform the copy on the GPU. */
|
||||
GPU_vertbuf_use(vbo);
|
||||
/* Perform a copy to avoid losing it after RE_engine_frame_set(). */
|
||||
mb_geom->vbo[mb_step] = vbo = GPU_vertbuf_duplicate(vbo);
|
||||
}
|
||||
else {
|
||||
GPUVertBuf *vbo = mb_geom->vbo[mb_step];
|
||||
if (vbo) {
|
||||
/* Use the vbo to perform the copy on the GPU. */
|
||||
GPU_vertbuf_use(vbo);
|
||||
/* Perform a copy to avoid losing it after RE_engine_frame_set(). */
|
||||
GPUVertBuf **vbo_cache_ptr;
|
||||
if (!BLI_ghash_ensure_p(effects->motion_blur.position_vbo_cache[mb_step],
|
||||
vbo,
|
||||
(void ***)&vbo_cache_ptr)) {
|
||||
/* Duplicate the vbo, otherwise it would be lost when evaluating another frame. */
|
||||
GPUVertBuf *duplicated_vbo = GPU_vertbuf_duplicate(vbo);
|
||||
*vbo_cache_ptr = duplicated_vbo;
|
||||
/* Find and replace "pos" attrib name. */
|
||||
GPUVertFormat *format = (GPUVertFormat *)GPU_vertbuf_get_format(vbo);
|
||||
GPUVertFormat *format = (GPUVertFormat *)GPU_vertbuf_get_format(duplicated_vbo);
|
||||
int attrib_id = GPU_vertformat_attr_id_get(format, "pos");
|
||||
GPU_vertformat_attr_rename(format, attrib_id, (mb_step == MB_PREV) ? "prv" : "nxt");
|
||||
}
|
||||
else {
|
||||
/* This might happen if the object visibility has been animated. */
|
||||
mb_geom->use_deform = false;
|
||||
}
|
||||
mb_geom->vbo[mb_step] = vbo = *vbo_cache_ptr;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
else {
|
||||
/* This might happen if the object visibility has been animated. */
|
||||
mb_geom->use_deform = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -503,54 +499,62 @@ void EEVEE_motion_blur_swap_data(EEVEE_Data *vedata)
|
|||
/* Camera Data. */
|
||||
effects->motion_blur.camera[MB_PREV] = effects->motion_blur.camera[MB_NEXT];
|
||||
|
||||
/* Object Data. */
|
||||
for (BLI_ghashIterator_init(&ghi, effects->motion_blur.object);
|
||||
BLI_ghashIterator_done(&ghi) == false;
|
||||
BLI_ghashIterator_step(&ghi)) {
|
||||
EEVEE_ObjectMotionData *mb_data = BLI_ghashIterator_getValue(&ghi);
|
||||
/* Swap #position_vbo_cache pointers. */
|
||||
if (effects->motion_blur.position_vbo_cache[MB_PREV]) {
|
||||
BLI_ghash_free(effects->motion_blur.position_vbo_cache[MB_PREV],
|
||||
NULL,
|
||||
(GHashValFreeFP)GPU_vertbuf_discard);
|
||||
}
|
||||
effects->motion_blur.position_vbo_cache[MB_PREV] =
|
||||
effects->motion_blur.position_vbo_cache[MB_NEXT];
|
||||
effects->motion_blur.position_vbo_cache[MB_NEXT] = NULL;
|
||||
|
||||
copy_m4_m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_NEXT]);
|
||||
/* Swap #hair_motion_step_cache pointers. */
|
||||
if (effects->motion_blur.hair_motion_step_cache[MB_PREV]) {
|
||||
BLI_ghash_free(effects->motion_blur.hair_motion_step_cache[MB_PREV],
|
||||
NULL,
|
||||
(GHashValFreeFP)EEVEE_motion_hair_step_free);
|
||||
}
|
||||
effects->motion_blur.hair_motion_step_cache[MB_PREV] =
|
||||
effects->motion_blur.hair_motion_step_cache[MB_NEXT];
|
||||
effects->motion_blur.hair_motion_step_cache[MB_NEXT] = NULL;
|
||||
|
||||
/* Rename attributes in #position_vbo_cache. */
|
||||
for (BLI_ghashIterator_init(&ghi, effects->motion_blur.position_vbo_cache[MB_PREV]);
|
||||
!BLI_ghashIterator_done(&ghi);
|
||||
BLI_ghashIterator_step(&ghi)) {
|
||||
GPUVertBuf *vbo = BLI_ghashIterator_getValue(&ghi);
|
||||
GPUVertFormat *format = (GPUVertFormat *)GPU_vertbuf_get_format(vbo);
|
||||
int attrib_id = GPU_vertformat_attr_id_get(format, "nxt");
|
||||
GPU_vertformat_attr_rename(format, attrib_id, "prv");
|
||||
}
|
||||
|
||||
/* Deformation Data. */
|
||||
for (BLI_ghashIterator_init(&ghi, effects->motion_blur.geom);
|
||||
BLI_ghashIterator_done(&ghi) == false;
|
||||
/* Object Data. */
|
||||
for (BLI_ghashIterator_init(&ghi, effects->motion_blur.object); !BLI_ghashIterator_done(&ghi);
|
||||
BLI_ghashIterator_step(&ghi)) {
|
||||
EEVEE_GeometryMotionData *mb_geom = BLI_ghashIterator_getValue(&ghi);
|
||||
EEVEE_HairMotionData *mb_hair = (EEVEE_HairMotionData *)mb_geom;
|
||||
EEVEE_ObjectMotionData *mb_data = BLI_ghashIterator_getValue(&ghi);
|
||||
EEVEE_GeometryMotionData *mb_geom = mb_data->geometry_data;
|
||||
EEVEE_HairMotionData *mb_hair = mb_data->hair_data;
|
||||
|
||||
switch (mb_geom->type) {
|
||||
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];
|
||||
mb_hair->psys[i].hair_pos[MB_NEXT] = NULL;
|
||||
mb_hair->psys[i].hair_pos_tx[MB_NEXT] = NULL;
|
||||
}
|
||||
break;
|
||||
copy_m4_m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_NEXT]);
|
||||
|
||||
case EEVEE_MOTION_DATA_MESH:
|
||||
if (mb_geom->batch != NULL) {
|
||||
motion_blur_remove_vbo_reference_from_batch(
|
||||
mb_geom->batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]);
|
||||
}
|
||||
GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_PREV]);
|
||||
mb_geom->vbo[MB_PREV] = mb_geom->vbo[MB_NEXT];
|
||||
mb_geom->vbo[MB_NEXT] = NULL;
|
||||
|
||||
if (mb_geom->vbo[MB_PREV]) {
|
||||
GPUVertBuf *vbo = mb_geom->vbo[MB_PREV];
|
||||
GPUVertFormat *format = (GPUVertFormat *)GPU_vertbuf_get_format(vbo);
|
||||
int attrib_id = GPU_vertformat_attr_id_get(format, "nxt");
|
||||
GPU_vertformat_attr_rename(format, attrib_id, "prv");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
if (mb_hair != NULL) {
|
||||
for (int i = 0; i < mb_hair->psys_len; i++) {
|
||||
mb_hair->psys[i].step_data[MB_PREV].hair_pos =
|
||||
mb_hair->psys[i].step_data[MB_NEXT].hair_pos;
|
||||
mb_hair->psys[i].step_data[MB_PREV].hair_pos_tx =
|
||||
mb_hair->psys[i].step_data[MB_NEXT].hair_pos_tx;
|
||||
mb_hair->psys[i].step_data[MB_NEXT].hair_pos = NULL;
|
||||
mb_hair->psys[i].step_data[MB_NEXT].hair_pos_tx = NULL;
|
||||
}
|
||||
}
|
||||
if (mb_geom != NULL) {
|
||||
if (mb_geom->batch != NULL) {
|
||||
motion_blur_remove_vbo_reference_from_batch(
|
||||
mb_geom->batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]);
|
||||
}
|
||||
mb_geom->vbo[MB_PREV] = mb_geom->vbo[MB_NEXT];
|
||||
mb_geom->vbo[MB_NEXT] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -618,8 +618,23 @@ enum {
|
|||
#define MB_CURR 2
|
||||
|
||||
typedef struct EEVEE_MotionBlurData {
|
||||
/**
|
||||
* Maps #EEVEE_ObjectKey to #EEVEE_ObjectMotionData.
|
||||
*/
|
||||
struct GHash *object;
|
||||
struct GHash *geom;
|
||||
/**
|
||||
* Maps original #GPUVertBuf to duplicated #GPUVertBuf.
|
||||
* There are two maps for #MB_PREV and #MB_NEXT.
|
||||
* Only the values are owned.
|
||||
*/
|
||||
struct GHash *position_vbo_cache[2];
|
||||
/**
|
||||
* Maps original #GPUVertBuf to #EEVEE_HairMotionStepData.
|
||||
* There are two maps for #MB_PREV and #MB_NEXT.
|
||||
* Only the values are owned.
|
||||
*/
|
||||
struct GHash *hair_motion_step_cache[2];
|
||||
|
||||
struct {
|
||||
float viewmat[4][4];
|
||||
float persmat[4][4];
|
||||
|
@ -637,15 +652,16 @@ typedef struct EEVEE_ObjectKey {
|
|||
int id[8]; /* MAX_DUPLI_RECUR */
|
||||
} EEVEE_ObjectKey;
|
||||
|
||||
typedef struct EEVEE_ObjectMotionData {
|
||||
float obmat[3][4][4];
|
||||
} EEVEE_ObjectMotionData;
|
||||
|
||||
typedef enum eEEVEEMotionData {
|
||||
EEVEE_MOTION_DATA_MESH = 0,
|
||||
EEVEE_MOTION_DATA_HAIR,
|
||||
} eEEVEEMotionData;
|
||||
|
||||
typedef struct EEVEE_HairMotionStepData {
|
||||
struct GPUVertBuf *hair_pos;
|
||||
struct GPUTexture *hair_pos_tx;
|
||||
} EEVEE_HairMotionStepData;
|
||||
|
||||
typedef struct EEVEE_HairMotionData {
|
||||
/** Needs to be first to ensure casting. */
|
||||
eEEVEEMotionData type;
|
||||
|
@ -653,8 +669,8 @@ typedef struct EEVEE_HairMotionData {
|
|||
/** Allocator will alloc enough slot for all particle systems. Or 1 if it's a hair object. */
|
||||
int psys_len;
|
||||
struct {
|
||||
struct GPUVertBuf *hair_pos[2]; /* Position buffer for time = t +/- step. */
|
||||
struct GPUTexture *hair_pos_tx[2]; /* Buffer Texture of the corresponding VBO. */
|
||||
/* The vbos and textures are not owned. */
|
||||
EEVEE_HairMotionStepData step_data[2]; /* Data for time = t +/- step. */
|
||||
} psys[0];
|
||||
} EEVEE_HairMotionData;
|
||||
|
||||
|
@ -664,10 +680,18 @@ typedef struct EEVEE_GeometryMotionData {
|
|||
/** To disable deform mb if vertcount mismatch. */
|
||||
int use_deform;
|
||||
|
||||
/* The batch and vbos are not owned. */
|
||||
struct GPUBatch *batch; /* Batch for time = t. */
|
||||
struct GPUVertBuf *vbo[2]; /* VBO for time = t +/- step. */
|
||||
} EEVEE_GeometryMotionData;
|
||||
|
||||
typedef struct EEVEE_ObjectMotionData {
|
||||
float obmat[3][4][4];
|
||||
|
||||
EEVEE_GeometryMotionData *geometry_data;
|
||||
EEVEE_HairMotionData *hair_data;
|
||||
} EEVEE_ObjectMotionData;
|
||||
|
||||
/* ************ EFFECTS DATA ************* */
|
||||
|
||||
typedef enum EEVEE_EffectsFlag {
|
||||
|
@ -1062,17 +1086,15 @@ typedef struct EEVEE_PrivateData {
|
|||
void EEVEE_motion_blur_data_init(EEVEE_MotionBlurData *mb);
|
||||
void EEVEE_motion_blur_data_free(EEVEE_MotionBlurData *mb);
|
||||
void EEVEE_view_layer_data_free(void *storage);
|
||||
void EEVEE_motion_hair_step_free(EEVEE_HairMotionStepData *step_data);
|
||||
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void);
|
||||
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer);
|
||||
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void);
|
||||
EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob);
|
||||
EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob);
|
||||
EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb,
|
||||
Object *ob,
|
||||
bool hair);
|
||||
EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb,
|
||||
Object *ob);
|
||||
EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_MotionBlurData *mb, Object *ob);
|
||||
EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, Object *ob);
|
||||
EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_ObjectMotionData *mb_data);
|
||||
EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_ObjectMotionData *mb_data, Object *ob);
|
||||
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob);
|
||||
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob);
|
||||
EEVEE_LightEngineData *EEVEE_light_data_get(Object *ob);
|
||||
|
|
|
@ -119,6 +119,7 @@ int GPU_batch_instbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
|
|||
* Returns the index of verts in the batch.
|
||||
*/
|
||||
int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
|
||||
bool GPU_batch_vertbuf_has(GPUBatch *, GPUVertBuf *);
|
||||
|
||||
#define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false)
|
||||
|
||||
|
|
|
@ -191,6 +191,16 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *batch, GPUVertBuf *verts, bool own_vbo)
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool GPU_batch_vertbuf_has(GPUBatch *batch, GPUVertBuf *verts)
|
||||
{
|
||||
for (uint v = 0; v < GPU_BATCH_VBO_MAX_LEN; v++) {
|
||||
if (batch->verts[v] == verts) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
Loading…
Reference in New Issue