Modifiers: export motion blur velocity through attribute

Previously fluid simulation and Alembic modifiers had a dedicated function
to query the velocity for motion blur. Now use a more generic system where
those modifiers output a velocity attribute.

Advantages:
* Geometry and particle nodes can output velocity through the same mechanism,
  or read the attribute coming from earlier modifiers.
* The velocity can be preserved through modifiers like subdivision surface or
  auto smooth.
* USD and Alembic previously only output velocity from fluid simulation, now
  they work with velocity from other sources too.
* Simplifies the code for renderers like Cycles and exporters like
  Alembic and USD.

This breaks compatibility:
* External renderers and exporters accessing these velocities through the
  Python API now need to use the attribute instead.
* Existing modifier node setups that create an attribute named "velocity"
  will render differently with motion blur.

Differential Revision: https://developer.blender.org/D12305
This commit is contained in:
Brecht Van Lommel
2021-09-09 17:22:20 +02:00
committed by Brecht Van Lommel
parent 42215d7cb8
commit 128eb6cbe9
30 changed files with 300 additions and 570 deletions

View File

@@ -105,10 +105,6 @@ static void freeData(ModifierData *md)
mcmd->reader_object_path[0] = '\0';
BKE_cachefile_reader_free(mcmd->cache_file, &mcmd->reader);
}
if (mcmd->vertex_velocities) {
MEM_freeN(mcmd->vertex_velocities);
}
}
static bool isDisabled(const struct Scene *UNUSED(scene),
@@ -233,11 +229,26 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Mesh *result = NULL;
switch (cache_file->type) {
case CACHEFILE_TYPE_ALEMBIC:
case CACHEFILE_TYPE_ALEMBIC: {
# ifdef WITH_ALEMBIC
result = ABC_read_mesh(mcmd->reader, ctx->object, mesh, time, &err_str, mcmd->read_flag);
/* Time (in frames or seconds) between two velocity samples. Automatically computed to
* scale the velocity vectors at render time for generating proper motion blur data. */
float velocity_scale = mcmd->velocity_scale;
if (mcmd->cache_file->velocity_unit == CACHEFILE_VELOCITY_UNIT_FRAME) {
velocity_scale *= FPS;
}
result = ABC_read_mesh(mcmd->reader,
ctx->object,
mesh,
time,
&err_str,
mcmd->read_flag,
mcmd->cache_file->velocity_name,
velocity_scale);
# endif
break;
}
case CACHEFILE_TYPE_USD:
# ifdef WITH_USD
result = USD_read_mesh(
@@ -248,17 +259,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
break;
}
mcmd->velocity_delta = 1.0f;
if (mcmd->cache_file->velocity_unit == CACHEFILE_VELOCITY_UNIT_SECOND) {
mcmd->velocity_delta /= FPS;
}
mcmd->last_lookup_time = time;
if (result != NULL) {
mcmd->num_vertices = result->totvert;
}
if (err_str) {
BKE_modifier_set_error(ctx->object, md, "%s", err_str);
}