Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/geom/geom_object.h
| Show All 31 Lines | enum ObjectTransform { | ||||
| OBJECT_TRANSFORM = 0, | OBJECT_TRANSFORM = 0, | ||||
| OBJECT_INVERSE_TRANSFORM = 1, | OBJECT_INVERSE_TRANSFORM = 1, | ||||
| }; | }; | ||||
| enum ObjectVectorTransform { OBJECT_PASS_MOTION_PRE = 0, OBJECT_PASS_MOTION_POST = 1 }; | enum ObjectVectorTransform { OBJECT_PASS_MOTION_PRE = 0, OBJECT_PASS_MOTION_POST = 1 }; | ||||
| /* Object to world space transformation */ | /* Object to world space transformation */ | ||||
| ccl_device_inline Transform object_fetch_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline Transform object_fetch_transform(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| enum ObjectTransform type) | enum ObjectTransform type) | ||||
| { | { | ||||
| if (type == OBJECT_INVERSE_TRANSFORM) { | if (type == OBJECT_INVERSE_TRANSFORM) { | ||||
| return kernel_tex_fetch(__objects, object).itfm; | return kernel_tex_fetch(__objects, object).itfm; | ||||
| } | } | ||||
| else { | else { | ||||
| return kernel_tex_fetch(__objects, object).tfm; | return kernel_tex_fetch(__objects, object).tfm; | ||||
| } | } | ||||
| } | } | ||||
| /* Lamp to world space transformation */ | /* Lamp to world space transformation */ | ||||
| ccl_device_inline Transform lamp_fetch_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline Transform lamp_fetch_transform(KernelGlobals kg, int lamp, bool inverse) | ||||
| int lamp, | |||||
| bool inverse) | |||||
| { | { | ||||
| if (inverse) { | if (inverse) { | ||||
| return kernel_tex_fetch(__lights, lamp).itfm; | return kernel_tex_fetch(__lights, lamp).itfm; | ||||
| } | } | ||||
| else { | else { | ||||
| return kernel_tex_fetch(__lights, lamp).tfm; | return kernel_tex_fetch(__lights, lamp).tfm; | ||||
| } | } | ||||
| } | } | ||||
| /* Object to world space transformation for motion vectors */ | /* Object to world space transformation for motion vectors */ | ||||
| ccl_device_inline Transform object_fetch_motion_pass_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline Transform object_fetch_motion_pass_transform(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| enum ObjectVectorTransform type) | enum ObjectVectorTransform type) | ||||
| { | { | ||||
| int offset = object * OBJECT_MOTION_PASS_SIZE + (int)type; | int offset = object * OBJECT_MOTION_PASS_SIZE + (int)type; | ||||
| return kernel_tex_fetch(__object_motion_pass, offset); | return kernel_tex_fetch(__object_motion_pass, offset); | ||||
| } | } | ||||
| /* Motion blurred object transformations */ | /* Motion blurred object transformations */ | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| ccl_device_inline Transform object_fetch_transform_motion(ccl_global const KernelGlobals *kg, | ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals kg, int object, float time) | ||||
| int object, | |||||
| float time) | |||||
| { | { | ||||
| const uint motion_offset = kernel_tex_fetch(__objects, object).motion_offset; | const uint motion_offset = kernel_tex_fetch(__objects, object).motion_offset; | ||||
| ccl_global const DecomposedTransform *motion = &kernel_tex_fetch(__object_motion, motion_offset); | ccl_global const DecomposedTransform *motion = &kernel_tex_fetch(__object_motion, motion_offset); | ||||
| const uint num_steps = kernel_tex_fetch(__objects, object).numsteps * 2 + 1; | const uint num_steps = kernel_tex_fetch(__objects, object).numsteps * 2 + 1; | ||||
| Transform tfm; | Transform tfm; | ||||
| transform_motion_array_interpolate(&tfm, motion, num_steps, time); | transform_motion_array_interpolate(&tfm, motion, num_steps, time); | ||||
| return tfm; | return tfm; | ||||
| } | } | ||||
| ccl_device_inline Transform object_fetch_transform_motion_test(ccl_global const KernelGlobals *kg, | ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| float time, | float time, | ||||
| ccl_private Transform *itfm) | ccl_private Transform *itfm) | ||||
| { | { | ||||
| int object_flag = kernel_tex_fetch(__object_flag, object); | int object_flag = kernel_tex_fetch(__object_flag, object); | ||||
| if (object_flag & SD_OBJECT_MOTION) { | if (object_flag & SD_OBJECT_MOTION) { | ||||
| /* if we do motion blur */ | /* if we do motion blur */ | ||||
| Transform tfm = object_fetch_transform_motion(kg, object, time); | Transform tfm = object_fetch_transform_motion(kg, object, time); | ||||
| Show All 10 Lines | else { | ||||
| return tfm; | return tfm; | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| /* Get transform matrix for shading point. */ | /* Get transform matrix for shading point. */ | ||||
| ccl_device_inline Transform object_get_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline Transform object_get_transform(KernelGlobals kg, | ||||
| ccl_private const ShaderData *sd) | ccl_private const ShaderData *sd) | ||||
| { | { | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| return (sd->object_flag & SD_OBJECT_MOTION) ? | return (sd->object_flag & SD_OBJECT_MOTION) ? | ||||
| sd->ob_tfm_motion : | sd->ob_tfm_motion : | ||||
| object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); | object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); | ||||
| #else | #else | ||||
| return object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); | return object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); | ||||
| #endif | #endif | ||||
| } | } | ||||
| ccl_device_inline Transform object_get_inverse_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline Transform object_get_inverse_transform(KernelGlobals kg, | ||||
| ccl_private const ShaderData *sd) | ccl_private const ShaderData *sd) | ||||
| { | { | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| return (sd->object_flag & SD_OBJECT_MOTION) ? | return (sd->object_flag & SD_OBJECT_MOTION) ? | ||||
| sd->ob_itfm_motion : | sd->ob_itfm_motion : | ||||
| object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); | object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); | ||||
| #else | #else | ||||
| return object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); | return object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); | ||||
| #endif | #endif | ||||
| } | } | ||||
| /* Transform position from object to world space */ | /* Transform position from object to world space */ | ||||
| ccl_device_inline void object_position_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline void object_position_transform(KernelGlobals kg, | ||||
| ccl_private const ShaderData *sd, | ccl_private const ShaderData *sd, | ||||
| ccl_private float3 *P) | ccl_private float3 *P) | ||||
| { | { | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| if (sd->object_flag & SD_OBJECT_MOTION) { | if (sd->object_flag & SD_OBJECT_MOTION) { | ||||
| *P = transform_point_auto(&sd->ob_tfm_motion, *P); | *P = transform_point_auto(&sd->ob_tfm_motion, *P); | ||||
| return; | return; | ||||
| } | } | ||||
| #endif | #endif | ||||
| Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); | Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); | ||||
| *P = transform_point(&tfm, *P); | *P = transform_point(&tfm, *P); | ||||
| } | } | ||||
| /* Transform position from world to object space */ | /* Transform position from world to object space */ | ||||
| ccl_device_inline void object_inverse_position_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline void object_inverse_position_transform(KernelGlobals kg, | ||||
| ccl_private const ShaderData *sd, | ccl_private const ShaderData *sd, | ||||
| ccl_private float3 *P) | ccl_private float3 *P) | ||||
| { | { | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| if (sd->object_flag & SD_OBJECT_MOTION) { | if (sd->object_flag & SD_OBJECT_MOTION) { | ||||
| *P = transform_point_auto(&sd->ob_itfm_motion, *P); | *P = transform_point_auto(&sd->ob_itfm_motion, *P); | ||||
| return; | return; | ||||
| } | } | ||||
| #endif | #endif | ||||
| Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); | Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); | ||||
| *P = transform_point(&tfm, *P); | *P = transform_point(&tfm, *P); | ||||
| } | } | ||||
| /* Transform normal from world to object space */ | /* Transform normal from world to object space */ | ||||
| ccl_device_inline void object_inverse_normal_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline void object_inverse_normal_transform(KernelGlobals kg, | ||||
| ccl_private const ShaderData *sd, | ccl_private const ShaderData *sd, | ||||
| ccl_private float3 *N) | ccl_private float3 *N) | ||||
| { | { | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| if (sd->object_flag & SD_OBJECT_MOTION) { | if (sd->object_flag & SD_OBJECT_MOTION) { | ||||
| if ((sd->object != OBJECT_NONE) || (sd->type == PRIMITIVE_LAMP)) { | if ((sd->object != OBJECT_NONE) || (sd->type == PRIMITIVE_LAMP)) { | ||||
| *N = normalize(transform_direction_transposed_auto(&sd->ob_tfm_motion, *N)); | *N = normalize(transform_direction_transposed_auto(&sd->ob_tfm_motion, *N)); | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| #endif | #endif | ||||
| if (sd->object != OBJECT_NONE) { | if (sd->object != OBJECT_NONE) { | ||||
| Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); | Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); | ||||
| *N = normalize(transform_direction_transposed(&tfm, *N)); | *N = normalize(transform_direction_transposed(&tfm, *N)); | ||||
| } | } | ||||
| else if (sd->type == PRIMITIVE_LAMP) { | else if (sd->type == PRIMITIVE_LAMP) { | ||||
| Transform tfm = lamp_fetch_transform(kg, sd->lamp, false); | Transform tfm = lamp_fetch_transform(kg, sd->lamp, false); | ||||
| *N = normalize(transform_direction_transposed(&tfm, *N)); | *N = normalize(transform_direction_transposed(&tfm, *N)); | ||||
| } | } | ||||
| } | } | ||||
| /* Transform normal from object to world space */ | /* Transform normal from object to world space */ | ||||
| ccl_device_inline void object_normal_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline void object_normal_transform(KernelGlobals kg, | ||||
| ccl_private const ShaderData *sd, | ccl_private const ShaderData *sd, | ||||
| ccl_private float3 *N) | ccl_private float3 *N) | ||||
| { | { | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| if (sd->object_flag & SD_OBJECT_MOTION) { | if (sd->object_flag & SD_OBJECT_MOTION) { | ||||
| *N = normalize(transform_direction_transposed_auto(&sd->ob_itfm_motion, *N)); | *N = normalize(transform_direction_transposed_auto(&sd->ob_itfm_motion, *N)); | ||||
| return; | return; | ||||
| } | } | ||||
| #endif | #endif | ||||
| Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); | Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); | ||||
| *N = normalize(transform_direction_transposed(&tfm, *N)); | *N = normalize(transform_direction_transposed(&tfm, *N)); | ||||
| } | } | ||||
| /* Transform direction vector from object to world space */ | /* Transform direction vector from object to world space */ | ||||
| ccl_device_inline void object_dir_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline void object_dir_transform(KernelGlobals kg, | ||||
| ccl_private const ShaderData *sd, | ccl_private const ShaderData *sd, | ||||
| ccl_private float3 *D) | ccl_private float3 *D) | ||||
| { | { | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| if (sd->object_flag & SD_OBJECT_MOTION) { | if (sd->object_flag & SD_OBJECT_MOTION) { | ||||
| *D = transform_direction_auto(&sd->ob_tfm_motion, *D); | *D = transform_direction_auto(&sd->ob_tfm_motion, *D); | ||||
| return; | return; | ||||
| } | } | ||||
| #endif | #endif | ||||
| Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); | Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); | ||||
| *D = transform_direction(&tfm, *D); | *D = transform_direction(&tfm, *D); | ||||
| } | } | ||||
| /* Transform direction vector from world to object space */ | /* Transform direction vector from world to object space */ | ||||
| ccl_device_inline void object_inverse_dir_transform(ccl_global const KernelGlobals *kg, | ccl_device_inline void object_inverse_dir_transform(KernelGlobals kg, | ||||
| ccl_private const ShaderData *sd, | ccl_private const ShaderData *sd, | ||||
| ccl_private float3 *D) | ccl_private float3 *D) | ||||
| { | { | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| if (sd->object_flag & SD_OBJECT_MOTION) { | if (sd->object_flag & SD_OBJECT_MOTION) { | ||||
| *D = transform_direction_auto(&sd->ob_itfm_motion, *D); | *D = transform_direction_auto(&sd->ob_itfm_motion, *D); | ||||
| return; | return; | ||||
| } | } | ||||
| #endif | #endif | ||||
| const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); | const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); | ||||
| *D = transform_direction(&tfm, *D); | *D = transform_direction(&tfm, *D); | ||||
| } | } | ||||
| /* Object center position */ | /* Object center position */ | ||||
| ccl_device_inline float3 object_location(ccl_global const KernelGlobals *kg, | ccl_device_inline float3 object_location(KernelGlobals kg, ccl_private const ShaderData *sd) | ||||
| ccl_private const ShaderData *sd) | |||||
| { | { | ||||
| if (sd->object == OBJECT_NONE) | if (sd->object == OBJECT_NONE) | ||||
| return make_float3(0.0f, 0.0f, 0.0f); | return make_float3(0.0f, 0.0f, 0.0f); | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| if (sd->object_flag & SD_OBJECT_MOTION) { | if (sd->object_flag & SD_OBJECT_MOTION) { | ||||
| return make_float3(sd->ob_tfm_motion.x.w, sd->ob_tfm_motion.y.w, sd->ob_tfm_motion.z.w); | return make_float3(sd->ob_tfm_motion.x.w, sd->ob_tfm_motion.y.w, sd->ob_tfm_motion.z.w); | ||||
| } | } | ||||
| #endif | #endif | ||||
| Transform tfm = object_fetch_transform(kg, 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); | return make_float3(tfm.x.w, tfm.y.w, tfm.z.w); | ||||
| } | } | ||||
| /* Color of the object */ | /* Color of the object */ | ||||
| ccl_device_inline float3 object_color(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline float3 object_color(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) | if (object == OBJECT_NONE) | ||||
| return make_float3(0.0f, 0.0f, 0.0f); | return make_float3(0.0f, 0.0f, 0.0f); | ||||
| ccl_global const KernelObject *kobject = &kernel_tex_fetch(__objects, object); | ccl_global const KernelObject *kobject = &kernel_tex_fetch(__objects, object); | ||||
| return make_float3(kobject->color[0], kobject->color[1], kobject->color[2]); | return make_float3(kobject->color[0], kobject->color[1], kobject->color[2]); | ||||
| } | } | ||||
| /* Pass ID number of object */ | /* Pass ID number of object */ | ||||
| ccl_device_inline float object_pass_id(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline float object_pass_id(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) | if (object == OBJECT_NONE) | ||||
| return 0.0f; | return 0.0f; | ||||
| return kernel_tex_fetch(__objects, object).pass_id; | return kernel_tex_fetch(__objects, object).pass_id; | ||||
| } | } | ||||
| /* Per lamp random number for shader variation */ | /* Per lamp random number for shader variation */ | ||||
| ccl_device_inline float lamp_random_number(ccl_global const KernelGlobals *kg, int lamp) | ccl_device_inline float lamp_random_number(KernelGlobals kg, int lamp) | ||||
| { | { | ||||
| if (lamp == LAMP_NONE) | if (lamp == LAMP_NONE) | ||||
| return 0.0f; | return 0.0f; | ||||
| return kernel_tex_fetch(__lights, lamp).random; | return kernel_tex_fetch(__lights, lamp).random; | ||||
| } | } | ||||
| /* Per object random number for shader variation */ | /* Per object random number for shader variation */ | ||||
| ccl_device_inline float object_random_number(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline float object_random_number(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) | if (object == OBJECT_NONE) | ||||
| return 0.0f; | return 0.0f; | ||||
| return kernel_tex_fetch(__objects, object).random_number; | return kernel_tex_fetch(__objects, object).random_number; | ||||
| } | } | ||||
| /* Particle ID from which this object was generated */ | /* Particle ID from which this object was generated */ | ||||
| ccl_device_inline int object_particle_id(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline int object_particle_id(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) | if (object == OBJECT_NONE) | ||||
| return 0; | return 0; | ||||
| return kernel_tex_fetch(__objects, object).particle_index; | return kernel_tex_fetch(__objects, object).particle_index; | ||||
| } | } | ||||
| /* Generated texture coordinate on surface from where object was instanced */ | /* Generated texture coordinate on surface from where object was instanced */ | ||||
| ccl_device_inline float3 object_dupli_generated(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline float3 object_dupli_generated(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) | if (object == OBJECT_NONE) | ||||
| return make_float3(0.0f, 0.0f, 0.0f); | return make_float3(0.0f, 0.0f, 0.0f); | ||||
| ccl_global const KernelObject *kobject = &kernel_tex_fetch(__objects, object); | ccl_global const KernelObject *kobject = &kernel_tex_fetch(__objects, object); | ||||
| return make_float3( | return make_float3( | ||||
| kobject->dupli_generated[0], kobject->dupli_generated[1], kobject->dupli_generated[2]); | kobject->dupli_generated[0], kobject->dupli_generated[1], kobject->dupli_generated[2]); | ||||
| } | } | ||||
| /* UV texture coordinate on surface from where object was instanced */ | /* UV texture coordinate on surface from where object was instanced */ | ||||
| ccl_device_inline float3 object_dupli_uv(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline float3 object_dupli_uv(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) | if (object == OBJECT_NONE) | ||||
| return make_float3(0.0f, 0.0f, 0.0f); | return make_float3(0.0f, 0.0f, 0.0f); | ||||
| ccl_global const KernelObject *kobject = &kernel_tex_fetch(__objects, object); | ccl_global const KernelObject *kobject = &kernel_tex_fetch(__objects, object); | ||||
| return make_float3(kobject->dupli_uv[0], kobject->dupli_uv[1], 0.0f); | return make_float3(kobject->dupli_uv[0], kobject->dupli_uv[1], 0.0f); | ||||
| } | } | ||||
| /* Information about mesh for motion blurred triangles and curves */ | /* Information about mesh for motion blurred triangles and curves */ | ||||
| ccl_device_inline void object_motion_info(ccl_global const KernelGlobals *kg, | ccl_device_inline void object_motion_info(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| ccl_private int *numsteps, | ccl_private int *numsteps, | ||||
| ccl_private int *numverts, | ccl_private int *numverts, | ||||
| ccl_private int *numkeys) | ccl_private int *numkeys) | ||||
| { | { | ||||
| if (numkeys) { | if (numkeys) { | ||||
| *numkeys = kernel_tex_fetch(__objects, object).numkeys; | *numkeys = kernel_tex_fetch(__objects, object).numkeys; | ||||
| } | } | ||||
| if (numsteps) | if (numsteps) | ||||
| *numsteps = kernel_tex_fetch(__objects, object).numsteps; | *numsteps = kernel_tex_fetch(__objects, object).numsteps; | ||||
| if (numverts) | if (numverts) | ||||
| *numverts = kernel_tex_fetch(__objects, object).numverts; | *numverts = kernel_tex_fetch(__objects, object).numverts; | ||||
| } | } | ||||
| /* Offset to an objects patch map */ | /* Offset to an objects patch map */ | ||||
| ccl_device_inline uint object_patch_map_offset(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline uint object_patch_map_offset(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) | if (object == OBJECT_NONE) | ||||
| return 0; | return 0; | ||||
| return kernel_tex_fetch(__objects, object).patch_map_offset; | return kernel_tex_fetch(__objects, object).patch_map_offset; | ||||
| } | } | ||||
| /* Volume step size */ | /* Volume step size */ | ||||
| ccl_device_inline float object_volume_density(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline float object_volume_density(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) { | if (object == OBJECT_NONE) { | ||||
| return 1.0f; | return 1.0f; | ||||
| } | } | ||||
| return kernel_tex_fetch(__objects, object).volume_density; | return kernel_tex_fetch(__objects, object).volume_density; | ||||
| } | } | ||||
| ccl_device_inline float object_volume_step_size(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline float object_volume_step_size(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) { | if (object == OBJECT_NONE) { | ||||
| return kernel_data.background.volume_step_size; | return kernel_data.background.volume_step_size; | ||||
| } | } | ||||
| return kernel_tex_fetch(__object_volume_step, object); | return kernel_tex_fetch(__object_volume_step, object); | ||||
| } | } | ||||
| /* Pass ID for shader */ | /* Pass ID for shader */ | ||||
| ccl_device int shader_pass_id(ccl_global const KernelGlobals *kg, ccl_private const ShaderData *sd) | ccl_device int shader_pass_id(KernelGlobals kg, ccl_private const ShaderData *sd) | ||||
| { | { | ||||
| return kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).pass_id; | return kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).pass_id; | ||||
| } | } | ||||
| /* Cryptomatte ID */ | /* Cryptomatte ID */ | ||||
| ccl_device_inline float object_cryptomatte_id(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline float object_cryptomatte_id(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) | if (object == OBJECT_NONE) | ||||
| return 0.0f; | return 0.0f; | ||||
| return kernel_tex_fetch(__objects, object).cryptomatte_object; | return kernel_tex_fetch(__objects, object).cryptomatte_object; | ||||
| } | } | ||||
| ccl_device_inline float object_cryptomatte_asset_id(ccl_global const KernelGlobals *kg, int object) | ccl_device_inline float object_cryptomatte_asset_id(KernelGlobals kg, int object) | ||||
| { | { | ||||
| if (object == OBJECT_NONE) | if (object == OBJECT_NONE) | ||||
| return 0; | return 0; | ||||
| return kernel_tex_fetch(__objects, object).cryptomatte_asset; | return kernel_tex_fetch(__objects, object).cryptomatte_asset; | ||||
| } | } | ||||
| /* Particle data from which object was instanced */ | /* Particle data from which object was instanced */ | ||||
| ccl_device_inline uint particle_index(ccl_global const KernelGlobals *kg, int particle) | ccl_device_inline uint particle_index(KernelGlobals kg, int particle) | ||||
| { | { | ||||
| return kernel_tex_fetch(__particles, particle).index; | return kernel_tex_fetch(__particles, particle).index; | ||||
| } | } | ||||
| ccl_device float particle_age(ccl_global const KernelGlobals *kg, int particle) | ccl_device float particle_age(KernelGlobals kg, int particle) | ||||
| { | { | ||||
| return kernel_tex_fetch(__particles, particle).age; | return kernel_tex_fetch(__particles, particle).age; | ||||
| } | } | ||||
| ccl_device float particle_lifetime(ccl_global const KernelGlobals *kg, int particle) | ccl_device float particle_lifetime(KernelGlobals kg, int particle) | ||||
| { | { | ||||
| return kernel_tex_fetch(__particles, particle).lifetime; | return kernel_tex_fetch(__particles, particle).lifetime; | ||||
| } | } | ||||
| ccl_device float particle_size(ccl_global const KernelGlobals *kg, int particle) | ccl_device float particle_size(KernelGlobals kg, int particle) | ||||
| { | { | ||||
| return kernel_tex_fetch(__particles, particle).size; | return kernel_tex_fetch(__particles, particle).size; | ||||
| } | } | ||||
| ccl_device float4 particle_rotation(ccl_global const KernelGlobals *kg, int particle) | ccl_device float4 particle_rotation(KernelGlobals kg, int particle) | ||||
| { | { | ||||
| return kernel_tex_fetch(__particles, particle).rotation; | return kernel_tex_fetch(__particles, particle).rotation; | ||||
| } | } | ||||
| ccl_device float3 particle_location(ccl_global const KernelGlobals *kg, int particle) | ccl_device float3 particle_location(KernelGlobals kg, int particle) | ||||
| { | { | ||||
| return float4_to_float3(kernel_tex_fetch(__particles, particle).location); | return float4_to_float3(kernel_tex_fetch(__particles, particle).location); | ||||
| } | } | ||||
| ccl_device float3 particle_velocity(ccl_global const KernelGlobals *kg, int particle) | ccl_device float3 particle_velocity(KernelGlobals kg, int particle) | ||||
| { | { | ||||
| return float4_to_float3(kernel_tex_fetch(__particles, particle).velocity); | return float4_to_float3(kernel_tex_fetch(__particles, particle).velocity); | ||||
| } | } | ||||
| ccl_device float3 particle_angular_velocity(ccl_global const KernelGlobals *kg, int particle) | ccl_device float3 particle_angular_velocity(KernelGlobals kg, int particle) | ||||
| { | { | ||||
| return float4_to_float3(kernel_tex_fetch(__particles, particle).angular_velocity); | return float4_to_float3(kernel_tex_fetch(__particles, particle).angular_velocity); | ||||
| } | } | ||||
| /* Object intersection in BVH */ | /* Object intersection in BVH */ | ||||
| ccl_device_inline float3 bvh_clamp_direction(float3 dir) | ccl_device_inline float3 bvh_clamp_direction(float3 dir) | ||||
| { | { | ||||
| const float ooeps = 8.271806E-25f; | const float ooeps = 8.271806E-25f; | ||||
| return make_float3((fabsf(dir.x) > ooeps) ? dir.x : copysignf(ooeps, dir.x), | return make_float3((fabsf(dir.x) > ooeps) ? dir.x : copysignf(ooeps, dir.x), | ||||
| (fabsf(dir.y) > ooeps) ? dir.y : copysignf(ooeps, dir.y), | (fabsf(dir.y) > ooeps) ? dir.y : copysignf(ooeps, dir.y), | ||||
| (fabsf(dir.z) > ooeps) ? dir.z : copysignf(ooeps, dir.z)); | (fabsf(dir.z) > ooeps) ? dir.z : copysignf(ooeps, dir.z)); | ||||
| } | } | ||||
| ccl_device_inline float3 bvh_inverse_direction(float3 dir) | ccl_device_inline float3 bvh_inverse_direction(float3 dir) | ||||
| { | { | ||||
| return rcp(dir); | return rcp(dir); | ||||
| } | } | ||||
| /* Transform ray into object space to enter static object in BVH */ | /* Transform ray into object space to enter static object in BVH */ | ||||
| ccl_device_inline float bvh_instance_push(ccl_global const KernelGlobals *kg, | ccl_device_inline float bvh_instance_push(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| ccl_private const Ray *ray, | ccl_private const Ray *ray, | ||||
| ccl_private float3 *P, | ccl_private float3 *P, | ||||
| ccl_private float3 *dir, | ccl_private float3 *dir, | ||||
| ccl_private float3 *idir) | ccl_private float3 *idir) | ||||
| { | { | ||||
| Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); | Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); | ||||
| *P = transform_point(&tfm, ray->P); | *P = transform_point(&tfm, ray->P); | ||||
| float len; | float len; | ||||
| *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len)); | *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len)); | ||||
| *idir = bvh_inverse_direction(*dir); | *idir = bvh_inverse_direction(*dir); | ||||
| return len; | return len; | ||||
| } | } | ||||
| /* Transform ray to exit static object in BVH. */ | /* Transform ray to exit static object in BVH. */ | ||||
| ccl_device_inline float bvh_instance_pop(ccl_global const KernelGlobals *kg, | ccl_device_inline float bvh_instance_pop(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| ccl_private const Ray *ray, | ccl_private const Ray *ray, | ||||
| ccl_private float3 *P, | ccl_private float3 *P, | ||||
| ccl_private float3 *dir, | ccl_private float3 *dir, | ||||
| ccl_private float3 *idir, | ccl_private float3 *idir, | ||||
| float t) | float t) | ||||
| { | { | ||||
| if (t != FLT_MAX) { | if (t != FLT_MAX) { | ||||
| Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); | 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; | *P = ray->P; | ||||
| *dir = bvh_clamp_direction(ray->D); | *dir = bvh_clamp_direction(ray->D); | ||||
| *idir = bvh_inverse_direction(*dir); | *idir = bvh_inverse_direction(*dir); | ||||
| return t; | return t; | ||||
| } | } | ||||
| /* Same as above, but returns scale factor to apply to multiple intersection distances */ | /* Same as above, but returns scale factor to apply to multiple intersection distances */ | ||||
| ccl_device_inline void bvh_instance_pop_factor(ccl_global const KernelGlobals *kg, | ccl_device_inline void bvh_instance_pop_factor(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| ccl_private const Ray *ray, | ccl_private const Ray *ray, | ||||
| ccl_private float3 *P, | ccl_private float3 *P, | ||||
| ccl_private float3 *dir, | ccl_private float3 *dir, | ||||
| ccl_private float3 *idir, | ccl_private float3 *idir, | ||||
| ccl_private float *t_fac) | ccl_private float *t_fac) | ||||
| { | { | ||||
| Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); | Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); | ||||
| *t_fac = 1.0f / len(transform_direction(&tfm, ray->D)); | *t_fac = 1.0f / len(transform_direction(&tfm, ray->D)); | ||||
| *P = ray->P; | *P = ray->P; | ||||
| *dir = bvh_clamp_direction(ray->D); | *dir = bvh_clamp_direction(ray->D); | ||||
| *idir = bvh_inverse_direction(*dir); | *idir = bvh_inverse_direction(*dir); | ||||
| } | } | ||||
| #ifdef __OBJECT_MOTION__ | #ifdef __OBJECT_MOTION__ | ||||
| /* Transform ray into object space to enter motion blurred object in BVH */ | /* Transform ray into object space to enter motion blurred object in BVH */ | ||||
| ccl_device_inline float bvh_instance_motion_push(ccl_global const KernelGlobals *kg, | ccl_device_inline float bvh_instance_motion_push(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| ccl_private const Ray *ray, | ccl_private const Ray *ray, | ||||
| ccl_private float3 *P, | ccl_private float3 *P, | ||||
| ccl_private float3 *dir, | ccl_private float3 *dir, | ||||
| ccl_private float3 *idir, | ccl_private float3 *idir, | ||||
| ccl_private Transform *itfm) | ccl_private Transform *itfm) | ||||
| { | { | ||||
| object_fetch_transform_motion_test(kg, object, ray->time, itfm); | object_fetch_transform_motion_test(kg, object, ray->time, itfm); | ||||
| *P = transform_point(itfm, ray->P); | *P = transform_point(itfm, ray->P); | ||||
| float len; | float len; | ||||
| *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len)); | *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len)); | ||||
| *idir = bvh_inverse_direction(*dir); | *idir = bvh_inverse_direction(*dir); | ||||
| return len; | return len; | ||||
| } | } | ||||
| /* Transform ray to exit motion blurred object in BVH. */ | /* Transform ray to exit motion blurred object in BVH. */ | ||||
| ccl_device_inline float bvh_instance_motion_pop(ccl_global const KernelGlobals *kg, | ccl_device_inline float bvh_instance_motion_pop(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| ccl_private const Ray *ray, | ccl_private const Ray *ray, | ||||
| ccl_private float3 *P, | ccl_private float3 *P, | ||||
| ccl_private float3 *dir, | ccl_private float3 *dir, | ||||
| ccl_private float3 *idir, | ccl_private float3 *idir, | ||||
| float t, | float t, | ||||
| ccl_private Transform *itfm) | ccl_private Transform *itfm) | ||||
| { | { | ||||
| if (t != FLT_MAX) { | if (t != FLT_MAX) { | ||||
| t /= len(transform_direction(itfm, ray->D)); | t /= len(transform_direction(itfm, ray->D)); | ||||
| } | } | ||||
| *P = ray->P; | *P = ray->P; | ||||
| *dir = bvh_clamp_direction(ray->D); | *dir = bvh_clamp_direction(ray->D); | ||||
| *idir = bvh_inverse_direction(*dir); | *idir = bvh_inverse_direction(*dir); | ||||
| return t; | return t; | ||||
| } | } | ||||
| /* Same as above, but returns scale factor to apply to multiple intersection distances */ | /* Same as above, but returns scale factor to apply to multiple intersection distances */ | ||||
| ccl_device_inline void bvh_instance_motion_pop_factor(ccl_global const KernelGlobals *kg, | ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals kg, | ||||
| int object, | int object, | ||||
| ccl_private const Ray *ray, | ccl_private const Ray *ray, | ||||
| ccl_private float3 *P, | ccl_private float3 *P, | ||||
| ccl_private float3 *dir, | ccl_private float3 *dir, | ||||
| ccl_private float3 *idir, | ccl_private float3 *idir, | ||||
| ccl_private float *t_fac, | ccl_private float *t_fac, | ||||
| ccl_private Transform *itfm) | ccl_private Transform *itfm) | ||||
| { | { | ||||
| Show All 16 Lines | |||||