From fe00dbcc23267ee435d0dd90a824f54989db233f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 May 2014 15:32:13 +0200 Subject: [PATCH] Fix cycles motion pass for hair curves showing a bit of motion when there isn't any. --- intern/cycles/kernel/geom/geom_curve.h | 17 ++++++++++++ intern/cycles/kernel/geom/geom_primitive.h | 30 +++++++++++++++------- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h index dbffcbcf6ca..e1d225436a6 100644 --- a/intern/cycles/kernel/geom/geom_curve.h +++ b/intern/cycles/kernel/geom/geom_curve.h @@ -125,6 +125,23 @@ ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd) return r*2.0f; } +/* Curve location for motion pass, linear interpolation between keys and + * ignoring radius because we do the same for the motion keys */ + +ccl_device float3 curve_motion_center_location(KernelGlobals *kg, ShaderData *sd) +{ + float4 curvedata = kernel_tex_fetch(__curves, sd->prim); + int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type); + int k1 = k0 + 1; + + float4 P_curve[2]; + + P_curve[0]= kernel_tex_fetch(__curve_keys, k0); + P_curve[1]= kernel_tex_fetch(__curve_keys, k1); + + return float4_to_float3(P_curve[1]) * sd->u + float4_to_float3(P_curve[0]) * (1.0f - sd->u); +} + /* Curve tangent normal */ ccl_device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd) diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h index f821e696a07..533973621d7 100644 --- a/intern/cycles/kernel/geom/geom_primitive.h +++ b/intern/cycles/kernel/geom/geom_primitive.h @@ -140,7 +140,19 @@ ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd) ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd) { - float3 motion_pre = sd->P, motion_post = sd->P; + /* center position */ + float3 center; + + if(sd->type & PRIMITIVE_ALL_CURVE) { + center = curve_motion_center_location(kg, sd); + + if(!(sd->flag & SD_TRANSFORM_APPLIED)) + object_position_transform(kg, sd, ¢er); + } + else + center = sd->P; + + float3 motion_pre = center, motion_post = center; /* deformation motion */ AttributeElement elem; @@ -168,13 +180,13 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd) tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_POST); motion_post = transform_point(&tfm, motion_post); - float3 P; + float3 motion_center; /* camera motion, for perspective/orthographic motion.pre/post will be a * world-to-raster matrix, for panorama it's world-to-camera */ if (kernel_data.cam.type != CAMERA_PANORAMA) { tfm = kernel_data.cam.worldtoraster; - P = transform_perspective(&tfm, sd->P); + motion_center = transform_perspective(&tfm, center); tfm = kernel_data.cam.motion.pre; motion_pre = transform_perspective(&tfm, motion_pre); @@ -184,10 +196,10 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd) } else { tfm = kernel_data.cam.worldtocamera; - P = normalize(transform_point(&tfm, sd->P)); - P = float2_to_float3(direction_to_panorama(kg, P)); - P.x *= kernel_data.cam.width; - P.y *= kernel_data.cam.height; + motion_center = normalize(transform_point(&tfm, center)); + motion_center = float2_to_float3(direction_to_panorama(kg, motion_center)); + motion_center.x *= kernel_data.cam.width; + motion_center.y *= kernel_data.cam.height; tfm = kernel_data.cam.motion.pre; motion_pre = normalize(transform_point(&tfm, motion_pre)); @@ -202,8 +214,8 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd) motion_post.y *= kernel_data.cam.height; } - motion_pre = motion_pre - P; - motion_post = P - motion_post; + motion_pre = motion_pre - motion_center; + motion_post = motion_center - motion_post; return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y); }