Page MenuHome

Cycles motion blur glitch with z-scale = 0
Closed, ResolvedPublic

Description

gtx 970; win 10 64

blender-2.76-741cf19-win64

Objects are not rendered with Motion Blur.
Please consult print screen and blend file.

Thanks


Update: Reported issue can be fixed by setting z-scale of objects to non-0 but it still gives weird results, see this

Details

Type
Bug

Event Timeline

pistol ioan (pistoltoto) updated the task description. (Show Details)
pistol ioan (pistoltoto) raised the priority of this task from to Needs Triage by Developer.
pistol ioan (pistoltoto) set Type to Bug.

I tried to add other objects, or render after animation ends, but give weird results also.

You have a Z-scale of 0 for all objects. Setting to 1 for all solves the issue.

@Sergey Sharybin (sergey), there's still something weird going on here, rendering the .blend as is, results in the blank canvas as in the report, setting scale of the red outline to != 0 results in this:

Working fine in BI.

Julian Eisel (Severin) renamed this task from Objects are not rendered with Motion Blur to Cycles motion blur glitch with z-scale = 0.Sep 29 2015, 10:13 PM
Julian Eisel (Severin) updated the task description. (Show Details)
Julian Eisel (Severin) triaged this task as Confirmed, Medium priority.

I forget to mention that some of the objects are imported from Adobe Illustrator as svg.

The problem (or at least one problem) here is that transform_quick_inverse(), which is called from qbvh_instance_motion_push() during traversal, fails if the z-scale is 0 and returns a null matrix, which then produces weird values for the rest of the traversal. Using transform_inverse() solves that problem, but 1. will most likely slow down rendering and 2. it seems that there still are issues. Generally, non-invertible transforms seem to produce various problems with motion blur...

In the Blender transform code pseudoinverse_m4_m4 is used to handle this kind of degenerate matrix, but doing an SVD decomposition here would be too slow and complex.

The comments in transform_quick_inverse mention inverting the individual components of the matrix on construction. The translation and rotation components would work reliably, it's the degenerate 3x3 scale matrix that we need to handle then. We could add a small epsilon to the diagonal of this 3x3 matrix if it is degenerate (same trick as in transform_inverse).

It's still possible then that the interpolation between two non-degenerate matrices produces a degenerate matrix, but that would be rare, and it would only happen for a very specific time sample so I don't think you'd notice.

By the way, if the object has no scale or uniform scale (which is almost always the case, shearing is rare), then composing the interpolated matrix and its inverse could be optimized quite a bit, no matrix-matrix multiplication or matrix inversion necessary then.

Actually, inverting the individual components isn't necessary at all, you can just add an epsilon in transform_decompose if the scale matrix is degenerate. It would be a nice optimization but not needed to fix this bug.

There's not only motion blur issue here, there is also "regular" instance push/pop issue involved here. It is caused by difference in the scale factor applied on the intersection distance in instance push and pop functions. Here's a quick patch for this issue:

1diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
2index 9d0a008..bf1a3eb 100644
3--- a/intern/cycles/kernel/geom/geom_object.h
4+++ b/intern/cycles/kernel/geom/geom_object.h
5@@ -428,8 +428,8 @@ ccl_device_inline void qbvh_instance_push(KernelGlobals *kg,
6 ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t)
7 {
8 if(*t != FLT_MAX) {
9- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
10- *t *= len(transform_direction(&tfm, 1.0f/(*idir)));
11+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
12+ *t /= len(transform_direction(&tfm, ray->D));
13 }
14
15 *P = ray->P;
16@@ -441,8 +441,8 @@ ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray
17
18 ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac)
19 {
20- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
21- *t_fac = len(transform_direction(&tfm, 1.0f/(*idir)));
22+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
23+ *t_fac = 1.0f / len(transform_direction(&tfm, ray->D));
24
25 *P = ray->P;
26 *dir = bvh_clamp_direction(ray->D);

Not really sure it could be less creepy, but on the other hand number of math operations seems to be the same, so it should be all the same performance.

In order to solve motion blur issue the same type of changes is to be applied to motion pop function. In order to motion blur to work correctly fix to quick matrix inverse is still to be applied tho. Think something like this will work:

1diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
2index ba8d04b..4450273 100644
3--- a/intern/cycles/util/util_transform.h
4+++ b/intern/cycles/util/util_transform.h
5@@ -347,7 +347,12 @@ ccl_device_inline Transform transform_quick_inverse(Transform M)
6 * scale can be inverted but what about shearing? */
7 Transform R;
8 float det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z);
9-
10+ if(det == 0.0f) {
11+ M[0][0] += 1e-8f;
12+ M[1][1] += 1e-8f;
13+ M[2][2] += 1e-8f;
14+ det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z);
15+ }
16 det = (det != 0.0f)? 1.0f/det: 0.0f;
17
18 float3 Rx = det*make_float3(M.z.z*M.y.y - M.z.y*M.y.z, M.z.y*M.x.z - M.z.z*M.x.y, M.y.z*M.x.y - M.y.y*M.x.z);

That det == 0.0 check could be done in transform_decompose ahead of time, but it won't really matter, so these fixes definitely look fine to me.

@Brecht Van Lommel (brecht), yeah we can do some preliminary checks there and maybe even move something out of the render kernel. Didn't have time to look into details -- crunchtime with PhD thesis pre-defense event at uni. Hopefully will have more time on thursday.

Sergey Sharybin (sergey) closed this task as Resolved.Oct 9 2015, 1:14 PM

Series of fixes went to the Git now, the issue should now be fixed.

Thanks everyone for feedback and discussion :)