Page MenuHome
Paste P755

Volume Motion Blur
ActivePublic

Authored by Geraldine Chua (gschua) on Jul 20 2018, 5:47 PM.
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 8d2ade1e30b..4de61a9d0f8 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -371,7 +371,7 @@ static void create_mesh_volume_attributes(Scene *scene,
create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_HEAT, frame);
if(mesh->need_attribute(scene, ATTR_STD_VOLUME_TEMPERATURE))
create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_TEMPERATURE, frame);
- if(mesh->need_attribute(scene, ATTR_STD_VOLUME_VELOCITY))
+ if(mesh->need_attribute(scene, ATTR_STD_VOLUME_VELOCITY) || scene->need_motion() == Scene::MOTION_BLUR)
create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_VELOCITY, frame);
}
diff --git a/intern/cycles/kernel/geom/geom_volume.h b/intern/cycles/kernel/geom/geom_volume.h
index 688413b74a1..08970a2e839 100644
--- a/intern/cycles/kernel/geom/geom_volume.h
+++ b/intern/cycles/kernel/geom/geom_volume.h
@@ -47,11 +47,38 @@ ccl_device_inline float3 volume_normalized_position(KernelGlobals *kg,
return P;
}
-ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
+ccl_device float4 volume_interpolate(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc)
{
float3 P = volume_normalized_position(kg, sd, sd->P);
InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC)? INTERPOLATION_CUBIC: INTERPOLATION_NONE;
- float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
+
+ /* Eulerian motion blur. */
+ if(kernel_data.cam.shuttertime != -1.0f) {
+ AttributeDescriptor velocity_desc = find_attribute(kg, sd, ATTR_STD_VOLUME_VELOCITY);
+
+ if (velocity_desc.offset != ATTR_STD_NOT_FOUND) {
+ float3 velocity = float4_to_float3(kernel_tex_image_interp_3d(kg, velocity_desc.offset, P.x, P.y, P.z, interp));
+ float motion_offset = sd->time + kernel_data.cam.motion_start_offset;
+ float time_step = kernel_data.cam.shuttertime / ((float)kernel_data.cam.motion_samples);
+ float4 r = make_float4(0.0f);
+
+ for(int i = 0; i < kernel_data.cam.motion_samples; ++i, motion_offset += time_step) {
+ float3 P_e = volume_normalized_position(kg, sd, sd->P + velocity * motion_offset);
+ r += kernel_tex_image_interp_3d(kg, desc.offset, P_e.x, P_e.y, P_e.z, interp);
+ }
+ r /= ((float)kernel_data.cam.motion_samples);
+
+ return r;
+ }
+ }
+
+ /* No motion blur. */
+ return kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
+}
+
+ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
+{
+ float4 r = volume_interpolate(kg, sd, desc);
if(dx) *dx = 0.0f;
if(dy) *dy = 0.0f;
@@ -61,9 +88,7 @@ ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd,
ccl_device float3 volume_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
{
- float3 P = volume_normalized_position(kg, sd, sd->P);
- InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC)? INTERPOLATION_CUBIC: INTERPOLATION_NONE;
- float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
+ float4 r = volume_interpolate(kg, sd, desc);
if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 85548484873..2de89dc4d8d 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1214,6 +1214,10 @@ typedef struct KernelCamera {
float rolling_shutter_duration;
int pad;
+
+ /* Motion blur */
+ float motion_start_offset;
+ int motion_samples;
} KernelCamera;
static_assert_align(KernelCamera, 16);
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index cc3dd1c923b..27e8843325e 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -383,6 +383,17 @@ void Camera::update(Scene *scene)
/* motion blur */
kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: -1.0f;
+ kcam->motion_samples = 3;
+
+ if(motion_position == MOTION_POSITION_START) {
+ kcam->motion_start_offset = 0.0f;
+ }
+ else if(motion_position == MOTION_POSITION_CENTER) {
+ kcam->motion_start_offset = -kcam->shuttertime * 0.5f;
+ }
+ else {
+ kcam->motion_start_offset = -kcam->shuttertime;
+ }
/* type */
kcam->type = type;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 7a9d604244d..971f11f3ecc 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1542,6 +1542,13 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
foreach(Shader *shader, mesh->used_shaders) {
mesh_attributes[i].add(shader->attributes);
+
+ /* motion blur for volumes */
+ if(shader->has_volume_spatial_varying &&
+ scene->need_motion() == Scene::MOTION_BLUR)
+ {
+ mesh_attributes[i].add(ATTR_STD_VOLUME_VELOCITY);
+ }
}
}

Event Timeline

Geraldine Chua (gschua) created this object with edit policy "No One".