diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 602574cb736..79ff7e2020a 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -23,8 +23,9 @@ enum ObjectTransform { OBJECT_INVERSE_TRANSFORM = 3, OBJECT_PROPERTIES = 6, OBJECT_TRANSFORM_MOTION_PRE = 8, - OBJECT_TRANSFORM_MOTION_POST = 12, - OBJECT_DUPLI = 16 + OBJECT_TRANSFORM_MOTION_MID = 12, + OBJECT_TRANSFORM_MOTION_POST = 16, + OBJECT_DUPLI = 18 }; __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type) @@ -59,11 +60,15 @@ __device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int o motion.pre.z = kernel_tex_fetch(__objects, offset + 2); motion.pre.w = kernel_tex_fetch(__objects, offset + 3); + motion.mid.x = kernel_tex_fetch(__objects, offset + 4); + motion.mid.y = kernel_tex_fetch(__objects, offset + 5); + motion.mid.z = kernel_tex_fetch(__objects, offset + 6); + motion.mid.w = kernel_tex_fetch(__objects, offset + 7); - motion.post.x = kernel_tex_fetch(__objects, offset + 4); - motion.post.y = kernel_tex_fetch(__objects, offset + 5); - motion.post.z = kernel_tex_fetch(__objects, offset + 6); - motion.post.w = 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_motion_interpolate(&tfm, &motion, time); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index bcf80cb76fb..4cf414091f5 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN /* constants */ -#define OBJECT_SIZE 18 +#define OBJECT_SIZE 22 #define LIGHT_SIZE 4 #define FILTER_TABLE_SIZE 256 #define RAMP_TABLE_SIZE 256 diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 727b9801d95..7703d0cbc8e 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -197,9 +197,8 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) } #ifdef __CAMERA_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { - /* todo: exact camera position will not be hit this way */ if(use_motion) { - transform_motion_decompose(&kcam->motion, &motion); + transform_motion_decompose(&kcam->motion, &motion, &matrix); kcam->have_motion = 1; } } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 0bd24f71930..ef139d994da 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1254,8 +1254,6 @@ void WardBsdfNode::attributes(AttributeRequestSet *attributes) void WardBsdfNode::compile(SVMCompiler& compiler) { - ShaderInput *tangent_in = input("Tangent"); - BsdfNode::compile(compiler, input("Roughness U"), input("Roughness V")); } diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index f5d78c080c8..63e904511e6 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -57,7 +57,7 @@ void Object::compute_bounds(bool motion_blur) if(motion_blur && use_motion) { MotionTransform decomp; - transform_motion_decompose(&decomp, &motion); + transform_motion_decompose(&decomp, &motion, &tfm); bounds = BoundBox::empty; @@ -219,7 +219,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene mtfm_post = mtfm_post * itfm; memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4); - memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4); + memcpy(&objects[offset+16], &mtfm_post, sizeof(float4)*4); } #ifdef __OBJECT_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { @@ -227,21 +227,21 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene /* decompose transformations for interpolation */ MotionTransform decomp; - transform_motion_decompose(&decomp, &ob->motion); - memcpy(&objects[offset+8], &decomp, sizeof(float4)*8); + transform_motion_decompose(&decomp, &ob->motion, &ob->tfm); + memcpy(&objects[offset+8], &decomp, sizeof(float4)*12); flag |= SD_OBJECT_MOTION; have_motion = true; } else { float4 no_motion = make_float4(FLT_MAX); - memcpy(&objects[offset+8], &no_motion, sizeof(float4)); + memcpy(&objects[offset+8], &no_motion, sizeof(float4)*12); } } #endif /* dupli object coords */ - objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); - objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f); + objects[offset+20] = 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); /* object flag */ if(ob->use_holdout) diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp index b3c6506dfa0..70ee13d96d7 100644 --- a/intern/cycles/util/util_transform.cpp +++ b/intern/cycles/util/util_transform.cpp @@ -246,9 +246,10 @@ 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); } -void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion) +void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid) { transform_decompose(&decomp->pre, &motion->pre); + transform_decompose(&decomp->mid, mid); transform_decompose(&decomp->post, &motion->post); } diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index 3d6aefed56d..df525542207 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -41,6 +41,7 @@ typedef struct Transform { typedef struct MotionTransform { Transform pre; + Transform mid; Transform post; } MotionTransform; @@ -383,11 +384,37 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform { Transform decomp; - decomp.x = quat_interpolate(motion->pre.x, motion->post.x, t); - decomp.y = (1.0f - t)*motion->pre.y + t*motion->post.y; - decomp.z = (1.0f - t)*motion->pre.z + t*motion->post.z; - decomp.w = (1.0f - t)*motion->pre.w + t*motion->post.w; + /* 3 point bezier curve interpolation for position */ + float3 Ppre = float4_to_float3(motion->pre.y); + float3 Pmid = float4_to_float3(motion->mid.y); + float3 Ppost = float4_to_float3(motion->post.y); + 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); + + decomp.y.x = P.x; + decomp.y.y = P.y; + decomp.y.z = P.z; + + /* linear interpolation for rotation and scale */ + if(t < 0.5f) { + t *= 2.0f; + + decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t); + decomp.y.w = (1.0f - t)*motion->pre.y.w + t*motion->mid.y.w; + 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 { + t = (t - 0.5f)*2.0f; + + decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t); + decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post.y.w; + decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z; + decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w; + } + + /* compose rotation, translation, scale into matrix */ transform_compose(tfm, &decomp); } @@ -398,7 +425,7 @@ __device_inline bool operator==(const MotionTransform& A, const MotionTransform& return (A.pre == B.pre && A.post == B.post); } -void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion); +void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid); #endif