Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/kernel_bvh.h19
-rw-r--r--intern/cycles/kernel/kernel_camera.h25
-rw-r--r--intern/cycles/kernel/kernel_emission.h8
-rw-r--r--intern/cycles/kernel/kernel_light.h13
-rw-r--r--intern/cycles/kernel/kernel_object.h70
-rw-r--r--intern/cycles/kernel/kernel_passes.h7
-rw-r--r--intern/cycles/kernel/kernel_path.h17
-rw-r--r--intern/cycles/kernel/kernel_shader.h58
-rw-r--r--intern/cycles/kernel/kernel_triangle.h63
-rw-r--r--intern/cycles/kernel/kernel_types.h65
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h24
11 files changed, 295 insertions, 74 deletions
diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h
index 523ae8ae926..5da4253bd86 100644
--- a/intern/cycles/kernel/kernel_bvh.h
+++ b/intern/cycles/kernel/kernel_bvh.h
@@ -57,7 +57,7 @@ __device_inline float3 bvh_inverse_direction(float3 dir)
__device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, ray->time, OBJECT_INVERSE_TRANSFORM);
*P = transform_point(&tfm, ray->P);
@@ -74,7 +74,7 @@ __device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray
__device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, ray->time, OBJECT_TRANSFORM);
if(*t != FLT_MAX)
*t *= len(transform_direction(&tfm, 1.0f/(*idir)));
@@ -341,7 +341,7 @@ __device_inline float3 ray_offset(float3 P, float3 Ng)
#endif
}
-__device_inline float3 bvh_triangle_refine(KernelGlobals *kg, const Intersection *isect, const Ray *ray)
+__device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
{
float3 P = ray->P;
float3 D = ray->D;
@@ -349,7 +349,11 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, const Intersection
#ifdef __INTERSECTION_REFINE__
if(isect->object != ~0) {
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#ifdef __MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_INVERSE_TRANSFORM);
+#endif
P = transform_point(&tfm, P);
D = transform_direction(&tfm, D*t);
@@ -366,7 +370,12 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, const Intersection
P = P + D*rt;
if(isect->object != ~0) {
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#ifdef __MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_TRANSFORM);
+#endif
+
P = transform_point(&tfm, P);
}
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 99dac18d545..7b93ed7c0e6 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -63,6 +63,11 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float
/* transform ray from camera to world */
Transform cameratoworld = kernel_data.cam.cameratoworld;
+#ifdef __MOTION__
+ if(ray->time != TIME_INVALID)
+ transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
+#endif
+
ray->P = transform_point(&cameratoworld, ray->P);
ray->D = transform_direction(&cameratoworld, ray->D);
ray->D = normalize(ray->D);
@@ -101,6 +106,11 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa
/* transform ray from camera to world */
Transform cameratoworld = kernel_data.cam.cameratoworld;
+#ifdef __MOTION__
+ if(ray->time != TIME_INVALID)
+ transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
+#endif
+
ray->P = transform_point(&cameratoworld, ray->P);
ray->D = transform_direction(&cameratoworld, ray->D);
ray->D = normalize(ray->D);
@@ -136,6 +146,11 @@ __device void camera_sample_environment(KernelGlobals *kg, float raster_x, float
/* transform ray from camera to world */
Transform cameratoworld = kernel_data.cam.cameratoworld;
+#ifdef __MOTION__
+ if(ray->time != TIME_INVALID)
+ transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
+#endif
+
ray->P = transform_point(&cameratoworld, ray->P);
ray->D = transform_direction(&cameratoworld, ray->D);
ray->D = normalize(ray->D);
@@ -162,14 +177,20 @@ __device void camera_sample_environment(KernelGlobals *kg, float raster_x, float
/* Common */
-__device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, float filter_v, float lens_u, float lens_v, Ray *ray)
+__device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, float filter_v,
+ float lens_u, float lens_v, float time, Ray *ray)
{
/* pixel filter */
float raster_x = x + kernel_tex_interp(__filter_table, filter_u, FILTER_TABLE_SIZE);
float raster_y = y + kernel_tex_interp(__filter_table, filter_v, FILTER_TABLE_SIZE);
+#ifdef __MOTION__
/* motion blur */
- //ray->time = lerp(time_t, kernel_data.cam.shutter_open, kernel_data.cam.shutter_close);
+ if(kernel_data.cam.shuttertime == 0.0f)
+ ray->time = TIME_INVALID;
+ else
+ ray->time = 0.5f + (time - 0.5f)*kernel_data.cam.shuttertime;
+#endif
/* sample */
if(kernel_data.cam.type == CAMERA_PERSPECTIVE)
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 764ac599991..cd7701a0c75 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -21,7 +21,7 @@ CCL_NAMESPACE_BEGIN
/* Direction Emission */
__device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
- LightSample *ls, float u, float v, float3 I)
+ LightSample *ls, float u, float v, float3 I, float time)
{
/* setup shading at emitter */
ShaderData sd;
@@ -40,7 +40,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
else
#endif
{
- shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v);
+ shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, time);
ls->Ng = sd.Ng;
/* no path flag, we're evaluating this for all closures. that's weak but
@@ -76,7 +76,7 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
#endif
{
/* sample a light and position on int */
- light_sample(kg, randt, randu, randv, sd->P, &ls, &pdf);
+ light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls, &pdf);
}
/* compute pdf */
@@ -87,7 +87,7 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
return false;
/* evaluate closure */
- float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D);
+ float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D, sd->time);
if(is_zero(light_eval))
return false;
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 42260577069..c2cf293cab3 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -251,7 +251,7 @@ __device float regular_light_pdf(KernelGlobals *kg,
/* Triangle Light */
__device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
- float randu, float randv, LightSample *ls)
+ float randu, float randv, float time, LightSample *ls)
{
/* triangle, so get position, normal, shader */
ls->P = triangle_sample_MT(kg, prim, randu, randv);
@@ -264,8 +264,11 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
#ifdef __INSTANCING__
/* instance transform */
if(ls->object >= 0) {
- object_position_transform(kg, ls->object, &ls->P);
- object_normal_transform(kg, ls->object, &ls->Ng);
+ Transform tfm = object_fetch_transform(kg, ls->object, time, OBJECT_TRANSFORM);
+ Transform itfm = object_fetch_transform(kg, ls->object, time, OBJECT_INVERSE_TRANSFORM);
+
+ ls->P = transform_point(&tfm, ls->P);
+ ls->Ng = transform_direction_transposed(&itfm, ls->Ng);
}
#endif
}
@@ -313,7 +316,7 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt)
/* Generic Light */
-__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float3 P, LightSample *ls, float *pdf)
+__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls, float *pdf)
{
/* sample index */
int index = light_distribution_sample(kg, randt);
@@ -324,7 +327,7 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
if(prim >= 0) {
int object = __float_as_int(l.w);
- triangle_light_sample(kg, prim, object, randu, randv, ls);
+ triangle_light_sample(kg, prim, object, randu, randv, time, ls);
}
else {
int point = -prim-1;
diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h
index b676f58e5d4..262ca848f28 100644
--- a/intern/cycles/kernel/kernel_object.h
+++ b/intern/cycles/kernel/kernel_object.h
@@ -20,41 +20,87 @@ CCL_NAMESPACE_BEGIN
enum ObjectTransform {
OBJECT_TRANSFORM = 0,
- OBJECT_INVERSE_TRANSFORM = 4,
- OBJECT_NORMAL_TRANSFORM = 8,
- OBJECT_PROPERTIES = 12
+ OBJECT_INVERSE_TRANSFORM = 3,
+ OBJECT_PROPERTIES = 6,
+ OBJECT_TRANSFORM_MOTION_PRE = 8,
+ OBJECT_TRANSFORM_MOTION_POST = 12
};
-__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
+__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, float time, enum ObjectTransform type)
{
Transform tfm;
+#ifdef __MOTION__
+ /* if we do motion blur */
+ if(time != TIME_INVALID) {
+ int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE;
+ float4 have_motion = kernel_tex_fetch(__objects, offset + 0);
+
+ /* if this object have motion */
+ if(have_motion.x != FLT_MAX) {
+ /* fetch motion transforms */
+ MotionTransform motion;
+
+ motion.pre.x = have_motion;
+ motion.pre.y = kernel_tex_fetch(__objects, offset + 1);
+ motion.pre.z = kernel_tex_fetch(__objects, offset + 2);
+ motion.pre.w = kernel_tex_fetch(__objects, offset + 3);
+
+ 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);
+
+ /* interpolate (todo: do only once per object) */
+ transform_motion_interpolate(&tfm, &motion, time);
+
+ /* invert */
+ if(type == OBJECT_INVERSE_TRANSFORM)
+ tfm = transform_quick_inverse(tfm);
+
+ return tfm;
+ }
+ }
+#endif
+
int offset = object*OBJECT_SIZE + (int)type;
tfm.x = kernel_tex_fetch(__objects, offset + 0);
tfm.y = kernel_tex_fetch(__objects, offset + 1);
tfm.z = kernel_tex_fetch(__objects, offset + 2);
- tfm.w = kernel_tex_fetch(__objects, offset + 3);
+ tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
return tfm;
}
-__device_inline void object_position_transform(KernelGlobals *kg, int object, float3 *P)
+__device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P)
{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+#ifdef __MOTION__
+ *P = transform_point(&sd->ob_tfm, *P);
+#else
+ Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM);
*P = transform_point(&tfm, *P);
+#endif
}
-__device_inline void object_normal_transform(KernelGlobals *kg, int object, float3 *N)
+__device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_NORMAL_TRANSFORM);
- *N = normalize(transform_direction(&tfm, *N));
+#ifdef __MOTION__
+ *N = normalize(transform_direction_transposed(&sd->ob_itfm, *N));
+#else
+ Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM);
+ *N = normalize(transform_direction_transposed(&tfm, *N));
+#endif
}
-__device_inline void object_dir_transform(KernelGlobals *kg, int object, float3 *D)
+__device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, float3 *D)
{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+#ifdef __MOTION__
+ *D = transform_direction(&sd->ob_tfm, *D);
+#else
+ Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM);
*D = transform_direction(&tfm, *D);
+#endif
}
__device_inline float object_surface_area(KernelGlobals *kg, int object)
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index fd4ee17cdc1..f3ddda4a392 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -72,9 +72,14 @@ __device_inline void kernel_write_data_passes(KernelGlobals *kg, __global float
kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, sample, normal);
}
if(flag & PASS_UV) {
- float3 uv = make_float3(0.0f, 0.0f, 0.0f); /* todo: request and lookup */
+ float3 uv = triangle_uv(kg, sd);
kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, sample, uv);
}
+ if(flag & PASS_MOTION) {
+ float4 speed = triangle_motion_vector(kg, sd);
+ kernel_write_pass_float4(buffer + kernel_data.film.pass_motion, sample, speed);
+ kernel_write_pass_float(buffer + kernel_data.film.pass_motion_weight, sample, 1.0f);
+ }
}
if(flag & (PASS_DIFFUSE_INDIRECT|PASS_DIFFUSE_COLOR|PASS_DIFFUSE_DIRECT))
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 8ebac177277..b7c22087e1f 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -18,8 +18,8 @@
#include "kernel_differential.h"
#include "kernel_montecarlo.h"
-#include "kernel_triangle.h"
#include "kernel_object.h"
+#include "kernel_triangle.h"
#ifdef __QBVH__
#include "kernel_qbvh.h"
#else
@@ -324,6 +324,9 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
light_ray.P = ray_offset(sd.P, sd.Ng);
light_ray.D = ao_D;
light_ray.t = kernel_data.background.ao_distance;
+#ifdef __MOTION__
+ light_ray.time = sd.time;
+#endif
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
@@ -346,6 +349,10 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
BsdfEval L_light;
bool is_lamp;
+#ifdef __MOTION__
+ light_ray.time = sd.time;
+#endif
+
#ifdef __MULTI_LIGHT__
/* index -1 means randomly sample from distribution */
int i = (kernel_data.integrator.num_distribution)? -1: 0;
@@ -449,7 +456,13 @@ __device void kernel_path_trace(KernelGlobals *kg,
float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U);
float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V);
- camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, &ray);
+#ifdef __MOTION__
+ float time = path_rng(kg, &rng, sample, PRNG_TIME);
+#else
+ float time = 0.0f;
+#endif
+
+ camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, &ray);
/* integrate */
float4 L = kernel_path_integrate(kg, &rng, sample, ray, buffer);
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 46ef5d2022a..b2f2a7577be 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -53,16 +53,9 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
int shader = __float_as_int(Ns.w);
- /* vectors */
- sd->P = bvh_triangle_refine(kg, isect, ray);
- sd->Ng = Ng;
- sd->N = Ng;
- sd->I = -ray->D;
- sd->shader = shader;
-
/* triangle */
#ifdef __INSTANCING__
- sd->object = isect->object;
+ sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
#endif
sd->prim = prim;
#ifdef __UV__
@@ -70,6 +63,21 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
sd->v = isect->v;
#endif
+ /* matrices and time */
+#ifdef __MOTION__
+ sd->ob_tfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_TRANSFORM);
+ sd->ob_itfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_INVERSE_TRANSFORM);
+
+ sd->time = ray->time;
+#endif
+
+ /* vectors */
+ sd->P = bvh_triangle_refine(kg, sd, isect, ray);
+ sd->Ng = Ng;
+ sd->N = Ng;
+ sd->I = -ray->D;
+ sd->shader = shader;
+
/* smooth normal */
if(sd->shader & SHADER_SMOOTH_NORMAL)
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
@@ -82,19 +90,15 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
#endif
#ifdef __INSTANCING__
- if(sd->object != ~0) {
+ if(isect->object != ~0) {
/* instance transform */
- object_normal_transform(kg, sd->object, &sd->N);
- object_normal_transform(kg, sd->object, &sd->Ng);
+ object_normal_transform(kg, sd, &sd->N);
+ object_normal_transform(kg, sd, &sd->Ng);
#ifdef __DPDU__
- object_dir_transform(kg, sd->object, &sd->dPdu);
- object_dir_transform(kg, sd->object, &sd->dPdv);
+ object_dir_transform(kg, sd, &sd->dPdu);
+ object_dir_transform(kg, sd, &sd->dPdv);
#endif
}
- else {
- /* non-instanced object index */
- sd->object = kernel_tex_fetch(__prim_object, isect->prim);
- }
#endif
/* backfacing test */
@@ -122,7 +126,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
__device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
const float3 P, const float3 Ng, const float3 I,
- int shader, int object, int prim, float u, float v)
+ int shader, int object, int prim, float u, float v, float time)
{
/* vectors */
sd->P = P;
@@ -155,13 +159,20 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
}
#endif
+#ifdef __MOTION__
+ sd->time = time;
+
+ sd->ob_tfm = object_fetch_transform(kg, sd->object, time, OBJECT_TRANSFORM);
+ sd->ob_itfm = object_fetch_transform(kg, sd->object, time, OBJECT_INVERSE_TRANSFORM);
+#endif
+
/* smooth normal */
if(sd->shader & SHADER_SMOOTH_NORMAL) {
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
#ifdef __INSTANCING__
if(instanced)
- object_normal_transform(kg, sd->object, &sd->N);
+ object_normal_transform(kg, sd, &sd->N);
#endif
}
@@ -178,8 +189,8 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#ifdef __INSTANCING__
if(instanced) {
- object_dir_transform(kg, sd->object, &sd->dPdu);
- object_dir_transform(kg, sd->object, &sd->dPdv);
+ object_dir_transform(kg, sd, &sd->dPdu);
+ object_dir_transform(kg, sd, &sd->dPdv);
}
#endif
}
@@ -229,7 +240,7 @@ __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
/* watch out: no instance transform currently */
- shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v);
+ shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, TIME_INVALID);
}
/* ShaderData setup from ray into background */
@@ -243,6 +254,9 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
sd->I = -sd->P;
sd->shader = kernel_data.background.shader;
sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
+#ifdef __MOTION__
+ sd->time = ray->time;
+#endif
#ifdef __INSTANCING__
sd->object = ~0;
diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h
index 7eaf54d14bf..1b3956c1dd4 100644
--- a/intern/cycles/kernel/kernel_triangle.h
+++ b/intern/cycles/kernel/kernel_triangle.h
@@ -179,5 +179,68 @@ __device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *s
}
}
+/* motion */
+
+__device int triangle_find_attribute(KernelGlobals *kg, ShaderData *sd, uint id)
+{
+ /* find attribute by unique id */
+ uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+ while(attr_map.x != id)
+ attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
+
+ /* return result */
+ return (attr_map.y == ATTR_ELEMENT_NONE)? ATTR_STD_NOT_FOUND: attr_map.z;
+}
+
+__device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd)
+{
+ float3 motion_pre = sd->P, motion_post = sd->P;
+
+ /* deformation motion */
+ int offset_pre = triangle_find_attribute(kg, sd, ATTR_STD_MOTION_PRE);
+ int offset_post = triangle_find_attribute(kg, sd, ATTR_STD_MOTION_POST);
+
+ if(offset_pre != ATTR_STD_NOT_FOUND)
+ motion_pre = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_pre, NULL, NULL);
+ if(offset_post != ATTR_STD_NOT_FOUND)
+ motion_post = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, offset_post, NULL, NULL);
+
+ /* object motion. note that depending on the mesh having motion vectors, this
+ transformation was set match the world/object space of motion_pre/post */
+ Transform tfm;
+
+ tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_PRE);
+ motion_pre = transform_point(&tfm, motion_pre);
+
+ tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_POST);
+ motion_post = transform_point(&tfm, motion_post);
+
+ /* camera motion */
+ tfm = kernel_data.cam.worldtoraster;
+ float3 P = transform_perspective(&tfm, sd->P);
+
+ tfm = kernel_data.cam.motion.pre;
+ motion_pre = transform_perspective(&tfm, motion_pre) - P;
+
+ tfm = kernel_data.cam.motion.post;
+ motion_post = P - transform_perspective(&tfm, motion_post);
+
+ return make_float4(motion_pre.x, motion_pre.y, motion_post.x, motion_post.y);
+}
+
+__device float3 triangle_uv(KernelGlobals *kg, ShaderData *sd)
+{
+ int offset_uv = triangle_find_attribute(kg, sd, ATTR_STD_UV);
+
+ if(offset_uv == ATTR_STD_NOT_FOUND)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ float3 uv = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, offset_uv, NULL, NULL);
+ uv.z = 1.0f;
+ return uv;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 102a2bb036d..e9103087025 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -20,9 +20,12 @@
#define __KERNEL_TYPES_H__
#include "kernel_math.h"
-
#include "svm/svm_types.h"
+#ifndef __KERNEL_GPU__
+#define __KERNEL_CPU__
+#endif
+
CCL_NAMESPACE_BEGIN
/* constants */
@@ -30,6 +33,7 @@ CCL_NAMESPACE_BEGIN
#define LIGHT_SIZE 4
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
+#define TIME_INVALID FLT_MAX
/* device capabilities */
#ifdef __KERNEL_CPU__
@@ -75,6 +79,7 @@ CCL_NAMESPACE_BEGIN
#define __PASSES__
#define __BACKGROUND_MIS__
#define __AO__
+//#define __MOTION__
#endif
//#define __MULTI_LIGHT__
@@ -90,14 +95,21 @@ enum ShaderEvalType {
SHADER_EVAL_BACKGROUND
};
-/* Path Tracing */
+/* Path Tracing
+ * note we need to keep the u/v pairs at even values */
enum PathTraceDimension {
PRNG_FILTER_U = 0,
PRNG_FILTER_V = 1,
PRNG_LENS_U = 2,
PRNG_LENS_V = 3,
+#ifdef __MOTION__
+ PRNG_TIME = 4,
+ PRNG_UNUSED = 5,
+ PRNG_BASE_NUM = 6,
+#else
PRNG_BASE_NUM = 4,
+#endif
PRNG_BSDF_U = 0,
PRNG_BSDF_V = 1,
@@ -177,7 +189,9 @@ typedef enum PassType {
PASS_EMISSION = 65536,
PASS_BACKGROUND = 131072,
PASS_AO = 262144,
- PASS_SHADOW = 524288
+ PASS_SHADOW = 524288,
+ PASS_MOTION = 1048576,
+ PASS_MOTION_WEIGHT = 2097152
} PassType;
#define PASS_ALL (~0)
@@ -275,6 +289,7 @@ typedef struct Ray {
float3 P;
float3 D;
float t;
+ float time;
#ifdef __RAY_DIFFERENTIALS__
differential3 dP;
@@ -300,6 +315,21 @@ typedef enum AttributeElement {
ATTR_ELEMENT_NONE
} AttributeElement;
+typedef enum AttributeStandard {
+ ATTR_STD_NONE = 0,
+ ATTR_STD_VERTEX_NORMAL,
+ ATTR_STD_FACE_NORMAL,
+ ATTR_STD_UV,
+ ATTR_STD_GENERATED,
+ ATTR_STD_POSITION_UNDEFORMED,
+ ATTR_STD_POSITION_UNDISPLACED,
+ ATTR_STD_MOTION_PRE,
+ ATTR_STD_MOTION_POST,
+ ATTR_STD_NUM,
+
+ ATTR_STD_NOT_FOUND = ~0
+} AttributeStandard;
+
/* Closure data */
#define MAX_CLOSURE 8
@@ -365,6 +395,16 @@ typedef struct ShaderData {
/* object id if there is one, ~0 otherwise */
int object;
+ /* motion blur sample time */
+ float time;
+
+#ifdef __MOTION__
+ /* object <-> world space transformations, cached to avoid
+ * re-interpolating them constantly for shading */
+ Transform ob_tfm;
+ Transform ob_itfm;
+#endif
+
#ifdef __RAY_DIFFERENTIALS__
/* differential of P. these are orthogonal to Ng, not N */
differential3 dP;
@@ -422,8 +462,8 @@ typedef struct KernelCamera {
float focaldistance;
/* motion blur */
- float shutteropen;
- float shutterclose;
+ float shuttertime;
+ float pad;
/* clipping */
float nearclip;
@@ -437,6 +477,8 @@ typedef struct KernelCamera {
Transform worldtoraster;
Transform worldtondc;
Transform worldtocamera;
+
+ MotionTransform motion;
} KernelCamera;
typedef struct KernelFilm {
@@ -448,27 +490,32 @@ typedef struct KernelFilm {
int pass_combined;
int pass_depth;
int pass_normal;
- int pass_pad;
+ int pass_motion;
+ int pass_motion_weight;
int pass_uv;
int pass_object_id;
int pass_material_id;
- int pass_diffuse_color;
+ int pass_diffuse_color;
int pass_glossy_color;
int pass_transmission_color;
int pass_diffuse_indirect;
- int pass_glossy_indirect;
+ int pass_glossy_indirect;
int pass_transmission_indirect;
int pass_diffuse_direct;
int pass_glossy_direct;
- int pass_transmission_direct;
+ int pass_transmission_direct;
int pass_emission;
int pass_background;
int pass_ao;
+
int pass_shadow;
+ int pass_pad1;
+ int pass_pad2;
+ int pass_pad3;
} KernelFilm;
typedef struct KernelBackground {
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 98f8734aed2..5ecda795251 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -33,8 +33,8 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack
switch(type) {
case NODE_TEXCO_OBJECT: {
if(sd->object != ~0) {
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- data = transform_point(&tfm, sd->P);
+ data = sd->P;
+ object_position_transform(kg, sd, &data);
}
else
data = sd->P;
@@ -42,8 +42,8 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack
}
case NODE_TEXCO_NORMAL: {
if(sd->object != ~0) {
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- data = transform_direction(&tfm, sd->N);
+ data = sd->N;
+ object_normal_transform(kg, sd, &data);
}
else
data = sd->N;
@@ -87,8 +87,8 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa
switch(type) {
case NODE_TEXCO_OBJECT: {
if(sd->object != ~0) {
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- data = transform_point(&tfm, sd->P + sd->dP.dx);
+ data = sd->P + sd->dP.dx;
+ object_position_transform(kg, sd, &data);
}
else
data = sd->P + sd->dP.dx;
@@ -96,8 +96,8 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa
}
case NODE_TEXCO_NORMAL: {
if(sd->object != ~0) {
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- data = transform_direction(&tfm, sd->N);
+ data = sd->N;
+ object_normal_transform(kg, sd, &data);
}
else
data = sd->N;
@@ -144,8 +144,8 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa
switch(type) {
case NODE_TEXCO_OBJECT: {
if(sd->object != ~0) {
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- data = transform_point(&tfm, sd->P + sd->dP.dy);
+ data = sd->P + sd->dP.dy;
+ object_position_transform(kg, sd, &data);
}
else
data = sd->P + sd->dP.dy;
@@ -153,8 +153,8 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa
}
case NODE_TEXCO_NORMAL: {
if(sd->object != ~0) {
- Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
- data = normalize(transform_direction(&tfm, sd->N));
+ data = sd->N;
+ object_normal_transform(kg, sd, &data);
}
else
data = sd->N;