Fix T71344: Optix render errors with motion blur and unknown bone constraint relationship

The OptiX SRT motion expects a motion defined by translation,
rotation, shear and scale, but the matrix decomposition code in
Cycles was not able to extract shear information and instead
produced a stretch matrix with the information baked in. This
caused conflicting transforms between traversal and shading
and lead to render artifacts.
This patch changes the matrix decomposition to produce factors
inline with what OptiX expects to fix that.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D6605
This commit is contained in:
Patrick Mours 2020-01-16 18:08:52 +01:00
parent cbbbb9d179
commit 26687dda5a
Notes: blender-bot 2023-02-14 09:29:42 +01:00
Referenced by issue #71344, Optix render errors with motion blur and unknown bone constraint relationship
3 changed files with 44 additions and 0 deletions

View File

@ -1461,6 +1461,9 @@ class OptiXDevice : public Device {
srt_data[i].a = decomp[i].z.x; // scale.x.y
srt_data[i].b = decomp[i].z.y; // scale.x.z
srt_data[i].c = decomp[i].w.x; // scale.y.z
assert(decomp[i].z.z == 0.0f); // scale.y.x
assert(decomp[i].w.y == 0.0f); // scale.z.x
assert(decomp[i].w.z == 0.0f); // scale.z.y
// Pivot point
srt_data[i].pvx = 0.0f;

View File

@ -179,6 +179,11 @@ ccl_device_inline float4 operator+=(float4 &a, const float4 &b)
return a = a + b;
}
ccl_device_inline float4 operator-=(float4 &a, const float4 &b)
{
return a = a - b;
}
ccl_device_inline float4 operator*=(float4 &a, const float4 &b)
{
return a = a * b;

View File

@ -227,6 +227,7 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf
M.y.w = 0.0f;
M.z.w = 0.0f;
#if 0
Transform R = M;
float norm;
int iteration = 0;
@ -260,6 +261,41 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf
decomp->y.w = scale.x.x;
decomp->z = make_float4(scale.x.y, scale.x.z, scale.y.x, scale.y.y);
decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
#else
float3 colx = transform_get_column(&M, 0);
float3 coly = transform_get_column(&M, 1);
float3 colz = transform_get_column(&M, 2);
/* extract scale and shear first */
float3 scale, shear;
scale.x = len(colx);
colx /= scale.x;
shear.z = dot(colx, coly);
coly -= shear.z * colx;
scale.y = len(coly);
coly /= scale.y;
shear.y = dot(colx, colz);
colz -= shear.y * colx;
shear.x = dot(coly, colz);
colz -= shear.x * coly;
scale.z = len(colz);
colz /= scale.z;
transform_set_column(&M, 0, colx);
transform_set_column(&M, 1, coly);
transform_set_column(&M, 2, colz);
if (transform_negative_scale(M)) {
scale *= -1.0f;
M = M * transform_scale(-1.0f, -1.0f, -1.0f);
}
decomp->x = transform_to_quat(M);
decomp->y.w = scale.x;
decomp->z = make_float4(shear.z, shear.y, 0.0f, scale.y);
decomp->w = make_float4(shear.x, 0.0f, 0.0f, scale.z);
#endif
}
void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size)