forked from bartvdbraak/blender
Fix #32900: object motion blur not working on the GPU. To make this work I disabled motion
blurring of scale animation, probably not a big loss in practice since it's not so common to animate this, can be added back later.
This commit is contained in:
parent
bb0195e039
commit
0d6976ad0c
@ -65,7 +65,7 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float
|
|||||||
|
|
||||||
#ifdef __CAMERA_MOTION__
|
#ifdef __CAMERA_MOTION__
|
||||||
if(kernel_data.cam.have_motion)
|
if(kernel_data.cam.have_motion)
|
||||||
transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
|
transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ray->P = transform_point(&cameratoworld, ray->P);
|
ray->P = transform_point(&cameratoworld, ray->P);
|
||||||
@ -108,7 +108,7 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa
|
|||||||
|
|
||||||
#ifdef __CAMERA_MOTION__
|
#ifdef __CAMERA_MOTION__
|
||||||
if(kernel_data.cam.have_motion)
|
if(kernel_data.cam.have_motion)
|
||||||
transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
|
transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ray->P = transform_point(&cameratoworld, ray->P);
|
ray->P = transform_point(&cameratoworld, ray->P);
|
||||||
@ -182,7 +182,7 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
|
|||||||
|
|
||||||
#ifdef __CAMERA_MOTION__
|
#ifdef __CAMERA_MOTION__
|
||||||
if(kernel_data.cam.have_motion)
|
if(kernel_data.cam.have_motion)
|
||||||
transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
|
transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ray->P = transform_point(&cameratoworld, ray->P);
|
ray->P = transform_point(&cameratoworld, ray->P);
|
||||||
|
@ -23,9 +23,8 @@ enum ObjectTransform {
|
|||||||
OBJECT_INVERSE_TRANSFORM = 3,
|
OBJECT_INVERSE_TRANSFORM = 3,
|
||||||
OBJECT_PROPERTIES = 6,
|
OBJECT_PROPERTIES = 6,
|
||||||
OBJECT_TRANSFORM_MOTION_PRE = 8,
|
OBJECT_TRANSFORM_MOTION_PRE = 8,
|
||||||
OBJECT_TRANSFORM_MOTION_MID = 12,
|
OBJECT_TRANSFORM_MOTION_POST = 12,
|
||||||
OBJECT_TRANSFORM_MOTION_POST = 16,
|
OBJECT_DUPLI = 16
|
||||||
OBJECT_DUPLI = 20
|
|
||||||
};
|
};
|
||||||
|
|
||||||
__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
|
__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
|
||||||
@ -44,24 +43,19 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object,
|
|||||||
#ifdef __OBJECT_MOTION__
|
#ifdef __OBJECT_MOTION__
|
||||||
__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
|
__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
|
||||||
{
|
{
|
||||||
MotionTransform motion;
|
DecompMotionTransform motion;
|
||||||
|
|
||||||
int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE;
|
int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE;
|
||||||
|
|
||||||
motion.pre.x = kernel_tex_fetch(__objects, offset + 0);
|
motion.mid.x = kernel_tex_fetch(__objects, offset + 0);
|
||||||
motion.pre.y = kernel_tex_fetch(__objects, offset + 1);
|
motion.mid.y = kernel_tex_fetch(__objects, offset + 1);
|
||||||
motion.pre.z = kernel_tex_fetch(__objects, offset + 2);
|
motion.mid.z = kernel_tex_fetch(__objects, offset + 2);
|
||||||
motion.pre.w = kernel_tex_fetch(__objects, offset + 3);
|
motion.mid.w = kernel_tex_fetch(__objects, offset + 3);
|
||||||
|
|
||||||
motion.mid.x = kernel_tex_fetch(__objects, offset + 4);
|
motion.pre_x = kernel_tex_fetch(__objects, offset + 4);
|
||||||
motion.mid.y = kernel_tex_fetch(__objects, offset + 5);
|
motion.pre_y = kernel_tex_fetch(__objects, offset + 5);
|
||||||
motion.mid.z = kernel_tex_fetch(__objects, offset + 6);
|
motion.post_x = kernel_tex_fetch(__objects, offset + 6);
|
||||||
motion.mid.w = kernel_tex_fetch(__objects, offset + 7);
|
motion.post_y = kernel_tex_fetch(__objects, offset + 7);
|
||||||
|
|
||||||
motion.post.x = kernel_tex_fetch(__objects, offset + 8);
|
|
||||||
motion.post.y = kernel_tex_fetch(__objects, offset + 9);
|
|
||||||
motion.post.z = kernel_tex_fetch(__objects, offset + 10);
|
|
||||||
motion.post.w = kernel_tex_fetch(__objects, offset + 11);
|
|
||||||
|
|
||||||
Transform tfm;
|
Transform tfm;
|
||||||
transform_motion_interpolate(&tfm, &motion, time);
|
transform_motion_interpolate(&tfm, &motion, time);
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
CCL_NAMESPACE_BEGIN
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
/* constants */
|
/* constants */
|
||||||
#define OBJECT_SIZE 22
|
#define OBJECT_SIZE 18
|
||||||
#define LIGHT_SIZE 4
|
#define LIGHT_SIZE 4
|
||||||
#define FILTER_TABLE_SIZE 256
|
#define FILTER_TABLE_SIZE 256
|
||||||
#define RAMP_TABLE_SIZE 256
|
#define RAMP_TABLE_SIZE 256
|
||||||
@ -112,13 +112,9 @@ CCL_NAMESPACE_BEGIN
|
|||||||
#define __AO__
|
#define __AO__
|
||||||
#define __CAMERA_MOTION__
|
#define __CAMERA_MOTION__
|
||||||
#define __ANISOTROPIC__
|
#define __ANISOTROPIC__
|
||||||
|
|
||||||
#ifndef __KERNEL_CUDA__
|
|
||||||
#define __OBJECT_MOTION__
|
#define __OBJECT_MOTION__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//#define __SOBOL_FULL_SCREEN__
|
//#define __SOBOL_FULL_SCREEN__
|
||||||
|
|
||||||
/* Shader Evaluation */
|
/* Shader Evaluation */
|
||||||
|
@ -202,7 +202,7 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
|
|||||||
#ifdef __CAMERA_MOTION__
|
#ifdef __CAMERA_MOTION__
|
||||||
else if(need_motion == Scene::MOTION_BLUR) {
|
else if(need_motion == Scene::MOTION_BLUR) {
|
||||||
if(use_motion) {
|
if(use_motion) {
|
||||||
transform_motion_decompose(&kcam->motion, &motion, &matrix);
|
transform_motion_decompose((DecompMotionTransform*)&kcam->motion, &motion, &matrix);
|
||||||
kcam->have_motion = 1;
|
kcam->have_motion = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ void Object::compute_bounds(bool motion_blur, float shuttertime)
|
|||||||
BoundBox mbounds = mesh->bounds;
|
BoundBox mbounds = mesh->bounds;
|
||||||
|
|
||||||
if(motion_blur && use_motion) {
|
if(motion_blur && use_motion) {
|
||||||
MotionTransform decomp;
|
DecompMotionTransform decomp;
|
||||||
transform_motion_decompose(&decomp, &motion, &tfm);
|
transform_motion_decompose(&decomp, &motion, &tfm);
|
||||||
|
|
||||||
bounds = BoundBox::empty;
|
bounds = BoundBox::empty;
|
||||||
@ -222,29 +222,29 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
|||||||
mtfm_post = mtfm_post * itfm;
|
mtfm_post = mtfm_post * itfm;
|
||||||
|
|
||||||
memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
|
memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
|
||||||
memcpy(&objects[offset+16], &mtfm_post, sizeof(float4)*4);
|
memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4);
|
||||||
}
|
}
|
||||||
#ifdef __OBJECT_MOTION__
|
#ifdef __OBJECT_MOTION__
|
||||||
else if(need_motion == Scene::MOTION_BLUR) {
|
else if(need_motion == Scene::MOTION_BLUR) {
|
||||||
if(ob->use_motion) {
|
if(ob->use_motion) {
|
||||||
/* decompose transformations for interpolation */
|
/* decompose transformations for interpolation */
|
||||||
MotionTransform decomp;
|
DecompMotionTransform decomp;
|
||||||
|
|
||||||
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
|
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
|
||||||
memcpy(&objects[offset+8], &decomp, sizeof(float4)*12);
|
memcpy(&objects[offset+8], &decomp, sizeof(float4)*8);
|
||||||
flag |= SD_OBJECT_MOTION;
|
flag |= SD_OBJECT_MOTION;
|
||||||
have_motion = true;
|
have_motion = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float4 no_motion = make_float4(FLT_MAX);
|
float4 no_motion = make_float4(FLT_MAX);
|
||||||
memcpy(&objects[offset+8], &no_motion, sizeof(float4)*12);
|
memcpy(&objects[offset+8], &no_motion, sizeof(float4)*8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* dupli object coords */
|
/* dupli object coords */
|
||||||
objects[offset+20] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
|
objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
|
||||||
objects[offset+21] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
|
objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
|
||||||
|
|
||||||
/* object flag */
|
/* object flag */
|
||||||
if(ob->use_holdout)
|
if(ob->use_holdout)
|
||||||
|
@ -246,18 +246,30 @@ static void transform_decompose(Transform *decomp, const Transform *tfm)
|
|||||||
decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
|
decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid)
|
void transform_motion_decompose(DecompMotionTransform *decomp, const MotionTransform *motion, const Transform *mid)
|
||||||
{
|
{
|
||||||
transform_decompose(&decomp->pre, &motion->pre);
|
Transform pre, post;
|
||||||
|
|
||||||
|
transform_decompose(&pre, &motion->pre);
|
||||||
transform_decompose(&decomp->mid, mid);
|
transform_decompose(&decomp->mid, mid);
|
||||||
transform_decompose(&decomp->post, &motion->post);
|
transform_decompose(&post, &motion->post);
|
||||||
|
|
||||||
/* ensure rotation around shortest angle, negated quaternions are the same
|
/* ensure rotation around shortest angle, negated quaternions are the same
|
||||||
* but this means we don't have to do the check in quat_interpolate */
|
* but this means we don't have to do the check in quat_interpolate */
|
||||||
if(dot(decomp->mid.x, decomp->post.x) < 0.0f)
|
if(dot(decomp->mid.x, post.x) < 0.0f)
|
||||||
decomp->mid.x = -decomp->mid.x;
|
decomp->mid.x = -decomp->mid.x;
|
||||||
if(dot(decomp->pre.x, decomp->mid.x) < 0.0f)
|
if(dot(pre.x, decomp->mid.x) < 0.0f)
|
||||||
decomp->pre.x = -decomp->pre.x;
|
pre.x = -pre.x;
|
||||||
|
|
||||||
|
/* drop scale of pre/post */
|
||||||
|
pre.y.w = decomp->mid.y.w;
|
||||||
|
post.y.w = decomp->mid.y.w;
|
||||||
|
|
||||||
|
/* store translation/rotation part of pre/post */
|
||||||
|
decomp->pre_x = pre.x;
|
||||||
|
decomp->pre_y = pre.y;
|
||||||
|
decomp->post_x = post.x;
|
||||||
|
decomp->post_y = post.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@ -41,7 +41,9 @@ typedef struct Transform {
|
|||||||
|
|
||||||
/* transform decomposed in rotation/translation/scale. we use the same data
|
/* transform decomposed in rotation/translation/scale. we use the same data
|
||||||
* structure as Transform, and tightly pack decomposition into it. first the
|
* structure as Transform, and tightly pack decomposition into it. first the
|
||||||
* rotation (4), then translation (3), then 3x3 scale matrix (9) */
|
* rotation (4), then translation (3), then 3x3 scale matrix (9).
|
||||||
|
*
|
||||||
|
* For the DecompMotionTransform we drop scale from pre/post. */
|
||||||
|
|
||||||
typedef struct MotionTransform {
|
typedef struct MotionTransform {
|
||||||
Transform pre;
|
Transform pre;
|
||||||
@ -49,6 +51,12 @@ typedef struct MotionTransform {
|
|||||||
Transform post;
|
Transform post;
|
||||||
} MotionTransform;
|
} MotionTransform;
|
||||||
|
|
||||||
|
typedef struct DecompMotionTransform {
|
||||||
|
Transform mid;
|
||||||
|
float4 pre_x, pre_y;
|
||||||
|
float4 post_x, post_y;
|
||||||
|
} DecompMotionTransform;
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
__device_inline float3 transform_perspective(const Transform *t, const float3 a)
|
__device_inline float3 transform_perspective(const Transform *t, const float3 a)
|
||||||
@ -384,7 +392,7 @@ __device_inline void transform_compose(Transform *tfm, const Transform *decomp)
|
|||||||
/* Disabled for now, need arc-length parametrization for constant speed motion.
|
/* Disabled for now, need arc-length parametrization for constant speed motion.
|
||||||
* #define CURVED_MOTION_INTERPOLATE */
|
* #define CURVED_MOTION_INTERPOLATE */
|
||||||
|
|
||||||
__device void transform_motion_interpolate(Transform *tfm, const MotionTransform *motion, float t)
|
__device void transform_motion_interpolate(Transform *tfm, const DecompMotionTransform *motion, float t)
|
||||||
{
|
{
|
||||||
/* possible optimization: is it worth it adding a check to skip scaling?
|
/* possible optimization: is it worth it adding a check to skip scaling?
|
||||||
* it's probably quite uncommon to have scaling objects. or can we skip
|
* it's probably quite uncommon to have scaling objects. or can we skip
|
||||||
@ -393,9 +401,9 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform
|
|||||||
|
|
||||||
#ifdef CURVED_MOTION_INTERPOLATE
|
#ifdef CURVED_MOTION_INTERPOLATE
|
||||||
/* 3 point bezier curve interpolation for position */
|
/* 3 point bezier curve interpolation for position */
|
||||||
float3 Ppre = float4_to_float3(motion->pre.y);
|
float3 Ppre = float4_to_float3(motion->pre_y);
|
||||||
float3 Pmid = float4_to_float3(motion->mid.y);
|
float3 Pmid = float4_to_float3(motion->mid.y);
|
||||||
float3 Ppost = float4_to_float3(motion->post.y);
|
float3 Ppost = float4_to_float3(motion->post_y);
|
||||||
|
|
||||||
float3 Pcontrol = 2.0f*Pmid - 0.5f*(Ppre + Ppost);
|
float3 Pcontrol = 2.0f*Pmid - 0.5f*(Ppre + Ppost);
|
||||||
float3 P = Ppre*t*t + Pcontrol*2.0f*t*(1.0f - t) + Ppost*(1.0f - t)*(1.0f - t);
|
float3 P = Ppre*t*t + Pcontrol*2.0f*t*(1.0f - t) + Ppost*(1.0f - t)*(1.0f - t);
|
||||||
@ -409,28 +417,27 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform
|
|||||||
if(t < 0.5f) {
|
if(t < 0.5f) {
|
||||||
t *= 2.0f;
|
t *= 2.0f;
|
||||||
|
|
||||||
decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t);
|
decomp.x = quat_interpolate(motion->pre_x, motion->mid.x, t);
|
||||||
#ifdef CURVED_MOTION_INTERPOLATE
|
#ifdef CURVED_MOTION_INTERPOLATE
|
||||||
decomp.y.w = (1.0f - t)*motion->pre.y.w + t*motion->mid.y.w;
|
decomp.y.w = (1.0f - t)*motion->pre_y.w + t*motion->mid.y.w;
|
||||||
#else
|
#else
|
||||||
decomp.y = (1.0f - t)*motion->pre.y + t*motion->mid.y;
|
decomp.y = (1.0f - t)*motion->pre_y + t*motion->mid.y;
|
||||||
#endif
|
#endif
|
||||||
decomp.z = (1.0f - t)*motion->pre.z + t*motion->mid.z;
|
|
||||||
decomp.w = (1.0f - t)*motion->pre.w + t*motion->mid.w;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
t = (t - 0.5f)*2.0f;
|
t = (t - 0.5f)*2.0f;
|
||||||
|
|
||||||
decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t);
|
decomp.x = quat_interpolate(motion->mid.x, motion->post_x, t);
|
||||||
#ifdef CURVED_MOTION_INTERPOLATE
|
#ifdef CURVED_MOTION_INTERPOLATE
|
||||||
decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post.y.w;
|
decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post_y.w;
|
||||||
#else
|
#else
|
||||||
decomp.y = (1.0f - t)*motion->mid.y + t*motion->post.y;
|
decomp.y = (1.0f - t)*motion->mid.y + t*motion->post_y;
|
||||||
#endif
|
#endif
|
||||||
decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z;
|
|
||||||
decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decomp.z = motion->mid.z;
|
||||||
|
decomp.w = motion->mid.w;
|
||||||
|
|
||||||
/* compose rotation, translation, scale into matrix */
|
/* compose rotation, translation, scale into matrix */
|
||||||
transform_compose(tfm, &decomp);
|
transform_compose(tfm, &decomp);
|
||||||
}
|
}
|
||||||
@ -442,7 +449,7 @@ __device_inline bool operator==(const MotionTransform& A, const MotionTransform&
|
|||||||
return (A.pre == B.pre && A.post == B.post);
|
return (A.pre == B.pre && A.post == B.post);
|
||||||
}
|
}
|
||||||
|
|
||||||
void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid);
|
void transform_motion_decompose(DecompMotionTransform *decomp, const MotionTransform *motion, const Transform *mid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user