diff options
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/kernel_bvh.h | 19 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_camera.h | 25 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_emission.h | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_light.h | 13 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_object.h | 70 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_passes.h | 7 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 17 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_shader.h | 58 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_triangle.h | 63 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 65 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_tex_coord.h | 24 |
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; |