Cycles: hide particles with broken motion blur traces.

Currently cycles cannot correctly render motion blur for objects that appear or
disappear during the shutter window. Until that can be fixed properly, it may be
better to hide such particles rather than let them render as if they were
stationary for half of the frame.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2125
This commit is contained in:
Alexander Gavrilov 2016-08-04 23:24:29 +02:00 committed by Brecht Van Lommel
parent 2ce9bab8ce
commit 1f19fba566
Notes: blender-bot 2023-02-14 07:39:47 +01:00
Referenced by issue #104539, Cycles Motion Blur setting causes dropped particle instances in animation.
Referenced by issue #49163, Animated object visibilty 1 frame off when turning on motion blur
3 changed files with 31 additions and 13 deletions

View File

@ -395,8 +395,8 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
object->name = b_ob.name().c_str();
object->pass_id = b_ob.pass_index();
object->tfm = tfm;
object->motion.pre = tfm;
object->motion.post = tfm;
object->motion.pre = transform_empty();
object->motion.post = transform_empty();
object->use_motion = false;
/* motion blur */

View File

@ -70,19 +70,28 @@ void Object::compute_bounds(bool motion_blur)
BoundBox mbounds = mesh->bounds;
if(motion_blur && use_motion) {
DecompMotionTransform decomp;
transform_motion_decompose(&decomp, &motion, &tfm);
if(motion.pre == transform_empty() ||
motion.post == transform_empty()) {
/* Hide objects that have no valid previous or next transform, for
* example particle that stop existing. TODO: add support for this
* case in the kernel so we don't get render artifacts. */
bounds = BoundBox::empty;
}
else {
DecompMotionTransform decomp;
transform_motion_decompose(&decomp, &motion, &tfm);
bounds = BoundBox::empty;
bounds = BoundBox::empty;
/* todo: this is really terrible. according to pbrt there is a better
* way to find this iteratively, but did not find implementation yet
* or try to implement myself */
for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
Transform ttfm;
/* todo: this is really terrible. according to pbrt there is a better
* way to find this iteratively, but did not find implementation yet
* or try to implement myself */
for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
Transform ttfm;
transform_motion_interpolate(&ttfm, &decomp, t);
bounds.grow(mbounds.transformed(&ttfm));
transform_motion_interpolate(&ttfm, &decomp, t);
bounds.grow(mbounds.transformed(&ttfm));
}
}
}
else {
@ -228,7 +237,7 @@ vector<float> Object::motion_times()
bool Object::is_traceable()
{
/* Mesh itself can be empty,can skip all such objects. */
if (bounds.size() == make_float3(0.0f, 0.0f, 0.0f)) {
if (!bounds.valid() || bounds.size() == make_float3(0.0f, 0.0f, 0.0f)) {
return false;
}
/* TODO(sergey): Check for mesh vertices/curves. visibility flags. */

View File

@ -323,6 +323,15 @@ ccl_device_inline Transform transform_clear_scale(const Transform& tfm)
return ntfm;
}
ccl_device_inline Transform transform_empty()
{
return make_transform(
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0);
}
#endif
/* Motion Transform */