Code refactor: avoid motion transform copy, remove unused curved code.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Wed, 7 Mar 2018 22:52:26 +0000 (23:52 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 10 Mar 2018 03:54:04 +0000 (04:54 +0100)
The purpose of the previous code refactoring is to make the code more readable,
but combined with this change benchmarks also render about 2-3% faster with an
NVIDIA Titan Xp.

intern/cycles/kernel/geom/geom_object.h
intern/cycles/kernel/kernel_camera.h
intern/cycles/util/util_transform.h

index 0b410f448c8c41d6ba3683aca1f8bd3cbe0397a9..3fbceded26151d5b5ab4b3c750b74f1e50829d41 100644 (file)
@@ -96,10 +96,10 @@ ccl_device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int
 #ifdef __OBJECT_MOTION__
 ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
 {
-       MotionTransform motion = kernel_tex_fetch(__objects, object).tfm;
+       const ccl_global MotionTransform *motion = &kernel_tex_fetch(__objects, object).tfm;
 
        Transform tfm;
-       transform_motion_interpolate(&tfm, &motion, time);
+       transform_motion_interpolate(&tfm, motion, time);
 
        return tfm;
 }
index 96cdb04d95548e43cf62f30223d6b82386717f98..66ed9f5fc0f1aa132f0ef0dc490b3e55c3044f0e 100644 (file)
@@ -92,16 +92,10 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
 
 #ifdef __CAMERA_MOTION__
        if(kernel_data.cam.have_motion) {
-#  ifdef __KERNEL_OPENCL__
-               const MotionTransform tfm = kernel_data.cam.motion;
-               transform_motion_interpolate(&cameratoworld,
-                                                                        &tfm,
-                                            ray->time);
-#  else
-               transform_motion_interpolate(&cameratoworld,
-                                            &kernel_data.cam.motion,
-                                            ray->time);
-#  endif
+               ccl_constant MotionTransform *motion = &kernel_data.cam.motion;
+               transform_motion_interpolate_constant(&cameratoworld,
+                                                     motion,
+                                                     ray->time);
        }
 #endif
 
@@ -204,16 +198,10 @@ ccl_device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, fl
 
 #ifdef __CAMERA_MOTION__
        if(kernel_data.cam.have_motion) {
-#  ifdef __KERNEL_OPENCL__
-               const MotionTransform tfm = kernel_data.cam.motion;
-               transform_motion_interpolate(&cameratoworld,
-                                            &tfm,
-                                            ray->time);
-#  else
-               transform_motion_interpolate(&cameratoworld,
-                                            &kernel_data.cam.motion,
-                                            ray->time);
-#  endif
+               ccl_constant MotionTransform *motion = &kernel_data.cam.motion;
+               transform_motion_interpolate_constant(&cameratoworld,
+                                                     motion,
+                                                     ray->time);
        }
 #endif
 
@@ -282,16 +270,10 @@ ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
 
 #ifdef __CAMERA_MOTION__
        if(cam->have_motion) {
-#  ifdef __KERNEL_OPENCL__
-               const MotionTransform tfm = cam->motion;
-               transform_motion_interpolate(&cameratoworld,
-                                            &tfm,
-                                            ray->time);
-#  else
-               transform_motion_interpolate(&cameratoworld,
-                                            &cam->motion,
-                                            ray->time);
-#  endif
+               ccl_constant MotionTransform *motion = &cam->motion;
+               transform_motion_interpolate_constant(&cameratoworld,
+                                                     motion,
+                                                     ray->time);
        }
 #endif
 
index ac0804a722722831cbf720a20075e88ca55cb159..1efe001f6a8f677e59ea91336846ca4f2f6a7af9 100644 (file)
@@ -455,40 +455,45 @@ ccl_device_inline void transform_compose(Transform *tfm, const Transform *decomp
        tfm->w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
 }
 
-/* Disabled for now, need arc-length parametrization for constant speed motion.
- * #define CURVED_MOTION_INTERPOLATE */
+ccl_device void transform_motion_interpolate(Transform *tfm, const ccl_global MotionTransform *motion, float t)
+{
+       Transform decomp;
+
+       /* 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 = (1.0f - t)*motion->pre.y + t*motion->mid.y;
+               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 = (1.0f - t)*motion->mid.y + t*motion->post.y;
+               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);
+}
 
-ccl_device void transform_motion_interpolate(Transform *tfm, const MotionTransform *motion, float t)
+ccl_device void transform_motion_interpolate_constant(Transform *tfm, ccl_constant MotionTransform *motion, float t)
 {
        /* 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
         * just shearing perhaps? */
        Transform decomp;
 
-#ifdef CURVED_MOTION_INTERPOLATE
-       /* 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;
-#endif
-
        /* linear interpolation for rotation and scale */
        if(t < 0.5f) {
                t *= 2.0f;
 
                decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t);
-#ifdef CURVED_MOTION_INTERPOLATE
-               decomp.y.w = (1.0f - t)*motion->pre.y.w + t*motion->mid.y.w;
-#else
                decomp.y = (1.0f - t)*motion->pre.y + t*motion->mid.y;
-#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;
        }
@@ -496,11 +501,7 @@ ccl_device void transform_motion_interpolate(Transform *tfm, const MotionTransfo
                t = (t - 0.5f)*2.0f;
 
                decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t);
-#ifdef CURVED_MOTION_INTERPOLATE
-               decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post.y.w;
-#else
                decomp.y = (1.0f - t)*motion->mid.y + t*motion->post.y;
-#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;
        }