diff options
Diffstat (limited to 'intern/cycles/kernel/geom/geom_object.h')
-rw-r--r-- | intern/cycles/kernel/geom/geom_object.h | 270 |
1 files changed, 122 insertions, 148 deletions
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index f51b2d18657..800649abf38 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -28,61 +28,44 @@ CCL_NAMESPACE_BEGIN enum ObjectTransform { OBJECT_TRANSFORM = 0, - OBJECT_TRANSFORM_MOTION_PRE = 0, - OBJECT_INVERSE_TRANSFORM = 4, - OBJECT_TRANSFORM_MOTION_POST = 4, - OBJECT_PROPERTIES = 8, - OBJECT_DUPLI = 9 + OBJECT_INVERSE_TRANSFORM = 1, }; enum ObjectVectorTransform { - OBJECT_VECTOR_MOTION_PRE = 0, - OBJECT_VECTOR_MOTION_POST = 3 + OBJECT_PASS_MOTION_PRE = 0, + OBJECT_PASS_MOTION_POST = 1 }; /* Object to world space transformation */ ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type) { - int offset = object*OBJECT_SIZE + (int)type; - - Transform tfm; - 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 = make_float4(0.0f, 0.0f, 0.0f, 1.0f); - - return tfm; + if(type == OBJECT_INVERSE_TRANSFORM) { + return kernel_tex_fetch(__objects, object).itfm; + } + else { + return kernel_tex_fetch(__objects, object).tfm; + } } /* Lamp to world space transformation */ ccl_device_inline Transform lamp_fetch_transform(KernelGlobals *kg, int lamp, bool inverse) { - int offset = lamp*LIGHT_SIZE + (inverse? 8 : 5); - - Transform tfm; - tfm.x = kernel_tex_fetch(__light_data, offset + 0); - tfm.y = kernel_tex_fetch(__light_data, offset + 1); - tfm.z = kernel_tex_fetch(__light_data, offset + 2); - tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f); - - return tfm; + if(inverse) { + return kernel_tex_fetch(__lights, lamp).itfm; + } + else { + return kernel_tex_fetch(__lights, lamp).tfm; + } } /* Object to world space transformation for motion vectors */ -ccl_device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type) +ccl_device_inline Transform object_fetch_motion_pass_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type) { - int offset = object*OBJECT_VECTOR_SIZE + (int)type; - - Transform tfm; - tfm.x = kernel_tex_fetch(__objects_vector, offset + 0); - tfm.y = kernel_tex_fetch(__objects_vector, offset + 1); - tfm.z = kernel_tex_fetch(__objects_vector, offset + 2); - tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f); - - return tfm; + int offset = object*OBJECT_MOTION_PASS_SIZE + (int)type; + return kernel_tex_fetch(__object_motion_pass, offset); } /* Motion blurred object transformations */ @@ -90,22 +73,12 @@ 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) { - DecompMotionTransform motion; - - int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE; - - motion.mid.x = kernel_tex_fetch(__objects, offset + 0); - motion.mid.y = kernel_tex_fetch(__objects, offset + 1); - motion.mid.z = kernel_tex_fetch(__objects, offset + 2); - motion.mid.w = kernel_tex_fetch(__objects, offset + 3); - - motion.pre_x = kernel_tex_fetch(__objects, offset + 4); - motion.pre_y = kernel_tex_fetch(__objects, offset + 5); - motion.post_x = kernel_tex_fetch(__objects, offset + 6); - motion.post_y = kernel_tex_fetch(__objects, offset + 7); + const uint motion_offset = kernel_tex_fetch(__objects, object).motion_offset; + const ccl_global DecomposedTransform *motion = &kernel_tex_fetch(__object_motion, motion_offset); + const uint num_steps = kernel_tex_fetch(__objects, object).numsteps * 2 + 1; Transform tfm; - transform_motion_interpolate(&tfm, &motion, time); + transform_motion_array_interpolate(&tfm, motion, num_steps, time); return tfm; } @@ -137,9 +110,9 @@ ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals *kg ccl_device_inline void object_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P) { #ifdef __OBJECT_MOTION__ - *P = transform_point_auto(&ccl_fetch(sd, ob_tfm), *P); + *P = transform_point_auto(&sd->ob_tfm, *P); #else - Transform tfm = object_fetch_transform(kg, ccl_fetch(sd, object), OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); *P = transform_point(&tfm, *P); #endif } @@ -149,9 +122,9 @@ ccl_device_inline void object_position_transform(KernelGlobals *kg, const Shader ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P) { #ifdef __OBJECT_MOTION__ - *P = transform_point_auto(&ccl_fetch(sd, ob_itfm), *P); + *P = transform_point_auto(&sd->ob_itfm, *P); #else - Transform tfm = object_fetch_transform(kg, ccl_fetch(sd, object), OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); *P = transform_point(&tfm, *P); #endif } @@ -161,12 +134,16 @@ ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, cons ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N) { #ifdef __OBJECT_MOTION__ - if((ccl_fetch(sd, object) != OBJECT_NONE) || (ccl_fetch(sd, type) == PRIMITIVE_LAMP)) { - *N = normalize(transform_direction_transposed_auto(&ccl_fetch(sd, ob_tfm), *N)); + if((sd->object != OBJECT_NONE) || (sd->type == PRIMITIVE_LAMP)) { + *N = normalize(transform_direction_transposed_auto(&sd->ob_tfm, *N)); } #else - if(ccl_fetch(sd, object) != OBJECT_NONE) { - Transform tfm = object_fetch_transform(kg, ccl_fetch(sd, object), OBJECT_TRANSFORM); + if(sd->object != OBJECT_NONE) { + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); + *N = normalize(transform_direction_transposed(&tfm, *N)); + } + else if(sd->type == PRIMITIVE_LAMP) { + Transform tfm = lamp_fetch_transform(kg, sd->lamp, false); *N = normalize(transform_direction_transposed(&tfm, *N)); } #endif @@ -177,9 +154,9 @@ ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, const ccl_device_inline void object_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N) { #ifdef __OBJECT_MOTION__ - *N = normalize(transform_direction_transposed_auto(&ccl_fetch(sd, ob_itfm), *N)); + *N = normalize(transform_direction_transposed_auto(&sd->ob_itfm, *N)); #else - Transform tfm = object_fetch_transform(kg, ccl_fetch(sd, object), OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); *N = normalize(transform_direction_transposed(&tfm, *N)); #endif } @@ -189,9 +166,9 @@ ccl_device_inline void object_normal_transform(KernelGlobals *kg, const ShaderDa ccl_device_inline void object_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D) { #ifdef __OBJECT_MOTION__ - *D = transform_direction_auto(&ccl_fetch(sd, ob_tfm), *D); + *D = transform_direction_auto(&sd->ob_tfm, *D); #else - Transform tfm = object_fetch_transform(kg, ccl_fetch(sd, object), OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); *D = transform_direction(&tfm, *D); #endif } @@ -201,9 +178,9 @@ ccl_device_inline void object_dir_transform(KernelGlobals *kg, const ShaderData ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D) { #ifdef __OBJECT_MOTION__ - *D = transform_direction_auto(&ccl_fetch(sd, ob_itfm), *D); + *D = transform_direction_auto(&sd->ob_itfm, *D); #else - Transform tfm = object_fetch_transform(kg, ccl_fetch(sd, object), OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); *D = transform_direction(&tfm, *D); #endif } @@ -212,13 +189,13 @@ ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, const Sha ccl_device_inline float3 object_location(KernelGlobals *kg, const ShaderData *sd) { - if(ccl_fetch(sd, object) == OBJECT_NONE) + if(sd->object == OBJECT_NONE) return make_float3(0.0f, 0.0f, 0.0f); #ifdef __OBJECT_MOTION__ - return make_float3(ccl_fetch(sd, ob_tfm).x.w, ccl_fetch(sd, ob_tfm).y.w, ccl_fetch(sd, ob_tfm).z.w); + return make_float3(sd->ob_tfm.x.w, sd->ob_tfm.y.w, sd->ob_tfm.z.w); #else - Transform tfm = object_fetch_transform(kg, ccl_fetch(sd, object), OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); return make_float3(tfm.x.w, tfm.y.w, tfm.z.w); #endif } @@ -227,9 +204,7 @@ ccl_device_inline float3 object_location(KernelGlobals *kg, const ShaderData *sd ccl_device_inline float object_surface_area(KernelGlobals *kg, int object) { - int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; - float4 f = kernel_tex_fetch(__objects, offset); - return f.x; + return kernel_tex_fetch(__objects, object).surface_area; } /* Pass ID number of object */ @@ -239,9 +214,17 @@ ccl_device_inline float object_pass_id(KernelGlobals *kg, int object) if(object == OBJECT_NONE) return 0.0f; - int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; - float4 f = kernel_tex_fetch(__objects, offset); - return f.y; + return kernel_tex_fetch(__objects, object).pass_id; +} + +/* Per lamp random number for shader variation */ + +ccl_device_inline float lamp_random_number(KernelGlobals *kg, int lamp) +{ + if(lamp == LAMP_NONE) + return 0.0f; + + return kernel_tex_fetch(__lights, lamp).random; } /* Per object random number for shader variation */ @@ -251,9 +234,7 @@ ccl_device_inline float object_random_number(KernelGlobals *kg, int object) if(object == OBJECT_NONE) return 0.0f; - int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; - float4 f = kernel_tex_fetch(__objects, offset); - return f.z; + return kernel_tex_fetch(__objects, object).random_number; } /* Particle ID from which this object was generated */ @@ -263,9 +244,7 @@ ccl_device_inline int object_particle_id(KernelGlobals *kg, int object) if(object == OBJECT_NONE) return 0; - int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; - float4 f = kernel_tex_fetch(__objects, offset); - return __float_as_uint(f.w); + return kernel_tex_fetch(__objects, object).particle_index; } /* Generated texture coordinate on surface from where object was instanced */ @@ -275,9 +254,10 @@ ccl_device_inline float3 object_dupli_generated(KernelGlobals *kg, int object) if(object == OBJECT_NONE) return make_float3(0.0f, 0.0f, 0.0f); - int offset = object*OBJECT_SIZE + OBJECT_DUPLI; - float4 f = kernel_tex_fetch(__objects, offset); - return make_float3(f.x, f.y, f.z); + const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object); + return make_float3(kobject->dupli_generated[0], + kobject->dupli_generated[1], + kobject->dupli_generated[2]); } /* UV texture coordinate on surface from where object was instanced */ @@ -287,27 +267,24 @@ ccl_device_inline float3 object_dupli_uv(KernelGlobals *kg, int object) if(object == OBJECT_NONE) return make_float3(0.0f, 0.0f, 0.0f); - int offset = object*OBJECT_SIZE + OBJECT_DUPLI; - float4 f = kernel_tex_fetch(__objects, offset + 1); - return make_float3(f.x, f.y, 0.0f); + const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object); + return make_float3(kobject->dupli_uv[0], + kobject->dupli_uv[1], + 0.0f); } /* Information about mesh for motion blurred triangles and curves */ ccl_device_inline void object_motion_info(KernelGlobals *kg, int object, int *numsteps, int *numverts, int *numkeys) { - int offset = object*OBJECT_SIZE + OBJECT_DUPLI; - if(numkeys) { - float4 f = kernel_tex_fetch(__objects, offset); - *numkeys = __float_as_int(f.w); + *numkeys = kernel_tex_fetch(__objects, object).numkeys; } - float4 f = kernel_tex_fetch(__objects, offset + 1); if(numsteps) - *numsteps = __float_as_int(f.z); + *numsteps = kernel_tex_fetch(__objects, object).numsteps; if(numverts) - *numverts = __float_as_int(f.w); + *numverts = kernel_tex_fetch(__objects, object).numverts; } /* Offset to an objects patch map */ @@ -317,76 +294,56 @@ ccl_device_inline uint object_patch_map_offset(KernelGlobals *kg, int object) if(object == OBJECT_NONE) return 0; - int offset = object*OBJECT_SIZE + 11; - float4 f = kernel_tex_fetch(__objects, offset); - return __float_as_uint(f.x); + return kernel_tex_fetch(__objects, object).patch_map_offset; } /* Pass ID for shader */ ccl_device int shader_pass_id(KernelGlobals *kg, const ShaderData *sd) { - return kernel_tex_fetch(__shader_flag, (ccl_fetch(sd, shader) & SHADER_MASK)*SHADER_SIZE + 1); + return kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).pass_id; } /* Particle data from which object was instanced */ -ccl_device_inline float particle_index(KernelGlobals *kg, int particle) +ccl_device_inline uint particle_index(KernelGlobals *kg, int particle) { - int offset = particle*PARTICLE_SIZE; - float4 f = kernel_tex_fetch(__particles, offset + 0); - return f.x; + return kernel_tex_fetch(__particles, particle).index; } ccl_device float particle_age(KernelGlobals *kg, int particle) { - int offset = particle*PARTICLE_SIZE; - float4 f = kernel_tex_fetch(__particles, offset + 0); - return f.y; + return kernel_tex_fetch(__particles, particle).age; } ccl_device float particle_lifetime(KernelGlobals *kg, int particle) { - int offset = particle*PARTICLE_SIZE; - float4 f = kernel_tex_fetch(__particles, offset + 0); - return f.z; + return kernel_tex_fetch(__particles, particle).lifetime; } ccl_device float particle_size(KernelGlobals *kg, int particle) { - int offset = particle*PARTICLE_SIZE; - float4 f = kernel_tex_fetch(__particles, offset + 0); - return f.w; + return kernel_tex_fetch(__particles, particle).size; } ccl_device float4 particle_rotation(KernelGlobals *kg, int particle) { - int offset = particle*PARTICLE_SIZE; - float4 f = kernel_tex_fetch(__particles, offset + 1); - return f; + return kernel_tex_fetch(__particles, particle).rotation; } ccl_device float3 particle_location(KernelGlobals *kg, int particle) { - int offset = particle*PARTICLE_SIZE; - float4 f = kernel_tex_fetch(__particles, offset + 2); - return make_float3(f.x, f.y, f.z); + return float4_to_float3(kernel_tex_fetch(__particles, particle).location); } ccl_device float3 particle_velocity(KernelGlobals *kg, int particle) { - int offset = particle*PARTICLE_SIZE; - float4 f2 = kernel_tex_fetch(__particles, offset + 2); - float4 f3 = kernel_tex_fetch(__particles, offset + 3); - return make_float3(f2.w, f3.x, f3.y); + return float4_to_float3(kernel_tex_fetch(__particles, particle).velocity); } ccl_device float3 particle_angular_velocity(KernelGlobals *kg, int particle) { - int offset = particle*PARTICLE_SIZE; - float4 f3 = kernel_tex_fetch(__particles, offset + 3); - float4 f4 = kernel_tex_fetch(__particles, offset + 4); - return make_float3(f3.z, f3.w, f4.x); + return float4_to_float3(kernel_tex_fetch(__particles, particle).angular_velocity); } /* Object intersection in BVH */ @@ -415,17 +372,18 @@ ccl_device_inline float3 bvh_clamp_direction(float3 dir) ccl_device_inline float3 bvh_inverse_direction(float3 dir) { - /* TODO(sergey): Currently disabled, gives speedup but causes precision issues. */ -#if defined(__KERNEL_SSE__) && 0 return rcp(dir); -#else - return 1.0f / dir; -#endif } /* Transform ray into object space to enter static object in BVH */ -ccl_device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t) +ccl_device_inline float bvh_instance_push(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + float t) { Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); @@ -435,8 +393,11 @@ ccl_device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ra *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len)); *idir = bvh_inverse_direction(*dir); - if(*t != FLT_MAX) - *t *= len; + if(t != FLT_MAX) { + t *= len; + } + + return t; } #ifdef __QBVH__ @@ -473,16 +434,24 @@ ccl_device_inline void qbvh_instance_push(KernelGlobals *kg, /* Transorm ray to exit static object in BVH */ -ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t) +ccl_device_inline float bvh_instance_pop(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + float t) { - if(*t != FLT_MAX) { + if(t != FLT_MAX) { Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); - *t /= len(transform_direction(&tfm, ray->D)); + t /= len(transform_direction(&tfm, ray->D)); } *P = ray->P; *dir = bvh_clamp_direction(ray->D); *idir = bvh_inverse_direction(*dir); + + return t; } /* Same as above, but returns scale factor to apply to multiple intersection distances */ @@ -501,13 +470,13 @@ ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, co #ifdef __OBJECT_MOTION__ /* Transform ray into object space to enter motion blurred object in BVH */ -ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, +ccl_device_inline float bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, - ccl_addr_space float *t, + float t, Transform *itfm) { object_fetch_transform_motion_test(kg, object, ray->time, itfm); @@ -518,8 +487,11 @@ ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len)); *idir = bvh_inverse_direction(*dir); - if(*t != FLT_MAX) - *t *= len; + if(t != FLT_MAX) { + t *= len; + } + + return t; } #ifdef __QBVH__ @@ -557,22 +529,24 @@ ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, /* Transorm ray to exit motion blurred object in BVH */ -ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, - int object, - const Ray *ray, - float3 *P, - float3 *dir, - float3 *idir, - ccl_addr_space float *t, - Transform *itfm) -{ - if(*t != FLT_MAX) { - *t /= len(transform_direction(itfm, ray->D)); +ccl_device_inline float bvh_instance_motion_pop(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + float t, + Transform *itfm) +{ + if(t != FLT_MAX) { + t /= len(transform_direction(itfm, ray->D)); } *P = ray->P; *dir = bvh_clamp_direction(ray->D); *idir = bvh_inverse_direction(*dir); + + return t; } /* Same as above, but returns scale factor to apply to multiple intersection distances */ |