Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2022-04-19 17:28:14 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2022-04-19 18:07:53 +0300
commit2890c11cd7b008c3c261b6aa833c826c85cac504 (patch)
tree5bc3432767fc6dd260e6fec18bd1817766572abd /intern/cycles/blender/volume.cpp
parent56cfd60d432bf387c21bf5bde08fece044fac99c (diff)
Cycles: add support for volume motion blur
This adds support for rendering motion blur for volumes, using their velocity field. This works for fluid simulations and imported VDB volumes. For the latter, the name of the velocity field can be set per volume object, with automatic detection of velocity fields that are split into 3 scalar grids. A new parameter is also added to scale velocity for more artistic control. Like for Alembic and USD caches, a parameter to set the unit of time in which the velocity vectors are expressed is also added. For Blender gas simulations, the velocity unit should always be in seconds, so this is only exposed for volume objects which may come from external OpenVDB files. These parameters are available under the `Render` panels for the fluid domain and the volume object data properties respectively. Credits: kernel advection code from Tangent Animation's Blackbird based on earlier work by Geraldine Chua Differential Revision: https://developer.blender.org/D14629
Diffstat (limited to 'intern/cycles/blender/volume.cpp')
-rw-r--r--intern/cycles/blender/volume.cpp49
1 files changed, 45 insertions, 4 deletions
diff --git a/intern/cycles/blender/volume.cpp b/intern/cycles/blender/volume.cpp
index 381b3385a5a..8dd2d45c0b6 100644
--- a/intern/cycles/blender/volume.cpp
+++ b/intern/cycles/blender/volume.cpp
@@ -168,7 +168,8 @@ class BlenderSmokeLoader : public ImageLoader {
AttributeStandard attribute;
};
-static void sync_smoke_volume(Scene *scene, BObjectInfo &b_ob_info, Volume *volume, float frame)
+static void sync_smoke_volume(
+ BL::Scene &b_scene, Scene *scene, BObjectInfo &b_ob_info, Volume *volume, float frame)
{
if (!b_ob_info.is_real_object_data()) {
return;
@@ -178,6 +179,18 @@ static void sync_smoke_volume(Scene *scene, BObjectInfo &b_ob_info, Volume *volu
return;
}
+ float velocity_scale = b_domain.velocity_scale();
+ /* Motion blur attribute is relative to seconds, we need it relative to frames. */
+ const bool need_motion = object_need_motion_attribute(b_ob_info, scene);
+ const float motion_scale = (need_motion) ?
+ scene->motion_shutter_time() /
+ (b_scene.render().fps() / b_scene.render().fps_base()) :
+ 0.0f;
+
+ velocity_scale *= motion_scale;
+
+ volume->set_velocity_scale(velocity_scale);
+
AttributeStandard attributes[] = {ATTR_STD_VOLUME_DENSITY,
ATTR_STD_VOLUME_COLOR,
ATTR_STD_VOLUME_FLAME,
@@ -234,6 +247,7 @@ class BlenderVolumeLoader : public VDBImageLoader {
};
static void sync_volume_object(BL::BlendData &b_data,
+ BL::Scene &b_scene,
BObjectInfo &b_ob_info,
Scene *scene,
Volume *volume)
@@ -247,6 +261,20 @@ static void sync_volume_object(BL::BlendData &b_data,
volume->set_step_size(b_render.step_size());
volume->set_object_space((b_render.space() == BL::VolumeRender::space_OBJECT));
+ float velocity_scale = b_volume.velocity_scale();
+ if (b_volume.velocity_unit() == BL::Volume::velocity_unit_SECOND) {
+ /* Motion blur attribute is relative to seconds, we need it relative to frames. */
+ const bool need_motion = object_need_motion_attribute(b_ob_info, scene);
+ const float motion_scale = (need_motion) ?
+ scene->motion_shutter_time() /
+ (b_scene.render().fps() / b_scene.render().fps_base()) :
+ 0.0f;
+
+ velocity_scale *= motion_scale;
+ }
+
+ volume->set_velocity_scale(velocity_scale);
+
/* Find grid with matching name. */
for (BL::VolumeGrid &b_grid : b_volume.grids) {
ustring name = ustring(b_grid.name());
@@ -267,9 +295,22 @@ static void sync_volume_object(BL::BlendData &b_data,
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) {
std = ATTR_STD_VOLUME_TEMPERATURE;
}
- else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
+ else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
+ name == b_volume.velocity_grid()) {
std = ATTR_STD_VOLUME_VELOCITY;
}
+ else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY_X) ||
+ name == b_volume.velocity_x_grid()) {
+ std = ATTR_STD_VOLUME_VELOCITY_X;
+ }
+ else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY_Y) ||
+ name == b_volume.velocity_y_grid()) {
+ std = ATTR_STD_VOLUME_VELOCITY_Y;
+ }
+ else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY_Z) ||
+ name == b_volume.velocity_z_grid()) {
+ std = ATTR_STD_VOLUME_VELOCITY_Z;
+ }
if ((std != ATTR_STD_NONE && volume->need_attribute(scene, std)) ||
volume->need_attribute(scene, name)) {
@@ -294,11 +335,11 @@ void BlenderSync::sync_volume(BObjectInfo &b_ob_info, Volume *volume)
if (b_ob_info.object_data.is_a(&RNA_Volume)) {
/* Volume object. Create only attributes, bounding mesh will then
* be automatically generated later. */
- sync_volume_object(b_data, b_ob_info, scene, volume);
+ sync_volume_object(b_data, b_scene, b_ob_info, scene, volume);
}
else {
/* Smoke domain. */
- sync_smoke_volume(scene, b_ob_info, volume, b_scene.frame_current());
+ sync_smoke_volume(b_scene, scene, b_ob_info, volume, b_scene.frame_current());
}
}