From e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Apr 2019 06:17:24 +0200 Subject: ClangFormat: apply to source, most of intern Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat --- intern/cycles/kernel/svm/svm.h | 624 +++---- intern/cycles/kernel/svm/svm_ao.h | 151 +- intern/cycles/kernel/svm/svm_attribute.h | 248 ++- intern/cycles/kernel/svm/svm_bevel.h | 379 ++-- intern/cycles/kernel/svm/svm_blackbody.h | 11 +- intern/cycles/kernel/svm/svm_brick.h | 196 ++- intern/cycles/kernel/svm/svm_brightness.h | 19 +- intern/cycles/kernel/svm/svm_bump.h | 58 +- intern/cycles/kernel/svm/svm_camera.h | 33 +- intern/cycles/kernel/svm/svm_checker.h | 42 +- intern/cycles/kernel/svm/svm_closure.h | 2147 ++++++++++++----------- intern/cycles/kernel/svm/svm_color_util.h | 366 ++-- intern/cycles/kernel/svm/svm_convert.h | 95 +- intern/cycles/kernel/svm/svm_displace.h | 225 +-- intern/cycles/kernel/svm/svm_fresnel.h | 66 +- intern/cycles/kernel/svm/svm_gamma.h | 13 +- intern/cycles/kernel/svm/svm_geometry.h | 325 ++-- intern/cycles/kernel/svm/svm_gradient.h | 84 +- intern/cycles/kernel/svm/svm_hsv.h | 55 +- intern/cycles/kernel/svm/svm_ies.h | 149 +- intern/cycles/kernel/svm/svm_image.h | 324 ++-- intern/cycles/kernel/svm/svm_invert.h | 19 +- intern/cycles/kernel/svm/svm_light_path.h | 116 +- intern/cycles/kernel/svm/svm_magic.h | 159 +- intern/cycles/kernel/svm/svm_mapping.h | 30 +- intern/cycles/kernel/svm/svm_math.h | 48 +- intern/cycles/kernel/svm/svm_math_util.h | 269 ++- intern/cycles/kernel/svm/svm_mix.h | 22 +- intern/cycles/kernel/svm/svm_musgrave.h | 319 ++-- intern/cycles/kernel/svm/svm_noise.h | 330 ++-- intern/cycles/kernel/svm/svm_noisetex.h | 55 +- intern/cycles/kernel/svm/svm_normal.h | 32 +- intern/cycles/kernel/svm/svm_ramp.h | 125 +- intern/cycles/kernel/svm/svm_ramp_util.h | 126 +- intern/cycles/kernel/svm/svm_sepcomb_hsv.h | 56 +- intern/cycles/kernel/svm/svm_sepcomb_vector.h | 30 +- intern/cycles/kernel/svm/svm_sky.h | 283 +-- intern/cycles/kernel/svm/svm_tex_coord.h | 709 ++++---- intern/cycles/kernel/svm/svm_texture.h | 56 +- intern/cycles/kernel/svm/svm_types.h | 745 ++++---- intern/cycles/kernel/svm/svm_value.h | 17 +- intern/cycles/kernel/svm/svm_vector_transform.h | 141 +- intern/cycles/kernel/svm/svm_voronoi.h | 290 +-- intern/cycles/kernel/svm/svm_voxel.h | 49 +- intern/cycles/kernel/svm/svm_wave.h | 70 +- intern/cycles/kernel/svm/svm_wavelength.h | 112 +- intern/cycles/kernel/svm/svm_wireframe.h | 150 +- 47 files changed, 5161 insertions(+), 4807 deletions(-) (limited to 'intern/cycles/kernel/svm') diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index ccb9aef7a5b..4a386afa5de 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -46,92 +46,102 @@ CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(float *stack, uint a) { - kernel_assert(a+2 < SVM_STACK_SIZE); + kernel_assert(a + 2 < SVM_STACK_SIZE); - return make_float3(stack[a+0], stack[a+1], stack[a+2]); + return make_float3(stack[a + 0], stack[a + 1], stack[a + 2]); } ccl_device_inline void stack_store_float3(float *stack, uint a, float3 f) { - kernel_assert(a+2 < SVM_STACK_SIZE); + kernel_assert(a + 2 < SVM_STACK_SIZE); - stack[a+0] = f.x; - stack[a+1] = f.y; - stack[a+2] = f.z; + stack[a + 0] = f.x; + stack[a + 1] = f.y; + stack[a + 2] = f.z; } ccl_device_inline float stack_load_float(float *stack, uint a) { - kernel_assert(a < SVM_STACK_SIZE); + kernel_assert(a < SVM_STACK_SIZE); - return stack[a]; + return stack[a]; } ccl_device_inline float stack_load_float_default(float *stack, uint a, uint value) { - return (a == (uint)SVM_STACK_INVALID)? __uint_as_float(value): stack_load_float(stack, a); + return (a == (uint)SVM_STACK_INVALID) ? __uint_as_float(value) : stack_load_float(stack, a); } ccl_device_inline void stack_store_float(float *stack, uint a, float f) { - kernel_assert(a < SVM_STACK_SIZE); + kernel_assert(a < SVM_STACK_SIZE); - stack[a] = f; + stack[a] = f; } ccl_device_inline int stack_load_int(float *stack, uint a) { - kernel_assert(a < SVM_STACK_SIZE); + kernel_assert(a < SVM_STACK_SIZE); - return __float_as_int(stack[a]); + return __float_as_int(stack[a]); } ccl_device_inline int stack_load_int_default(float *stack, uint a, uint value) { - return (a == (uint)SVM_STACK_INVALID)? (int)value: stack_load_int(stack, a); + return (a == (uint)SVM_STACK_INVALID) ? (int)value : stack_load_int(stack, a); } ccl_device_inline void stack_store_int(float *stack, uint a, int i) { - kernel_assert(a < SVM_STACK_SIZE); + kernel_assert(a < SVM_STACK_SIZE); - stack[a] = __int_as_float(i); + stack[a] = __int_as_float(i); } ccl_device_inline bool stack_valid(uint a) { - return a != (uint)SVM_STACK_INVALID; + return a != (uint)SVM_STACK_INVALID; } /* Reading Nodes */ ccl_device_inline uint4 read_node(KernelGlobals *kg, int *offset) { - uint4 node = kernel_tex_fetch(__svm_nodes, *offset); - (*offset)++; - return node; + uint4 node = kernel_tex_fetch(__svm_nodes, *offset); + (*offset)++; + return node; } ccl_device_inline float4 read_node_float(KernelGlobals *kg, int *offset) { - uint4 node = kernel_tex_fetch(__svm_nodes, *offset); - float4 f = make_float4(__uint_as_float(node.x), __uint_as_float(node.y), __uint_as_float(node.z), __uint_as_float(node.w)); - (*offset)++; - return f; + uint4 node = kernel_tex_fetch(__svm_nodes, *offset); + float4 f = make_float4(__uint_as_float(node.x), + __uint_as_float(node.y), + __uint_as_float(node.z), + __uint_as_float(node.w)); + (*offset)++; + return f; } ccl_device_inline float4 fetch_node_float(KernelGlobals *kg, int offset) { - uint4 node = kernel_tex_fetch(__svm_nodes, offset); - return make_float4(__uint_as_float(node.x), __uint_as_float(node.y), __uint_as_float(node.z), __uint_as_float(node.w)); + uint4 node = kernel_tex_fetch(__svm_nodes, offset); + return make_float4(__uint_as_float(node.x), + __uint_as_float(node.y), + __uint_as_float(node.z), + __uint_as_float(node.w)); } ccl_device_inline void decode_node_uchar4(uint i, uint *x, uint *y, uint *z, uint *w) { - if(x) *x = (i & 0xFF); - if(y) *y = ((i >> 8) & 0xFF); - if(z) *z = ((i >> 16) & 0xFF); - if(w) *w = ((i >> 24) & 0xFF); + if (x) + *x = (i & 0xFF); + if (y) + *y = ((i >> 8) & 0xFF); + if (z) + *z = ((i >> 16) & 0xFF); + if (w) + *w = ((i >> 24) & 0xFF); } CCL_NAMESPACE_END @@ -194,302 +204,310 @@ CCL_NAMESPACE_BEGIN #define NODES_FEATURE(feature) ((__NODES_FEATURES__ & (feature)) != 0) /* Main Interpreter Loop */ -ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, ShaderType type, int path_flag) +ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, + ShaderData *sd, + ccl_addr_space PathState *state, + ShaderType type, + int path_flag) { - float stack[SVM_STACK_SIZE]; - int offset = sd->shader & SHADER_MASK; + float stack[SVM_STACK_SIZE]; + int offset = sd->shader & SHADER_MASK; - while(1) { - uint4 node = read_node(kg, &offset); + while (1) { + uint4 node = read_node(kg, &offset); - switch(node.x) { + switch (node.x) { #if NODES_GROUP(NODE_GROUP_LEVEL_0) - case NODE_SHADER_JUMP: { - if(type == SHADER_TYPE_SURFACE) offset = node.y; - else if(type == SHADER_TYPE_VOLUME) offset = node.z; - else if(type == SHADER_TYPE_DISPLACEMENT) offset = node.w; - else return; - break; - } - case NODE_CLOSURE_BSDF: - svm_node_closure_bsdf(kg, sd, stack, node, type, path_flag, &offset); - break; - case NODE_CLOSURE_EMISSION: - svm_node_closure_emission(sd, stack, node); - break; - case NODE_CLOSURE_BACKGROUND: - svm_node_closure_background(sd, stack, node); - break; - case NODE_CLOSURE_SET_WEIGHT: - svm_node_closure_set_weight(sd, node.y, node.z, node.w); - break; - case NODE_CLOSURE_WEIGHT: - svm_node_closure_weight(sd, stack, node.y); - break; - case NODE_EMISSION_WEIGHT: - svm_node_emission_weight(kg, sd, stack, node); - break; - case NODE_MIX_CLOSURE: - svm_node_mix_closure(sd, stack, node); - break; - case NODE_JUMP_IF_ZERO: - if(stack_load_float(stack, node.z) == 0.0f) - offset += node.y; - break; - case NODE_JUMP_IF_ONE: - if(stack_load_float(stack, node.z) == 1.0f) - offset += node.y; - break; - case NODE_GEOMETRY: - svm_node_geometry(kg, sd, stack, node.y, node.z); - break; - case NODE_CONVERT: - svm_node_convert(kg, sd, stack, node.y, node.z, node.w); - break; - case NODE_TEX_COORD: - svm_node_tex_coord(kg, sd, path_flag, stack, node, &offset); - break; - case NODE_VALUE_F: - svm_node_value_f(kg, sd, stack, node.y, node.z); - break; - case NODE_VALUE_V: - svm_node_value_v(kg, sd, stack, node.y, &offset); - break; - case NODE_ATTR: - svm_node_attr(kg, sd, stack, node); - break; + case NODE_SHADER_JUMP: { + if (type == SHADER_TYPE_SURFACE) + offset = node.y; + else if (type == SHADER_TYPE_VOLUME) + offset = node.z; + else if (type == SHADER_TYPE_DISPLACEMENT) + offset = node.w; + else + return; + break; + } + case NODE_CLOSURE_BSDF: + svm_node_closure_bsdf(kg, sd, stack, node, type, path_flag, &offset); + break; + case NODE_CLOSURE_EMISSION: + svm_node_closure_emission(sd, stack, node); + break; + case NODE_CLOSURE_BACKGROUND: + svm_node_closure_background(sd, stack, node); + break; + case NODE_CLOSURE_SET_WEIGHT: + svm_node_closure_set_weight(sd, node.y, node.z, node.w); + break; + case NODE_CLOSURE_WEIGHT: + svm_node_closure_weight(sd, stack, node.y); + break; + case NODE_EMISSION_WEIGHT: + svm_node_emission_weight(kg, sd, stack, node); + break; + case NODE_MIX_CLOSURE: + svm_node_mix_closure(sd, stack, node); + break; + case NODE_JUMP_IF_ZERO: + if (stack_load_float(stack, node.z) == 0.0f) + offset += node.y; + break; + case NODE_JUMP_IF_ONE: + if (stack_load_float(stack, node.z) == 1.0f) + offset += node.y; + break; + case NODE_GEOMETRY: + svm_node_geometry(kg, sd, stack, node.y, node.z); + break; + case NODE_CONVERT: + svm_node_convert(kg, sd, stack, node.y, node.z, node.w); + break; + case NODE_TEX_COORD: + svm_node_tex_coord(kg, sd, path_flag, stack, node, &offset); + break; + case NODE_VALUE_F: + svm_node_value_f(kg, sd, stack, node.y, node.z); + break; + case NODE_VALUE_V: + svm_node_value_v(kg, sd, stack, node.y, &offset); + break; + case NODE_ATTR: + svm_node_attr(kg, sd, stack, node); + break; # if NODES_FEATURE(NODE_FEATURE_BUMP) - case NODE_GEOMETRY_BUMP_DX: - svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z); - break; - case NODE_GEOMETRY_BUMP_DY: - svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z); - break; - case NODE_SET_DISPLACEMENT: - svm_node_set_displacement(kg, sd, stack, node.y); - break; - case NODE_DISPLACEMENT: - svm_node_displacement(kg, sd, stack, node); - break; - case NODE_VECTOR_DISPLACEMENT: - svm_node_vector_displacement(kg, sd, stack, node, &offset); - break; -# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */ + case NODE_GEOMETRY_BUMP_DX: + svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z); + break; + case NODE_GEOMETRY_BUMP_DY: + svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z); + break; + case NODE_SET_DISPLACEMENT: + svm_node_set_displacement(kg, sd, stack, node.y); + break; + case NODE_DISPLACEMENT: + svm_node_displacement(kg, sd, stack, node); + break; + case NODE_VECTOR_DISPLACEMENT: + svm_node_vector_displacement(kg, sd, stack, node, &offset); + break; +# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */ # ifdef __TEXTURES__ - case NODE_TEX_IMAGE: - svm_node_tex_image(kg, sd, stack, node); - break; - case NODE_TEX_IMAGE_BOX: - svm_node_tex_image_box(kg, sd, stack, node); - break; - case NODE_TEX_NOISE: - svm_node_tex_noise(kg, sd, stack, node, &offset); - break; -# endif /* __TEXTURES__ */ + case NODE_TEX_IMAGE: + svm_node_tex_image(kg, sd, stack, node); + break; + case NODE_TEX_IMAGE_BOX: + svm_node_tex_image_box(kg, sd, stack, node); + break; + case NODE_TEX_NOISE: + svm_node_tex_noise(kg, sd, stack, node, &offset); + break; +# endif /* __TEXTURES__ */ # ifdef __EXTRA_NODES__ # if NODES_FEATURE(NODE_FEATURE_BUMP) - case NODE_SET_BUMP: - svm_node_set_bump(kg, sd, stack, node); - break; - case NODE_ATTR_BUMP_DX: - svm_node_attr_bump_dx(kg, sd, stack, node); - break; - case NODE_ATTR_BUMP_DY: - svm_node_attr_bump_dy(kg, sd, stack, node); - break; - case NODE_TEX_COORD_BUMP_DX: - svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node, &offset); - break; - case NODE_TEX_COORD_BUMP_DY: - svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node, &offset); - break; - case NODE_CLOSURE_SET_NORMAL: - svm_node_set_normal(kg, sd, stack, node.y, node.z); - break; + case NODE_SET_BUMP: + svm_node_set_bump(kg, sd, stack, node); + break; + case NODE_ATTR_BUMP_DX: + svm_node_attr_bump_dx(kg, sd, stack, node); + break; + case NODE_ATTR_BUMP_DY: + svm_node_attr_bump_dy(kg, sd, stack, node); + break; + case NODE_TEX_COORD_BUMP_DX: + svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node, &offset); + break; + case NODE_TEX_COORD_BUMP_DY: + svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node, &offset); + break; + case NODE_CLOSURE_SET_NORMAL: + svm_node_set_normal(kg, sd, stack, node.y, node.z); + break; # if NODES_FEATURE(NODE_FEATURE_BUMP_STATE) - case NODE_ENTER_BUMP_EVAL: - svm_node_enter_bump_eval(kg, sd, stack, node.y); - break; - case NODE_LEAVE_BUMP_EVAL: - svm_node_leave_bump_eval(kg, sd, stack, node.y); - break; -# endif /* NODES_FEATURE(NODE_FEATURE_BUMP_STATE) */ -# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */ - case NODE_HSV: - svm_node_hsv(kg, sd, stack, node, &offset); - break; -# endif /* __EXTRA_NODES__ */ -#endif /* NODES_GROUP(NODE_GROUP_LEVEL_0) */ + case NODE_ENTER_BUMP_EVAL: + svm_node_enter_bump_eval(kg, sd, stack, node.y); + break; + case NODE_LEAVE_BUMP_EVAL: + svm_node_leave_bump_eval(kg, sd, stack, node.y); + break; +# endif /* NODES_FEATURE(NODE_FEATURE_BUMP_STATE) */ +# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */ + case NODE_HSV: + svm_node_hsv(kg, sd, stack, node, &offset); + break; +# endif /* __EXTRA_NODES__ */ +#endif /* NODES_GROUP(NODE_GROUP_LEVEL_0) */ #if NODES_GROUP(NODE_GROUP_LEVEL_1) - case NODE_CLOSURE_HOLDOUT: - svm_node_closure_holdout(sd, stack, node); - break; - case NODE_FRESNEL: - svm_node_fresnel(sd, stack, node.y, node.z, node.w); - break; - case NODE_LAYER_WEIGHT: - svm_node_layer_weight(sd, stack, node); - break; + case NODE_CLOSURE_HOLDOUT: + svm_node_closure_holdout(sd, stack, node); + break; + case NODE_FRESNEL: + svm_node_fresnel(sd, stack, node.y, node.z, node.w); + break; + case NODE_LAYER_WEIGHT: + svm_node_layer_weight(sd, stack, node); + break; # if NODES_FEATURE(NODE_FEATURE_VOLUME) - case NODE_CLOSURE_VOLUME: - svm_node_closure_volume(kg, sd, stack, node, type); - break; - case NODE_PRINCIPLED_VOLUME: - svm_node_principled_volume(kg, sd, stack, node, type, path_flag, &offset); - break; -# endif /* NODES_FEATURE(NODE_FEATURE_VOLUME) */ + case NODE_CLOSURE_VOLUME: + svm_node_closure_volume(kg, sd, stack, node, type); + break; + case NODE_PRINCIPLED_VOLUME: + svm_node_principled_volume(kg, sd, stack, node, type, path_flag, &offset); + break; +# endif /* NODES_FEATURE(NODE_FEATURE_VOLUME) */ # ifdef __EXTRA_NODES__ - case NODE_MATH: - svm_node_math(kg, sd, stack, node.y, node.z, node.w, &offset); - break; - case NODE_VECTOR_MATH: - svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, &offset); - break; - case NODE_RGB_RAMP: - svm_node_rgb_ramp(kg, sd, stack, node, &offset); - break; - case NODE_GAMMA: - svm_node_gamma(sd, stack, node.y, node.z, node.w); - break; - case NODE_BRIGHTCONTRAST: - svm_node_brightness(sd, stack, node.y, node.z, node.w); - break; - case NODE_LIGHT_PATH: - svm_node_light_path(sd, state, stack, node.y, node.z, path_flag); - break; - case NODE_OBJECT_INFO: - svm_node_object_info(kg, sd, stack, node.y, node.z); - break; - case NODE_PARTICLE_INFO: - svm_node_particle_info(kg, sd, stack, node.y, node.z); - break; + case NODE_MATH: + svm_node_math(kg, sd, stack, node.y, node.z, node.w, &offset); + break; + case NODE_VECTOR_MATH: + svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, &offset); + break; + case NODE_RGB_RAMP: + svm_node_rgb_ramp(kg, sd, stack, node, &offset); + break; + case NODE_GAMMA: + svm_node_gamma(sd, stack, node.y, node.z, node.w); + break; + case NODE_BRIGHTCONTRAST: + svm_node_brightness(sd, stack, node.y, node.z, node.w); + break; + case NODE_LIGHT_PATH: + svm_node_light_path(sd, state, stack, node.y, node.z, path_flag); + break; + case NODE_OBJECT_INFO: + svm_node_object_info(kg, sd, stack, node.y, node.z); + break; + case NODE_PARTICLE_INFO: + svm_node_particle_info(kg, sd, stack, node.y, node.z); + break; # ifdef __HAIR__ # if NODES_FEATURE(NODE_FEATURE_HAIR) - case NODE_HAIR_INFO: - svm_node_hair_info(kg, sd, stack, node.y, node.z); - break; -# endif /* NODES_FEATURE(NODE_FEATURE_HAIR) */ -# endif /* __HAIR__ */ -# endif /* __EXTRA_NODES__ */ -#endif /* NODES_GROUP(NODE_GROUP_LEVEL_1) */ + case NODE_HAIR_INFO: + svm_node_hair_info(kg, sd, stack, node.y, node.z); + break; +# endif /* NODES_FEATURE(NODE_FEATURE_HAIR) */ +# endif /* __HAIR__ */ +# endif /* __EXTRA_NODES__ */ +#endif /* NODES_GROUP(NODE_GROUP_LEVEL_1) */ #if NODES_GROUP(NODE_GROUP_LEVEL_2) - case NODE_MAPPING: - svm_node_mapping(kg, sd, stack, node.y, node.z, &offset); - break; - case NODE_MIN_MAX: - svm_node_min_max(kg, sd, stack, node.y, node.z, &offset); - break; - case NODE_CAMERA: - svm_node_camera(kg, sd, stack, node.y, node.z, node.w); - break; + case NODE_MAPPING: + svm_node_mapping(kg, sd, stack, node.y, node.z, &offset); + break; + case NODE_MIN_MAX: + svm_node_min_max(kg, sd, stack, node.y, node.z, &offset); + break; + case NODE_CAMERA: + svm_node_camera(kg, sd, stack, node.y, node.z, node.w); + break; # ifdef __TEXTURES__ - case NODE_TEX_ENVIRONMENT: - svm_node_tex_environment(kg, sd, stack, node); - break; - case NODE_TEX_SKY: - svm_node_tex_sky(kg, sd, stack, node, &offset); - break; - case NODE_TEX_GRADIENT: - svm_node_tex_gradient(sd, stack, node); - break; - case NODE_TEX_VORONOI: - svm_node_tex_voronoi(kg, sd, stack, node, &offset); - break; - case NODE_TEX_MUSGRAVE: - svm_node_tex_musgrave(kg, sd, stack, node, &offset); - break; - case NODE_TEX_WAVE: - svm_node_tex_wave(kg, sd, stack, node, &offset); - break; - case NODE_TEX_MAGIC: - svm_node_tex_magic(kg, sd, stack, node, &offset); - break; - case NODE_TEX_CHECKER: - svm_node_tex_checker(kg, sd, stack, node); - break; - case NODE_TEX_BRICK: - svm_node_tex_brick(kg, sd, stack, node, &offset); - break; -# endif /* __TEXTURES__ */ + case NODE_TEX_ENVIRONMENT: + svm_node_tex_environment(kg, sd, stack, node); + break; + case NODE_TEX_SKY: + svm_node_tex_sky(kg, sd, stack, node, &offset); + break; + case NODE_TEX_GRADIENT: + svm_node_tex_gradient(sd, stack, node); + break; + case NODE_TEX_VORONOI: + svm_node_tex_voronoi(kg, sd, stack, node, &offset); + break; + case NODE_TEX_MUSGRAVE: + svm_node_tex_musgrave(kg, sd, stack, node, &offset); + break; + case NODE_TEX_WAVE: + svm_node_tex_wave(kg, sd, stack, node, &offset); + break; + case NODE_TEX_MAGIC: + svm_node_tex_magic(kg, sd, stack, node, &offset); + break; + case NODE_TEX_CHECKER: + svm_node_tex_checker(kg, sd, stack, node); + break; + case NODE_TEX_BRICK: + svm_node_tex_brick(kg, sd, stack, node, &offset); + break; +# endif /* __TEXTURES__ */ # ifdef __EXTRA_NODES__ - case NODE_NORMAL: - svm_node_normal(kg, sd, stack, node.y, node.z, node.w, &offset); - break; - case NODE_LIGHT_FALLOFF: - svm_node_light_falloff(sd, stack, node); - break; - case NODE_IES: - svm_node_ies(kg, sd, stack, node, &offset); - break; -# endif /* __EXTRA_NODES__ */ -#endif /* NODES_GROUP(NODE_GROUP_LEVEL_2) */ + case NODE_NORMAL: + svm_node_normal(kg, sd, stack, node.y, node.z, node.w, &offset); + break; + case NODE_LIGHT_FALLOFF: + svm_node_light_falloff(sd, stack, node); + break; + case NODE_IES: + svm_node_ies(kg, sd, stack, node, &offset); + break; +# endif /* __EXTRA_NODES__ */ +#endif /* NODES_GROUP(NODE_GROUP_LEVEL_2) */ #if NODES_GROUP(NODE_GROUP_LEVEL_3) - case NODE_RGB_CURVES: - case NODE_VECTOR_CURVES: - svm_node_curves(kg, sd, stack, node, &offset); - break; - case NODE_TANGENT: - svm_node_tangent(kg, sd, stack, node); - break; - case NODE_NORMAL_MAP: - svm_node_normal_map(kg, sd, stack, node); - break; + case NODE_RGB_CURVES: + case NODE_VECTOR_CURVES: + svm_node_curves(kg, sd, stack, node, &offset); + break; + case NODE_TANGENT: + svm_node_tangent(kg, sd, stack, node); + break; + case NODE_NORMAL_MAP: + svm_node_normal_map(kg, sd, stack, node); + break; # ifdef __EXTRA_NODES__ - case NODE_INVERT: - svm_node_invert(sd, stack, node.y, node.z, node.w); - break; - case NODE_MIX: - svm_node_mix(kg, sd, stack, node.y, node.z, node.w, &offset); - break; - case NODE_SEPARATE_VECTOR: - svm_node_separate_vector(sd, stack, node.y, node.z, node.w); - break; - case NODE_COMBINE_VECTOR: - svm_node_combine_vector(sd, stack, node.y, node.z, node.w); - break; - case NODE_SEPARATE_HSV: - svm_node_separate_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); - break; - case NODE_COMBINE_HSV: - svm_node_combine_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); - break; - case NODE_VECTOR_TRANSFORM: - svm_node_vector_transform(kg, sd, stack, node); - break; - case NODE_WIREFRAME: - svm_node_wireframe(kg, sd, stack, node); - break; - case NODE_WAVELENGTH: - svm_node_wavelength(kg, sd, stack, node.y, node.z); - break; - case NODE_BLACKBODY: - svm_node_blackbody(kg, sd, stack, node.y, node.z); - break; -# endif /* __EXTRA_NODES__ */ + case NODE_INVERT: + svm_node_invert(sd, stack, node.y, node.z, node.w); + break; + case NODE_MIX: + svm_node_mix(kg, sd, stack, node.y, node.z, node.w, &offset); + break; + case NODE_SEPARATE_VECTOR: + svm_node_separate_vector(sd, stack, node.y, node.z, node.w); + break; + case NODE_COMBINE_VECTOR: + svm_node_combine_vector(sd, stack, node.y, node.z, node.w); + break; + case NODE_SEPARATE_HSV: + svm_node_separate_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); + break; + case NODE_COMBINE_HSV: + svm_node_combine_hsv(kg, sd, stack, node.y, node.z, node.w, &offset); + break; + case NODE_VECTOR_TRANSFORM: + svm_node_vector_transform(kg, sd, stack, node); + break; + case NODE_WIREFRAME: + svm_node_wireframe(kg, sd, stack, node); + break; + case NODE_WAVELENGTH: + svm_node_wavelength(kg, sd, stack, node.y, node.z); + break; + case NODE_BLACKBODY: + svm_node_blackbody(kg, sd, stack, node.y, node.z); + break; +# endif /* __EXTRA_NODES__ */ # if NODES_FEATURE(NODE_FEATURE_VOLUME) - case NODE_TEX_VOXEL: - svm_node_tex_voxel(kg, sd, stack, node, &offset); - break; -# endif /* NODES_FEATURE(NODE_FEATURE_VOLUME) */ + case NODE_TEX_VOXEL: + svm_node_tex_voxel(kg, sd, stack, node, &offset); + break; +# endif /* NODES_FEATURE(NODE_FEATURE_VOLUME) */ # ifdef __SHADER_RAYTRACE__ - case NODE_BEVEL: - svm_node_bevel(kg, sd, state, stack, node); - break; - case NODE_AMBIENT_OCCLUSION: - svm_node_ao(kg, sd, state, stack, node); - break; -# endif /* __SHADER_RAYTRACE__ */ -#endif /* NODES_GROUP(NODE_GROUP_LEVEL_3) */ - case NODE_END: - return; - default: - kernel_assert(!"Unknown node type was passed to the SVM machine"); - return; - } - } + case NODE_BEVEL: + svm_node_bevel(kg, sd, state, stack, node); + break; + case NODE_AMBIENT_OCCLUSION: + svm_node_ao(kg, sd, state, stack, node); + break; +# endif /* __SHADER_RAYTRACE__ */ +#endif /* NODES_GROUP(NODE_GROUP_LEVEL_3) */ + case NODE_END: + return; + default: + kernel_assert(!"Unknown node type was passed to the SVM machine"); + return; + } + } } #undef NODES_GROUP @@ -497,4 +515,4 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a CCL_NAMESPACE_END -#endif /* __SVM_H__ */ +#endif /* __SVM_H__ */ diff --git a/intern/cycles/kernel/svm/svm_ao.h b/intern/cycles/kernel/svm/svm_ao.h index 0744ec1768f..06076175c40 100644 --- a/intern/cycles/kernel/svm/svm_ao.h +++ b/intern/cycles/kernel/svm/svm_ao.h @@ -24,95 +24,82 @@ ccl_device_noinline float svm_ao(KernelGlobals *kg, int num_samples, int flags) { - if(flags & NODE_AO_GLOBAL_RADIUS) { - max_dist = kernel_data.background.ao_distance; - } - - /* Early out if no sampling needed. */ - if(max_dist <= 0.0f || num_samples < 1 || sd->object == OBJECT_NONE) { - return 1.0f; - } - - /* Can't raytrace from shaders like displacement, before BVH exists. */ - if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) { - return 1.0f; - } - - if(flags & NODE_AO_INSIDE) { - N = -N; - } - - float3 T, B; - make_orthonormals(N, &T, &B); - - int unoccluded = 0; - for(int sample = 0; sample < num_samples; sample++) { - float disk_u, disk_v; - path_branched_rng_2D(kg, state->rng_hash, state, sample, num_samples, - PRNG_BEVEL_U, &disk_u, &disk_v); - - float2 d = concentric_sample_disk(disk_u, disk_v); - float3 D = make_float3(d.x, d.y, safe_sqrtf(1.0f - dot(d, d))); - - /* Create ray. */ - Ray ray; - ray.P = ray_offset(sd->P, N); - ray.D = D.x*T + D.y*B + D.z*N; - ray.t = max_dist; - ray.time = sd->time; - ray.dP = sd->dP; - ray.dD = differential3_zero(); - - if(flags & NODE_AO_ONLY_LOCAL) { - if(!scene_intersect_local(kg, - ray, - NULL, - sd->object, - NULL, - 0)) { - unoccluded++; - } - } - else { - Intersection isect; - if(!scene_intersect(kg, - ray, - PATH_RAY_SHADOW_OPAQUE, - &isect, - NULL, - 0.0f, 0.0f)) { - unoccluded++; - } - } - } - - return ((float) unoccluded) / num_samples; + if (flags & NODE_AO_GLOBAL_RADIUS) { + max_dist = kernel_data.background.ao_distance; + } + + /* Early out if no sampling needed. */ + if (max_dist <= 0.0f || num_samples < 1 || sd->object == OBJECT_NONE) { + return 1.0f; + } + + /* Can't raytrace from shaders like displacement, before BVH exists. */ + if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) { + return 1.0f; + } + + if (flags & NODE_AO_INSIDE) { + N = -N; + } + + float3 T, B; + make_orthonormals(N, &T, &B); + + int unoccluded = 0; + for (int sample = 0; sample < num_samples; sample++) { + float disk_u, disk_v; + path_branched_rng_2D( + kg, state->rng_hash, state, sample, num_samples, PRNG_BEVEL_U, &disk_u, &disk_v); + + float2 d = concentric_sample_disk(disk_u, disk_v); + float3 D = make_float3(d.x, d.y, safe_sqrtf(1.0f - dot(d, d))); + + /* Create ray. */ + Ray ray; + ray.P = ray_offset(sd->P, N); + ray.D = D.x * T + D.y * B + D.z * N; + ray.t = max_dist; + ray.time = sd->time; + ray.dP = sd->dP; + ray.dD = differential3_zero(); + + if (flags & NODE_AO_ONLY_LOCAL) { + if (!scene_intersect_local(kg, ray, NULL, sd->object, NULL, 0)) { + unoccluded++; + } + } + else { + Intersection isect; + if (!scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f)) { + unoccluded++; + } + } + } + + return ((float)unoccluded) / num_samples; } -ccl_device void svm_node_ao(KernelGlobals *kg, - ShaderData *sd, - ccl_addr_space PathState *state, - float *stack, - uint4 node) +ccl_device void svm_node_ao( + KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, float *stack, uint4 node) { - uint flags, dist_offset, normal_offset, out_ao_offset; - decode_node_uchar4(node.y, &flags, &dist_offset, &normal_offset, &out_ao_offset); + uint flags, dist_offset, normal_offset, out_ao_offset; + decode_node_uchar4(node.y, &flags, &dist_offset, &normal_offset, &out_ao_offset); - uint color_offset, out_color_offset, samples; - decode_node_uchar4(node.z, &color_offset, &out_color_offset, &samples, NULL); + uint color_offset, out_color_offset, samples; + decode_node_uchar4(node.z, &color_offset, &out_color_offset, &samples, NULL); - float dist = stack_load_float_default(stack, dist_offset, node.w); - float3 normal = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N; - float ao = svm_ao(kg, sd, normal, state, dist, samples, flags); + float dist = stack_load_float_default(stack, dist_offset, node.w); + float3 normal = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N; + float ao = svm_ao(kg, sd, normal, state, dist, samples, flags); - if(stack_valid(out_ao_offset)) { - stack_store_float(stack, out_ao_offset, ao); - } + if (stack_valid(out_ao_offset)) { + stack_store_float(stack, out_ao_offset, ao); + } - if(stack_valid(out_color_offset)) { - float3 color = stack_load_float3(stack, color_offset); - stack_store_float3(stack, out_color_offset, ao * color); - } + if (stack_valid(out_color_offset)) { + float3 color = stack_load_float3(stack, color_offset); + stack_store_float3(stack, out_color_offset, ao * color); + } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h index c2366df71d0..a67cfe91a30 100644 --- a/intern/cycles/kernel/svm/svm_attribute.h +++ b/intern/cycles/kernel/svm/svm_attribute.h @@ -18,67 +18,66 @@ CCL_NAMESPACE_BEGIN /* Attribute Node */ -ccl_device AttributeDescriptor svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, - uint4 node, NodeAttributeType *type, - uint *out_offset) +ccl_device AttributeDescriptor svm_node_attr_init( + KernelGlobals *kg, ShaderData *sd, uint4 node, NodeAttributeType *type, uint *out_offset) { - *out_offset = node.z; - *type = (NodeAttributeType)node.w; + *out_offset = node.z; + *type = (NodeAttributeType)node.w; - AttributeDescriptor desc; + AttributeDescriptor desc; - if(sd->object != OBJECT_NONE) { - desc = find_attribute(kg, sd, node.y); - if(desc.offset == ATTR_STD_NOT_FOUND) { - desc = attribute_not_found(); - desc.offset = 0; - desc.type = (NodeAttributeType)node.w; - } - } - else { - /* background */ - desc = attribute_not_found(); - desc.offset = 0; - desc.type = (NodeAttributeType)node.w; - } + if (sd->object != OBJECT_NONE) { + desc = find_attribute(kg, sd, node.y); + if (desc.offset == ATTR_STD_NOT_FOUND) { + desc = attribute_not_found(); + desc.offset = 0; + desc.type = (NodeAttributeType)node.w; + } + } + else { + /* background */ + desc = attribute_not_found(); + desc.offset = 0; + desc.type = (NodeAttributeType)node.w; + } - return desc; + return desc; } ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - NodeAttributeType type; - uint out_offset; - AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); + NodeAttributeType type; + uint out_offset; + AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); - /* fetch and store attribute */ - if(desc.type == NODE_ATTR_FLOAT) { - float f = primitive_attribute_float(kg, sd, desc, NULL, NULL); - if(type == NODE_ATTR_FLOAT) { - stack_store_float(stack, out_offset, f); - } - else { - stack_store_float3(stack, out_offset, make_float3(f, f, f)); - } - } - else if(desc.type == NODE_ATTR_FLOAT2) { - float2 f = primitive_attribute_float2(kg, sd, desc, NULL, NULL); - if(type == NODE_ATTR_FLOAT) { - stack_store_float(stack, out_offset, f.x); - } - else { - stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f)); - } - } - else { - float3 f = primitive_attribute_float3(kg, sd, desc, NULL, NULL); - if(type == NODE_ATTR_FLOAT) { - stack_store_float(stack, out_offset, average(f)); - } - else { - stack_store_float3(stack, out_offset, f); - } - } + /* fetch and store attribute */ + if (desc.type == NODE_ATTR_FLOAT) { + float f = primitive_attribute_float(kg, sd, desc, NULL, NULL); + if (type == NODE_ATTR_FLOAT) { + stack_store_float(stack, out_offset, f); + } + else { + stack_store_float3(stack, out_offset, make_float3(f, f, f)); + } + } + else if (desc.type == NODE_ATTR_FLOAT2) { + float2 f = primitive_attribute_float2(kg, sd, desc, NULL, NULL); + if (type == NODE_ATTR_FLOAT) { + stack_store_float(stack, out_offset, f.x); + } + else { + stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f)); + } + } + else { + float3 f = primitive_attribute_float3(kg, sd, desc, NULL, NULL); + if (type == NODE_ATTR_FLOAT) { + stack_store_float(stack, out_offset, average(f)); + } + else { + stack_store_float3(stack, out_offset, f); + } + } } #ifndef __KERNEL_CUDA__ @@ -86,43 +85,44 @@ ccl_device #else ccl_device_noinline #endif -void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) + void + svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - NodeAttributeType type; - uint out_offset; - AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); + NodeAttributeType type; + uint out_offset; + AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); - /* fetch and store attribute */ - if(desc.type == NODE_ATTR_FLOAT) { - float dx; - float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL); - if(type == NODE_ATTR_FLOAT) { - stack_store_float(stack, out_offset, f+dx); - } - else { - stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx)); - } - } - else if(desc.type == NODE_ATTR_FLOAT2) { - float2 dx; - float2 f = primitive_attribute_float2(kg, sd, desc, &dx, NULL); - if (type == NODE_ATTR_FLOAT) { - stack_store_float(stack, out_offset, f.x + dx.x); - } - else { - stack_store_float3(stack, out_offset, make_float3(f.x+dx.x, f.y+dx.y, 0.0f)); - } - } - else { - float3 dx; - float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL); - if(type == NODE_ATTR_FLOAT) { - stack_store_float(stack, out_offset, average(f+dx)); - } - else { - stack_store_float3(stack, out_offset, f+dx); - } - } + /* fetch and store attribute */ + if (desc.type == NODE_ATTR_FLOAT) { + float dx; + float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL); + if (type == NODE_ATTR_FLOAT) { + stack_store_float(stack, out_offset, f + dx); + } + else { + stack_store_float3(stack, out_offset, make_float3(f + dx, f + dx, f + dx)); + } + } + else if (desc.type == NODE_ATTR_FLOAT2) { + float2 dx; + float2 f = primitive_attribute_float2(kg, sd, desc, &dx, NULL); + if (type == NODE_ATTR_FLOAT) { + stack_store_float(stack, out_offset, f.x + dx.x); + } + else { + stack_store_float3(stack, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f)); + } + } + else { + float3 dx; + float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL); + if (type == NODE_ATTR_FLOAT) { + stack_store_float(stack, out_offset, average(f + dx)); + } + else { + stack_store_float3(stack, out_offset, f + dx); + } + } } #ifndef __KERNEL_CUDA__ @@ -130,46 +130,44 @@ ccl_device #else ccl_device_noinline #endif -void svm_node_attr_bump_dy(KernelGlobals *kg, - ShaderData *sd, - float *stack, - uint4 node) + void + svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - NodeAttributeType type; - uint out_offset; - AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); + NodeAttributeType type; + uint out_offset; + AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); - /* fetch and store attribute */ - if(desc.type == NODE_ATTR_FLOAT) { - float dy; - float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy); - if(type == NODE_ATTR_FLOAT) { - stack_store_float(stack, out_offset, f+dy); - } - else { - stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy)); - } - } - else if(desc.type == NODE_ATTR_FLOAT2) { - float2 dy; - float2 f = primitive_attribute_float2(kg, sd, desc, NULL, &dy); - if(type == NODE_ATTR_FLOAT) { - stack_store_float(stack, out_offset, f.x + dy.x); - } - else { - stack_store_float3(stack, out_offset, make_float3(f.x+dy.x, f.y+dy.y, 0.0f)); - } - } - else { - float3 dy; - float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy); - if(type == NODE_ATTR_FLOAT) { - stack_store_float(stack, out_offset, average(f+dy)); - } - else { - stack_store_float3(stack, out_offset, f+dy); - } - } + /* fetch and store attribute */ + if (desc.type == NODE_ATTR_FLOAT) { + float dy; + float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy); + if (type == NODE_ATTR_FLOAT) { + stack_store_float(stack, out_offset, f + dy); + } + else { + stack_store_float3(stack, out_offset, make_float3(f + dy, f + dy, f + dy)); + } + } + else if (desc.type == NODE_ATTR_FLOAT2) { + float2 dy; + float2 f = primitive_attribute_float2(kg, sd, desc, NULL, &dy); + if (type == NODE_ATTR_FLOAT) { + stack_store_float(stack, out_offset, f.x + dy.x); + } + else { + stack_store_float3(stack, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f)); + } + } + else { + float3 dy; + float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy); + if (type == NODE_ATTR_FLOAT) { + stack_store_float(stack, out_offset, average(f + dy)); + } + else { + stack_store_float3(stack, out_offset, f + dy); + } + } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_bevel.h b/intern/cycles/kernel/svm/svm_bevel.h index b5bb9df422b..fcf28e96e98 100644 --- a/intern/cycles/kernel/svm/svm_bevel.h +++ b/intern/cycles/kernel/svm/svm_bevel.h @@ -22,215 +22,196 @@ CCL_NAMESPACE_BEGIN * http://library.imageworks.com/pdfs/imageworks-library-BSSRDF-sampling.pdf */ -ccl_device_noinline float3 svm_bevel( - KernelGlobals *kg, - ShaderData *sd, - ccl_addr_space PathState *state, - float radius, - int num_samples) +ccl_device_noinline float3 svm_bevel(KernelGlobals *kg, + ShaderData *sd, + ccl_addr_space PathState *state, + float radius, + int num_samples) { - /* Early out if no sampling needed. */ - if(radius <= 0.0f || num_samples < 1 || sd->object == OBJECT_NONE) { - return sd->N; - } - - /* Can't raytrace from shaders like displacement, before BVH exists. */ - if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) { - return sd->N; - } - - /* Don't bevel for blurry indirect rays. */ - if(state->min_ray_pdf < 8.0f) { - return sd->N; - } - - /* Setup for multi intersection. */ - LocalIntersection isect; - uint lcg_state = lcg_state_init_addrspace(state, 0x64c6a40e); - - /* Sample normals from surrounding points on surface. */ - float3 sum_N = make_float3(0.0f, 0.0f, 0.0f); - - for(int sample = 0; sample < num_samples; sample++) { - float disk_u, disk_v; - path_branched_rng_2D(kg, state->rng_hash, state, sample, num_samples, - PRNG_BEVEL_U, &disk_u, &disk_v); - - /* Pick random axis in local frame and point on disk. */ - float3 disk_N, disk_T, disk_B; - float pick_pdf_N, pick_pdf_T, pick_pdf_B; - - disk_N = sd->Ng; - make_orthonormals(disk_N, &disk_T, &disk_B); - - float axisu = disk_u; - - if(axisu < 0.5f) { - pick_pdf_N = 0.5f; - pick_pdf_T = 0.25f; - pick_pdf_B = 0.25f; - disk_u *= 2.0f; - } - else if(axisu < 0.75f) { - float3 tmp = disk_N; - disk_N = disk_T; - disk_T = tmp; - pick_pdf_N = 0.25f; - pick_pdf_T = 0.5f; - pick_pdf_B = 0.25f; - disk_u = (disk_u - 0.5f)*4.0f; - } - else { - float3 tmp = disk_N; - disk_N = disk_B; - disk_B = tmp; - pick_pdf_N = 0.25f; - pick_pdf_T = 0.25f; - pick_pdf_B = 0.5f; - disk_u = (disk_u - 0.75f)*4.0f; - } - - /* Sample point on disk. */ - float phi = M_2PI_F * disk_u; - float disk_r = disk_v; - float disk_height; - - /* Perhaps find something better than Cubic BSSRDF, but happens to work well. */ - bssrdf_cubic_sample(radius, 0.0f, disk_r, &disk_r, &disk_height); - - float3 disk_P = (disk_r*cosf(phi)) * disk_T + (disk_r*sinf(phi)) * disk_B; - - /* Create ray. */ - Ray *ray = &isect.ray; - ray->P = sd->P + disk_N*disk_height + disk_P; - ray->D = -disk_N; - ray->t = 2.0f*disk_height; - ray->dP = sd->dP; - ray->dD = differential3_zero(); - ray->time = sd->time; - - /* Intersect with the same object. if multiple intersections are found it - * will use at most LOCAL_MAX_HITS hits, a random subset of all hits. */ - scene_intersect_local(kg, - *ray, - &isect, - sd->object, - &lcg_state, - LOCAL_MAX_HITS); - - int num_eval_hits = min(isect.num_hits, LOCAL_MAX_HITS); - - for(int hit = 0; hit < num_eval_hits; hit++) { - /* Quickly retrieve P and Ng without setting up ShaderData. */ - float3 hit_P; - if(sd->type & PRIMITIVE_TRIANGLE) { - hit_P = triangle_refine_local(kg, - sd, - &isect.hits[hit], - ray); - } + /* Early out if no sampling needed. */ + if (radius <= 0.0f || num_samples < 1 || sd->object == OBJECT_NONE) { + return sd->N; + } + + /* Can't raytrace from shaders like displacement, before BVH exists. */ + if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) { + return sd->N; + } + + /* Don't bevel for blurry indirect rays. */ + if (state->min_ray_pdf < 8.0f) { + return sd->N; + } + + /* Setup for multi intersection. */ + LocalIntersection isect; + uint lcg_state = lcg_state_init_addrspace(state, 0x64c6a40e); + + /* Sample normals from surrounding points on surface. */ + float3 sum_N = make_float3(0.0f, 0.0f, 0.0f); + + for (int sample = 0; sample < num_samples; sample++) { + float disk_u, disk_v; + path_branched_rng_2D( + kg, state->rng_hash, state, sample, num_samples, PRNG_BEVEL_U, &disk_u, &disk_v); + + /* Pick random axis in local frame and point on disk. */ + float3 disk_N, disk_T, disk_B; + float pick_pdf_N, pick_pdf_T, pick_pdf_B; + + disk_N = sd->Ng; + make_orthonormals(disk_N, &disk_T, &disk_B); + + float axisu = disk_u; + + if (axisu < 0.5f) { + pick_pdf_N = 0.5f; + pick_pdf_T = 0.25f; + pick_pdf_B = 0.25f; + disk_u *= 2.0f; + } + else if (axisu < 0.75f) { + float3 tmp = disk_N; + disk_N = disk_T; + disk_T = tmp; + pick_pdf_N = 0.25f; + pick_pdf_T = 0.5f; + pick_pdf_B = 0.25f; + disk_u = (disk_u - 0.5f) * 4.0f; + } + else { + float3 tmp = disk_N; + disk_N = disk_B; + disk_B = tmp; + pick_pdf_N = 0.25f; + pick_pdf_T = 0.25f; + pick_pdf_B = 0.5f; + disk_u = (disk_u - 0.75f) * 4.0f; + } + + /* Sample point on disk. */ + float phi = M_2PI_F * disk_u; + float disk_r = disk_v; + float disk_height; + + /* Perhaps find something better than Cubic BSSRDF, but happens to work well. */ + bssrdf_cubic_sample(radius, 0.0f, disk_r, &disk_r, &disk_height); + + float3 disk_P = (disk_r * cosf(phi)) * disk_T + (disk_r * sinf(phi)) * disk_B; + + /* Create ray. */ + Ray *ray = &isect.ray; + ray->P = sd->P + disk_N * disk_height + disk_P; + ray->D = -disk_N; + ray->t = 2.0f * disk_height; + ray->dP = sd->dP; + ray->dD = differential3_zero(); + ray->time = sd->time; + + /* Intersect with the same object. if multiple intersections are found it + * will use at most LOCAL_MAX_HITS hits, a random subset of all hits. */ + scene_intersect_local(kg, *ray, &isect, sd->object, &lcg_state, LOCAL_MAX_HITS); + + int num_eval_hits = min(isect.num_hits, LOCAL_MAX_HITS); + + for (int hit = 0; hit < num_eval_hits; hit++) { + /* Quickly retrieve P and Ng without setting up ShaderData. */ + float3 hit_P; + if (sd->type & PRIMITIVE_TRIANGLE) { + hit_P = triangle_refine_local(kg, sd, &isect.hits[hit], ray); + } #ifdef __OBJECT_MOTION__ - else if(sd->type & PRIMITIVE_MOTION_TRIANGLE) { - float3 verts[3]; - motion_triangle_vertices( - kg, - sd->object, - kernel_tex_fetch(__prim_index, isect.hits[hit].prim), - sd->time, - verts); - hit_P = motion_triangle_refine_local(kg, - sd, - &isect.hits[hit], - ray, - verts); - } -#endif /* __OBJECT_MOTION__ */ - - /* Get geometric normal. */ - float3 hit_Ng = isect.Ng[hit]; - int object = (isect.hits[hit].object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, isect.hits[hit].prim): isect.hits[hit].object; - int object_flag = kernel_tex_fetch(__object_flag, object); - if(object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { - hit_Ng = -hit_Ng; - } - - /* Compute smooth normal. */ - float3 N = hit_Ng; - int prim = kernel_tex_fetch(__prim_index, isect.hits[hit].prim); - int shader = kernel_tex_fetch(__tri_shader, prim); - - if(shader & SHADER_SMOOTH_NORMAL) { - float u = isect.hits[hit].u; - float v = isect.hits[hit].v; - - if(sd->type & PRIMITIVE_TRIANGLE) { - N = triangle_smooth_normal(kg, N, prim, u, v); - } + else if (sd->type & PRIMITIVE_MOTION_TRIANGLE) { + float3 verts[3]; + motion_triangle_vertices( + kg, sd->object, kernel_tex_fetch(__prim_index, isect.hits[hit].prim), sd->time, verts); + hit_P = motion_triangle_refine_local(kg, sd, &isect.hits[hit], ray, verts); + } +#endif /* __OBJECT_MOTION__ */ + + /* Get geometric normal. */ + float3 hit_Ng = isect.Ng[hit]; + int object = (isect.hits[hit].object == OBJECT_NONE) ? + kernel_tex_fetch(__prim_object, isect.hits[hit].prim) : + isect.hits[hit].object; + int object_flag = kernel_tex_fetch(__object_flag, object); + if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { + hit_Ng = -hit_Ng; + } + + /* Compute smooth normal. */ + float3 N = hit_Ng; + int prim = kernel_tex_fetch(__prim_index, isect.hits[hit].prim); + int shader = kernel_tex_fetch(__tri_shader, prim); + + if (shader & SHADER_SMOOTH_NORMAL) { + float u = isect.hits[hit].u; + float v = isect.hits[hit].v; + + if (sd->type & PRIMITIVE_TRIANGLE) { + N = triangle_smooth_normal(kg, N, prim, u, v); + } #ifdef __OBJECT_MOTION__ - else if(sd->type & PRIMITIVE_MOTION_TRIANGLE) { - N = motion_triangle_smooth_normal(kg, N, sd->object, prim, u, v, sd->time); - } -#endif /* __OBJECT_MOTION__ */ - } - - /* Transform normals to world space. */ - if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { - object_normal_transform(kg, sd, &N); - object_normal_transform(kg, sd, &hit_Ng); - } - - /* Probability densities for local frame axes. */ - float pdf_N = pick_pdf_N * fabsf(dot(disk_N, hit_Ng)); - float pdf_T = pick_pdf_T * fabsf(dot(disk_T, hit_Ng)); - float pdf_B = pick_pdf_B * fabsf(dot(disk_B, hit_Ng)); - - /* Multiple importance sample between 3 axes, power heuristic - * found to be slightly better than balance heuristic. pdf_N - * in the MIS weight and denominator cancelled out. */ - float w = pdf_N / (sqr(pdf_N) + sqr(pdf_T) + sqr(pdf_B)); - if(isect.num_hits > LOCAL_MAX_HITS) { - w *= isect.num_hits/(float)LOCAL_MAX_HITS; - } - - /* Real distance to sampled point. */ - float r = len(hit_P - sd->P); - - /* Compute weight. */ - float pdf = bssrdf_cubic_pdf(radius, 0.0f, r); - float disk_pdf = bssrdf_cubic_pdf(radius, 0.0f, disk_r); - - w *= pdf / disk_pdf; - - /* Sum normal and weight. */ - sum_N += w * N; - } - } - - /* Normalize. */ - float3 N = safe_normalize(sum_N); - return is_zero(N) ? sd->N : (sd->flag & SD_BACKFACING) ? -N : N; + else if (sd->type & PRIMITIVE_MOTION_TRIANGLE) { + N = motion_triangle_smooth_normal(kg, N, sd->object, prim, u, v, sd->time); + } +#endif /* __OBJECT_MOTION__ */ + } + + /* Transform normals to world space. */ + if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { + object_normal_transform(kg, sd, &N); + object_normal_transform(kg, sd, &hit_Ng); + } + + /* Probability densities for local frame axes. */ + float pdf_N = pick_pdf_N * fabsf(dot(disk_N, hit_Ng)); + float pdf_T = pick_pdf_T * fabsf(dot(disk_T, hit_Ng)); + float pdf_B = pick_pdf_B * fabsf(dot(disk_B, hit_Ng)); + + /* Multiple importance sample between 3 axes, power heuristic + * found to be slightly better than balance heuristic. pdf_N + * in the MIS weight and denominator cancelled out. */ + float w = pdf_N / (sqr(pdf_N) + sqr(pdf_T) + sqr(pdf_B)); + if (isect.num_hits > LOCAL_MAX_HITS) { + w *= isect.num_hits / (float)LOCAL_MAX_HITS; + } + + /* Real distance to sampled point. */ + float r = len(hit_P - sd->P); + + /* Compute weight. */ + float pdf = bssrdf_cubic_pdf(radius, 0.0f, r); + float disk_pdf = bssrdf_cubic_pdf(radius, 0.0f, disk_r); + + w *= pdf / disk_pdf; + + /* Sum normal and weight. */ + sum_N += w * N; + } + } + + /* Normalize. */ + float3 N = safe_normalize(sum_N); + return is_zero(N) ? sd->N : (sd->flag & SD_BACKFACING) ? -N : N; } ccl_device void svm_node_bevel( - KernelGlobals *kg, - ShaderData *sd, - ccl_addr_space PathState *state, - float *stack, - uint4 node) + KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state, float *stack, uint4 node) { - uint num_samples, radius_offset, normal_offset, out_offset; - decode_node_uchar4(node.y, &num_samples, &radius_offset, &normal_offset, &out_offset); + uint num_samples, radius_offset, normal_offset, out_offset; + decode_node_uchar4(node.y, &num_samples, &radius_offset, &normal_offset, &out_offset); - float radius = stack_load_float(stack, radius_offset); - float3 bevel_N = svm_bevel(kg, sd, state, radius, num_samples); + float radius = stack_load_float(stack, radius_offset); + float3 bevel_N = svm_bevel(kg, sd, state, radius, num_samples); - if(stack_valid(normal_offset)) { - /* Preserve input normal. */ - float3 ref_N = stack_load_float3(stack, normal_offset); - bevel_N = normalize(ref_N + (bevel_N - sd->N)); - } + if (stack_valid(normal_offset)) { + /* Preserve input normal. */ + float3 ref_N = stack_load_float3(stack, normal_offset); + bevel_N = normalize(ref_N + (bevel_N - sd->N)); + } - stack_store_float3(stack, out_offset, bevel_N); + stack_store_float3(stack, out_offset, bevel_N); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_blackbody.h b/intern/cycles/kernel/svm/svm_blackbody.h index 51590b18505..adfc50d961e 100644 --- a/intern/cycles/kernel/svm/svm_blackbody.h +++ b/intern/cycles/kernel/svm/svm_blackbody.h @@ -34,14 +34,15 @@ CCL_NAMESPACE_BEGIN /* Blackbody Node */ -ccl_device void svm_node_blackbody(KernelGlobals *kg, ShaderData *sd, float *stack, uint temperature_offset, uint col_offset) +ccl_device void svm_node_blackbody( + KernelGlobals *kg, ShaderData *sd, float *stack, uint temperature_offset, uint col_offset) { - /* Input */ - float temperature = stack_load_float(stack, temperature_offset); + /* Input */ + float temperature = stack_load_float(stack, temperature_offset); - float3 color_rgb = svm_math_blackbody_color(temperature); + float3 color_rgb = svm_math_blackbody_color(temperature); - stack_store_float3(stack, col_offset, color_rgb); + stack_store_float3(stack, col_offset, color_rgb); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_brick.h b/intern/cycles/kernel/svm/svm_brick.h index 744d9ff16c5..b5cbfcc72df 100644 --- a/intern/cycles/kernel/svm/svm_brick.h +++ b/intern/cycles/kernel/svm/svm_brick.h @@ -20,101 +20,119 @@ CCL_NAMESPACE_BEGIN ccl_device_noinline float brick_noise(uint n) /* fast integer noise */ { - uint nn; - n = (n + 1013) & 0x7fffffff; - n = (n >> 13) ^ n; - nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; - return 0.5f * ((float)nn / 1073741824.0f); + uint nn; + n = (n + 1013) & 0x7fffffff; + n = (n >> 13) ^ n; + nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; + return 0.5f * ((float)nn / 1073741824.0f); } -ccl_device_noinline float2 svm_brick(float3 p, float mortar_size, float mortar_smooth, float bias, - float brick_width, float row_height, float offset_amount, int offset_frequency, - float squash_amount, int squash_frequency) +ccl_device_noinline float2 svm_brick(float3 p, + float mortar_size, + float mortar_smooth, + float bias, + float brick_width, + float row_height, + float offset_amount, + int offset_frequency, + float squash_amount, + int squash_frequency) { - int bricknum, rownum; - float offset = 0.0f; - float x, y; - - rownum = floor_to_int(p.y / row_height); - - if(offset_frequency && squash_frequency) { - brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount; /* squash */ - offset = (rownum % offset_frequency) ? 0.0f : (brick_width*offset_amount); /* offset */ - } - - bricknum = floor_to_int((p.x+offset) / brick_width); - - x = (p.x+offset) - brick_width*bricknum; - y = p.y - row_height*rownum; - - float tint = saturate((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias)); - float min_dist = min(min(x, y), min(brick_width - x, row_height - y)); - - float mortar; - if(min_dist >= mortar_size) { - mortar = 0.0f; - } - else if(mortar_smooth == 0.0f) { - mortar = 1.0f; - } - else { - min_dist = 1.0f - min_dist/mortar_size; - mortar = (min_dist < mortar_smooth)? smoothstepf(min_dist / mortar_smooth) : 1.0f; - } - - return make_float2(tint, mortar); + int bricknum, rownum; + float offset = 0.0f; + float x, y; + + rownum = floor_to_int(p.y / row_height); + + if (offset_frequency && squash_frequency) { + brick_width *= (rownum % squash_frequency) ? 1.0f : squash_amount; /* squash */ + offset = (rownum % offset_frequency) ? 0.0f : (brick_width * offset_amount); /* offset */ + } + + bricknum = floor_to_int((p.x + offset) / brick_width); + + x = (p.x + offset) - brick_width * bricknum; + y = p.y - row_height * rownum; + + float tint = saturate((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias)); + float min_dist = min(min(x, y), min(brick_width - x, row_height - y)); + + float mortar; + if (min_dist >= mortar_size) { + mortar = 0.0f; + } + else if (mortar_smooth == 0.0f) { + mortar = 1.0f; + } + else { + min_dist = 1.0f - min_dist / mortar_size; + mortar = (min_dist < mortar_smooth) ? smoothstepf(min_dist / mortar_smooth) : 1.0f; + } + + return make_float2(tint, mortar); } -ccl_device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_tex_brick( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint4 node2 = read_node(kg, offset); - uint4 node3 = read_node(kg, offset); - uint4 node4 = read_node(kg, offset); - - /* Input and Output Sockets */ - uint co_offset, color1_offset, color2_offset, mortar_offset, scale_offset; - uint mortar_size_offset, bias_offset, brick_width_offset, row_height_offset; - uint color_offset, fac_offset, mortar_smooth_offset; - - /* RNA properties */ - uint offset_frequency, squash_frequency; - - decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &mortar_offset); - decode_node_uchar4(node.z, &scale_offset, &mortar_size_offset, &bias_offset, &brick_width_offset); - decode_node_uchar4(node.w, &row_height_offset, &color_offset, &fac_offset, &mortar_smooth_offset); - - decode_node_uchar4(node2.x, &offset_frequency, &squash_frequency, NULL, NULL); - - float3 co = stack_load_float3(stack, co_offset); - - float3 color1 = stack_load_float3(stack, color1_offset); - float3 color2 = stack_load_float3(stack, color2_offset); - float3 mortar = stack_load_float3(stack, mortar_offset); - - float scale = stack_load_float_default(stack, scale_offset, node2.y); - float mortar_size = stack_load_float_default(stack, mortar_size_offset, node2.z); - float mortar_smooth = stack_load_float_default(stack, mortar_smooth_offset, node4.x); - float bias = stack_load_float_default(stack, bias_offset, node2.w); - float brick_width = stack_load_float_default(stack, brick_width_offset, node3.x); - float row_height = stack_load_float_default(stack, row_height_offset, node3.y); - float offset_amount = __int_as_float(node3.z); - float squash_amount = __int_as_float(node3.w); - - float2 f2 = svm_brick(co*scale, mortar_size, mortar_smooth, bias, brick_width, row_height, - offset_amount, offset_frequency, squash_amount, squash_frequency); - - float tint = f2.x; - float f = f2.y; - - if(f != 1.0f) { - float facm = 1.0f - tint; - color1 = facm * color1 + tint * color2; - } - - if(stack_valid(color_offset)) - stack_store_float3(stack, color_offset, color1*(1.0f-f) + mortar*f); - if(stack_valid(fac_offset)) - stack_store_float(stack, fac_offset, f); + uint4 node2 = read_node(kg, offset); + uint4 node3 = read_node(kg, offset); + uint4 node4 = read_node(kg, offset); + + /* Input and Output Sockets */ + uint co_offset, color1_offset, color2_offset, mortar_offset, scale_offset; + uint mortar_size_offset, bias_offset, brick_width_offset, row_height_offset; + uint color_offset, fac_offset, mortar_smooth_offset; + + /* RNA properties */ + uint offset_frequency, squash_frequency; + + decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &mortar_offset); + decode_node_uchar4( + node.z, &scale_offset, &mortar_size_offset, &bias_offset, &brick_width_offset); + decode_node_uchar4( + node.w, &row_height_offset, &color_offset, &fac_offset, &mortar_smooth_offset); + + decode_node_uchar4(node2.x, &offset_frequency, &squash_frequency, NULL, NULL); + + float3 co = stack_load_float3(stack, co_offset); + + float3 color1 = stack_load_float3(stack, color1_offset); + float3 color2 = stack_load_float3(stack, color2_offset); + float3 mortar = stack_load_float3(stack, mortar_offset); + + float scale = stack_load_float_default(stack, scale_offset, node2.y); + float mortar_size = stack_load_float_default(stack, mortar_size_offset, node2.z); + float mortar_smooth = stack_load_float_default(stack, mortar_smooth_offset, node4.x); + float bias = stack_load_float_default(stack, bias_offset, node2.w); + float brick_width = stack_load_float_default(stack, brick_width_offset, node3.x); + float row_height = stack_load_float_default(stack, row_height_offset, node3.y); + float offset_amount = __int_as_float(node3.z); + float squash_amount = __int_as_float(node3.w); + + float2 f2 = svm_brick(co * scale, + mortar_size, + mortar_smooth, + bias, + brick_width, + row_height, + offset_amount, + offset_frequency, + squash_amount, + squash_frequency); + + float tint = f2.x; + float f = f2.y; + + if (f != 1.0f) { + float facm = 1.0f - tint; + color1 = facm * color1 + tint * color2; + } + + if (stack_valid(color_offset)) + stack_store_float3(stack, color_offset, color1 * (1.0f - f) + mortar * f); + if (stack_valid(fac_offset)) + stack_store_float(stack, fac_offset, f); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_brightness.h b/intern/cycles/kernel/svm/svm_brightness.h index d71b0ee0b61..dcd75a2fe8f 100644 --- a/intern/cycles/kernel/svm/svm_brightness.h +++ b/intern/cycles/kernel/svm/svm_brightness.h @@ -16,19 +16,20 @@ CCL_NAMESPACE_BEGIN -ccl_device void svm_node_brightness(ShaderData *sd, float *stack, uint in_color, uint out_color, uint node) +ccl_device void svm_node_brightness( + ShaderData *sd, float *stack, uint in_color, uint out_color, uint node) { - uint bright_offset, contrast_offset; - float3 color = stack_load_float3(stack, in_color); + uint bright_offset, contrast_offset; + float3 color = stack_load_float3(stack, in_color); - decode_node_uchar4(node, &bright_offset, &contrast_offset, NULL, NULL); - float brightness = stack_load_float(stack, bright_offset); - float contrast = stack_load_float(stack, contrast_offset); + decode_node_uchar4(node, &bright_offset, &contrast_offset, NULL, NULL); + float brightness = stack_load_float(stack, bright_offset); + float contrast = stack_load_float(stack, contrast_offset); - color = svm_brightness_contrast(color, brightness, contrast); + color = svm_brightness_contrast(color, brightness, contrast); - if(stack_valid(out_color)) - stack_store_float3(stack, out_color, color); + if (stack_valid(out_color)) + stack_store_float3(stack, out_color, color); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_bump.h b/intern/cycles/kernel/svm/svm_bump.h index 35aac174409..c9d430a2bba 100644 --- a/intern/cycles/kernel/svm/svm_bump.h +++ b/intern/cycles/kernel/svm/svm_bump.h @@ -18,36 +18,42 @@ CCL_NAMESPACE_BEGIN /* Bump Eval Nodes */ -ccl_device void svm_node_enter_bump_eval(KernelGlobals *kg, ShaderData *sd, float *stack, uint offset) +ccl_device void svm_node_enter_bump_eval(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint offset) { - /* save state */ - stack_store_float3(stack, offset+0, sd->P); - stack_store_float3(stack, offset+3, sd->dP.dx); - stack_store_float3(stack, offset+6, sd->dP.dy); - - /* set state as if undisplaced */ - const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_POSITION_UNDISPLACED); - - if(desc.offset != ATTR_STD_NOT_FOUND) { - float3 P, dPdx, dPdy; - P = primitive_surface_attribute_float3(kg, sd, desc, &dPdx, &dPdy); - - object_position_transform(kg, sd, &P); - object_dir_transform(kg, sd, &dPdx); - object_dir_transform(kg, sd, &dPdy); - - sd->P = P; - sd->dP.dx = dPdx; - sd->dP.dy = dPdy; - } + /* save state */ + stack_store_float3(stack, offset + 0, sd->P); + stack_store_float3(stack, offset + 3, sd->dP.dx); + stack_store_float3(stack, offset + 6, sd->dP.dy); + + /* set state as if undisplaced */ + const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_POSITION_UNDISPLACED); + + if (desc.offset != ATTR_STD_NOT_FOUND) { + float3 P, dPdx, dPdy; + P = primitive_surface_attribute_float3(kg, sd, desc, &dPdx, &dPdy); + + object_position_transform(kg, sd, &P); + object_dir_transform(kg, sd, &dPdx); + object_dir_transform(kg, sd, &dPdy); + + sd->P = P; + sd->dP.dx = dPdx; + sd->dP.dy = dPdy; + } } -ccl_device void svm_node_leave_bump_eval(KernelGlobals *kg, ShaderData *sd, float *stack, uint offset) +ccl_device void svm_node_leave_bump_eval(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint offset) { - /* restore state */ - sd->P = stack_load_float3(stack, offset+0); - sd->dP.dx = stack_load_float3(stack, offset+3); - sd->dP.dy = stack_load_float3(stack, offset+6); + /* restore state */ + sd->P = stack_load_float3(stack, offset + 0); + sd->dP.dx = stack_load_float3(stack, offset + 3); + sd->dP.dy = stack_load_float3(stack, offset + 6); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_camera.h b/intern/cycles/kernel/svm/svm_camera.h index cf90229b53b..21a17acf5f1 100644 --- a/intern/cycles/kernel/svm/svm_camera.h +++ b/intern/cycles/kernel/svm/svm_camera.h @@ -16,25 +16,30 @@ CCL_NAMESPACE_BEGIN -ccl_device void svm_node_camera(KernelGlobals *kg, ShaderData *sd, float *stack, uint out_vector, uint out_zdepth, uint out_distance) +ccl_device void svm_node_camera(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint out_vector, + uint out_zdepth, + uint out_distance) { - float distance; - float zdepth; - float3 vector; + float distance; + float zdepth; + float3 vector; - Transform tfm = kernel_data.cam.worldtocamera; - vector = transform_point(&tfm, sd->P); - zdepth = vector.z; - distance = len(vector); + Transform tfm = kernel_data.cam.worldtocamera; + vector = transform_point(&tfm, sd->P); + zdepth = vector.z; + distance = len(vector); - if(stack_valid(out_vector)) - stack_store_float3(stack, out_vector, normalize(vector)); + if (stack_valid(out_vector)) + stack_store_float3(stack, out_vector, normalize(vector)); - if(stack_valid(out_zdepth)) - stack_store_float(stack, out_zdepth, zdepth); + if (stack_valid(out_zdepth)) + stack_store_float(stack, out_zdepth, zdepth); - if(stack_valid(out_distance)) - stack_store_float(stack, out_distance, distance); + if (stack_valid(out_distance)) + stack_store_float(stack, out_distance, distance); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_checker.h b/intern/cycles/kernel/svm/svm_checker.h index 45e6c181e9e..63b4d1e149b 100644 --- a/intern/cycles/kernel/svm/svm_checker.h +++ b/intern/cycles/kernel/svm/svm_checker.h @@ -20,37 +20,37 @@ CCL_NAMESPACE_BEGIN ccl_device_noinline float svm_checker(float3 p) { - /* avoid precision issues on unit coordinates */ - p.x = (p.x + 0.000001f)*0.999999f; - p.y = (p.y + 0.000001f)*0.999999f; - p.z = (p.z + 0.000001f)*0.999999f; + /* avoid precision issues on unit coordinates */ + p.x = (p.x + 0.000001f) * 0.999999f; + p.y = (p.y + 0.000001f) * 0.999999f; + p.z = (p.z + 0.000001f) * 0.999999f; - int xi = abs(float_to_int(floorf(p.x))); - int yi = abs(float_to_int(floorf(p.y))); - int zi = abs(float_to_int(floorf(p.z))); + int xi = abs(float_to_int(floorf(p.x))); + int yi = abs(float_to_int(floorf(p.y))); + int zi = abs(float_to_int(floorf(p.z))); - return ((xi % 2 == yi % 2) == (zi % 2))? 1.0f: 0.0f; + return ((xi % 2 == yi % 2) == (zi % 2)) ? 1.0f : 0.0f; } ccl_device void svm_node_tex_checker(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - uint co_offset, color1_offset, color2_offset, scale_offset; - uint color_offset, fac_offset; + uint co_offset, color1_offset, color2_offset, scale_offset; + uint color_offset, fac_offset; - decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &scale_offset); - decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL); + decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &scale_offset); + decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL); - float3 co = stack_load_float3(stack, co_offset); - float3 color1 = stack_load_float3(stack, color1_offset); - float3 color2 = stack_load_float3(stack, color2_offset); - float scale = stack_load_float_default(stack, scale_offset, node.w); + float3 co = stack_load_float3(stack, co_offset); + float3 color1 = stack_load_float3(stack, color1_offset); + float3 color2 = stack_load_float3(stack, color2_offset); + float scale = stack_load_float_default(stack, scale_offset, node.w); - float f = svm_checker(co*scale); + float f = svm_checker(co * scale); - if(stack_valid(color_offset)) - stack_store_float3(stack, color_offset, (f == 1.0f)? color1: color2); - if(stack_valid(fac_offset)) - stack_store_float(stack, fac_offset, f); + if (stack_valid(color_offset)) + stack_store_float3(stack, color_offset, (f == 1.0f) ? color1 : color2); + if (stack_valid(fac_offset)) + stack_store_float(stack, fac_offset, f); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index a7e87715ed4..270fe4c8615 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -20,1140 +20,1237 @@ CCL_NAMESPACE_BEGIN ccl_device_inline float3 sigma_from_concentration(float eumelanin, float pheomelanin) { - return eumelanin*make_float3(0.506f, 0.841f, 1.653f) + pheomelanin*make_float3(0.343f, 0.733f, 1.924f); + return eumelanin * make_float3(0.506f, 0.841f, 1.653f) + + pheomelanin * make_float3(0.343f, 0.733f, 1.924f); } ccl_device_inline float3 sigma_from_reflectance(float3 color, float azimuthal_roughness) { - float x = azimuthal_roughness; - float roughness_fac = (((((0.245f*x) + 5.574f)*x - 10.73f)*x + 2.532f)*x - 0.215f)*x + 5.969f; - float3 sigma = log3(color) / roughness_fac; - return sigma * sigma; + float x = azimuthal_roughness; + float roughness_fac = (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + + 5.969f; + float3 sigma = log3(color) / roughness_fac; + return sigma * sigma; } /* Closure Nodes */ -ccl_device void svm_node_glass_setup(ShaderData *sd, MicrofacetBsdf *bsdf, int type, float eta, float roughness, bool refract) +ccl_device void svm_node_glass_setup( + ShaderData *sd, MicrofacetBsdf *bsdf, int type, float eta, float roughness, bool refract) { - if(type == CLOSURE_BSDF_SHARP_GLASS_ID) { - if(refract) { - bsdf->alpha_y = 0.0f; - bsdf->alpha_x = 0.0f; - bsdf->ior = eta; - sd->flag |= bsdf_refraction_setup(bsdf); - } - else { - bsdf->alpha_y = 0.0f; - bsdf->alpha_x = 0.0f; - bsdf->ior = 0.0f; - sd->flag |= bsdf_reflection_setup(bsdf); - } - } - else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) { - bsdf->alpha_x = roughness; - bsdf->alpha_y = roughness; - bsdf->ior = eta; - - if(refract) - sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); - else - sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); - } - else { - bsdf->alpha_x = roughness; - bsdf->alpha_y = roughness; - bsdf->ior = eta; - - if(refract) - sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); - else - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - } + if (type == CLOSURE_BSDF_SHARP_GLASS_ID) { + if (refract) { + bsdf->alpha_y = 0.0f; + bsdf->alpha_x = 0.0f; + bsdf->ior = eta; + sd->flag |= bsdf_refraction_setup(bsdf); + } + else { + bsdf->alpha_y = 0.0f; + bsdf->alpha_x = 0.0f; + bsdf->ior = 0.0f; + sd->flag |= bsdf_reflection_setup(bsdf); + } + } + else if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) { + bsdf->alpha_x = roughness; + bsdf->alpha_y = roughness; + bsdf->ior = eta; + + if (refract) + sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); + else + sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); + } + else { + bsdf->alpha_x = roughness; + bsdf->alpha_y = roughness; + bsdf->ior = eta; + + if (refract) + sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); + else + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + } } -ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type, int path_flag, int *offset) +ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint4 node, + ShaderType shader_type, + int path_flag, + int *offset) { - uint type, param1_offset, param2_offset; + uint type, param1_offset, param2_offset; - uint mix_weight_offset; - decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); - float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f); + uint mix_weight_offset; + decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); + float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) : + 1.0f); - /* note we read this extra node before weight check, so offset is added */ - uint4 data_node = read_node(kg, offset); + /* note we read this extra node before weight check, so offset is added */ + uint4 data_node = read_node(kg, offset); - /* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */ - if(mix_weight == 0.0f || shader_type != SHADER_TYPE_SURFACE) { - if(type == CLOSURE_BSDF_PRINCIPLED_ID) { - /* Read all principled BSDF extra data to get the right offset. */ - read_node(kg, offset); - read_node(kg, offset); - read_node(kg, offset); - read_node(kg, offset); - } + /* Only compute BSDF for surfaces, transparent variable is shared with volume extinction. */ + if (mix_weight == 0.0f || shader_type != SHADER_TYPE_SURFACE) { + if (type == CLOSURE_BSDF_PRINCIPLED_ID) { + /* Read all principled BSDF extra data to get the right offset. */ + read_node(kg, offset); + read_node(kg, offset); + read_node(kg, offset); + read_node(kg, offset); + } - return; - } + return; + } - float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N; + float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N; - float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z); - float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w); + float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) : + __uint_as_float(node.z); + float param2 = (stack_valid(param2_offset)) ? stack_load_float(stack, param2_offset) : + __uint_as_float(node.w); - switch(type) { + switch (type) { #ifdef __PRINCIPLED__ - case CLOSURE_BSDF_PRINCIPLED_ID: { - uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset, sheen_offset, - sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset, eta_offset, transmission_offset, - anisotropic_rotation_offset, transmission_roughness_offset; - uint4 data_node2 = read_node(kg, offset); - - float3 T = stack_load_float3(stack, data_node.y); - decode_node_uchar4(data_node.z, &specular_offset, &roughness_offset, &specular_tint_offset, &anisotropic_offset); - decode_node_uchar4(data_node.w, &sheen_offset, &sheen_tint_offset, &clearcoat_offset, &clearcoat_roughness_offset); - decode_node_uchar4(data_node2.x, &eta_offset, &transmission_offset, &anisotropic_rotation_offset, &transmission_roughness_offset); - - // get Disney principled parameters - float metallic = param1; - float subsurface = param2; - float specular = stack_load_float(stack, specular_offset); - float roughness = stack_load_float(stack, roughness_offset); - float specular_tint = stack_load_float(stack, specular_tint_offset); - float anisotropic = stack_load_float(stack, anisotropic_offset); - float sheen = stack_load_float(stack, sheen_offset); - float sheen_tint = stack_load_float(stack, sheen_tint_offset); - float clearcoat = stack_load_float(stack, clearcoat_offset); - float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset); - float transmission = stack_load_float(stack, transmission_offset); - float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset); - float transmission_roughness = stack_load_float(stack, transmission_roughness_offset); - float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f); - - ClosureType distribution = (ClosureType) data_node2.y; - ClosureType subsurface_method = (ClosureType) data_node2.z; - - /* rotate tangent */ - if(anisotropic_rotation != 0.0f) - T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F); - - /* calculate ior */ - float ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; - - // calculate fresnel for refraction - float cosNO = dot(N, sd->I); - float fresnel = fresnel_dielectric_cos(cosNO, ior); - - // calculate weights of the diffuse and specular part - float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(transmission)); - - float final_transmission = saturate(transmission) * (1.0f - saturate(metallic)); - float specular_weight = (1.0f - final_transmission); - - // get the base color - uint4 data_base_color = read_node(kg, offset); - float3 base_color = stack_valid(data_base_color.x) ? stack_load_float3(stack, data_base_color.x) : - make_float3(__uint_as_float(data_base_color.y), __uint_as_float(data_base_color.z), __uint_as_float(data_base_color.w)); - - // get the additional clearcoat normal and subsurface scattering radius - uint4 data_cn_ssr = read_node(kg, offset); - float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ? stack_load_float3(stack, data_cn_ssr.x) : sd->N; - float3 subsurface_radius = stack_valid(data_cn_ssr.y) ? stack_load_float3(stack, data_cn_ssr.y) : make_float3(1.0f, 1.0f, 1.0f); - - // get the subsurface color - uint4 data_subsurface_color = read_node(kg, offset); - float3 subsurface_color = stack_valid(data_subsurface_color.x) ? stack_load_float3(stack, data_subsurface_color.x) : - make_float3(__uint_as_float(data_subsurface_color.y), __uint_as_float(data_subsurface_color.z), __uint_as_float(data_subsurface_color.w)); - - float3 weight = sd->svm_closure_weight * mix_weight; - -#ifdef __SUBSURFACE__ - float3 mixed_ss_base_color = subsurface_color * subsurface + base_color * (1.0f - subsurface); - float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight; - - /* disable in case of diffuse ancestor, can't see it well then and - * adds considerably noise due to probabilities of continuing path - * getting lower and lower */ - if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) { - subsurface = 0.0f; - - /* need to set the base color in this case such that the - * rays get the correctly mixed color after transmitting - * the object */ - base_color = mixed_ss_base_color; - } - - /* diffuse */ - if(fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) { - if(subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { - float3 diff_weight = weight * base_color * diffuse_weight; - - PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight); - - if(bsdf) { - bsdf->N = N; - bsdf->roughness = roughness; - - /* setup bsdf */ - sd->flag |= bsdf_principled_diffuse_setup(bsdf); - } - } - else if(subsurface > CLOSURE_WEIGHT_CUTOFF) { - Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight); - - if(bssrdf) { - bssrdf->radius = subsurface_radius * subsurface; - bssrdf->albedo = (subsurface_method == CLOSURE_BSSRDF_PRINCIPLED_ID)? subsurface_color: mixed_ss_base_color; - bssrdf->texture_blur = 0.0f; - bssrdf->sharpness = 0.0f; - bssrdf->N = N; - bssrdf->roughness = roughness; - - /* setup bsdf */ - sd->flag |= bssrdf_setup(sd, bssrdf, subsurface_method); - } - } - } -#else - /* diffuse */ - if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { - float3 diff_weight = weight * base_color * diffuse_weight; - - PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight); - - if(bsdf) { - bsdf->N = N; - bsdf->roughness = roughness; - - /* setup bsdf */ - sd->flag |= bsdf_principled_diffuse_setup(bsdf); - } - } -#endif - - /* sheen */ - if(diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) { - float m_cdlum = linear_rgb_to_gray(kg, base_color); - float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat - - /* color of the sheen component */ - float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) + m_ctint * sheen_tint; - - float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight; - - PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf*)bsdf_alloc(sd, sizeof(PrincipledSheenBsdf), sheen_weight); - - if(bsdf) { - bsdf->N = N; - - /* setup bsdf */ - sd->flag |= bsdf_principled_sheen_setup(bsdf); - } - } - - /* specular reflection */ + case CLOSURE_BSDF_PRINCIPLED_ID: { + uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset, + sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset, + eta_offset, transmission_offset, anisotropic_rotation_offset, + transmission_roughness_offset; + uint4 data_node2 = read_node(kg, offset); + + float3 T = stack_load_float3(stack, data_node.y); + decode_node_uchar4(data_node.z, + &specular_offset, + &roughness_offset, + &specular_tint_offset, + &anisotropic_offset); + decode_node_uchar4(data_node.w, + &sheen_offset, + &sheen_tint_offset, + &clearcoat_offset, + &clearcoat_roughness_offset); + decode_node_uchar4(data_node2.x, + &eta_offset, + &transmission_offset, + &anisotropic_rotation_offset, + &transmission_roughness_offset); + + // get Disney principled parameters + float metallic = param1; + float subsurface = param2; + float specular = stack_load_float(stack, specular_offset); + float roughness = stack_load_float(stack, roughness_offset); + float specular_tint = stack_load_float(stack, specular_tint_offset); + float anisotropic = stack_load_float(stack, anisotropic_offset); + float sheen = stack_load_float(stack, sheen_offset); + float sheen_tint = stack_load_float(stack, sheen_tint_offset); + float clearcoat = stack_load_float(stack, clearcoat_offset); + float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset); + float transmission = stack_load_float(stack, transmission_offset); + float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset); + float transmission_roughness = stack_load_float(stack, transmission_roughness_offset); + float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f); + + ClosureType distribution = (ClosureType)data_node2.y; + ClosureType subsurface_method = (ClosureType)data_node2.z; + + /* rotate tangent */ + if (anisotropic_rotation != 0.0f) + T = rotate_around_axis(T, N, anisotropic_rotation * M_2PI_F); + + /* calculate ior */ + float ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; + + // calculate fresnel for refraction + float cosNO = dot(N, sd->I); + float fresnel = fresnel_dielectric_cos(cosNO, ior); + + // calculate weights of the diffuse and specular part + float diffuse_weight = (1.0f - saturate(metallic)) * (1.0f - saturate(transmission)); + + float final_transmission = saturate(transmission) * (1.0f - saturate(metallic)); + float specular_weight = (1.0f - final_transmission); + + // get the base color + uint4 data_base_color = read_node(kg, offset); + float3 base_color = stack_valid(data_base_color.x) ? + stack_load_float3(stack, data_base_color.x) : + make_float3(__uint_as_float(data_base_color.y), + __uint_as_float(data_base_color.z), + __uint_as_float(data_base_color.w)); + + // get the additional clearcoat normal and subsurface scattering radius + uint4 data_cn_ssr = read_node(kg, offset); + float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ? + stack_load_float3(stack, data_cn_ssr.x) : + sd->N; + float3 subsurface_radius = stack_valid(data_cn_ssr.y) ? + stack_load_float3(stack, data_cn_ssr.y) : + make_float3(1.0f, 1.0f, 1.0f); + + // get the subsurface color + uint4 data_subsurface_color = read_node(kg, offset); + float3 subsurface_color = stack_valid(data_subsurface_color.x) ? + stack_load_float3(stack, data_subsurface_color.x) : + make_float3(__uint_as_float(data_subsurface_color.y), + __uint_as_float(data_subsurface_color.z), + __uint_as_float(data_subsurface_color.w)); + + float3 weight = sd->svm_closure_weight * mix_weight; + +# ifdef __SUBSURFACE__ + float3 mixed_ss_base_color = subsurface_color * subsurface + + base_color * (1.0f - subsurface); + float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight; + + /* disable in case of diffuse ancestor, can't see it well then and + * adds considerably noise due to probabilities of continuing path + * getting lower and lower */ + if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) { + subsurface = 0.0f; + + /* need to set the base color in this case such that the + * rays get the correctly mixed color after transmitting + * the object */ + base_color = mixed_ss_base_color; + } + + /* diffuse */ + if (fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) { + if (subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { + float3 diff_weight = weight * base_color * diffuse_weight; + + PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc( + sd, sizeof(PrincipledDiffuseBsdf), diff_weight); + + if (bsdf) { + bsdf->N = N; + bsdf->roughness = roughness; + + /* setup bsdf */ + sd->flag |= bsdf_principled_diffuse_setup(bsdf); + } + } + else if (subsurface > CLOSURE_WEIGHT_CUTOFF) { + Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight); + + if (bssrdf) { + bssrdf->radius = subsurface_radius * subsurface; + bssrdf->albedo = (subsurface_method == CLOSURE_BSSRDF_PRINCIPLED_ID) ? + subsurface_color : + mixed_ss_base_color; + bssrdf->texture_blur = 0.0f; + bssrdf->sharpness = 0.0f; + bssrdf->N = N; + bssrdf->roughness = roughness; + + /* setup bsdf */ + sd->flag |= bssrdf_setup(sd, bssrdf, subsurface_method); + } + } + } +# else + /* diffuse */ + if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { + float3 diff_weight = weight * base_color * diffuse_weight; + + PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf *)bsdf_alloc( + sd, sizeof(PrincipledDiffuseBsdf), diff_weight); + + if (bsdf) { + bsdf->N = N; + bsdf->roughness = roughness; + + /* setup bsdf */ + sd->flag |= bsdf_principled_diffuse_setup(bsdf); + } + } +# endif + + /* sheen */ + if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) { + float m_cdlum = linear_rgb_to_gray(kg, base_color); + float3 m_ctint = m_cdlum > 0.0f ? + base_color / m_cdlum : + make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat + + /* color of the sheen component */ + float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) + + m_ctint * sheen_tint; + + float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight; + + PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc( + sd, sizeof(PrincipledSheenBsdf), sheen_weight); + + if (bsdf) { + bsdf->N = N; + + /* setup bsdf */ + sd->flag |= bsdf_principled_sheen_setup(bsdf); + } + } + + /* specular reflection */ +# ifdef __CAUSTICS_TRICKS__ + if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) { +# endif + if (specular_weight > CLOSURE_WEIGHT_CUTOFF && + (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) { + float3 spec_weight = weight * specular_weight; + + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), spec_weight); + MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)) : + NULL; + + if (bsdf && extra) { + bsdf->N = N; + bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f; + bsdf->T = T; + bsdf->extra = extra; + + float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f); + float r2 = roughness * roughness; + + bsdf->alpha_x = r2 / aspect; + bsdf->alpha_y = r2 * aspect; + + float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y + + 0.1f * base_color.z; // luminance approx. + float3 m_ctint = m_cdlum > 0.0f ? + base_color / m_cdlum : + make_float3( + 0.0f, 0.0f, 0.0f); // normalize lum. to isolate hue+sat + float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint) + + m_ctint * specular_tint; + + bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + + base_color * metallic; + bsdf->extra->color = base_color; + bsdf->extra->clearcoat = 0.0f; + + /* setup bsdf */ + if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || + roughness <= 0.075f) /* use single-scatter GGX */ + sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd); + else /* use multi-scatter GGX */ + sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd); + } + } +# ifdef __CAUSTICS_TRICKS__ + } +# endif + + /* BSDF */ +# ifdef __CAUSTICS_TRICKS__ + if (kernel_data.integrator.caustics_reflective || + kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) { +# endif + if (final_transmission > CLOSURE_WEIGHT_CUTOFF) { + float3 glass_weight = weight * final_transmission; + float3 cspec0 = base_color * specular_tint + + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint); + + if (roughness <= 5e-2f || + distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */ + float refl_roughness = roughness; + + /* reflection */ +# ifdef __CAUSTICS_TRICKS__ + if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) +# endif + { + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), glass_weight * fresnel); + MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)) : + NULL; + + if (bsdf && extra) { + bsdf->N = N; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra = extra; + + bsdf->alpha_x = refl_roughness * refl_roughness; + bsdf->alpha_y = refl_roughness * refl_roughness; + bsdf->ior = ior; + + bsdf->extra->color = base_color; + bsdf->extra->cspec0 = cspec0; + bsdf->extra->clearcoat = 0.0f; + + /* setup bsdf */ + sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); + } + } + + /* refraction */ +# ifdef __CAUSTICS_TRICKS__ + if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) +# endif + { + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), base_color * glass_weight * (1.0f - fresnel)); + if (bsdf) { + bsdf->N = N; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra = NULL; + + if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) + transmission_roughness = 1.0f - (1.0f - refl_roughness) * + (1.0f - transmission_roughness); + else + transmission_roughness = refl_roughness; + + bsdf->alpha_x = transmission_roughness * transmission_roughness; + bsdf->alpha_y = transmission_roughness * transmission_roughness; + bsdf->ior = ior; + + /* setup bsdf */ + sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); + } + } + } + else { /* use multi-scatter GGX */ + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), glass_weight); + MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)) : + NULL; + + if (bsdf && extra) { + bsdf->N = N; + bsdf->extra = extra; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + + bsdf->alpha_x = roughness * roughness; + bsdf->alpha_y = roughness * roughness; + bsdf->ior = ior; + + bsdf->extra->color = base_color; + bsdf->extra->cspec0 = cspec0; + bsdf->extra->clearcoat = 0.0f; + + /* setup bsdf */ + sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd); + } + } + } +# ifdef __CAUSTICS_TRICKS__ + } +# endif + + /* clearcoat */ +# ifdef __CAUSTICS_TRICKS__ + if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) { +# endif + if (clearcoat > CLOSURE_WEIGHT_CUTOFF) { + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); + MicrofacetExtra *extra = (bsdf != NULL) ? (MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)) : + NULL; + + if (bsdf && extra) { + bsdf->N = clearcoat_normal; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->ior = 1.5f; + bsdf->extra = extra; + + bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness; + bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness; + + bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f); + bsdf->extra->clearcoat = clearcoat; + + /* setup bsdf */ + sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd); + } + } +# ifdef __CAUSTICS_TRICKS__ + } +# endif + + break; + } +#endif /* __PRINCIPLED__ */ + case CLOSURE_BSDF_DIFFUSE_ID: { + float3 weight = sd->svm_closure_weight * mix_weight; + OrenNayarBsdf *bsdf = (OrenNayarBsdf *)bsdf_alloc(sd, sizeof(OrenNayarBsdf), weight); + + if (bsdf) { + bsdf->N = N; + + float roughness = param1; + + if (roughness == 0.0f) { + sd->flag |= bsdf_diffuse_setup((DiffuseBsdf *)bsdf); + } + else { + bsdf->roughness = roughness; + sd->flag |= bsdf_oren_nayar_setup(bsdf); + } + } + break; + } + case CLOSURE_BSDF_TRANSLUCENT_ID: { + float3 weight = sd->svm_closure_weight * mix_weight; + DiffuseBsdf *bsdf = (DiffuseBsdf *)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight); + + if (bsdf) { + bsdf->N = N; + sd->flag |= bsdf_translucent_setup(bsdf); + } + break; + } + case CLOSURE_BSDF_TRANSPARENT_ID: { + float3 weight = sd->svm_closure_weight * mix_weight; + bsdf_transparent_setup(sd, weight, path_flag); + break; + } + case CLOSURE_BSDF_REFLECTION_ID: + case CLOSURE_BSDF_MICROFACET_GGX_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: + case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: + case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: { #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) { + if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) + break; #endif - if(specular_weight > CLOSURE_WEIGHT_CUTOFF && (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) { - float3 spec_weight = weight * specular_weight; - - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), spec_weight); - MicrofacetExtra *extra = (bsdf != NULL) - ? (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)) - : NULL; - - if(bsdf && extra) { - bsdf->N = N; - bsdf->ior = (2.0f / (1.0f - safe_sqrtf(0.08f * specular))) - 1.0f; - bsdf->T = T; - bsdf->extra = extra; - - float aspect = safe_sqrtf(1.0f - anisotropic * 0.9f); - float r2 = roughness * roughness; - - bsdf->alpha_x = r2 / aspect; - bsdf->alpha_y = r2 * aspect; - - float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y + 0.1f * base_color.z; // luminance approx. - float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : make_float3(0.0f, 0.0f, 0.0f); // normalize lum. to isolate hue+sat - float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint) + m_ctint * specular_tint; - - bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + base_color * metallic; - bsdf->extra->color = base_color; - bsdf->extra->clearcoat = 0.0f; - - /* setup bsdf */ - if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || roughness <= 0.075f) /* use single-scatter GGX */ - sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd); - else /* use multi-scatter GGX */ - sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd); - } - } + float3 weight = sd->svm_closure_weight * mix_weight; + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); + + if (!bsdf) { + break; + } + + float roughness = sqr(param1); + + bsdf->N = N; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->alpha_x = roughness; + bsdf->alpha_y = roughness; + bsdf->ior = 0.0f; + bsdf->extra = NULL; + + /* setup bsdf */ + if (type == CLOSURE_BSDF_REFLECTION_ID) + sd->flag |= bsdf_reflection_setup(bsdf); + else if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) + sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); + else if (type == CLOSURE_BSDF_MICROFACET_GGX_ID) + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) { + kernel_assert(stack_valid(data_node.z)); + bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); + if (bsdf->extra) { + bsdf->extra->color = stack_load_float3(stack, data_node.z); + bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra->clearcoat = 0.0f; + sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); + } + } + else { + sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); + } + + break; + } + case CLOSURE_BSDF_REFRACTION_ID: + case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: { #ifdef __CAUSTICS_TRICKS__ - } + if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) + break; #endif - - /* BSDF */ + float3 weight = sd->svm_closure_weight * mix_weight; + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); + + if (bsdf) { + bsdf->N = N; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra = NULL; + + float eta = fmaxf(param2, 1e-5f); + eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; + + /* setup bsdf */ + if (type == CLOSURE_BSDF_REFRACTION_ID) { + bsdf->alpha_x = 0.0f; + bsdf->alpha_y = 0.0f; + bsdf->ior = eta; + + sd->flag |= bsdf_refraction_setup(bsdf); + } + else { + float roughness = sqr(param1); + bsdf->alpha_x = roughness; + bsdf->alpha_y = roughness; + bsdf->ior = eta; + + if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) + sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); + else + sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); + } + } + + break; + } + case CLOSURE_BSDF_SHARP_GLASS_ID: + case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.caustics_reflective || kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) { + if (!kernel_data.integrator.caustics_reflective && + !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) { + break; + } #endif - if(final_transmission > CLOSURE_WEIGHT_CUTOFF) { - float3 glass_weight = weight * final_transmission; - float3 cspec0 = base_color * specular_tint + make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint); + float3 weight = sd->svm_closure_weight * mix_weight; - if(roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */ - float refl_roughness = roughness; + /* index of refraction */ + float eta = fmaxf(param2, 1e-5f); + eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; - /* reflection */ -#ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) -#endif - { - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight*fresnel); - MicrofacetExtra *extra = (bsdf != NULL) - ? (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)) - : NULL; - - if(bsdf && extra) { - bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra = extra; - - bsdf->alpha_x = refl_roughness * refl_roughness; - bsdf->alpha_y = refl_roughness * refl_roughness; - bsdf->ior = ior; - - bsdf->extra->color = base_color; - bsdf->extra->cspec0 = cspec0; - bsdf->extra->clearcoat = 0.0f; - - /* setup bsdf */ - sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); - } - } - - /* refraction */ -#ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) -#endif - { - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), base_color*glass_weight*(1.0f - fresnel)); - if(bsdf) { - bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra = NULL; - - if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) - transmission_roughness = 1.0f - (1.0f - refl_roughness) * (1.0f - transmission_roughness); - else - transmission_roughness = refl_roughness; - - bsdf->alpha_x = transmission_roughness * transmission_roughness; - bsdf->alpha_y = transmission_roughness * transmission_roughness; - bsdf->ior = ior; - - /* setup bsdf */ - sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); - } - } - } - else { /* use multi-scatter GGX */ - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), glass_weight); - MicrofacetExtra *extra = (bsdf != NULL) - ? (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)) - : NULL; - - if(bsdf && extra) { - bsdf->N = N; - bsdf->extra = extra; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); - - bsdf->alpha_x = roughness * roughness; - bsdf->alpha_y = roughness * roughness; - bsdf->ior = ior; - - bsdf->extra->color = base_color; - bsdf->extra->cspec0 = cspec0; - bsdf->extra->clearcoat = 0.0f; - - /* setup bsdf */ - sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd); - } - } - } -#ifdef __CAUSTICS_TRICKS__ - } -#endif + /* fresnel */ + float cosNO = dot(N, sd->I); + float fresnel = fresnel_dielectric_cos(cosNO, eta); + float roughness = sqr(param1); - /* clearcoat */ + /* reflection */ #ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) { + if (kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) #endif - if(clearcoat > CLOSURE_WEIGHT_CUTOFF) { - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); - MicrofacetExtra *extra = (bsdf != NULL) - ? (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)) - : NULL; - - if(bsdf && extra) { - bsdf->N = clearcoat_normal; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); - bsdf->ior = 1.5f; - bsdf->extra = extra; - - bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness; - bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness; - - bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f); - bsdf->extra->clearcoat = clearcoat; - - /* setup bsdf */ - sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd); - } - } + { + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), weight * fresnel); + + if (bsdf) { + bsdf->N = N; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra = NULL; + svm_node_glass_setup(sd, bsdf, type, eta, roughness, false); + } + } + + /* refraction */ #ifdef __CAUSTICS_TRICKS__ - } + if (kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) #endif - - break; - } -#endif /* __PRINCIPLED__ */ - case CLOSURE_BSDF_DIFFUSE_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; - OrenNayarBsdf *bsdf = (OrenNayarBsdf*)bsdf_alloc(sd, sizeof(OrenNayarBsdf), weight); - - if(bsdf) { - bsdf->N = N; - - float roughness = param1; - - if(roughness == 0.0f) { - sd->flag |= bsdf_diffuse_setup((DiffuseBsdf*)bsdf); - } - else { - bsdf->roughness = roughness; - sd->flag |= bsdf_oren_nayar_setup(bsdf); - } - } - break; - } - case CLOSURE_BSDF_TRANSLUCENT_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; - DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd, sizeof(DiffuseBsdf), weight); - - if(bsdf) { - bsdf->N = N; - sd->flag |= bsdf_translucent_setup(bsdf); - } - break; - } - case CLOSURE_BSDF_TRANSPARENT_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; - bsdf_transparent_setup(sd, weight, path_flag); - break; - } - case CLOSURE_BSDF_REFLECTION_ID: - case CLOSURE_BSDF_MICROFACET_GGX_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: - case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: { + { + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), weight * (1.0f - fresnel)); + + if (bsdf) { + bsdf->N = N; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra = NULL; + svm_node_glass_setup(sd, bsdf, type, eta, roughness, true); + } + } + + break; + } + case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: { #ifdef __CAUSTICS_TRICKS__ - if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) - break; + if (!kernel_data.integrator.caustics_reflective && + !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) + break; #endif - float3 weight = sd->svm_closure_weight * mix_weight; - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); - - if(!bsdf) { - break; - } - - float roughness = sqr(param1); - - bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); - bsdf->alpha_x = roughness; - bsdf->alpha_y = roughness; - bsdf->ior = 0.0f; - bsdf->extra = NULL; - - /* setup bsdf */ - if(type == CLOSURE_BSDF_REFLECTION_ID) - sd->flag |= bsdf_reflection_setup(bsdf); - else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) - sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); - else if(type == CLOSURE_BSDF_MICROFACET_GGX_ID) - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - else if(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) { - kernel_assert(stack_valid(data_node.z)); - bsdf->extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if(bsdf->extra) { - bsdf->extra->color = stack_load_float3(stack, data_node.z); - bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra->clearcoat = 0.0f; - sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); - } - } - else { - sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); - } - - break; - } - case CLOSURE_BSDF_REFRACTION_ID: - case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: { + float3 weight = sd->svm_closure_weight * mix_weight; + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); + if (!bsdf) { + break; + } + + MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); + if (!extra) { + break; + } + + bsdf->N = N; + bsdf->extra = extra; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + + float roughness = sqr(param1); + bsdf->alpha_x = roughness; + bsdf->alpha_y = roughness; + float eta = fmaxf(param2, 1e-5f); + bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; + + kernel_assert(stack_valid(data_node.z)); + bsdf->extra->color = stack_load_float3(stack, data_node.z); + bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra->clearcoat = 0.0f; + + /* setup bsdf */ + sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); + break; + } + case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID: + case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID: + case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID: + case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: { #ifdef __CAUSTICS_TRICKS__ - if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) - break; + if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) + break; #endif - float3 weight = sd->svm_closure_weight * mix_weight; - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); - - if(bsdf) { - bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra = NULL; - - float eta = fmaxf(param2, 1e-5f); - eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta; - - /* setup bsdf */ - if(type == CLOSURE_BSDF_REFRACTION_ID) { - bsdf->alpha_x = 0.0f; - bsdf->alpha_y = 0.0f; - bsdf->ior = eta; - - sd->flag |= bsdf_refraction_setup(bsdf); - } - else { - float roughness = sqr(param1); - bsdf->alpha_x = roughness; - bsdf->alpha_y = roughness; - bsdf->ior = eta; - - if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) - sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); - else - sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); - } - } - - break; - } - case CLOSURE_BSDF_SHARP_GLASS_ID: - case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { + float3 weight = sd->svm_closure_weight * mix_weight; + MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); + + if (bsdf) { + bsdf->N = N; + bsdf->extra = NULL; + bsdf->T = stack_load_float3(stack, data_node.y); + + /* rotate tangent */ + float rotation = stack_load_float(stack, data_node.z); + + if (rotation != 0.0f) + bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F); + + /* compute roughness */ + float roughness = sqr(param1); + float anisotropy = clamp(param2, -0.99f, 0.99f); + + if (anisotropy < 0.0f) { + bsdf->alpha_x = roughness / (1.0f + anisotropy); + bsdf->alpha_y = roughness * (1.0f + anisotropy); + } + else { + bsdf->alpha_x = roughness * (1.0f - anisotropy); + bsdf->alpha_y = roughness / (1.0f - anisotropy); + } + + bsdf->ior = 0.0f; + + if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID) { + sd->flag |= bsdf_microfacet_beckmann_aniso_setup(bsdf); + } + else if (type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID) { + sd->flag |= bsdf_microfacet_ggx_aniso_setup(bsdf); + } + else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID) { + kernel_assert(stack_valid(data_node.w)); + bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); + if (bsdf->extra) { + bsdf->extra->color = stack_load_float3(stack, data_node.w); + bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra->clearcoat = 0.0f; + sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf); + } + } + else + sd->flag |= bsdf_ashikhmin_shirley_aniso_setup(bsdf); + } + break; + } + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { + float3 weight = sd->svm_closure_weight * mix_weight; + VelvetBsdf *bsdf = (VelvetBsdf *)bsdf_alloc(sd, sizeof(VelvetBsdf), weight); + + if (bsdf) { + bsdf->N = N; + + bsdf->sigma = saturate(param1); + sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf); + } + break; + } + case CLOSURE_BSDF_GLOSSY_TOON_ID: #ifdef __CAUSTICS_TRICKS__ - if(!kernel_data.integrator.caustics_reflective && - !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) - { - break; - } + if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) + break; + ATTR_FALLTHROUGH; #endif - float3 weight = sd->svm_closure_weight * mix_weight; - - /* index of refraction */ - float eta = fmaxf(param2, 1e-5f); - eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta; - - /* fresnel */ - float cosNO = dot(N, sd->I); - float fresnel = fresnel_dielectric_cos(cosNO, eta); - float roughness = sqr(param1); - - /* reflection */ -#ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) -#endif - { - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight*fresnel); - - if(bsdf) { - bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra = NULL; - svm_node_glass_setup(sd, bsdf, type, eta, roughness, false); - } - } - - /* refraction */ -#ifdef __CAUSTICS_TRICKS__ - if(kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) -#endif - { - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight*(1.0f - fresnel)); - - if(bsdf) { - bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra = NULL; - svm_node_glass_setup(sd, bsdf, type, eta, roughness, true); - } - } - - break; - } - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: { -#ifdef __CAUSTICS_TRICKS__ - if(!kernel_data.integrator.caustics_reflective && !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) - break; -#endif - float3 weight = sd->svm_closure_weight * mix_weight; - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); - if(!bsdf) { - break; - } - - MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if(!extra) { - break; - } - - bsdf->N = N; - bsdf->extra = extra; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); - - float roughness = sqr(param1); - bsdf->alpha_x = roughness; - bsdf->alpha_y = roughness; - float eta = fmaxf(param2, 1e-5f); - bsdf->ior = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta; - - kernel_assert(stack_valid(data_node.z)); - bsdf->extra->color = stack_load_float3(stack, data_node.z); - bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra->clearcoat = 0.0f; - - /* setup bsdf */ - sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); - break; - } - case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID: - case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID: - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID: - case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: { -#ifdef __CAUSTICS_TRICKS__ - if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) - break; -#endif - float3 weight = sd->svm_closure_weight * mix_weight; - MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight); - - if(bsdf) { - bsdf->N = N; - bsdf->extra = NULL; - bsdf->T = stack_load_float3(stack, data_node.y); - - /* rotate tangent */ - float rotation = stack_load_float(stack, data_node.z); - - if(rotation != 0.0f) - bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F); - - /* compute roughness */ - float roughness = sqr(param1); - float anisotropy = clamp(param2, -0.99f, 0.99f); - - if(anisotropy < 0.0f) { - bsdf->alpha_x = roughness/(1.0f + anisotropy); - bsdf->alpha_y = roughness*(1.0f + anisotropy); - } - else { - bsdf->alpha_x = roughness*(1.0f - anisotropy); - bsdf->alpha_y = roughness/(1.0f - anisotropy); - } - - bsdf->ior = 0.0f; - - if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID) { - sd->flag |= bsdf_microfacet_beckmann_aniso_setup(bsdf); - } - else if(type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID) { - sd->flag |= bsdf_microfacet_ggx_aniso_setup(bsdf); - } - else if(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID) { - kernel_assert(stack_valid(data_node.w)); - bsdf->extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if(bsdf->extra) { - bsdf->extra->color = stack_load_float3(stack, data_node.w); - bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra->clearcoat = 0.0f; - sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf); - } - } - else - sd->flag |= bsdf_ashikhmin_shirley_aniso_setup(bsdf); - } - break; - } - case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; - VelvetBsdf *bsdf = (VelvetBsdf*)bsdf_alloc(sd, sizeof(VelvetBsdf), weight); - - if(bsdf) { - bsdf->N = N; - - bsdf->sigma = saturate(param1); - sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf); - } - break; - } - case CLOSURE_BSDF_GLOSSY_TOON_ID: -#ifdef __CAUSTICS_TRICKS__ - if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) - break; - ATTR_FALLTHROUGH; -#endif - case CLOSURE_BSDF_DIFFUSE_TOON_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; - ToonBsdf *bsdf = (ToonBsdf*)bsdf_alloc(sd, sizeof(ToonBsdf), weight); - - if(bsdf) { - bsdf->N = N; - bsdf->size = param1; - bsdf->smooth = param2; - - if(type == CLOSURE_BSDF_DIFFUSE_TOON_ID) - sd->flag |= bsdf_diffuse_toon_setup(bsdf); - else - sd->flag |= bsdf_glossy_toon_setup(bsdf); - } - break; - } + case CLOSURE_BSDF_DIFFUSE_TOON_ID: { + float3 weight = sd->svm_closure_weight * mix_weight; + ToonBsdf *bsdf = (ToonBsdf *)bsdf_alloc(sd, sizeof(ToonBsdf), weight); + + if (bsdf) { + bsdf->N = N; + bsdf->size = param1; + bsdf->smooth = param2; + + if (type == CLOSURE_BSDF_DIFFUSE_TOON_ID) + sd->flag |= bsdf_diffuse_toon_setup(bsdf); + else + sd->flag |= bsdf_glossy_toon_setup(bsdf); + } + break; + } #ifdef __HAIR__ - case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: { - uint4 data_node2 = read_node(kg, offset); - uint4 data_node3 = read_node(kg, offset); - uint4 data_node4 = read_node(kg, offset); - - float3 weight = sd->svm_closure_weight * mix_weight; - - uint offset_ofs, ior_ofs, color_ofs, parametrization; - decode_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, ¶metrization); - float alpha = stack_load_float_default(stack, offset_ofs, data_node.z); - float ior = stack_load_float_default(stack, ior_ofs, data_node.w); - - uint coat_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs; - decode_node_uchar4(data_node2.x, &coat_ofs, &melanin_ofs, &melanin_redness_ofs, &absorption_coefficient_ofs); - - uint tint_ofs, random_ofs, random_color_ofs, random_roughness_ofs; - decode_node_uchar4(data_node3.x, &tint_ofs, &random_ofs, &random_color_ofs, &random_roughness_ofs); - - const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node4.y); - float random = 0.0f; - if(attr_descr_random.offset != ATTR_STD_NOT_FOUND) { - random = primitive_surface_attribute_float(kg, sd, attr_descr_random, NULL, NULL); - } - else { - random = stack_load_float_default(stack, random_ofs, data_node3.y); - } - - - PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*)bsdf_alloc(sd, sizeof(PrincipledHairBSDF), weight); - if(bsdf) { - PrincipledHairExtra *extra = (PrincipledHairExtra*)closure_alloc_extra(sd, sizeof(PrincipledHairExtra)); - - if(!extra) - break; - - /* Random factors range: [-randomization/2, +randomization/2]. */ - float random_roughness = stack_load_float_default(stack, random_roughness_ofs, data_node3.w); - float factor_random_roughness = 1.0f + 2.0f*(random - 0.5f)*random_roughness; - float roughness = param1 * factor_random_roughness; - float radial_roughness = param2 * factor_random_roughness; - - /* Remap Coat value to [0, 100]% of Roughness. */ - float coat = stack_load_float_default(stack, coat_ofs, data_node2.y); - float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f); - - bsdf->N = N; - bsdf->v = roughness; - bsdf->s = radial_roughness; - bsdf->m0_roughness = m0_roughness; - bsdf->alpha = alpha; - bsdf->eta = ior; - bsdf->extra = extra; - - switch(parametrization) { - case NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION: { - float3 absorption_coefficient = stack_load_float3(stack, absorption_coefficient_ofs); - bsdf->sigma = absorption_coefficient; - break; - } - case NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION: { - float melanin = stack_load_float_default(stack, melanin_ofs, data_node2.z); - float melanin_redness = stack_load_float_default(stack, melanin_redness_ofs, data_node2.w); - - /* Randomize melanin. */ - float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z); - random_color = clamp(random_color, 0.0f, 1.0f); - float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color; - melanin *= factor_random_color; - - /* Map melanin 0..inf from more perceptually linear 0..1. */ - melanin = -logf(fmaxf(1.0f - melanin, 0.0001f)); - - /* Benedikt Bitterli's melanin ratio remapping. */ - float eumelanin = melanin * (1.0f - melanin_redness); - float pheomelanin = melanin * melanin_redness; - float3 melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin); - - /* Optional tint. */ - float3 tint = stack_load_float3(stack, tint_ofs); - float3 tint_sigma = sigma_from_reflectance(tint, radial_roughness); - - bsdf->sigma = melanin_sigma + tint_sigma; - break; - } - case NODE_PRINCIPLED_HAIR_REFLECTANCE: { - float3 color = stack_load_float3(stack, color_ofs); - bsdf->sigma = sigma_from_reflectance(color, radial_roughness); - break; - } - default: { - /* Fallback to brownish hair, same as defaults for melanin. */ - kernel_assert(!"Invalid Principled Hair parametrization!"); - bsdf->sigma = sigma_from_concentration(0.0f, 0.8054375f); - break; - } - } - - sd->flag |= bsdf_principled_hair_setup(sd, bsdf); - } - break; - } - case CLOSURE_BSDF_HAIR_REFLECTION_ID: - case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; - - if(sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) { - /* todo: giving a fixed weight here will cause issues when - * mixing multiple BSDFS. energy will not be conserved and - * the throughput can blow up after multiple bounces. we - * better figure out a way to skip backfaces from rays - * spawned by transmission from the front */ - bsdf_transparent_setup(sd, make_float3(1.0f, 1.0f, 1.0f), path_flag); - } - else { - HairBsdf *bsdf = (HairBsdf*)bsdf_alloc(sd, sizeof(HairBsdf), weight); - - if(bsdf) { - bsdf->N = N; - bsdf->roughness1 = param1; - bsdf->roughness2 = param2; - bsdf->offset = -stack_load_float(stack, data_node.z); - - if(stack_valid(data_node.y)) { - bsdf->T = normalize(stack_load_float3(stack, data_node.y)); - } - else if(!(sd->type & PRIMITIVE_ALL_CURVE)) { - bsdf->T = normalize(sd->dPdv); - bsdf->offset = 0.0f; - } - else - bsdf->T = normalize(sd->dPdu); - - if(type == CLOSURE_BSDF_HAIR_REFLECTION_ID) { - sd->flag |= bsdf_hair_reflection_setup(bsdf); - } - else { - sd->flag |= bsdf_hair_transmission_setup(bsdf); - } - } - } - - break; - } -#endif /* __HAIR__ */ + case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: { + uint4 data_node2 = read_node(kg, offset); + uint4 data_node3 = read_node(kg, offset); + uint4 data_node4 = read_node(kg, offset); + + float3 weight = sd->svm_closure_weight * mix_weight; + + uint offset_ofs, ior_ofs, color_ofs, parametrization; + decode_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, ¶metrization); + float alpha = stack_load_float_default(stack, offset_ofs, data_node.z); + float ior = stack_load_float_default(stack, ior_ofs, data_node.w); + + uint coat_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs; + decode_node_uchar4(data_node2.x, + &coat_ofs, + &melanin_ofs, + &melanin_redness_ofs, + &absorption_coefficient_ofs); + + uint tint_ofs, random_ofs, random_color_ofs, random_roughness_ofs; + decode_node_uchar4( + data_node3.x, &tint_ofs, &random_ofs, &random_color_ofs, &random_roughness_ofs); + + const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node4.y); + float random = 0.0f; + if (attr_descr_random.offset != ATTR_STD_NOT_FOUND) { + random = primitive_surface_attribute_float(kg, sd, attr_descr_random, NULL, NULL); + } + else { + random = stack_load_float_default(stack, random_ofs, data_node3.y); + } + + PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc( + sd, sizeof(PrincipledHairBSDF), weight); + if (bsdf) { + PrincipledHairExtra *extra = (PrincipledHairExtra *)closure_alloc_extra( + sd, sizeof(PrincipledHairExtra)); + + if (!extra) + break; + + /* Random factors range: [-randomization/2, +randomization/2]. */ + float random_roughness = stack_load_float_default( + stack, random_roughness_ofs, data_node3.w); + float factor_random_roughness = 1.0f + 2.0f * (random - 0.5f) * random_roughness; + float roughness = param1 * factor_random_roughness; + float radial_roughness = param2 * factor_random_roughness; + + /* Remap Coat value to [0, 100]% of Roughness. */ + float coat = stack_load_float_default(stack, coat_ofs, data_node2.y); + float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f); + + bsdf->N = N; + bsdf->v = roughness; + bsdf->s = radial_roughness; + bsdf->m0_roughness = m0_roughness; + bsdf->alpha = alpha; + bsdf->eta = ior; + bsdf->extra = extra; + + switch (parametrization) { + case NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION: { + float3 absorption_coefficient = stack_load_float3(stack, absorption_coefficient_ofs); + bsdf->sigma = absorption_coefficient; + break; + } + case NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION: { + float melanin = stack_load_float_default(stack, melanin_ofs, data_node2.z); + float melanin_redness = stack_load_float_default( + stack, melanin_redness_ofs, data_node2.w); + + /* Randomize melanin. */ + float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z); + random_color = clamp(random_color, 0.0f, 1.0f); + float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color; + melanin *= factor_random_color; + + /* Map melanin 0..inf from more perceptually linear 0..1. */ + melanin = -logf(fmaxf(1.0f - melanin, 0.0001f)); + + /* Benedikt Bitterli's melanin ratio remapping. */ + float eumelanin = melanin * (1.0f - melanin_redness); + float pheomelanin = melanin * melanin_redness; + float3 melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin); + + /* Optional tint. */ + float3 tint = stack_load_float3(stack, tint_ofs); + float3 tint_sigma = sigma_from_reflectance(tint, radial_roughness); + + bsdf->sigma = melanin_sigma + tint_sigma; + break; + } + case NODE_PRINCIPLED_HAIR_REFLECTANCE: { + float3 color = stack_load_float3(stack, color_ofs); + bsdf->sigma = sigma_from_reflectance(color, radial_roughness); + break; + } + default: { + /* Fallback to brownish hair, same as defaults for melanin. */ + kernel_assert(!"Invalid Principled Hair parametrization!"); + bsdf->sigma = sigma_from_concentration(0.0f, 0.8054375f); + break; + } + } + + sd->flag |= bsdf_principled_hair_setup(sd, bsdf); + } + break; + } + case CLOSURE_BSDF_HAIR_REFLECTION_ID: + case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: { + float3 weight = sd->svm_closure_weight * mix_weight; + + if (sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) { + /* todo: giving a fixed weight here will cause issues when + * mixing multiple BSDFS. energy will not be conserved and + * the throughput can blow up after multiple bounces. we + * better figure out a way to skip backfaces from rays + * spawned by transmission from the front */ + bsdf_transparent_setup(sd, make_float3(1.0f, 1.0f, 1.0f), path_flag); + } + else { + HairBsdf *bsdf = (HairBsdf *)bsdf_alloc(sd, sizeof(HairBsdf), weight); + + if (bsdf) { + bsdf->N = N; + bsdf->roughness1 = param1; + bsdf->roughness2 = param2; + bsdf->offset = -stack_load_float(stack, data_node.z); + + if (stack_valid(data_node.y)) { + bsdf->T = normalize(stack_load_float3(stack, data_node.y)); + } + else if (!(sd->type & PRIMITIVE_ALL_CURVE)) { + bsdf->T = normalize(sd->dPdv); + bsdf->offset = 0.0f; + } + else + bsdf->T = normalize(sd->dPdu); + + if (type == CLOSURE_BSDF_HAIR_REFLECTION_ID) { + sd->flag |= bsdf_hair_reflection_setup(bsdf); + } + else { + sd->flag |= bsdf_hair_transmission_setup(bsdf); + } + } + } + + break; + } +#endif /* __HAIR__ */ #ifdef __SUBSURFACE__ - case CLOSURE_BSSRDF_CUBIC_ID: - case CLOSURE_BSSRDF_GAUSSIAN_ID: - case CLOSURE_BSSRDF_BURLEY_ID: - case CLOSURE_BSSRDF_RANDOM_WALK_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; - Bssrdf *bssrdf = bssrdf_alloc(sd, weight); - - if(bssrdf) { - /* disable in case of diffuse ancestor, can't see it well then and - * adds considerably noise due to probabilities of continuing path - * getting lower and lower */ - if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) - param1 = 0.0f; - - bssrdf->radius = stack_load_float3(stack, data_node.z)*param1; - bssrdf->albedo = sd->svm_closure_weight; - bssrdf->texture_blur = param2; - bssrdf->sharpness = stack_load_float(stack, data_node.w); - bssrdf->N = N; - bssrdf->roughness = 0.0f; - sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type); - } - - break; - } + case CLOSURE_BSSRDF_CUBIC_ID: + case CLOSURE_BSSRDF_GAUSSIAN_ID: + case CLOSURE_BSSRDF_BURLEY_ID: + case CLOSURE_BSSRDF_RANDOM_WALK_ID: { + float3 weight = sd->svm_closure_weight * mix_weight; + Bssrdf *bssrdf = bssrdf_alloc(sd, weight); + + if (bssrdf) { + /* disable in case of diffuse ancestor, can't see it well then and + * adds considerably noise due to probabilities of continuing path + * getting lower and lower */ + if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) + param1 = 0.0f; + + bssrdf->radius = stack_load_float3(stack, data_node.z) * param1; + bssrdf->albedo = sd->svm_closure_weight; + bssrdf->texture_blur = param2; + bssrdf->sharpness = stack_load_float(stack, data_node.w); + bssrdf->N = N; + bssrdf->roughness = 0.0f; + sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type); + } + + break; + } #endif - default: - break; - } + default: + break; + } } -ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type) +ccl_device void svm_node_closure_volume( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type) { #ifdef __VOLUME__ - /* Only sum extinction for volumes, variable is shared with surface transparency. */ - if(shader_type != SHADER_TYPE_VOLUME) { - return; - } - - uint type, density_offset, anisotropy_offset; - - uint mix_weight_offset; - decode_node_uchar4(node.y, &type, &density_offset, &anisotropy_offset, &mix_weight_offset); - float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f); - - if(mix_weight == 0.0f) { - return; - } - - float density = (stack_valid(density_offset))? stack_load_float(stack, density_offset): __uint_as_float(node.z); - density = mix_weight * fmaxf(density, 0.0f); - - /* Compute scattering coefficient. */ - float3 weight = sd->svm_closure_weight; - - if(type == CLOSURE_VOLUME_ABSORPTION_ID) { - weight = make_float3(1.0f, 1.0f, 1.0f) - weight; - } - - weight *= density; - - /* Add closure for volume scattering. */ - if(type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) { - HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), weight); - - if(volume) { - float anisotropy = (stack_valid(anisotropy_offset))? stack_load_float(stack, anisotropy_offset): __uint_as_float(node.w); - volume->g = anisotropy; /* g */ - sd->flag |= volume_henyey_greenstein_setup(volume); - } - } - - /* Sum total extinction weight. */ - volume_extinction_setup(sd, weight); + /* Only sum extinction for volumes, variable is shared with surface transparency. */ + if (shader_type != SHADER_TYPE_VOLUME) { + return; + } + + uint type, density_offset, anisotropy_offset; + + uint mix_weight_offset; + decode_node_uchar4(node.y, &type, &density_offset, &anisotropy_offset, &mix_weight_offset); + float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) : + 1.0f); + + if (mix_weight == 0.0f) { + return; + } + + float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) : + __uint_as_float(node.z); + density = mix_weight * fmaxf(density, 0.0f); + + /* Compute scattering coefficient. */ + float3 weight = sd->svm_closure_weight; + + if (type == CLOSURE_VOLUME_ABSORPTION_ID) { + weight = make_float3(1.0f, 1.0f, 1.0f) - weight; + } + + weight *= density; + + /* Add closure for volume scattering. */ + if (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) { + HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc( + sd, sizeof(HenyeyGreensteinVolume), weight); + + if (volume) { + float anisotropy = (stack_valid(anisotropy_offset)) ? + stack_load_float(stack, anisotropy_offset) : + __uint_as_float(node.w); + volume->g = anisotropy; /* g */ + sd->flag |= volume_henyey_greenstein_setup(volume); + } + } + + /* Sum total extinction weight. */ + volume_extinction_setup(sd, weight); #endif } -ccl_device void svm_node_principled_volume(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, ShaderType shader_type, int path_flag, int *offset) +ccl_device void svm_node_principled_volume(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint4 node, + ShaderType shader_type, + int path_flag, + int *offset) { #ifdef __VOLUME__ - uint4 value_node = read_node(kg, offset); - uint4 attr_node = read_node(kg, offset); - - /* Only sum extinction for volumes, variable is shared with surface transparency. */ - if(shader_type != SHADER_TYPE_VOLUME) { - return; - } - - uint density_offset, anisotropy_offset, absorption_color_offset, mix_weight_offset; - decode_node_uchar4(node.y, &density_offset, &anisotropy_offset, &absorption_color_offset, &mix_weight_offset); - float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f); - - if(mix_weight == 0.0f) { - return; - } - - /* Compute density. */ - float primitive_density = 1.0f; - float density = (stack_valid(density_offset))? stack_load_float(stack, density_offset): __uint_as_float(value_node.x); - density = mix_weight * fmaxf(density, 0.0f); - - if(density > CLOSURE_WEIGHT_CUTOFF) { - /* Density and color attribute lookup if available. */ - const AttributeDescriptor attr_density = find_attribute(kg, sd, attr_node.x); - if(attr_density.offset != ATTR_STD_NOT_FOUND) { - primitive_density = primitive_volume_attribute_float(kg, sd, attr_density); - density = fmaxf(density * primitive_density, 0.0f); - } - } - - if(density > CLOSURE_WEIGHT_CUTOFF) { - /* Compute scattering color. */ - float3 color = sd->svm_closure_weight; - - const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y); - if(attr_color.offset != ATTR_STD_NOT_FOUND) { - color *= primitive_volume_attribute_float3(kg, sd, attr_color); - } - - /* Add closure for volume scattering. */ - HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc(sd, sizeof(HenyeyGreensteinVolume), color * density); - if(volume) { - float anisotropy = (stack_valid(anisotropy_offset))? stack_load_float(stack, anisotropy_offset): __uint_as_float(value_node.y); - volume->g = anisotropy; - sd->flag |= volume_henyey_greenstein_setup(volume); - } - - /* Add extinction weight. */ - float3 zero = make_float3(0.0f, 0.0f, 0.0f); - float3 one = make_float3(1.0f, 1.0f, 1.0f); - float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)), zero); - float3 absorption = max(one - color, zero) * max(one - absorption_color, zero); - volume_extinction_setup(sd, (color + absorption) * density); - } - - /* Compute emission. */ - if(path_flag & PATH_RAY_SHADOW) { - /* Don't need emission for shadows. */ - return; - } - - uint emission_offset, emission_color_offset, blackbody_offset, temperature_offset; - decode_node_uchar4(node.z, &emission_offset, &emission_color_offset, &blackbody_offset, &temperature_offset); - float emission = (stack_valid(emission_offset))? stack_load_float(stack, emission_offset): __uint_as_float(value_node.z); - float blackbody = (stack_valid(blackbody_offset))? stack_load_float(stack, blackbody_offset): __uint_as_float(value_node.w); - - if(emission > CLOSURE_WEIGHT_CUTOFF) { - float3 emission_color = stack_load_float3(stack, emission_color_offset); - emission_setup(sd, emission * emission_color); - } - - if(blackbody > CLOSURE_WEIGHT_CUTOFF) { - float T = stack_load_float(stack, temperature_offset); - - /* Add flame temperature from attribute if available. */ - const AttributeDescriptor attr_temperature = find_attribute(kg, sd, attr_node.z); - if(attr_temperature.offset != ATTR_STD_NOT_FOUND) { - float temperature = primitive_volume_attribute_float(kg, sd, attr_temperature); - T *= fmaxf(temperature, 0.0f); - } - - T = fmaxf(T, 0.0f); - - /* Stefan-Boltzmann law. */ - float T4 = sqr(sqr(T)); - float sigma = 5.670373e-8f * 1e-6f / M_PI_F; - float intensity = sigma * mix(1.0f, T4, blackbody); - - if(intensity > CLOSURE_WEIGHT_CUTOFF) { - float3 blackbody_tint = stack_load_float3(stack, node.w); - float3 bb = blackbody_tint * intensity * svm_math_blackbody_color(T); - emission_setup(sd, bb); - } - } + uint4 value_node = read_node(kg, offset); + uint4 attr_node = read_node(kg, offset); + + /* Only sum extinction for volumes, variable is shared with surface transparency. */ + if (shader_type != SHADER_TYPE_VOLUME) { + return; + } + + uint density_offset, anisotropy_offset, absorption_color_offset, mix_weight_offset; + decode_node_uchar4( + node.y, &density_offset, &anisotropy_offset, &absorption_color_offset, &mix_weight_offset); + float mix_weight = (stack_valid(mix_weight_offset) ? stack_load_float(stack, mix_weight_offset) : + 1.0f); + + if (mix_weight == 0.0f) { + return; + } + + /* Compute density. */ + float primitive_density = 1.0f; + float density = (stack_valid(density_offset)) ? stack_load_float(stack, density_offset) : + __uint_as_float(value_node.x); + density = mix_weight * fmaxf(density, 0.0f); + + if (density > CLOSURE_WEIGHT_CUTOFF) { + /* Density and color attribute lookup if available. */ + const AttributeDescriptor attr_density = find_attribute(kg, sd, attr_node.x); + if (attr_density.offset != ATTR_STD_NOT_FOUND) { + primitive_density = primitive_volume_attribute_float(kg, sd, attr_density); + density = fmaxf(density * primitive_density, 0.0f); + } + } + + if (density > CLOSURE_WEIGHT_CUTOFF) { + /* Compute scattering color. */ + float3 color = sd->svm_closure_weight; + + const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y); + if (attr_color.offset != ATTR_STD_NOT_FOUND) { + color *= primitive_volume_attribute_float3(kg, sd, attr_color); + } + + /* Add closure for volume scattering. */ + HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc( + sd, sizeof(HenyeyGreensteinVolume), color * density); + if (volume) { + float anisotropy = (stack_valid(anisotropy_offset)) ? + stack_load_float(stack, anisotropy_offset) : + __uint_as_float(value_node.y); + volume->g = anisotropy; + sd->flag |= volume_henyey_greenstein_setup(volume); + } + + /* Add extinction weight. */ + float3 zero = make_float3(0.0f, 0.0f, 0.0f); + float3 one = make_float3(1.0f, 1.0f, 1.0f); + float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)), zero); + float3 absorption = max(one - color, zero) * max(one - absorption_color, zero); + volume_extinction_setup(sd, (color + absorption) * density); + } + + /* Compute emission. */ + if (path_flag & PATH_RAY_SHADOW) { + /* Don't need emission for shadows. */ + return; + } + + uint emission_offset, emission_color_offset, blackbody_offset, temperature_offset; + decode_node_uchar4( + node.z, &emission_offset, &emission_color_offset, &blackbody_offset, &temperature_offset); + float emission = (stack_valid(emission_offset)) ? stack_load_float(stack, emission_offset) : + __uint_as_float(value_node.z); + float blackbody = (stack_valid(blackbody_offset)) ? stack_load_float(stack, blackbody_offset) : + __uint_as_float(value_node.w); + + if (emission > CLOSURE_WEIGHT_CUTOFF) { + float3 emission_color = stack_load_float3(stack, emission_color_offset); + emission_setup(sd, emission * emission_color); + } + + if (blackbody > CLOSURE_WEIGHT_CUTOFF) { + float T = stack_load_float(stack, temperature_offset); + + /* Add flame temperature from attribute if available. */ + const AttributeDescriptor attr_temperature = find_attribute(kg, sd, attr_node.z); + if (attr_temperature.offset != ATTR_STD_NOT_FOUND) { + float temperature = primitive_volume_attribute_float(kg, sd, attr_temperature); + T *= fmaxf(temperature, 0.0f); + } + + T = fmaxf(T, 0.0f); + + /* Stefan-Boltzmann law. */ + float T4 = sqr(sqr(T)); + float sigma = 5.670373e-8f * 1e-6f / M_PI_F; + float intensity = sigma * mix(1.0f, T4, blackbody); + + if (intensity > CLOSURE_WEIGHT_CUTOFF) { + float3 blackbody_tint = stack_load_float3(stack, node.w); + float3 bb = blackbody_tint * intensity * svm_math_blackbody_color(T); + emission_setup(sd, bb); + } + } #endif } ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node) { - uint mix_weight_offset = node.y; - float3 weight = sd->svm_closure_weight; + uint mix_weight_offset = node.y; + float3 weight = sd->svm_closure_weight; - if(stack_valid(mix_weight_offset)) { - float mix_weight = stack_load_float(stack, mix_weight_offset); + if (stack_valid(mix_weight_offset)) { + float mix_weight = stack_load_float(stack, mix_weight_offset); - if(mix_weight == 0.0f) - return; + if (mix_weight == 0.0f) + return; - weight *= mix_weight; - } + weight *= mix_weight; + } - emission_setup(sd, weight); + emission_setup(sd, weight); } ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node) { - uint mix_weight_offset = node.y; - float3 weight = sd->svm_closure_weight; + uint mix_weight_offset = node.y; + float3 weight = sd->svm_closure_weight; - if(stack_valid(mix_weight_offset)) { - float mix_weight = stack_load_float(stack, mix_weight_offset); + if (stack_valid(mix_weight_offset)) { + float mix_weight = stack_load_float(stack, mix_weight_offset); - if(mix_weight == 0.0f) - return; + if (mix_weight == 0.0f) + return; - weight *= mix_weight; - } + weight *= mix_weight; + } - background_setup(sd, weight); + background_setup(sd, weight); } ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node) { - uint mix_weight_offset = node.y; + uint mix_weight_offset = node.y; - if(stack_valid(mix_weight_offset)) { - float mix_weight = stack_load_float(stack, mix_weight_offset); + if (stack_valid(mix_weight_offset)) { + float mix_weight = stack_load_float(stack, mix_weight_offset); - if(mix_weight == 0.0f) - return; + if (mix_weight == 0.0f) + return; - closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight * mix_weight); - } - else - closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight); + closure_alloc( + sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight * mix_weight); + } + else + closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, sd->svm_closure_weight); - sd->flag |= SD_HOLDOUT; + sd->flag |= SD_HOLDOUT; } /* Closure Nodes */ ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight) { - sd->svm_closure_weight = weight; + sd->svm_closure_weight = weight; } ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b) { - float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b)); - svm_node_closure_store_weight(sd, weight); + float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b)); + svm_node_closure_store_weight(sd, weight); } ccl_device void svm_node_closure_weight(ShaderData *sd, float *stack, uint weight_offset) { - float3 weight = stack_load_float3(stack, weight_offset); + float3 weight = stack_load_float3(stack, weight_offset); - svm_node_closure_store_weight(sd, weight); + svm_node_closure_store_weight(sd, weight); } -ccl_device void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) +ccl_device void svm_node_emission_weight(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint4 node) { - uint color_offset = node.y; - uint strength_offset = node.z; + uint color_offset = node.y; + uint strength_offset = node.z; - float strength = stack_load_float(stack, strength_offset); - float3 weight = stack_load_float3(stack, color_offset)*strength; + float strength = stack_load_float(stack, strength_offset); + float3 weight = stack_load_float3(stack, color_offset) * strength; - svm_node_closure_store_weight(sd, weight); + svm_node_closure_store_weight(sd, weight); } ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node) { - /* fetch weight from blend input, previous mix closures, - * and write to stack to be used by closure nodes later */ - uint weight_offset, in_weight_offset, weight1_offset, weight2_offset; - decode_node_uchar4(node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset); + /* fetch weight from blend input, previous mix closures, + * and write to stack to be used by closure nodes later */ + uint weight_offset, in_weight_offset, weight1_offset, weight2_offset; + decode_node_uchar4(node.y, &weight_offset, &in_weight_offset, &weight1_offset, &weight2_offset); - float weight = stack_load_float(stack, weight_offset); - weight = saturate(weight); + float weight = stack_load_float(stack, weight_offset); + weight = saturate(weight); - float in_weight = (stack_valid(in_weight_offset))? stack_load_float(stack, in_weight_offset): 1.0f; + float in_weight = (stack_valid(in_weight_offset)) ? stack_load_float(stack, in_weight_offset) : + 1.0f; - if(stack_valid(weight1_offset)) - stack_store_float(stack, weight1_offset, in_weight*(1.0f - weight)); - if(stack_valid(weight2_offset)) - stack_store_float(stack, weight2_offset, in_weight*weight); + if (stack_valid(weight1_offset)) + stack_store_float(stack, weight1_offset, in_weight * (1.0f - weight)); + if (stack_valid(weight2_offset)) + stack_store_float(stack, weight2_offset, in_weight * weight); } /* (Bump) normal */ -ccl_device void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal) +ccl_device void svm_node_set_normal( + KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal) { - float3 normal = stack_load_float3(stack, in_direction); - sd->N = normal; - stack_store_float3(stack, out_normal, normal); + float3 normal = stack_load_float3(stack, in_direction); + sd->N = normal; + stack_store_float3(stack, out_normal, normal); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_color_util.h b/intern/cycles/kernel/svm/svm_color_util.h index d5945f915c6..12b59d2616b 100644 --- a/intern/cycles/kernel/svm/svm_color_util.h +++ b/intern/cycles/kernel/svm/svm_color_util.h @@ -18,288 +18,310 @@ CCL_NAMESPACE_BEGIN ccl_device float3 svm_mix_blend(float t, float3 col1, float3 col2) { - return interp(col1, col2, t); + return interp(col1, col2, t); } ccl_device float3 svm_mix_add(float t, float3 col1, float3 col2) { - return interp(col1, col1 + col2, t); + return interp(col1, col1 + col2, t); } ccl_device float3 svm_mix_mul(float t, float3 col1, float3 col2) { - return interp(col1, col1 * col2, t); + return interp(col1, col1 * col2, t); } ccl_device float3 svm_mix_screen(float t, float3 col1, float3 col2) { - float tm = 1.0f - t; - float3 one = make_float3(1.0f, 1.0f, 1.0f); - float3 tm3 = make_float3(tm, tm, tm); + float tm = 1.0f - t; + float3 one = make_float3(1.0f, 1.0f, 1.0f); + float3 tm3 = make_float3(tm, tm, tm); - return one - (tm3 + t*(one - col2))*(one - col1); + return one - (tm3 + t * (one - col2)) * (one - col1); } ccl_device float3 svm_mix_overlay(float t, float3 col1, float3 col2) { - float tm = 1.0f - t; + float tm = 1.0f - t; - float3 outcol = col1; + float3 outcol = col1; - if(outcol.x < 0.5f) - outcol.x *= tm + 2.0f*t*col2.x; - else - outcol.x = 1.0f - (tm + 2.0f*t*(1.0f - col2.x))*(1.0f - outcol.x); + if (outcol.x < 0.5f) + outcol.x *= tm + 2.0f * t * col2.x; + else + outcol.x = 1.0f - (tm + 2.0f * t * (1.0f - col2.x)) * (1.0f - outcol.x); - if(outcol.y < 0.5f) - outcol.y *= tm + 2.0f*t*col2.y; - else - outcol.y = 1.0f - (tm + 2.0f*t*(1.0f - col2.y))*(1.0f - outcol.y); + if (outcol.y < 0.5f) + outcol.y *= tm + 2.0f * t * col2.y; + else + outcol.y = 1.0f - (tm + 2.0f * t * (1.0f - col2.y)) * (1.0f - outcol.y); - if(outcol.z < 0.5f) - outcol.z *= tm + 2.0f*t*col2.z; - else - outcol.z = 1.0f - (tm + 2.0f*t*(1.0f - col2.z))*(1.0f - outcol.z); + if (outcol.z < 0.5f) + outcol.z *= tm + 2.0f * t * col2.z; + else + outcol.z = 1.0f - (tm + 2.0f * t * (1.0f - col2.z)) * (1.0f - outcol.z); - return outcol; + return outcol; } ccl_device float3 svm_mix_sub(float t, float3 col1, float3 col2) { - return interp(col1, col1 - col2, t); + return interp(col1, col1 - col2, t); } ccl_device float3 svm_mix_div(float t, float3 col1, float3 col2) { - float tm = 1.0f - t; + float tm = 1.0f - t; - float3 outcol = col1; + float3 outcol = col1; - if(col2.x != 0.0f) outcol.x = tm*outcol.x + t*outcol.x/col2.x; - if(col2.y != 0.0f) outcol.y = tm*outcol.y + t*outcol.y/col2.y; - if(col2.z != 0.0f) outcol.z = tm*outcol.z + t*outcol.z/col2.z; + if (col2.x != 0.0f) + outcol.x = tm * outcol.x + t * outcol.x / col2.x; + if (col2.y != 0.0f) + outcol.y = tm * outcol.y + t * outcol.y / col2.y; + if (col2.z != 0.0f) + outcol.z = tm * outcol.z + t * outcol.z / col2.z; - return outcol; + return outcol; } ccl_device float3 svm_mix_diff(float t, float3 col1, float3 col2) { - return interp(col1, fabs(col1 - col2), t); + return interp(col1, fabs(col1 - col2), t); } ccl_device float3 svm_mix_dark(float t, float3 col1, float3 col2) { - return min(col1, col2)*t + col1*(1.0f - t); + return min(col1, col2) * t + col1 * (1.0f - t); } ccl_device float3 svm_mix_light(float t, float3 col1, float3 col2) { - return max(col1, col2*t); + return max(col1, col2 * t); } ccl_device float3 svm_mix_dodge(float t, float3 col1, float3 col2) { - float3 outcol = col1; - - if(outcol.x != 0.0f) { - float tmp = 1.0f - t*col2.x; - if(tmp <= 0.0f) - outcol.x = 1.0f; - else if((tmp = outcol.x/tmp) > 1.0f) - outcol.x = 1.0f; - else - outcol.x = tmp; - } - if(outcol.y != 0.0f) { - float tmp = 1.0f - t*col2.y; - if(tmp <= 0.0f) - outcol.y = 1.0f; - else if((tmp = outcol.y/tmp) > 1.0f) - outcol.y = 1.0f; - else - outcol.y = tmp; - } - if(outcol.z != 0.0f) { - float tmp = 1.0f - t*col2.z; - if(tmp <= 0.0f) - outcol.z = 1.0f; - else if((tmp = outcol.z/tmp) > 1.0f) - outcol.z = 1.0f; - else - outcol.z = tmp; - } - - return outcol; + float3 outcol = col1; + + if (outcol.x != 0.0f) { + float tmp = 1.0f - t * col2.x; + if (tmp <= 0.0f) + outcol.x = 1.0f; + else if ((tmp = outcol.x / tmp) > 1.0f) + outcol.x = 1.0f; + else + outcol.x = tmp; + } + if (outcol.y != 0.0f) { + float tmp = 1.0f - t * col2.y; + if (tmp <= 0.0f) + outcol.y = 1.0f; + else if ((tmp = outcol.y / tmp) > 1.0f) + outcol.y = 1.0f; + else + outcol.y = tmp; + } + if (outcol.z != 0.0f) { + float tmp = 1.0f - t * col2.z; + if (tmp <= 0.0f) + outcol.z = 1.0f; + else if ((tmp = outcol.z / tmp) > 1.0f) + outcol.z = 1.0f; + else + outcol.z = tmp; + } + + return outcol; } ccl_device float3 svm_mix_burn(float t, float3 col1, float3 col2) { - float tmp, tm = 1.0f - t; - - float3 outcol = col1; - - tmp = tm + t*col2.x; - if(tmp <= 0.0f) - outcol.x = 0.0f; - else if((tmp = (1.0f - (1.0f - outcol.x)/tmp)) < 0.0f) - outcol.x = 0.0f; - else if(tmp > 1.0f) - outcol.x = 1.0f; - else - outcol.x = tmp; - - tmp = tm + t*col2.y; - if(tmp <= 0.0f) - outcol.y = 0.0f; - else if((tmp = (1.0f - (1.0f - outcol.y)/tmp)) < 0.0f) - outcol.y = 0.0f; - else if(tmp > 1.0f) - outcol.y = 1.0f; - else - outcol.y = tmp; - - tmp = tm + t*col2.z; - if(tmp <= 0.0f) - outcol.z = 0.0f; - else if((tmp = (1.0f - (1.0f - outcol.z)/tmp)) < 0.0f) - outcol.z = 0.0f; - else if(tmp > 1.0f) - outcol.z = 1.0f; - else - outcol.z = tmp; - - return outcol; + float tmp, tm = 1.0f - t; + + float3 outcol = col1; + + tmp = tm + t * col2.x; + if (tmp <= 0.0f) + outcol.x = 0.0f; + else if ((tmp = (1.0f - (1.0f - outcol.x) / tmp)) < 0.0f) + outcol.x = 0.0f; + else if (tmp > 1.0f) + outcol.x = 1.0f; + else + outcol.x = tmp; + + tmp = tm + t * col2.y; + if (tmp <= 0.0f) + outcol.y = 0.0f; + else if ((tmp = (1.0f - (1.0f - outcol.y) / tmp)) < 0.0f) + outcol.y = 0.0f; + else if (tmp > 1.0f) + outcol.y = 1.0f; + else + outcol.y = tmp; + + tmp = tm + t * col2.z; + if (tmp <= 0.0f) + outcol.z = 0.0f; + else if ((tmp = (1.0f - (1.0f - outcol.z) / tmp)) < 0.0f) + outcol.z = 0.0f; + else if (tmp > 1.0f) + outcol.z = 1.0f; + else + outcol.z = tmp; + + return outcol; } ccl_device float3 svm_mix_hue(float t, float3 col1, float3 col2) { - float3 outcol = col1; + float3 outcol = col1; - float3 hsv2 = rgb_to_hsv(col2); + float3 hsv2 = rgb_to_hsv(col2); - if(hsv2.y != 0.0f) { - float3 hsv = rgb_to_hsv(outcol); - hsv.x = hsv2.x; - float3 tmp = hsv_to_rgb(hsv); + if (hsv2.y != 0.0f) { + float3 hsv = rgb_to_hsv(outcol); + hsv.x = hsv2.x; + float3 tmp = hsv_to_rgb(hsv); - outcol = interp(outcol, tmp, t); - } + outcol = interp(outcol, tmp, t); + } - return outcol; + return outcol; } ccl_device float3 svm_mix_sat(float t, float3 col1, float3 col2) { - float tm = 1.0f - t; + float tm = 1.0f - t; - float3 outcol = col1; + float3 outcol = col1; - float3 hsv = rgb_to_hsv(outcol); + float3 hsv = rgb_to_hsv(outcol); - if(hsv.y != 0.0f) { - float3 hsv2 = rgb_to_hsv(col2); + if (hsv.y != 0.0f) { + float3 hsv2 = rgb_to_hsv(col2); - hsv.y = tm*hsv.y + t*hsv2.y; - outcol = hsv_to_rgb(hsv); - } + hsv.y = tm * hsv.y + t * hsv2.y; + outcol = hsv_to_rgb(hsv); + } - return outcol; + return outcol; } ccl_device float3 svm_mix_val(float t, float3 col1, float3 col2) { - float tm = 1.0f - t; + float tm = 1.0f - t; - float3 hsv = rgb_to_hsv(col1); - float3 hsv2 = rgb_to_hsv(col2); + float3 hsv = rgb_to_hsv(col1); + float3 hsv2 = rgb_to_hsv(col2); - hsv.z = tm*hsv.z + t*hsv2.z; + hsv.z = tm * hsv.z + t * hsv2.z; - return hsv_to_rgb(hsv); + return hsv_to_rgb(hsv); } ccl_device float3 svm_mix_color(float t, float3 col1, float3 col2) { - float3 outcol = col1; - float3 hsv2 = rgb_to_hsv(col2); + float3 outcol = col1; + float3 hsv2 = rgb_to_hsv(col2); - if(hsv2.y != 0.0f) { - float3 hsv = rgb_to_hsv(outcol); - hsv.x = hsv2.x; - hsv.y = hsv2.y; - float3 tmp = hsv_to_rgb(hsv); + if (hsv2.y != 0.0f) { + float3 hsv = rgb_to_hsv(outcol); + hsv.x = hsv2.x; + hsv.y = hsv2.y; + float3 tmp = hsv_to_rgb(hsv); - outcol = interp(outcol, tmp, t); - } + outcol = interp(outcol, tmp, t); + } - return outcol; + return outcol; } ccl_device float3 svm_mix_soft(float t, float3 col1, float3 col2) { - float tm = 1.0f - t; + float tm = 1.0f - t; - float3 one = make_float3(1.0f, 1.0f, 1.0f); - float3 scr = one - (one - col2)*(one - col1); + float3 one = make_float3(1.0f, 1.0f, 1.0f); + float3 scr = one - (one - col2) * (one - col1); - return tm*col1 + t*((one - col1)*col2*col1 + col1*scr); + return tm * col1 + t * ((one - col1) * col2 * col1 + col1 * scr); } ccl_device float3 svm_mix_linear(float t, float3 col1, float3 col2) { - return col1 + t*(2.0f*col2 + make_float3(-1.0f, -1.0f, -1.0f)); + return col1 + t * (2.0f * col2 + make_float3(-1.0f, -1.0f, -1.0f)); } ccl_device float3 svm_mix_clamp(float3 col) { - float3 outcol = col; + float3 outcol = col; - outcol.x = saturate(col.x); - outcol.y = saturate(col.y); - outcol.z = saturate(col.z); + outcol.x = saturate(col.x); + outcol.y = saturate(col.y); + outcol.z = saturate(col.z); - return outcol; + return outcol; } ccl_device_noinline float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2) { - float t = saturate(fac); - - switch(type) { - case NODE_MIX_BLEND: return svm_mix_blend(t, c1, c2); - case NODE_MIX_ADD: return svm_mix_add(t, c1, c2); - case NODE_MIX_MUL: return svm_mix_mul(t, c1, c2); - case NODE_MIX_SCREEN: return svm_mix_screen(t, c1, c2); - case NODE_MIX_OVERLAY: return svm_mix_overlay(t, c1, c2); - case NODE_MIX_SUB: return svm_mix_sub(t, c1, c2); - case NODE_MIX_DIV: return svm_mix_div(t, c1, c2); - case NODE_MIX_DIFF: return svm_mix_diff(t, c1, c2); - case NODE_MIX_DARK: return svm_mix_dark(t, c1, c2); - case NODE_MIX_LIGHT: return svm_mix_light(t, c1, c2); - case NODE_MIX_DODGE: return svm_mix_dodge(t, c1, c2); - case NODE_MIX_BURN: return svm_mix_burn(t, c1, c2); - case NODE_MIX_HUE: return svm_mix_hue(t, c1, c2); - case NODE_MIX_SAT: return svm_mix_sat(t, c1, c2); - case NODE_MIX_VAL: return svm_mix_val (t, c1, c2); - case NODE_MIX_COLOR: return svm_mix_color(t, c1, c2); - case NODE_MIX_SOFT: return svm_mix_soft(t, c1, c2); - case NODE_MIX_LINEAR: return svm_mix_linear(t, c1, c2); - case NODE_MIX_CLAMP: return svm_mix_clamp(c1); - } - - return make_float3(0.0f, 0.0f, 0.0f); + float t = saturate(fac); + + switch (type) { + case NODE_MIX_BLEND: + return svm_mix_blend(t, c1, c2); + case NODE_MIX_ADD: + return svm_mix_add(t, c1, c2); + case NODE_MIX_MUL: + return svm_mix_mul(t, c1, c2); + case NODE_MIX_SCREEN: + return svm_mix_screen(t, c1, c2); + case NODE_MIX_OVERLAY: + return svm_mix_overlay(t, c1, c2); + case NODE_MIX_SUB: + return svm_mix_sub(t, c1, c2); + case NODE_MIX_DIV: + return svm_mix_div(t, c1, c2); + case NODE_MIX_DIFF: + return svm_mix_diff(t, c1, c2); + case NODE_MIX_DARK: + return svm_mix_dark(t, c1, c2); + case NODE_MIX_LIGHT: + return svm_mix_light(t, c1, c2); + case NODE_MIX_DODGE: + return svm_mix_dodge(t, c1, c2); + case NODE_MIX_BURN: + return svm_mix_burn(t, c1, c2); + case NODE_MIX_HUE: + return svm_mix_hue(t, c1, c2); + case NODE_MIX_SAT: + return svm_mix_sat(t, c1, c2); + case NODE_MIX_VAL: + return svm_mix_val(t, c1, c2); + case NODE_MIX_COLOR: + return svm_mix_color(t, c1, c2); + case NODE_MIX_SOFT: + return svm_mix_soft(t, c1, c2); + case NODE_MIX_LINEAR: + return svm_mix_linear(t, c1, c2); + case NODE_MIX_CLAMP: + return svm_mix_clamp(c1); + } + + return make_float3(0.0f, 0.0f, 0.0f); } ccl_device_inline float3 svm_brightness_contrast(float3 color, float brightness, float contrast) { - float a = 1.0f + contrast; - float b = brightness - contrast*0.5f; + float a = 1.0f + contrast; + float b = brightness - contrast * 0.5f; - color.x = max(a*color.x + b, 0.0f); - color.y = max(a*color.y + b, 0.0f); - color.z = max(a*color.z + b, 0.0f); + color.x = max(a * color.x + b, 0.0f); + color.y = max(a * color.y + b, 0.0f); + color.z = max(a * color.z + b, 0.0f); - return color; + return color; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_convert.h b/intern/cycles/kernel/svm/svm_convert.h index 63b1dc6865e..5df6c9fb755 100644 --- a/intern/cycles/kernel/svm/svm_convert.h +++ b/intern/cycles/kernel/svm/svm_convert.h @@ -18,54 +18,55 @@ CCL_NAMESPACE_BEGIN /* Conversion Nodes */ -ccl_device void svm_node_convert(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint from, uint to) +ccl_device void svm_node_convert( + KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint from, uint to) { - switch(type) { - case NODE_CONVERT_FI: { - float f = stack_load_float(stack, from); - stack_store_int(stack, to, float_to_int(f)); - break; - } - case NODE_CONVERT_FV: { - float f = stack_load_float(stack, from); - stack_store_float3(stack, to, make_float3(f, f, f)); - break; - } - case NODE_CONVERT_CF: { - float3 f = stack_load_float3(stack, from); - float g = linear_rgb_to_gray(kg, f); - stack_store_float(stack, to, g); - break; - } - case NODE_CONVERT_CI: { - float3 f = stack_load_float3(stack, from); - int i = (int)linear_rgb_to_gray(kg, f); - stack_store_int(stack, to, i); - break; - } - case NODE_CONVERT_VF: { - float3 f = stack_load_float3(stack, from); - float g = average(f); - stack_store_float(stack, to, g); - break; - } - case NODE_CONVERT_VI: { - float3 f = stack_load_float3(stack, from); - int i = (int)average(f); - stack_store_int(stack, to, i); - break; - } - case NODE_CONVERT_IF: { - float f = (float)stack_load_int(stack, from); - stack_store_float(stack, to, f); - break; - } - case NODE_CONVERT_IV: { - float f = (float)stack_load_int(stack, from); - stack_store_float3(stack, to, make_float3(f, f, f)); - break; - } - } + switch (type) { + case NODE_CONVERT_FI: { + float f = stack_load_float(stack, from); + stack_store_int(stack, to, float_to_int(f)); + break; + } + case NODE_CONVERT_FV: { + float f = stack_load_float(stack, from); + stack_store_float3(stack, to, make_float3(f, f, f)); + break; + } + case NODE_CONVERT_CF: { + float3 f = stack_load_float3(stack, from); + float g = linear_rgb_to_gray(kg, f); + stack_store_float(stack, to, g); + break; + } + case NODE_CONVERT_CI: { + float3 f = stack_load_float3(stack, from); + int i = (int)linear_rgb_to_gray(kg, f); + stack_store_int(stack, to, i); + break; + } + case NODE_CONVERT_VF: { + float3 f = stack_load_float3(stack, from); + float g = average(f); + stack_store_float(stack, to, g); + break; + } + case NODE_CONVERT_VI: { + float3 f = stack_load_float3(stack, from); + int i = (int)average(f); + stack_store_int(stack, to, i); + break; + } + case NODE_CONVERT_IF: { + float f = (float)stack_load_int(stack, from); + stack_store_float(stack, to, f); + break; + } + case NODE_CONVERT_IV: { + float f = (float)stack_load_int(stack, from); + stack_store_float3(stack, to, make_float3(f, f, f)); + break; + } + } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h index a69c9fe81f9..f16664a684c 100644 --- a/intern/cycles/kernel/svm/svm_displace.h +++ b/intern/cycles/kernel/svm/svm_displace.h @@ -21,144 +21,149 @@ CCL_NAMESPACE_BEGIN ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { #ifdef __RAY_DIFFERENTIALS__ - /* get normal input */ - uint normal_offset, scale_offset, invert, use_object_space; - decode_node_uchar4(node.y, &normal_offset, &scale_offset, &invert, &use_object_space); + /* get normal input */ + uint normal_offset, scale_offset, invert, use_object_space; + decode_node_uchar4(node.y, &normal_offset, &scale_offset, &invert, &use_object_space); - float3 normal_in = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N; + float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N; - float3 dPdx = sd->dP.dx; - float3 dPdy = sd->dP.dy; + float3 dPdx = sd->dP.dx; + float3 dPdy = sd->dP.dy; - if(use_object_space) { - object_inverse_normal_transform(kg, sd, &normal_in); - object_inverse_dir_transform(kg, sd, &dPdx); - object_inverse_dir_transform(kg, sd, &dPdy); - } + if (use_object_space) { + object_inverse_normal_transform(kg, sd, &normal_in); + object_inverse_dir_transform(kg, sd, &dPdx); + object_inverse_dir_transform(kg, sd, &dPdy); + } - /* get surface tangents from normal */ - float3 Rx = cross(dPdy, normal_in); - float3 Ry = cross(normal_in, dPdx); + /* get surface tangents from normal */ + float3 Rx = cross(dPdy, normal_in); + float3 Ry = cross(normal_in, dPdx); - /* get bump values */ - uint c_offset, x_offset, y_offset, strength_offset; - decode_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset); + /* get bump values */ + uint c_offset, x_offset, y_offset, strength_offset; + decode_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset); - float h_c = stack_load_float(stack, c_offset); - float h_x = stack_load_float(stack, x_offset); - float h_y = stack_load_float(stack, y_offset); + float h_c = stack_load_float(stack, c_offset); + float h_x = stack_load_float(stack, x_offset); + float h_y = stack_load_float(stack, y_offset); - /* compute surface gradient and determinant */ - float det = dot(dPdx, Rx); - float3 surfgrad = (h_x - h_c)*Rx + (h_y - h_c)*Ry; + /* compute surface gradient and determinant */ + float det = dot(dPdx, Rx); + float3 surfgrad = (h_x - h_c) * Rx + (h_y - h_c) * Ry; - float absdet = fabsf(det); + float absdet = fabsf(det); - float strength = stack_load_float(stack, strength_offset); - float scale = stack_load_float(stack, scale_offset); + float strength = stack_load_float(stack, strength_offset); + float scale = stack_load_float(stack, scale_offset); - if(invert) - scale *= -1.0f; + if (invert) + scale *= -1.0f; - strength = max(strength, 0.0f); + strength = max(strength, 0.0f); - /* compute and output perturbed normal */ - float3 normal_out = safe_normalize(absdet*normal_in - scale*signf(det)*surfgrad); - if(is_zero(normal_out)) { - normal_out = normal_in; - } - else { - normal_out = normalize(strength*normal_out + (1.0f - strength)*normal_in); - } + /* compute and output perturbed normal */ + float3 normal_out = safe_normalize(absdet * normal_in - scale * signf(det) * surfgrad); + if (is_zero(normal_out)) { + normal_out = normal_in; + } + else { + normal_out = normalize(strength * normal_out + (1.0f - strength) * normal_in); + } - if(use_object_space) { - object_normal_transform(kg, sd, &normal_out); - } + if (use_object_space) { + object_normal_transform(kg, sd, &normal_out); + } - normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out); + normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out); - stack_store_float3(stack, node.w, normal_out); + stack_store_float3(stack, node.w, normal_out); #endif } /* Displacement Node */ -ccl_device void svm_node_set_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint fac_offset) +ccl_device void svm_node_set_displacement(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint fac_offset) { - float3 dP = stack_load_float3(stack, fac_offset); - sd->P += dP; + float3 dP = stack_load_float3(stack, fac_offset); + sd->P += dP; } ccl_device void svm_node_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - uint height_offset, midlevel_offset, scale_offset, normal_offset; - decode_node_uchar4(node.y, &height_offset, &midlevel_offset, &scale_offset, &normal_offset); - - float height = stack_load_float(stack, height_offset); - float midlevel = stack_load_float(stack, midlevel_offset); - float scale = stack_load_float(stack, scale_offset); - float3 normal = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N; - uint space = node.w; - - float3 dP = normal; - - if(space == NODE_NORMAL_MAP_OBJECT) { - /* Object space. */ - object_inverse_normal_transform(kg, sd, &dP); - dP *= (height - midlevel) * scale; - object_dir_transform(kg, sd, &dP); - } - else { - /* World space. */ - dP *= (height - midlevel) * scale; - } - - stack_store_float3(stack, node.z, dP); + uint height_offset, midlevel_offset, scale_offset, normal_offset; + decode_node_uchar4(node.y, &height_offset, &midlevel_offset, &scale_offset, &normal_offset); + + float height = stack_load_float(stack, height_offset); + float midlevel = stack_load_float(stack, midlevel_offset); + float scale = stack_load_float(stack, scale_offset); + float3 normal = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N; + uint space = node.w; + + float3 dP = normal; + + if (space == NODE_NORMAL_MAP_OBJECT) { + /* Object space. */ + object_inverse_normal_transform(kg, sd, &dP); + dP *= (height - midlevel) * scale; + object_dir_transform(kg, sd, &dP); + } + else { + /* World space. */ + dP *= (height - midlevel) * scale; + } + + stack_store_float3(stack, node.z, dP); } -ccl_device void svm_node_vector_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_vector_displacement( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint4 data_node = read_node(kg, offset); - uint space = data_node.x; - - uint vector_offset, midlevel_offset,scale_offset, displacement_offset; - decode_node_uchar4(node.y, &vector_offset, &midlevel_offset, &scale_offset, &displacement_offset); - - float3 vector = stack_load_float3(stack, vector_offset); - float midlevel = stack_load_float(stack, midlevel_offset); - float scale = stack_load_float(stack, scale_offset); - float3 dP = (vector - make_float3(midlevel, midlevel, midlevel)) * scale; - - if(space == NODE_NORMAL_MAP_TANGENT) { - /* Tangent space. */ - float3 normal = sd->N; - object_inverse_normal_transform(kg, sd, &normal); - - const AttributeDescriptor attr = find_attribute(kg, sd, node.z); - float3 tangent; - if(attr.offset != ATTR_STD_NOT_FOUND) { - tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL); - } - else { - tangent = normalize(sd->dPdu); - } - - float3 bitangent = normalize(cross(normal, tangent)); - const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w); - if(attr_sign.offset != ATTR_STD_NOT_FOUND) { - float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL); - bitangent *= sign; - } - - dP = tangent*dP.x + normal*dP.y + bitangent*dP.z; - } - - if(space != NODE_NORMAL_MAP_WORLD) { - /* Tangent or object space. */ - object_dir_transform(kg, sd, &dP); - } - - stack_store_float3(stack, displacement_offset, dP); + uint4 data_node = read_node(kg, offset); + uint space = data_node.x; + + uint vector_offset, midlevel_offset, scale_offset, displacement_offset; + decode_node_uchar4( + node.y, &vector_offset, &midlevel_offset, &scale_offset, &displacement_offset); + + float3 vector = stack_load_float3(stack, vector_offset); + float midlevel = stack_load_float(stack, midlevel_offset); + float scale = stack_load_float(stack, scale_offset); + float3 dP = (vector - make_float3(midlevel, midlevel, midlevel)) * scale; + + if (space == NODE_NORMAL_MAP_TANGENT) { + /* Tangent space. */ + float3 normal = sd->N; + object_inverse_normal_transform(kg, sd, &normal); + + const AttributeDescriptor attr = find_attribute(kg, sd, node.z); + float3 tangent; + if (attr.offset != ATTR_STD_NOT_FOUND) { + tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL); + } + else { + tangent = normalize(sd->dPdu); + } + + float3 bitangent = normalize(cross(normal, tangent)); + const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w); + if (attr_sign.offset != ATTR_STD_NOT_FOUND) { + float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL); + bitangent *= sign; + } + + dP = tangent * dP.x + normal * dP.y + bitangent * dP.z; + } + + if (space != NODE_NORMAL_MAP_WORLD) { + /* Tangent or object space. */ + object_dir_transform(kg, sd, &dP); + } + + stack_store_float3(stack, displacement_offset, dP); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_fresnel.h b/intern/cycles/kernel/svm/svm_fresnel.h index 99dda5fb170..03119991597 100644 --- a/intern/cycles/kernel/svm/svm_fresnel.h +++ b/intern/cycles/kernel/svm/svm_fresnel.h @@ -18,56 +18,60 @@ CCL_NAMESPACE_BEGIN /* Fresnel Node */ -ccl_device void svm_node_fresnel(ShaderData *sd, float *stack, uint ior_offset, uint ior_value, uint node) +ccl_device void svm_node_fresnel( + ShaderData *sd, float *stack, uint ior_offset, uint ior_value, uint node) { - uint normal_offset, out_offset; - decode_node_uchar4(node, &normal_offset, &out_offset, NULL, NULL); - float eta = (stack_valid(ior_offset))? stack_load_float(stack, ior_offset): __uint_as_float(ior_value); - float3 normal_in = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N; + uint normal_offset, out_offset; + decode_node_uchar4(node, &normal_offset, &out_offset, NULL, NULL); + float eta = (stack_valid(ior_offset)) ? stack_load_float(stack, ior_offset) : + __uint_as_float(ior_value); + float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N; - eta = fmaxf(eta, 1e-5f); - eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta; + eta = fmaxf(eta, 1e-5f); + eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; - float f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta); + float f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta); - stack_store_float(stack, out_offset, f); + stack_store_float(stack, out_offset, f); } /* Layer Weight Node */ ccl_device void svm_node_layer_weight(ShaderData *sd, float *stack, uint4 node) { - uint blend_offset = node.y; - uint blend_value = node.z; + uint blend_offset = node.y; + uint blend_value = node.z; - uint type, normal_offset, out_offset; - decode_node_uchar4(node.w, &type, &normal_offset, &out_offset, NULL); + uint type, normal_offset, out_offset; + decode_node_uchar4(node.w, &type, &normal_offset, &out_offset, NULL); - float blend = (stack_valid(blend_offset))? stack_load_float(stack, blend_offset): __uint_as_float(blend_value); - float3 normal_in = (stack_valid(normal_offset))? stack_load_float3(stack, normal_offset): sd->N; + float blend = (stack_valid(blend_offset)) ? stack_load_float(stack, blend_offset) : + __uint_as_float(blend_value); + float3 normal_in = (stack_valid(normal_offset)) ? stack_load_float3(stack, normal_offset) : + sd->N; - float f; + float f; - if(type == NODE_LAYER_WEIGHT_FRESNEL) { - float eta = fmaxf(1.0f - blend, 1e-5f); - eta = (sd->flag & SD_BACKFACING)? eta: 1.0f/eta; + if (type == NODE_LAYER_WEIGHT_FRESNEL) { + float eta = fmaxf(1.0f - blend, 1e-5f); + eta = (sd->flag & SD_BACKFACING) ? eta : 1.0f / eta; - f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta); - } - else { - f = fabsf(dot(sd->I, normal_in)); + f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta); + } + else { + f = fabsf(dot(sd->I, normal_in)); - if(blend != 0.5f) { - blend = clamp(blend, 0.0f, 1.0f-1e-5f); - blend = (blend < 0.5f)? 2.0f*blend: 0.5f/(1.0f - blend); + if (blend != 0.5f) { + blend = clamp(blend, 0.0f, 1.0f - 1e-5f); + blend = (blend < 0.5f) ? 2.0f * blend : 0.5f / (1.0f - blend); - f = powf(f, blend); - } + f = powf(f, blend); + } - f = 1.0f - f; - } + f = 1.0f - f; + } - stack_store_float(stack, out_offset, f); + stack_store_float(stack, out_offset, f); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_gamma.h b/intern/cycles/kernel/svm/svm_gamma.h index 171945a60bc..65eb08eb0eb 100644 --- a/intern/cycles/kernel/svm/svm_gamma.h +++ b/intern/cycles/kernel/svm/svm_gamma.h @@ -16,15 +16,16 @@ CCL_NAMESPACE_BEGIN -ccl_device void svm_node_gamma(ShaderData *sd, float *stack, uint in_gamma, uint in_color, uint out_color) +ccl_device void svm_node_gamma( + ShaderData *sd, float *stack, uint in_gamma, uint in_color, uint out_color) { - float3 color = stack_load_float3(stack, in_color); - float gamma = stack_load_float(stack, in_gamma); + float3 color = stack_load_float3(stack, in_color); + float gamma = stack_load_float(stack, in_gamma); - color = svm_math_gamma_color(color, gamma); + color = svm_math_gamma_color(color, gamma); - if(stack_valid(out_color)) - stack_store_float3(stack, out_color, color); + if (stack_valid(out_color)) + stack_store_float3(stack, out_color, color); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 05443772505..a9104643299 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -18,192 +18,217 @@ CCL_NAMESPACE_BEGIN /* Geometry Node */ -ccl_device_inline void svm_node_geometry(KernelGlobals *kg, - ShaderData *sd, - float *stack, - uint type, - uint out_offset) +ccl_device_inline void svm_node_geometry( + KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { - float3 data; - - switch(type) { - case NODE_GEOM_P: data = sd->P; break; - case NODE_GEOM_N: data = sd->N; break; + float3 data; + + switch (type) { + case NODE_GEOM_P: + data = sd->P; + break; + case NODE_GEOM_N: + data = sd->N; + break; #ifdef __DPDU__ - case NODE_GEOM_T: data = primitive_tangent(kg, sd); break; + case NODE_GEOM_T: + data = primitive_tangent(kg, sd); + break; #endif - case NODE_GEOM_I: data = sd->I; break; - case NODE_GEOM_Ng: data = sd->Ng; break; + case NODE_GEOM_I: + data = sd->I; + break; + case NODE_GEOM_Ng: + data = sd->Ng; + break; #ifdef __UV__ - case NODE_GEOM_uv: data = make_float3(sd->u, sd->v, 0.0f); break; + case NODE_GEOM_uv: + data = make_float3(sd->u, sd->v, 0.0f); + break; #endif - default: data = make_float3(0.0f, 0.0f, 0.0f); - } + default: + data = make_float3(0.0f, 0.0f, 0.0f); + } - stack_store_float3(stack, out_offset, data); + stack_store_float3(stack, out_offset, data); } -ccl_device void svm_node_geometry_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) +ccl_device void svm_node_geometry_bump_dx( + KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { #ifdef __RAY_DIFFERENTIALS__ - float3 data; - - switch(type) { - case NODE_GEOM_P: data = sd->P + sd->dP.dx; break; - case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dx, sd->v + sd->dv.dx, 0.0f); break; - default: svm_node_geometry(kg, sd, stack, type, out_offset); return; - } - - stack_store_float3(stack, out_offset, data); + float3 data; + + switch (type) { + case NODE_GEOM_P: + data = sd->P + sd->dP.dx; + break; + case NODE_GEOM_uv: + data = make_float3(sd->u + sd->du.dx, sd->v + sd->dv.dx, 0.0f); + break; + default: + svm_node_geometry(kg, sd, stack, type, out_offset); + return; + } + + stack_store_float3(stack, out_offset, data); #else - svm_node_geometry(kg, sd, stack, type, out_offset); + svm_node_geometry(kg, sd, stack, type, out_offset); #endif } -ccl_device void svm_node_geometry_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) +ccl_device void svm_node_geometry_bump_dy( + KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { #ifdef __RAY_DIFFERENTIALS__ - float3 data; - - switch(type) { - case NODE_GEOM_P: data = sd->P + sd->dP.dy; break; - case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dy, sd->v + sd->dv.dy, 0.0f); break; - default: svm_node_geometry(kg, sd, stack, type, out_offset); return; - } - - stack_store_float3(stack, out_offset, data); + float3 data; + + switch (type) { + case NODE_GEOM_P: + data = sd->P + sd->dP.dy; + break; + case NODE_GEOM_uv: + data = make_float3(sd->u + sd->du.dy, sd->v + sd->dv.dy, 0.0f); + break; + default: + svm_node_geometry(kg, sd, stack, type, out_offset); + return; + } + + stack_store_float3(stack, out_offset, data); #else - svm_node_geometry(kg, sd, stack, type, out_offset); + svm_node_geometry(kg, sd, stack, type, out_offset); #endif } /* Object Info */ -ccl_device void svm_node_object_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) +ccl_device void svm_node_object_info( + KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { - float data; - - switch(type) { - case NODE_INFO_OB_LOCATION: { - stack_store_float3(stack, out_offset, object_location(kg, sd)); - return; - } - case NODE_INFO_OB_INDEX: data = object_pass_id(kg, sd->object); break; - case NODE_INFO_MAT_INDEX: data = shader_pass_id(kg, sd); break; - case NODE_INFO_OB_RANDOM: { - if(sd->lamp != LAMP_NONE) { - data = lamp_random_number(kg, sd->lamp); - } - else { - data = object_random_number(kg, sd->object); - } - break; - } - default: data = 0.0f; break; - } - - stack_store_float(stack, out_offset, data); + float data; + + switch (type) { + case NODE_INFO_OB_LOCATION: { + stack_store_float3(stack, out_offset, object_location(kg, sd)); + return; + } + case NODE_INFO_OB_INDEX: + data = object_pass_id(kg, sd->object); + break; + case NODE_INFO_MAT_INDEX: + data = shader_pass_id(kg, sd); + break; + case NODE_INFO_OB_RANDOM: { + if (sd->lamp != LAMP_NONE) { + data = lamp_random_number(kg, sd->lamp); + } + else { + data = object_random_number(kg, sd->object); + } + break; + } + default: + data = 0.0f; + break; + } + + stack_store_float(stack, out_offset, data); } /* Particle Info */ -ccl_device void svm_node_particle_info(KernelGlobals *kg, - ShaderData *sd, - float *stack, - uint type, - uint out_offset) +ccl_device void svm_node_particle_info( + KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { - switch(type) { - case NODE_INFO_PAR_INDEX: { - int particle_id = object_particle_id(kg, sd->object); - stack_store_float(stack, out_offset, particle_index(kg, particle_id)); - break; - } - case NODE_INFO_PAR_RANDOM: { - int particle_id = object_particle_id(kg, sd->object); - float random = hash_int_01(particle_index(kg, particle_id)); - stack_store_float(stack, out_offset, random); - break; - } - case NODE_INFO_PAR_AGE: { - int particle_id = object_particle_id(kg, sd->object); - stack_store_float(stack, out_offset, particle_age(kg, particle_id)); - break; - } - case NODE_INFO_PAR_LIFETIME: { - int particle_id = object_particle_id(kg, sd->object); - stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id)); - break; - } - case NODE_INFO_PAR_LOCATION: { - int particle_id = object_particle_id(kg, sd->object); - stack_store_float3(stack, out_offset, particle_location(kg, particle_id)); - break; - } -#if 0 /* XXX float4 currently not supported in SVM stack */ - case NODE_INFO_PAR_ROTATION: { - int particle_id = object_particle_id(kg, sd->object); - stack_store_float4(stack, out_offset, particle_rotation(kg, particle_id)); - break; - } + switch (type) { + case NODE_INFO_PAR_INDEX: { + int particle_id = object_particle_id(kg, sd->object); + stack_store_float(stack, out_offset, particle_index(kg, particle_id)); + break; + } + case NODE_INFO_PAR_RANDOM: { + int particle_id = object_particle_id(kg, sd->object); + float random = hash_int_01(particle_index(kg, particle_id)); + stack_store_float(stack, out_offset, random); + break; + } + case NODE_INFO_PAR_AGE: { + int particle_id = object_particle_id(kg, sd->object); + stack_store_float(stack, out_offset, particle_age(kg, particle_id)); + break; + } + case NODE_INFO_PAR_LIFETIME: { + int particle_id = object_particle_id(kg, sd->object); + stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id)); + break; + } + case NODE_INFO_PAR_LOCATION: { + int particle_id = object_particle_id(kg, sd->object); + stack_store_float3(stack, out_offset, particle_location(kg, particle_id)); + break; + } +#if 0 /* XXX float4 currently not supported in SVM stack */ + case NODE_INFO_PAR_ROTATION: { + int particle_id = object_particle_id(kg, sd->object); + stack_store_float4(stack, out_offset, particle_rotation(kg, particle_id)); + break; + } #endif - case NODE_INFO_PAR_SIZE: { - int particle_id = object_particle_id(kg, sd->object); - stack_store_float(stack, out_offset, particle_size(kg, particle_id)); - break; - } - case NODE_INFO_PAR_VELOCITY: { - int particle_id = object_particle_id(kg, sd->object); - stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id)); - break; - } - case NODE_INFO_PAR_ANGULAR_VELOCITY: { - int particle_id = object_particle_id(kg, sd->object); - stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id)); - break; - } - } + case NODE_INFO_PAR_SIZE: { + int particle_id = object_particle_id(kg, sd->object); + stack_store_float(stack, out_offset, particle_size(kg, particle_id)); + break; + } + case NODE_INFO_PAR_VELOCITY: { + int particle_id = object_particle_id(kg, sd->object); + stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id)); + break; + } + case NODE_INFO_PAR_ANGULAR_VELOCITY: { + int particle_id = object_particle_id(kg, sd->object); + stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id)); + break; + } + } } #ifdef __HAIR__ /* Hair Info */ -ccl_device void svm_node_hair_info(KernelGlobals *kg, - ShaderData *sd, - float *stack, - uint type, - uint out_offset) +ccl_device void svm_node_hair_info( + KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { - float data; - float3 data3; - - switch(type) { - case NODE_INFO_CURVE_IS_STRAND: { - data = (sd->type & PRIMITIVE_ALL_CURVE) != 0; - stack_store_float(stack, out_offset, data); - break; - } - case NODE_INFO_CURVE_INTERCEPT: - break; /* handled as attribute */ - case NODE_INFO_CURVE_RANDOM: - break; /* handled as attribute */ - case NODE_INFO_CURVE_THICKNESS: { - data = curve_thickness(kg, sd); - stack_store_float(stack, out_offset, data); - break; - } - /*case NODE_INFO_CURVE_FADE: { - data = sd->curve_transparency; - stack_store_float(stack, out_offset, data); - break; - }*/ - case NODE_INFO_CURVE_TANGENT_NORMAL: { - data3 = curve_tangent_normal(kg, sd); - stack_store_float3(stack, out_offset, data3); - break; - } - } + float data; + float3 data3; + + switch (type) { + case NODE_INFO_CURVE_IS_STRAND: { + data = (sd->type & PRIMITIVE_ALL_CURVE) != 0; + stack_store_float(stack, out_offset, data); + break; + } + case NODE_INFO_CURVE_INTERCEPT: + break; /* handled as attribute */ + case NODE_INFO_CURVE_RANDOM: + break; /* handled as attribute */ + case NODE_INFO_CURVE_THICKNESS: { + data = curve_thickness(kg, sd); + stack_store_float(stack, out_offset, data); + break; + } + /*case NODE_INFO_CURVE_FADE: { + data = sd->curve_transparency; + stack_store_float(stack, out_offset, data); + break; + }*/ + case NODE_INFO_CURVE_TANGENT_NORMAL: { + data3 = curve_tangent_normal(kg, sd); + stack_store_float3(stack, out_offset, data3); + break; + } + } } #endif diff --git a/intern/cycles/kernel/svm/svm_gradient.h b/intern/cycles/kernel/svm/svm_gradient.h index 177e0506dee..c315564fbc2 100644 --- a/intern/cycles/kernel/svm/svm_gradient.h +++ b/intern/cycles/kernel/svm/svm_gradient.h @@ -20,61 +20,61 @@ CCL_NAMESPACE_BEGIN ccl_device float svm_gradient(float3 p, NodeGradientType type) { - float x, y, z; + float x, y, z; - x = p.x; - y = p.y; - z = p.z; + x = p.x; + y = p.y; + z = p.z; - if(type == NODE_BLEND_LINEAR) { - return x; - } - else if(type == NODE_BLEND_QUADRATIC) { - float r = fmaxf(x, 0.0f); - return r*r; - } - else if(type == NODE_BLEND_EASING) { - float r = fminf(fmaxf(x, 0.0f), 1.0f); - float t = r*r; + if (type == NODE_BLEND_LINEAR) { + return x; + } + else if (type == NODE_BLEND_QUADRATIC) { + float r = fmaxf(x, 0.0f); + return r * r; + } + else if (type == NODE_BLEND_EASING) { + float r = fminf(fmaxf(x, 0.0f), 1.0f); + float t = r * r; - return (3.0f*t - 2.0f*t*r); - } - else if(type == NODE_BLEND_DIAGONAL) { - return (x + y) * 0.5f; - } - else if(type == NODE_BLEND_RADIAL) { - return atan2f(y, x) / M_2PI_F + 0.5f; - } - else { - /* Bias a little bit for the case where p is a unit length vector, - * to get exactly zero instead of a small random value depending - * on float precision. */ - float r = fmaxf(0.999999f - sqrtf(x*x + y*y + z*z), 0.0f); + return (3.0f * t - 2.0f * t * r); + } + else if (type == NODE_BLEND_DIAGONAL) { + return (x + y) * 0.5f; + } + else if (type == NODE_BLEND_RADIAL) { + return atan2f(y, x) / M_2PI_F + 0.5f; + } + else { + /* Bias a little bit for the case where p is a unit length vector, + * to get exactly zero instead of a small random value depending + * on float precision. */ + float r = fmaxf(0.999999f - sqrtf(x * x + y * y + z * z), 0.0f); - if(type == NODE_BLEND_QUADRATIC_SPHERE) - return r*r; - else if(type == NODE_BLEND_SPHERICAL) - return r; - } + if (type == NODE_BLEND_QUADRATIC_SPHERE) + return r * r; + else if (type == NODE_BLEND_SPHERICAL) + return r; + } - return 0.0f; + return 0.0f; } ccl_device void svm_node_tex_gradient(ShaderData *sd, float *stack, uint4 node) { - uint type, co_offset, color_offset, fac_offset; + uint type, co_offset, color_offset, fac_offset; - decode_node_uchar4(node.y, &type, &co_offset, &fac_offset, &color_offset); + decode_node_uchar4(node.y, &type, &co_offset, &fac_offset, &color_offset); - float3 co = stack_load_float3(stack, co_offset); + float3 co = stack_load_float3(stack, co_offset); - float f = svm_gradient(co, (NodeGradientType)type); - f = saturate(f); + float f = svm_gradient(co, (NodeGradientType)type); + f = saturate(f); - if(stack_valid(fac_offset)) - stack_store_float(stack, fac_offset, f); - if(stack_valid(color_offset)) - stack_store_float3(stack, color_offset, make_float3(f, f, f)); + if (stack_valid(fac_offset)) + stack_store_float(stack, fac_offset, f); + if (stack_valid(color_offset)) + stack_store_float3(stack, color_offset, make_float3(f, f, f)); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_hsv.h b/intern/cycles/kernel/svm/svm_hsv.h index 6f3efa639e2..72379fba870 100644 --- a/intern/cycles/kernel/svm/svm_hsv.h +++ b/intern/cycles/kernel/svm/svm_hsv.h @@ -19,43 +19,44 @@ CCL_NAMESPACE_BEGIN -ccl_device void svm_node_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_hsv( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint in_color_offset, fac_offset, out_color_offset; - uint hue_offset, sat_offset, val_offset; - decode_node_uchar4(node.y, &in_color_offset, &fac_offset, &out_color_offset, NULL); - decode_node_uchar4(node.z, &hue_offset, &sat_offset, &val_offset, NULL); + uint in_color_offset, fac_offset, out_color_offset; + uint hue_offset, sat_offset, val_offset; + decode_node_uchar4(node.y, &in_color_offset, &fac_offset, &out_color_offset, NULL); + decode_node_uchar4(node.z, &hue_offset, &sat_offset, &val_offset, NULL); - float fac = stack_load_float(stack, fac_offset); - float3 in_color = stack_load_float3(stack, in_color_offset); - float3 color = in_color; + float fac = stack_load_float(stack, fac_offset); + float3 in_color = stack_load_float3(stack, in_color_offset); + float3 color = in_color; - float hue = stack_load_float(stack, hue_offset); - float sat = stack_load_float(stack, sat_offset); - float val = stack_load_float(stack, val_offset); + float hue = stack_load_float(stack, hue_offset); + float sat = stack_load_float(stack, sat_offset); + float val = stack_load_float(stack, val_offset); - color = rgb_to_hsv(color); + color = rgb_to_hsv(color); - /* remember: fmod doesn't work for negative numbers here */ - color.x = fmodf(color.x + hue + 0.5f, 1.0f); - color.y = saturate(color.y * sat); - color.z *= val; + /* remember: fmod doesn't work for negative numbers here */ + color.x = fmodf(color.x + hue + 0.5f, 1.0f); + color.y = saturate(color.y * sat); + color.z *= val; - color = hsv_to_rgb(color); + color = hsv_to_rgb(color); - color.x = fac*color.x + (1.0f - fac)*in_color.x; - color.y = fac*color.y + (1.0f - fac)*in_color.y; - color.z = fac*color.z + (1.0f - fac)*in_color.z; + color.x = fac * color.x + (1.0f - fac) * in_color.x; + color.y = fac * color.y + (1.0f - fac) * in_color.y; + color.z = fac * color.z + (1.0f - fac) * in_color.z; - /* Clamp color to prevent negative values caused by oversaturation. */ - color.x = max(color.x, 0.0f); - color.y = max(color.y, 0.0f); - color.z = max(color.z, 0.0f); + /* Clamp color to prevent negative values caused by oversaturation. */ + color.x = max(color.x, 0.0f); + color.y = max(color.y, 0.0f); + color.z = max(color.z, 0.0f); - if(stack_valid(out_color_offset)) - stack_store_float3(stack, out_color_offset, color); + if (stack_valid(out_color_offset)) + stack_store_float3(stack, out_color_offset, color); } CCL_NAMESPACE_END -#endif /* __SVM_HSV_H__ */ +#endif /* __SVM_HSV_H__ */ diff --git a/intern/cycles/kernel/svm/svm_ies.h b/intern/cycles/kernel/svm/svm_ies.h index 6130c3348b0..9434c0c5505 100644 --- a/intern/cycles/kernel/svm/svm_ies.h +++ b/intern/cycles/kernel/svm/svm_ies.h @@ -18,93 +18,102 @@ CCL_NAMESPACE_BEGIN /* IES Light */ -ccl_device_inline float interpolate_ies_vertical(KernelGlobals *kg, int ofs, int v, int v_num, float v_frac, int h) +ccl_device_inline float interpolate_ies_vertical( + KernelGlobals *kg, int ofs, int v, int v_num, float v_frac, int h) { - /* Since lookups are performed in spherical coordinates, clamping the coordinates at the low end of v - * (corresponding to the north pole) would result in artifacts. - * The proper way of dealing with this would be to lookup the corresponding value on the other side of the pole, - * but since the horizontal coordinates might be nonuniform, this would require yet another interpolation. - * Therefore, the assumtion is made that the light is going to be symmetrical, which means that we can just take - * the corresponding value at the current horizontal coordinate. */ - -#define IES_LOOKUP(v) kernel_tex_fetch(__ies, ofs+h*v_num+(v)) - /* If v is zero, assume symmetry and read at v=1 instead of v=-1. */ - float a = IES_LOOKUP((v == 0)? 1 : v-1); - float b = IES_LOOKUP(v); - float c = IES_LOOKUP(v+1); - float d = IES_LOOKUP(min(v+2, v_num-1)); + /* Since lookups are performed in spherical coordinates, clamping the coordinates at the low end of v + * (corresponding to the north pole) would result in artifacts. + * The proper way of dealing with this would be to lookup the corresponding value on the other side of the pole, + * but since the horizontal coordinates might be nonuniform, this would require yet another interpolation. + * Therefore, the assumtion is made that the light is going to be symmetrical, which means that we can just take + * the corresponding value at the current horizontal coordinate. */ + +#define IES_LOOKUP(v) kernel_tex_fetch(__ies, ofs + h * v_num + (v)) + /* If v is zero, assume symmetry and read at v=1 instead of v=-1. */ + float a = IES_LOOKUP((v == 0) ? 1 : v - 1); + float b = IES_LOOKUP(v); + float c = IES_LOOKUP(v + 1); + float d = IES_LOOKUP(min(v + 2, v_num - 1)); #undef IES_LOOKUP - return cubic_interp(a, b, c, d, v_frac); + return cubic_interp(a, b, c, d, v_frac); } -ccl_device_inline float kernel_ies_interp(KernelGlobals *kg, int slot, float h_angle, float v_angle) +ccl_device_inline float kernel_ies_interp(KernelGlobals *kg, + int slot, + float h_angle, + float v_angle) { - /* Find offset of the IES data in the table. */ - int ofs = __float_as_int(kernel_tex_fetch(__ies, slot)); - if(ofs == -1) { - return 100.0f; - } - - int h_num = __float_as_int(kernel_tex_fetch(__ies, ofs++)); - int v_num = __float_as_int(kernel_tex_fetch(__ies, ofs++)); - -#define IES_LOOKUP_ANGLE_H(h) kernel_tex_fetch(__ies, ofs+(h)) -#define IES_LOOKUP_ANGLE_V(v) kernel_tex_fetch(__ies, ofs+h_num+(v)) - - /* Check whether the angle is within the bounds of the IES texture. */ - if(v_angle >= IES_LOOKUP_ANGLE_V(v_num-1)) { - return 0.0f; - } - kernel_assert(v_angle >= IES_LOOKUP_ANGLE_V(0)); - kernel_assert(h_angle >= IES_LOOKUP_ANGLE_H(0)); - kernel_assert(h_angle <= IES_LOOKUP_ANGLE_H(h_num-1)); - - /* Lookup the angles to find the table position. */ - int h_i, v_i; - /* TODO(lukas): Consider using bisection. Probably not worth it for the vast majority of IES files. */ - for(h_i = 0; IES_LOOKUP_ANGLE_H(h_i+1) < h_angle; h_i++); - for(v_i = 0; IES_LOOKUP_ANGLE_V(v_i+1) < v_angle; v_i++); - - float h_frac = inverse_lerp(IES_LOOKUP_ANGLE_H(h_i), IES_LOOKUP_ANGLE_H(h_i+1), h_angle); - float v_frac = inverse_lerp(IES_LOOKUP_ANGLE_V(v_i), IES_LOOKUP_ANGLE_V(v_i+1), v_angle); + /* Find offset of the IES data in the table. */ + int ofs = __float_as_int(kernel_tex_fetch(__ies, slot)); + if (ofs == -1) { + return 100.0f; + } + + int h_num = __float_as_int(kernel_tex_fetch(__ies, ofs++)); + int v_num = __float_as_int(kernel_tex_fetch(__ies, ofs++)); + +#define IES_LOOKUP_ANGLE_H(h) kernel_tex_fetch(__ies, ofs + (h)) +#define IES_LOOKUP_ANGLE_V(v) kernel_tex_fetch(__ies, ofs + h_num + (v)) + + /* Check whether the angle is within the bounds of the IES texture. */ + if (v_angle >= IES_LOOKUP_ANGLE_V(v_num - 1)) { + return 0.0f; + } + kernel_assert(v_angle >= IES_LOOKUP_ANGLE_V(0)); + kernel_assert(h_angle >= IES_LOOKUP_ANGLE_H(0)); + kernel_assert(h_angle <= IES_LOOKUP_ANGLE_H(h_num - 1)); + + /* Lookup the angles to find the table position. */ + int h_i, v_i; + /* TODO(lukas): Consider using bisection. Probably not worth it for the vast majority of IES files. */ + for (h_i = 0; IES_LOOKUP_ANGLE_H(h_i + 1) < h_angle; h_i++) + ; + for (v_i = 0; IES_LOOKUP_ANGLE_V(v_i + 1) < v_angle; v_i++) + ; + + float h_frac = inverse_lerp(IES_LOOKUP_ANGLE_H(h_i), IES_LOOKUP_ANGLE_H(h_i + 1), h_angle); + float v_frac = inverse_lerp(IES_LOOKUP_ANGLE_V(v_i), IES_LOOKUP_ANGLE_V(v_i + 1), v_angle); #undef IES_LOOKUP_ANGLE_H #undef IES_LOOKUP_ANGLE_V - /* Skip forward to the actual intensity data. */ - ofs += h_num+v_num; - - /* Perform cubic interpolation along the horizontal coordinate to get the intensity value. - * If h_i is zero, just wrap around since the horizontal angles always go over the full circle. - * However, the last entry (360°) equals the first one, so we need to wrap around to the one before that. */ - float a = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, (h_i == 0)? h_num-2 : h_i-1); - float b = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, h_i); - float c = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, h_i+1); - /* Same logic here, wrap around to the second element if necessary. */ - float d = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, (h_i+2 == h_num)? 1 : h_i+2); - - /* Cubic interpolation can result in negative values, so get rid of them. */ - return max(cubic_interp(a, b, c, d, h_frac), 0.0f); + /* Skip forward to the actual intensity data. */ + ofs += h_num + v_num; + + /* Perform cubic interpolation along the horizontal coordinate to get the intensity value. + * If h_i is zero, just wrap around since the horizontal angles always go over the full circle. + * However, the last entry (360°) equals the first one, so we need to wrap around to the one before that. */ + float a = interpolate_ies_vertical( + kg, ofs, v_i, v_num, v_frac, (h_i == 0) ? h_num - 2 : h_i - 1); + float b = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, h_i); + float c = interpolate_ies_vertical(kg, ofs, v_i, v_num, v_frac, h_i + 1); + /* Same logic here, wrap around to the second element if necessary. */ + float d = interpolate_ies_vertical( + kg, ofs, v_i, v_num, v_frac, (h_i + 2 == h_num) ? 1 : h_i + 2); + + /* Cubic interpolation can result in negative values, so get rid of them. */ + return max(cubic_interp(a, b, c, d, h_frac), 0.0f); } -ccl_device void svm_node_ies(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_ies( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint vector_offset, strength_offset, fac_offset, dummy, slot = node.z; - decode_node_uchar4(node.y, &strength_offset, &vector_offset, &fac_offset, &dummy); + uint vector_offset, strength_offset, fac_offset, dummy, slot = node.z; + decode_node_uchar4(node.y, &strength_offset, &vector_offset, &fac_offset, &dummy); - float3 vector = stack_load_float3(stack, vector_offset); - float strength = stack_load_float_default(stack, strength_offset, node.w); + float3 vector = stack_load_float3(stack, vector_offset); + float strength = stack_load_float_default(stack, strength_offset, node.w); - vector = normalize(vector); - float v_angle = safe_acosf(-vector.z); - float h_angle = atan2f(vector.x, vector.y) + M_PI_F; + vector = normalize(vector); + float v_angle = safe_acosf(-vector.z); + float h_angle = atan2f(vector.x, vector.y) + M_PI_F; - float fac = strength * kernel_ies_interp(kg, slot, h_angle, v_angle); + float fac = strength * kernel_ies_interp(kg, slot, h_angle, v_angle); - if(stack_valid(fac_offset)) { - stack_store_float(stack, fac_offset, fac); - } + if (stack_valid(fac_offset)) { + stack_store_float(stack, fac_offset, fac); + } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index 81ee79c984e..ee4b8b6e50c 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -16,190 +16,192 @@ CCL_NAMESPACE_BEGIN -ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha) +ccl_device float4 +svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha) { - float4 r = kernel_tex_image_interp(kg, id, x, y); - const float alpha = r.w; - - if(use_alpha && alpha != 1.0f && alpha != 0.0f) { - r /= alpha; - const int texture_type = kernel_tex_type(id); - if(texture_type == IMAGE_DATA_TYPE_BYTE4 || - texture_type == IMAGE_DATA_TYPE_BYTE) - { - r = min(r, make_float4(1.0f, 1.0f, 1.0f, 1.0f)); - } - r.w = alpha; - } - - if(srgb) { - /* TODO(lukas): Implement proper conversion for image textures. */ - r = color_srgb_to_linear_v4(r); - } - - return r; + float4 r = kernel_tex_image_interp(kg, id, x, y); + const float alpha = r.w; + + if (use_alpha && alpha != 1.0f && alpha != 0.0f) { + r /= alpha; + const int texture_type = kernel_tex_type(id); + if (texture_type == IMAGE_DATA_TYPE_BYTE4 || texture_type == IMAGE_DATA_TYPE_BYTE) { + r = min(r, make_float4(1.0f, 1.0f, 1.0f, 1.0f)); + } + r.w = alpha; + } + + if (srgb) { + /* TODO(lukas): Implement proper conversion for image textures. */ + r = color_srgb_to_linear_v4(r); + } + + return r; } /* Remap coordnate from 0..1 box to -1..-1 */ ccl_device_inline float3 texco_remap_square(float3 co) { - return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f; + return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f; } ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - uint id = node.y; - uint co_offset, out_offset, alpha_offset, srgb; - - decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); - - float3 co = stack_load_float3(stack, co_offset); - float2 tex_co; - uint use_alpha = stack_valid(alpha_offset); - if(node.w == NODE_IMAGE_PROJ_SPHERE) { - co = texco_remap_square(co); - tex_co = map_to_sphere(co); - } - else if(node.w == NODE_IMAGE_PROJ_TUBE) { - co = texco_remap_square(co); - tex_co = map_to_tube(co); - } - else { - tex_co = make_float2(co.x, co.y); - } - float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, srgb, use_alpha); - - if(stack_valid(out_offset)) - stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); - if(stack_valid(alpha_offset)) - stack_store_float(stack, alpha_offset, f.w); + uint id = node.y; + uint co_offset, out_offset, alpha_offset, srgb; + + decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); + + float3 co = stack_load_float3(stack, co_offset); + float2 tex_co; + uint use_alpha = stack_valid(alpha_offset); + if (node.w == NODE_IMAGE_PROJ_SPHERE) { + co = texco_remap_square(co); + tex_co = map_to_sphere(co); + } + else if (node.w == NODE_IMAGE_PROJ_TUBE) { + co = texco_remap_square(co); + tex_co = map_to_tube(co); + } + else { + tex_co = make_float2(co.x, co.y); + } + float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, srgb, use_alpha); + + if (stack_valid(out_offset)) + stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); + if (stack_valid(alpha_offset)) + stack_store_float(stack, alpha_offset, f.w); } ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - /* get object space normal */ - float3 N = sd->N; - - N = sd->N; - object_inverse_normal_transform(kg, sd, &N); - - /* project from direction vector to barycentric coordinates in triangles */ - float3 signed_N = N; - - N.x = fabsf(N.x); - N.y = fabsf(N.y); - N.z = fabsf(N.z); - - N /= (N.x + N.y + N.z); - - /* basic idea is to think of this as a triangle, each corner representing - * one of the 3 faces of the cube. in the corners we have single textures, - * in between we blend between two textures, and in the middle we a blend - * between three textures. - * - * the Nxyz values are the barycentric coordinates in an equilateral - * triangle, which in case of blending, in the middle has a smaller - * equilateral triangle where 3 textures blend. this divides things into - * 7 zones, with an if() test for each zone */ - - float3 weight = make_float3(0.0f, 0.0f, 0.0f); - float blend = __int_as_float(node.w); - float limit = 0.5f*(1.0f + blend); - - /* first test for corners with single texture */ - if(N.x > limit*(N.x + N.y) && N.x > limit*(N.x + N.z)) { - weight.x = 1.0f; - } - else if(N.y > limit*(N.x + N.y) && N.y > limit*(N.y + N.z)) { - weight.y = 1.0f; - } - else if(N.z > limit*(N.x + N.z) && N.z > limit*(N.y + N.z)) { - weight.z = 1.0f; - } - else if(blend > 0.0f) { - /* in case of blending, test for mixes between two textures */ - if(N.z < (1.0f - limit)*(N.y + N.x)) { - weight.x = N.x/(N.x + N.y); - weight.x = saturate((weight.x - 0.5f*(1.0f - blend))/blend); - weight.y = 1.0f - weight.x; - } - else if(N.x < (1.0f - limit)*(N.y + N.z)) { - weight.y = N.y/(N.y + N.z); - weight.y = saturate((weight.y - 0.5f*(1.0f - blend))/blend); - weight.z = 1.0f - weight.y; - } - else if(N.y < (1.0f - limit)*(N.x + N.z)) { - weight.x = N.x/(N.x + N.z); - weight.x = saturate((weight.x - 0.5f*(1.0f - blend))/blend); - weight.z = 1.0f - weight.x; - } - else { - /* last case, we have a mix between three */ - weight.x = ((2.0f - limit)*N.x + (limit - 1.0f))/(2.0f*limit - 1.0f); - weight.y = ((2.0f - limit)*N.y + (limit - 1.0f))/(2.0f*limit - 1.0f); - weight.z = ((2.0f - limit)*N.z + (limit - 1.0f))/(2.0f*limit - 1.0f); - } - } - else { - /* Desperate mode, no valid choice anyway, fallback to one side.*/ - weight.x = 1.0f; - } - - /* now fetch textures */ - uint co_offset, out_offset, alpha_offset, srgb; - decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); - - float3 co = stack_load_float3(stack, co_offset); - uint id = node.y; - - float4 f = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - uint use_alpha = stack_valid(alpha_offset); - - /* Map so that no textures are flipped, rotation is somewhat arbitrary. */ - if(weight.x > 0.0f) { - float2 uv = make_float2((signed_N.x < 0.0f)? 1.0f - co.y: co.y, co.z); - f += weight.x*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); - } - if(weight.y > 0.0f) { - float2 uv = make_float2((signed_N.y > 0.0f)? 1.0f - co.x: co.x, co.z); - f += weight.y*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); - } - if(weight.z > 0.0f) { - float2 uv = make_float2((signed_N.z > 0.0f)? 1.0f - co.y: co.y, co.x); - f += weight.z*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); - } - - if(stack_valid(out_offset)) - stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); - if(stack_valid(alpha_offset)) - stack_store_float(stack, alpha_offset, f.w); + /* get object space normal */ + float3 N = sd->N; + + N = sd->N; + object_inverse_normal_transform(kg, sd, &N); + + /* project from direction vector to barycentric coordinates in triangles */ + float3 signed_N = N; + + N.x = fabsf(N.x); + N.y = fabsf(N.y); + N.z = fabsf(N.z); + + N /= (N.x + N.y + N.z); + + /* basic idea is to think of this as a triangle, each corner representing + * one of the 3 faces of the cube. in the corners we have single textures, + * in between we blend between two textures, and in the middle we a blend + * between three textures. + * + * the Nxyz values are the barycentric coordinates in an equilateral + * triangle, which in case of blending, in the middle has a smaller + * equilateral triangle where 3 textures blend. this divides things into + * 7 zones, with an if() test for each zone */ + + float3 weight = make_float3(0.0f, 0.0f, 0.0f); + float blend = __int_as_float(node.w); + float limit = 0.5f * (1.0f + blend); + + /* first test for corners with single texture */ + if (N.x > limit * (N.x + N.y) && N.x > limit * (N.x + N.z)) { + weight.x = 1.0f; + } + else if (N.y > limit * (N.x + N.y) && N.y > limit * (N.y + N.z)) { + weight.y = 1.0f; + } + else if (N.z > limit * (N.x + N.z) && N.z > limit * (N.y + N.z)) { + weight.z = 1.0f; + } + else if (blend > 0.0f) { + /* in case of blending, test for mixes between two textures */ + if (N.z < (1.0f - limit) * (N.y + N.x)) { + weight.x = N.x / (N.x + N.y); + weight.x = saturate((weight.x - 0.5f * (1.0f - blend)) / blend); + weight.y = 1.0f - weight.x; + } + else if (N.x < (1.0f - limit) * (N.y + N.z)) { + weight.y = N.y / (N.y + N.z); + weight.y = saturate((weight.y - 0.5f * (1.0f - blend)) / blend); + weight.z = 1.0f - weight.y; + } + else if (N.y < (1.0f - limit) * (N.x + N.z)) { + weight.x = N.x / (N.x + N.z); + weight.x = saturate((weight.x - 0.5f * (1.0f - blend)) / blend); + weight.z = 1.0f - weight.x; + } + else { + /* last case, we have a mix between three */ + weight.x = ((2.0f - limit) * N.x + (limit - 1.0f)) / (2.0f * limit - 1.0f); + weight.y = ((2.0f - limit) * N.y + (limit - 1.0f)) / (2.0f * limit - 1.0f); + weight.z = ((2.0f - limit) * N.z + (limit - 1.0f)) / (2.0f * limit - 1.0f); + } + } + else { + /* Desperate mode, no valid choice anyway, fallback to one side.*/ + weight.x = 1.0f; + } + + /* now fetch textures */ + uint co_offset, out_offset, alpha_offset, srgb; + decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); + + float3 co = stack_load_float3(stack, co_offset); + uint id = node.y; + + float4 f = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + uint use_alpha = stack_valid(alpha_offset); + + /* Map so that no textures are flipped, rotation is somewhat arbitrary. */ + if (weight.x > 0.0f) { + float2 uv = make_float2((signed_N.x < 0.0f) ? 1.0f - co.y : co.y, co.z); + f += weight.x * svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + } + if (weight.y > 0.0f) { + float2 uv = make_float2((signed_N.y > 0.0f) ? 1.0f - co.x : co.x, co.z); + f += weight.y * svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + } + if (weight.z > 0.0f) { + float2 uv = make_float2((signed_N.z > 0.0f) ? 1.0f - co.y : co.y, co.x); + f += weight.z * svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + } + + if (stack_valid(out_offset)) + stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); + if (stack_valid(alpha_offset)) + stack_store_float(stack, alpha_offset, f.w); } -ccl_device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) +ccl_device void svm_node_tex_environment(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint4 node) { - uint id = node.y; - uint co_offset, out_offset, alpha_offset, srgb; - uint projection = node.w; + uint id = node.y; + uint co_offset, out_offset, alpha_offset, srgb; + uint projection = node.w; - decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); + decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb); - float3 co = stack_load_float3(stack, co_offset); - float2 uv; + float3 co = stack_load_float3(stack, co_offset); + float2 uv; - co = safe_normalize(co); + co = safe_normalize(co); - if(projection == 0) - uv = direction_to_equirectangular(co); - else - uv = direction_to_mirrorball(co); + if (projection == 0) + uv = direction_to_equirectangular(co); + else + uv = direction_to_mirrorball(co); - uint use_alpha = stack_valid(alpha_offset); - float4 f = svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); + uint use_alpha = stack_valid(alpha_offset); + float4 f = svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha); - if(stack_valid(out_offset)) - stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); - if(stack_valid(alpha_offset)) - stack_store_float(stack, alpha_offset, f.w); + if (stack_valid(out_offset)) + stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z)); + if (stack_valid(alpha_offset)) + stack_store_float(stack, alpha_offset, f.w); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_invert.h b/intern/cycles/kernel/svm/svm_invert.h index 57cc4281101..02024742b13 100644 --- a/intern/cycles/kernel/svm/svm_invert.h +++ b/intern/cycles/kernel/svm/svm_invert.h @@ -18,20 +18,21 @@ CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor) { - return factor*(1.0f - color) + (1.0f - factor) * color; + return factor * (1.0f - color) + (1.0f - factor) * color; } -ccl_device void svm_node_invert(ShaderData *sd, float *stack, uint in_fac, uint in_color, uint out_color) +ccl_device void svm_node_invert( + ShaderData *sd, float *stack, uint in_fac, uint in_color, uint out_color) { - float factor = stack_load_float(stack, in_fac); - float3 color = stack_load_float3(stack, in_color); + float factor = stack_load_float(stack, in_fac); + float3 color = stack_load_float3(stack, in_color); - color.x = invert(color.x, factor); - color.y = invert(color.y, factor); - color.z = invert(color.z, factor); + color.x = invert(color.x, factor); + color.y = invert(color.y, factor); + color.z = invert(color.z, factor); - if(stack_valid(out_color)) - stack_store_float3(stack, out_color, color); + if (stack_valid(out_color)) + stack_store_float3(stack, out_color, color); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_light_path.h b/intern/cycles/kernel/svm/svm_light_path.h index dd4390057cf..65a9a284a17 100644 --- a/intern/cycles/kernel/svm/svm_light_path.h +++ b/intern/cycles/kernel/svm/svm_light_path.h @@ -18,59 +18,99 @@ CCL_NAMESPACE_BEGIN /* Light Path Node */ -ccl_device void svm_node_light_path(ShaderData *sd, ccl_addr_space PathState *state, float *stack, uint type, uint out_offset, int path_flag) +ccl_device void svm_node_light_path(ShaderData *sd, + ccl_addr_space PathState *state, + float *stack, + uint type, + uint out_offset, + int path_flag) { - float info = 0.0f; + float info = 0.0f; - switch(type) { - case NODE_LP_camera: info = (path_flag & PATH_RAY_CAMERA)? 1.0f: 0.0f; break; - case NODE_LP_shadow: info = (path_flag & PATH_RAY_SHADOW)? 1.0f: 0.0f; break; - case NODE_LP_diffuse: info = (path_flag & PATH_RAY_DIFFUSE)? 1.0f: 0.0f; break; - case NODE_LP_glossy: info = (path_flag & PATH_RAY_GLOSSY)? 1.0f: 0.0f; break; - case NODE_LP_singular: info = (path_flag & PATH_RAY_SINGULAR)? 1.0f: 0.0f; break; - case NODE_LP_reflection: info = (path_flag & PATH_RAY_REFLECT)? 1.0f: 0.0f; break; - case NODE_LP_transmission: info = (path_flag & PATH_RAY_TRANSMIT)? 1.0f: 0.0f; break; - case NODE_LP_volume_scatter: info = (path_flag & PATH_RAY_VOLUME_SCATTER)? 1.0f: 0.0f; break; - case NODE_LP_backfacing: info = (sd->flag & SD_BACKFACING)? 1.0f: 0.0f; break; - case NODE_LP_ray_length: info = sd->ray_length; break; - case NODE_LP_ray_depth: info = (float)state->bounce; break; - case NODE_LP_ray_diffuse: info = (float)state->diffuse_bounce; break; - case NODE_LP_ray_glossy: info = (float)state->glossy_bounce; break; - case NODE_LP_ray_transparent: info = (float)state->transparent_bounce; break; - case NODE_LP_ray_transmission: info = (float)state->transmission_bounce; break; - } + switch (type) { + case NODE_LP_camera: + info = (path_flag & PATH_RAY_CAMERA) ? 1.0f : 0.0f; + break; + case NODE_LP_shadow: + info = (path_flag & PATH_RAY_SHADOW) ? 1.0f : 0.0f; + break; + case NODE_LP_diffuse: + info = (path_flag & PATH_RAY_DIFFUSE) ? 1.0f : 0.0f; + break; + case NODE_LP_glossy: + info = (path_flag & PATH_RAY_GLOSSY) ? 1.0f : 0.0f; + break; + case NODE_LP_singular: + info = (path_flag & PATH_RAY_SINGULAR) ? 1.0f : 0.0f; + break; + case NODE_LP_reflection: + info = (path_flag & PATH_RAY_REFLECT) ? 1.0f : 0.0f; + break; + case NODE_LP_transmission: + info = (path_flag & PATH_RAY_TRANSMIT) ? 1.0f : 0.0f; + break; + case NODE_LP_volume_scatter: + info = (path_flag & PATH_RAY_VOLUME_SCATTER) ? 1.0f : 0.0f; + break; + case NODE_LP_backfacing: + info = (sd->flag & SD_BACKFACING) ? 1.0f : 0.0f; + break; + case NODE_LP_ray_length: + info = sd->ray_length; + break; + case NODE_LP_ray_depth: + info = (float)state->bounce; + break; + case NODE_LP_ray_diffuse: + info = (float)state->diffuse_bounce; + break; + case NODE_LP_ray_glossy: + info = (float)state->glossy_bounce; + break; + case NODE_LP_ray_transparent: + info = (float)state->transparent_bounce; + break; + case NODE_LP_ray_transmission: + info = (float)state->transmission_bounce; + break; + } - stack_store_float(stack, out_offset, info); + stack_store_float(stack, out_offset, info); } /* Light Falloff Node */ ccl_device void svm_node_light_falloff(ShaderData *sd, float *stack, uint4 node) { - uint strength_offset, out_offset, smooth_offset; + uint strength_offset, out_offset, smooth_offset; - decode_node_uchar4(node.z, &strength_offset, &smooth_offset, &out_offset, NULL); + decode_node_uchar4(node.z, &strength_offset, &smooth_offset, &out_offset, NULL); - float strength = stack_load_float(stack, strength_offset); - uint type = node.y; + float strength = stack_load_float(stack, strength_offset); + uint type = node.y; - switch(type) { - case NODE_LIGHT_FALLOFF_QUADRATIC: break; - case NODE_LIGHT_FALLOFF_LINEAR: strength *= sd->ray_length; break; - case NODE_LIGHT_FALLOFF_CONSTANT: strength *= sd->ray_length*sd->ray_length; break; - } + switch (type) { + case NODE_LIGHT_FALLOFF_QUADRATIC: + break; + case NODE_LIGHT_FALLOFF_LINEAR: + strength *= sd->ray_length; + break; + case NODE_LIGHT_FALLOFF_CONSTANT: + strength *= sd->ray_length * sd->ray_length; + break; + } - float smooth = stack_load_float(stack, smooth_offset); + float smooth = stack_load_float(stack, smooth_offset); - if(smooth > 0.0f) { - float squared = sd->ray_length*sd->ray_length; - /* Distant lamps set the ray length to FLT_MAX, which causes squared to overflow. */ - if(isfinite(squared)) { - strength *= squared/(smooth + squared); - } - } + if (smooth > 0.0f) { + float squared = sd->ray_length * sd->ray_length; + /* Distant lamps set the ray length to FLT_MAX, which causes squared to overflow. */ + if (isfinite(squared)) { + strength *= squared / (smooth + squared); + } + } - stack_store_float(stack, out_offset, strength); + stack_store_float(stack, out_offset, strength); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_magic.h b/intern/cycles/kernel/svm/svm_magic.h index 6afaff37acd..115d2e2fe4b 100644 --- a/intern/cycles/kernel/svm/svm_magic.h +++ b/intern/cycles/kernel/svm/svm_magic.h @@ -20,92 +20,93 @@ CCL_NAMESPACE_BEGIN ccl_device_noinline float3 svm_magic(float3 p, int n, float distortion) { - float x = sinf((p.x + p.y + p.z)*5.0f); - float y = cosf((-p.x + p.y - p.z)*5.0f); - float z = -cosf((-p.x - p.y + p.z)*5.0f); - - if(n > 0) { - x *= distortion; - y *= distortion; - z *= distortion; - y = -cosf(x-y+z); - y *= distortion; - - if(n > 1) { - x = cosf(x-y-z); - x *= distortion; - - if(n > 2) { - z = sinf(-x-y-z); - z *= distortion; - - if(n > 3) { - x = -cosf(-x+y-z); - x *= distortion; - - if(n > 4) { - y = -sinf(-x+y+z); - y *= distortion; - - if(n > 5) { - y = -cosf(-x+y+z); - y *= distortion; - - if(n > 6) { - x = cosf(x+y+z); - x *= distortion; - - if(n > 7) { - z = sinf(x+y-z); - z *= distortion; - - if(n > 8) { - x = -cosf(-x-y+z); - x *= distortion; - - if(n > 9) { - y = -sinf(x-y+z); - y *= distortion; - } - } - } - } - } - } - } - } - } - } - - if(distortion != 0.0f) { - distortion *= 2.0f; - x /= distortion; - y /= distortion; - z /= distortion; - } - - return make_float3(0.5f - x, 0.5f - y, 0.5f - z); + float x = sinf((p.x + p.y + p.z) * 5.0f); + float y = cosf((-p.x + p.y - p.z) * 5.0f); + float z = -cosf((-p.x - p.y + p.z) * 5.0f); + + if (n > 0) { + x *= distortion; + y *= distortion; + z *= distortion; + y = -cosf(x - y + z); + y *= distortion; + + if (n > 1) { + x = cosf(x - y - z); + x *= distortion; + + if (n > 2) { + z = sinf(-x - y - z); + z *= distortion; + + if (n > 3) { + x = -cosf(-x + y - z); + x *= distortion; + + if (n > 4) { + y = -sinf(-x + y + z); + y *= distortion; + + if (n > 5) { + y = -cosf(-x + y + z); + y *= distortion; + + if (n > 6) { + x = cosf(x + y + z); + x *= distortion; + + if (n > 7) { + z = sinf(x + y - z); + z *= distortion; + + if (n > 8) { + x = -cosf(-x - y + z); + x *= distortion; + + if (n > 9) { + y = -sinf(x - y + z); + y *= distortion; + } + } + } + } + } + } + } + } + } + } + + if (distortion != 0.0f) { + distortion *= 2.0f; + x /= distortion; + y /= distortion; + z /= distortion; + } + + return make_float3(0.5f - x, 0.5f - y, 0.5f - z); } -ccl_device void svm_node_tex_magic(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_tex_magic( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint depth; - uint scale_offset, distortion_offset, co_offset, fac_offset, color_offset; + uint depth; + uint scale_offset, distortion_offset, co_offset, fac_offset, color_offset; - decode_node_uchar4(node.y, &depth, &color_offset, &fac_offset, NULL); - decode_node_uchar4(node.z, &co_offset, &scale_offset, &distortion_offset, NULL); + decode_node_uchar4(node.y, &depth, &color_offset, &fac_offset, NULL); + decode_node_uchar4(node.z, &co_offset, &scale_offset, &distortion_offset, NULL); - uint4 node2 = read_node(kg, offset); - float3 co = stack_load_float3(stack, co_offset); - float scale = stack_load_float_default(stack, scale_offset, node2.x); - float distortion = stack_load_float_default(stack, distortion_offset, node2.y); + uint4 node2 = read_node(kg, offset); + float3 co = stack_load_float3(stack, co_offset); + float scale = stack_load_float_default(stack, scale_offset, node2.x); + float distortion = stack_load_float_default(stack, distortion_offset, node2.y); - float3 color = svm_magic(co*scale, depth, distortion); + float3 color = svm_magic(co * scale, depth, distortion); - if(stack_valid(fac_offset)) - stack_store_float(stack, fac_offset, average(color)); - if(stack_valid(color_offset)) - stack_store_float3(stack, color_offset, color); + if (stack_valid(fac_offset)) + stack_store_float(stack, fac_offset, average(color)); + if (stack_valid(color_offset)) + stack_store_float3(stack, color_offset, color); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_mapping.h b/intern/cycles/kernel/svm/svm_mapping.h index 86181283821..998a29912d4 100644 --- a/intern/cycles/kernel/svm/svm_mapping.h +++ b/intern/cycles/kernel/svm/svm_mapping.h @@ -18,28 +18,30 @@ CCL_NAMESPACE_BEGIN /* Mapping Node */ -ccl_device void svm_node_mapping(KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset) +ccl_device void svm_node_mapping( + KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset) { - float3 v = stack_load_float3(stack, vec_offset); + float3 v = stack_load_float3(stack, vec_offset); - Transform tfm; - tfm.x = read_node_float(kg, offset); - tfm.y = read_node_float(kg, offset); - tfm.z = read_node_float(kg, offset); + Transform tfm; + tfm.x = read_node_float(kg, offset); + tfm.y = read_node_float(kg, offset); + tfm.z = read_node_float(kg, offset); - float3 r = transform_point(&tfm, v); - stack_store_float3(stack, out_offset, r); + float3 r = transform_point(&tfm, v); + stack_store_float3(stack, out_offset, r); } -ccl_device void svm_node_min_max(KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset) +ccl_device void svm_node_min_max( + KernelGlobals *kg, ShaderData *sd, float *stack, uint vec_offset, uint out_offset, int *offset) { - float3 v = stack_load_float3(stack, vec_offset); + float3 v = stack_load_float3(stack, vec_offset); - float3 mn = float4_to_float3(read_node_float(kg, offset)); - float3 mx = float4_to_float3(read_node_float(kg, offset)); + float3 mn = float4_to_float3(read_node_float(kg, offset)); + float3 mx = float4_to_float3(read_node_float(kg, offset)); - float3 r = min(max(mn, v), mx); - stack_store_float3(stack, out_offset, r); + float3 r = min(max(mn, v), mx); + stack_store_float3(stack, out_offset, r); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h index c9a838361cd..5920913825b 100644 --- a/intern/cycles/kernel/svm/svm_math.h +++ b/intern/cycles/kernel/svm/svm_math.h @@ -18,32 +18,46 @@ CCL_NAMESPACE_BEGIN /* Nodes */ -ccl_device void svm_node_math(KernelGlobals *kg, ShaderData *sd, float *stack, uint itype, uint f1_offset, uint f2_offset, int *offset) +ccl_device void svm_node_math(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint itype, + uint f1_offset, + uint f2_offset, + int *offset) { - NodeMath type = (NodeMath)itype; - float f1 = stack_load_float(stack, f1_offset); - float f2 = stack_load_float(stack, f2_offset); - float f = svm_math(type, f1, f2); + NodeMath type = (NodeMath)itype; + float f1 = stack_load_float(stack, f1_offset); + float f2 = stack_load_float(stack, f2_offset); + float f = svm_math(type, f1, f2); - uint4 node1 = read_node(kg, offset); + uint4 node1 = read_node(kg, offset); - stack_store_float(stack, node1.y, f); + stack_store_float(stack, node1.y, f); } -ccl_device void svm_node_vector_math(KernelGlobals *kg, ShaderData *sd, float *stack, uint itype, uint v1_offset, uint v2_offset, int *offset) +ccl_device void svm_node_vector_math(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint itype, + uint v1_offset, + uint v2_offset, + int *offset) { - NodeVectorMath type = (NodeVectorMath)itype; - float3 v1 = stack_load_float3(stack, v1_offset); - float3 v2 = stack_load_float3(stack, v2_offset); - float f; - float3 v; + NodeVectorMath type = (NodeVectorMath)itype; + float3 v1 = stack_load_float3(stack, v1_offset); + float3 v2 = stack_load_float3(stack, v2_offset); + float f; + float3 v; - svm_vector_math(&f, &v, type, v1, v2); + svm_vector_math(&f, &v, type, v1, v2); - uint4 node1 = read_node(kg, offset); + uint4 node1 = read_node(kg, offset); - if(stack_valid(node1.y)) stack_store_float(stack, node1.y, f); - if(stack_valid(node1.z)) stack_store_float3(stack, node1.z, v); + if (stack_valid(node1.y)) + stack_store_float(stack, node1.y, f); + if (stack_valid(node1.z)) + stack_store_float3(stack, node1.z, v); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h index 669b174e4a3..e3544515f1b 100644 --- a/intern/cycles/kernel/svm/svm_math_util.h +++ b/intern/cycles/kernel/svm/svm_math_util.h @@ -18,96 +18,97 @@ CCL_NAMESPACE_BEGIN ccl_device float average_fac(float3 v) { - return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z))/3.0f; + return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z)) / 3.0f; } -ccl_device void svm_vector_math(float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2) +ccl_device void svm_vector_math( + float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2) { - if(type == NODE_VECTOR_MATH_ADD) { - *Vector = Vector1 + Vector2; - *Fac = average_fac(*Vector); - } - else if(type == NODE_VECTOR_MATH_SUBTRACT) { - *Vector = Vector1 - Vector2; - *Fac = average_fac(*Vector); - } - else if(type == NODE_VECTOR_MATH_AVERAGE) { - *Vector = safe_normalize_len(Vector1 + Vector2, Fac); - } - else if(type == NODE_VECTOR_MATH_DOT_PRODUCT) { - *Fac = dot(Vector1, Vector2); - *Vector = make_float3(0.0f, 0.0f, 0.0f); - } - else if(type == NODE_VECTOR_MATH_CROSS_PRODUCT) { - *Vector = safe_normalize_len(cross(Vector1, Vector2), Fac); - } - else if(type == NODE_VECTOR_MATH_NORMALIZE) { - *Vector = safe_normalize_len(Vector1, Fac); - } - else { - *Fac = 0.0f; - *Vector = make_float3(0.0f, 0.0f, 0.0f); - } + if (type == NODE_VECTOR_MATH_ADD) { + *Vector = Vector1 + Vector2; + *Fac = average_fac(*Vector); + } + else if (type == NODE_VECTOR_MATH_SUBTRACT) { + *Vector = Vector1 - Vector2; + *Fac = average_fac(*Vector); + } + else if (type == NODE_VECTOR_MATH_AVERAGE) { + *Vector = safe_normalize_len(Vector1 + Vector2, Fac); + } + else if (type == NODE_VECTOR_MATH_DOT_PRODUCT) { + *Fac = dot(Vector1, Vector2); + *Vector = make_float3(0.0f, 0.0f, 0.0f); + } + else if (type == NODE_VECTOR_MATH_CROSS_PRODUCT) { + *Vector = safe_normalize_len(cross(Vector1, Vector2), Fac); + } + else if (type == NODE_VECTOR_MATH_NORMALIZE) { + *Vector = safe_normalize_len(Vector1, Fac); + } + else { + *Fac = 0.0f; + *Vector = make_float3(0.0f, 0.0f, 0.0f); + } } ccl_device float svm_math(NodeMath type, float Fac1, float Fac2) { - float Fac; - - if(type == NODE_MATH_ADD) - Fac = Fac1 + Fac2; - else if(type == NODE_MATH_SUBTRACT) - Fac = Fac1 - Fac2; - else if(type == NODE_MATH_MULTIPLY) - Fac = Fac1*Fac2; - else if(type == NODE_MATH_DIVIDE) - Fac = safe_divide(Fac1, Fac2); - else if(type == NODE_MATH_SINE) - Fac = sinf(Fac1); - else if(type == NODE_MATH_COSINE) - Fac = cosf(Fac1); - else if(type == NODE_MATH_TANGENT) - Fac = tanf(Fac1); - else if(type == NODE_MATH_ARCSINE) - Fac = safe_asinf(Fac1); - else if(type == NODE_MATH_ARCCOSINE) - Fac = safe_acosf(Fac1); - else if(type == NODE_MATH_ARCTANGENT) - Fac = atanf(Fac1); - else if(type == NODE_MATH_POWER) - Fac = safe_powf(Fac1, Fac2); - else if(type == NODE_MATH_LOGARITHM) - Fac = safe_logf(Fac1, Fac2); - else if(type == NODE_MATH_MINIMUM) - Fac = fminf(Fac1, Fac2); - else if(type == NODE_MATH_MAXIMUM) - Fac = fmaxf(Fac1, Fac2); - else if(type == NODE_MATH_ROUND) - Fac = floorf(Fac1 + 0.5f); - else if(type == NODE_MATH_LESS_THAN) - Fac = Fac1 < Fac2; - else if(type == NODE_MATH_GREATER_THAN) - Fac = Fac1 > Fac2; - else if(type == NODE_MATH_MODULO) - Fac = safe_modulo(Fac1, Fac2); - else if(type == NODE_MATH_ABSOLUTE) - Fac = fabsf(Fac1); - else if(type == NODE_MATH_ARCTAN2) - Fac = atan2f(Fac1, Fac2); - else if(type == NODE_MATH_FLOOR) - Fac = floorf(Fac1); - else if(type == NODE_MATH_CEIL) - Fac = ceilf(Fac1); - else if(type == NODE_MATH_FRACT) - Fac = Fac1 - floorf(Fac1); - else if(type == NODE_MATH_SQRT) - Fac = safe_sqrtf(Fac1); - else if(type == NODE_MATH_CLAMP) - Fac = saturate(Fac1); - else - Fac = 0.0f; - - return Fac; + float Fac; + + if (type == NODE_MATH_ADD) + Fac = Fac1 + Fac2; + else if (type == NODE_MATH_SUBTRACT) + Fac = Fac1 - Fac2; + else if (type == NODE_MATH_MULTIPLY) + Fac = Fac1 * Fac2; + else if (type == NODE_MATH_DIVIDE) + Fac = safe_divide(Fac1, Fac2); + else if (type == NODE_MATH_SINE) + Fac = sinf(Fac1); + else if (type == NODE_MATH_COSINE) + Fac = cosf(Fac1); + else if (type == NODE_MATH_TANGENT) + Fac = tanf(Fac1); + else if (type == NODE_MATH_ARCSINE) + Fac = safe_asinf(Fac1); + else if (type == NODE_MATH_ARCCOSINE) + Fac = safe_acosf(Fac1); + else if (type == NODE_MATH_ARCTANGENT) + Fac = atanf(Fac1); + else if (type == NODE_MATH_POWER) + Fac = safe_powf(Fac1, Fac2); + else if (type == NODE_MATH_LOGARITHM) + Fac = safe_logf(Fac1, Fac2); + else if (type == NODE_MATH_MINIMUM) + Fac = fminf(Fac1, Fac2); + else if (type == NODE_MATH_MAXIMUM) + Fac = fmaxf(Fac1, Fac2); + else if (type == NODE_MATH_ROUND) + Fac = floorf(Fac1 + 0.5f); + else if (type == NODE_MATH_LESS_THAN) + Fac = Fac1 < Fac2; + else if (type == NODE_MATH_GREATER_THAN) + Fac = Fac1 > Fac2; + else if (type == NODE_MATH_MODULO) + Fac = safe_modulo(Fac1, Fac2); + else if (type == NODE_MATH_ABSOLUTE) + Fac = fabsf(Fac1); + else if (type == NODE_MATH_ARCTAN2) + Fac = atan2f(Fac1, Fac2); + else if (type == NODE_MATH_FLOOR) + Fac = floorf(Fac1); + else if (type == NODE_MATH_CEIL) + Fac = ceilf(Fac1); + else if (type == NODE_MATH_FRACT) + Fac = Fac1 - floorf(Fac1); + else if (type == NODE_MATH_SQRT) + Fac = safe_sqrtf(Fac1); + else if (type == NODE_MATH_CLAMP) + Fac = saturate(Fac1); + else + Fac = 0.0f; + + return Fac; } /* Calculate color in range 800..12000 using an approximation @@ -117,74 +118,72 @@ ccl_device float svm_math(NodeMath type, float Fac1, float Fac2) */ ccl_static_constant float blackbody_table_r[6][3] = { - { 2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f }, - { 3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f }, - { 4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f }, - { 4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f }, - { 4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f }, - { 3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f }, + {2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f}, + {3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f}, + {4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f}, + {4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f}, + {4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f}, + {3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f}, }; ccl_static_constant float blackbody_table_g[6][3] = { - { -7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f }, - { -1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f }, - { -1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f }, - { -1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f }, - { -1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f }, - { -5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f }, + {-7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f}, + {-1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f}, + {-1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f}, + {-1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f}, + {-1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f}, + {-5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f}, }; ccl_static_constant float blackbody_table_b[6][4] = { - { 0.0f, 0.0f, 0.0f, 0.0f }, /* zeros should be optimized by compiler */ - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { -2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f }, - { -2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f }, - { 6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f }, + {0.0f, 0.0f, 0.0f, 0.0f}, /* zeros should be optimized by compiler */ + {0.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 0.0f}, + {-2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f}, + {-2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f}, + {6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f}, }; - ccl_device float3 svm_math_blackbody_color(float t) { - /* TODO(lukas): Reimplement in XYZ. */ - - if(t >= 12000.0f) { - return make_float3(0.826270103f, 0.994478524f, 1.56626022f); - } - else if(t < 965.0f) { - /* For 800 <= t < 965 color does not change in OSL implementation, so keep color the same */ - return make_float3(4.70366907f, 0.0f, 0.0f); - } - - int i = (t >= 6365.0f)? 5: - (t >= 3315.0f)? 4: - (t >= 1902.0f)? 3: - (t >= 1449.0f)? 2: - (t >= 1167.0f)? 1: 0; - - ccl_constant float *r = blackbody_table_r[i]; - ccl_constant float *g = blackbody_table_g[i]; - ccl_constant float *b = blackbody_table_b[i]; - - const float t_inv = 1.0f / t; - return make_float3(r[0] * t_inv + r[1] * t + r[2], - g[0] * t_inv + g[1] * t + g[2], - ((b[0] * t + b[1]) * t + b[2]) * t + b[3]); + /* TODO(lukas): Reimplement in XYZ. */ + + if (t >= 12000.0f) { + return make_float3(0.826270103f, 0.994478524f, 1.56626022f); + } + else if (t < 965.0f) { + /* For 800 <= t < 965 color does not change in OSL implementation, so keep color the same */ + return make_float3(4.70366907f, 0.0f, 0.0f); + } + + int i = (t >= 6365.0f) ? + 5 : + (t >= 3315.0f) ? 4 : + (t >= 1902.0f) ? 3 : (t >= 1449.0f) ? 2 : (t >= 1167.0f) ? 1 : 0; + + ccl_constant float *r = blackbody_table_r[i]; + ccl_constant float *g = blackbody_table_g[i]; + ccl_constant float *b = blackbody_table_b[i]; + + const float t_inv = 1.0f / t; + return make_float3(r[0] * t_inv + r[1] * t + r[2], + g[0] * t_inv + g[1] * t + g[2], + ((b[0] * t + b[1]) * t + b[2]) * t + b[3]); } ccl_device_inline float3 svm_math_gamma_color(float3 color, float gamma) { - if(gamma == 0.0f) - return make_float3(1.0f, 1.0f, 1.0f); + if (gamma == 0.0f) + return make_float3(1.0f, 1.0f, 1.0f); - if(color.x > 0.0f) - color.x = powf(color.x, gamma); - if(color.y > 0.0f) - color.y = powf(color.y, gamma); - if(color.z > 0.0f) - color.z = powf(color.z, gamma); + if (color.x > 0.0f) + color.x = powf(color.x, gamma); + if (color.y > 0.0f) + color.y = powf(color.y, gamma); + if (color.z > 0.0f) + color.z = powf(color.z, gamma); - return color; + return color; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_mix.h b/intern/cycles/kernel/svm/svm_mix.h index 903a4dacebf..15114bfd5e4 100644 --- a/intern/cycles/kernel/svm/svm_mix.h +++ b/intern/cycles/kernel/svm/svm_mix.h @@ -18,17 +18,23 @@ CCL_NAMESPACE_BEGIN /* Node */ -ccl_device void svm_node_mix(KernelGlobals *kg, ShaderData *sd, float *stack, uint fac_offset, uint c1_offset, uint c2_offset, int *offset) +ccl_device void svm_node_mix(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint fac_offset, + uint c1_offset, + uint c2_offset, + int *offset) { - /* read extra data */ - uint4 node1 = read_node(kg, offset); + /* read extra data */ + uint4 node1 = read_node(kg, offset); - float fac = stack_load_float(stack, fac_offset); - float3 c1 = stack_load_float3(stack, c1_offset); - float3 c2 = stack_load_float3(stack, c2_offset); - float3 result = svm_mix((NodeMix)node1.y, fac, c1, c2); + float fac = stack_load_float(stack, fac_offset); + float3 c1 = stack_load_float3(stack, c1_offset); + float3 c2 = stack_load_float3(stack, c2_offset); + float3 result = svm_mix((NodeMix)node1.y, fac, c1, c2); - stack_store_float3(stack, node1.z, result); + stack_store_float3(stack, node1.z, result); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_musgrave.h b/intern/cycles/kernel/svm/svm_musgrave.h index 5d9e12628ca..67fb5ca6241 100644 --- a/intern/cycles/kernel/svm/svm_musgrave.h +++ b/intern/cycles/kernel/svm/svm_musgrave.h @@ -27,23 +27,23 @@ CCL_NAMESPACE_BEGIN ccl_device_noinline float noise_musgrave_fBm(float3 p, float H, float lacunarity, float octaves) { - float rmd; - float value = 0.0f; - float pwr = 1.0f; - float pwHL = powf(lacunarity, -H); - int i; - - for(i = 0; i < float_to_int(octaves); i++) { - value += snoise(p) * pwr; - pwr *= pwHL; - p *= lacunarity; - } - - rmd = octaves - floorf(octaves); - if(rmd != 0.0f) - value += rmd * snoise(p) * pwr; - - return value; + float rmd; + float value = 0.0f; + float pwr = 1.0f; + float pwHL = powf(lacunarity, -H); + int i; + + for (i = 0; i < float_to_int(octaves); i++) { + value += snoise(p) * pwr; + pwr *= pwHL; + p *= lacunarity; + } + + rmd = octaves - floorf(octaves); + if (rmd != 0.0f) + value += rmd * snoise(p) * pwr; + + return value; } /* Musgrave Multifractal @@ -53,25 +53,28 @@ ccl_device_noinline float noise_musgrave_fBm(float3 p, float H, float lacunarity * octaves: number of frequencies in the fBm */ -ccl_device_noinline float noise_musgrave_multi_fractal(float3 p, float H, float lacunarity, float octaves) +ccl_device_noinline float noise_musgrave_multi_fractal(float3 p, + float H, + float lacunarity, + float octaves) { - float rmd; - float value = 1.0f; - float pwr = 1.0f; - float pwHL = powf(lacunarity, -H); - int i; - - for(i = 0; i < float_to_int(octaves); i++) { - value *= (pwr * snoise(p) + 1.0f); - pwr *= pwHL; - p *= lacunarity; - } - - rmd = octaves - floorf(octaves); - if(rmd != 0.0f) - value *= (rmd * pwr * snoise(p) + 1.0f); /* correct? */ - - return value; + float rmd; + float value = 1.0f; + float pwr = 1.0f; + float pwHL = powf(lacunarity, -H); + int i; + + for (i = 0; i < float_to_int(octaves); i++) { + value *= (pwr * snoise(p) + 1.0f); + pwr *= pwHL; + p *= lacunarity; + } + + rmd = octaves - floorf(octaves); + if (rmd != 0.0f) + value *= (rmd * pwr * snoise(p) + 1.0f); /* correct? */ + + return value; } /* Musgrave Heterogeneous Terrain @@ -82,31 +85,32 @@ ccl_device_noinline float noise_musgrave_multi_fractal(float3 p, float H, float * offset: raises the terrain from `sea level' */ -ccl_device_noinline float noise_musgrave_hetero_terrain(float3 p, float H, float lacunarity, float octaves, float offset) +ccl_device_noinline float noise_musgrave_hetero_terrain( + float3 p, float H, float lacunarity, float octaves, float offset) { - float value, increment, rmd; - float pwHL = powf(lacunarity, -H); - float pwr = pwHL; - int i; - - /* first unscaled octave of function; later octaves are scaled */ - value = offset + snoise(p); - p *= lacunarity; - - for(i = 1; i < float_to_int(octaves); i++) { - increment = (snoise(p) + offset) * pwr * value; - value += increment; - pwr *= pwHL; - p *= lacunarity; - } - - rmd = octaves - floorf(octaves); - if(rmd != 0.0f) { - increment = (snoise(p) + offset) * pwr * value; - value += rmd * increment; - } - - return value; + float value, increment, rmd; + float pwHL = powf(lacunarity, -H); + float pwr = pwHL; + int i; + + /* first unscaled octave of function; later octaves are scaled */ + value = offset + snoise(p); + p *= lacunarity; + + for (i = 1; i < float_to_int(octaves); i++) { + increment = (snoise(p) + offset) * pwr * value; + value += increment; + pwr *= pwHL; + p *= lacunarity; + } + + rmd = octaves - floorf(octaves); + if (rmd != 0.0f) { + increment = (snoise(p) + offset) * pwr * value; + value += rmd * increment; + } + + return value; } /* Hybrid Additive/Multiplicative Multifractal Terrain @@ -117,33 +121,34 @@ ccl_device_noinline float noise_musgrave_hetero_terrain(float3 p, float H, float * offset: raises the terrain from `sea level' */ -ccl_device_noinline float noise_musgrave_hybrid_multi_fractal(float3 p, float H, float lacunarity, float octaves, float offset, float gain) +ccl_device_noinline float noise_musgrave_hybrid_multi_fractal( + float3 p, float H, float lacunarity, float octaves, float offset, float gain) { - float result, signal, weight, rmd; - float pwHL = powf(lacunarity, -H); - float pwr = pwHL; - int i; - - result = snoise(p) + offset; - weight = gain * result; - p *= lacunarity; - - for(i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) { - if(weight > 1.0f) - weight = 1.0f; - - signal = (snoise(p) + offset) * pwr; - pwr *= pwHL; - result += weight * signal; - weight *= gain * signal; - p *= lacunarity; - } - - rmd = octaves - floorf(octaves); - if(rmd != 0.0f) - result += rmd * ((snoise(p) + offset) * pwr); - - return result; + float result, signal, weight, rmd; + float pwHL = powf(lacunarity, -H); + float pwr = pwHL; + int i; + + result = snoise(p) + offset; + weight = gain * result; + p *= lacunarity; + + for (i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) { + if (weight > 1.0f) + weight = 1.0f; + + signal = (snoise(p) + offset) * pwr; + pwr *= pwHL; + result += weight * signal; + weight *= gain * signal; + p *= lacunarity; + } + + rmd = octaves - floorf(octaves); + if (rmd != 0.0f) + result += rmd * ((snoise(p) + offset) * pwr); + + return result; } /* Ridged Multifractal Terrain @@ -154,81 +159,93 @@ ccl_device_noinline float noise_musgrave_hybrid_multi_fractal(float3 p, float H, * offset: raises the terrain from `sea level' */ -ccl_device_noinline float noise_musgrave_ridged_multi_fractal(float3 p, float H, float lacunarity, float octaves, float offset, float gain) +ccl_device_noinline float noise_musgrave_ridged_multi_fractal( + float3 p, float H, float lacunarity, float octaves, float offset, float gain) { - float result, signal, weight; - float pwHL = powf(lacunarity, -H); - float pwr = pwHL; - int i; - - signal = offset - fabsf(snoise(p)); - signal *= signal; - result = signal; - weight = 1.0f; - - for(i = 1; i < float_to_int(octaves); i++) { - p *= lacunarity; - weight = saturate(signal * gain); - signal = offset - fabsf(snoise(p)); - signal *= signal; - signal *= weight; - result += signal * pwr; - pwr *= pwHL; - } - - return result; + float result, signal, weight; + float pwHL = powf(lacunarity, -H); + float pwr = pwHL; + int i; + + signal = offset - fabsf(snoise(p)); + signal *= signal; + result = signal; + weight = 1.0f; + + for (i = 1; i < float_to_int(octaves); i++) { + p *= lacunarity; + weight = saturate(signal * gain); + signal = offset - fabsf(snoise(p)); + signal *= signal; + signal *= weight; + result += signal * pwr; + pwr *= pwHL; + } + + return result; } /* Shader */ -ccl_device float svm_musgrave(NodeMusgraveType type, float dimension, float lacunarity, float octaves, float offset, float intensity, float gain, float3 p) +ccl_device float svm_musgrave(NodeMusgraveType type, + float dimension, + float lacunarity, + float octaves, + float offset, + float intensity, + float gain, + float3 p) { - if(type == NODE_MUSGRAVE_MULTIFRACTAL) - return intensity*noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves); - else if(type == NODE_MUSGRAVE_FBM) - return intensity*noise_musgrave_fBm(p, dimension, lacunarity, octaves); - else if(type == NODE_MUSGRAVE_HYBRID_MULTIFRACTAL) - return intensity*noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain); - else if(type == NODE_MUSGRAVE_RIDGED_MULTIFRACTAL) - return intensity*noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain); - else if(type == NODE_MUSGRAVE_HETERO_TERRAIN) - return intensity*noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset); - - return 0.0f; + if (type == NODE_MUSGRAVE_MULTIFRACTAL) + return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves); + else if (type == NODE_MUSGRAVE_FBM) + return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves); + else if (type == NODE_MUSGRAVE_HYBRID_MULTIFRACTAL) + return intensity * + noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain); + else if (type == NODE_MUSGRAVE_RIDGED_MULTIFRACTAL) + return intensity * + noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain); + else if (type == NODE_MUSGRAVE_HETERO_TERRAIN) + return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset); + + return 0.0f; } -ccl_device void svm_node_tex_musgrave(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_tex_musgrave( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint4 node2 = read_node(kg, offset); - uint4 node3 = read_node(kg, offset); - - uint type, co_offset, color_offset, fac_offset; - uint dimension_offset, lacunarity_offset, detail_offset, offset_offset; - uint gain_offset, scale_offset; - - decode_node_uchar4(node.y, &type, &co_offset, &color_offset, &fac_offset); - decode_node_uchar4(node.z, &dimension_offset, &lacunarity_offset, &detail_offset, &offset_offset); - decode_node_uchar4(node.w, &gain_offset, &scale_offset, NULL, NULL); - - float3 co = stack_load_float3(stack, co_offset); - float dimension = stack_load_float_default(stack, dimension_offset, node2.x); - float lacunarity = stack_load_float_default(stack, lacunarity_offset, node2.y); - float detail = stack_load_float_default(stack, detail_offset, node2.z); - float foffset = stack_load_float_default(stack, offset_offset, node2.w); - float gain = stack_load_float_default(stack, gain_offset, node3.x); - float scale = stack_load_float_default(stack, scale_offset, node3.y); - - dimension = fmaxf(dimension, 1e-5f); - detail = clamp(detail, 0.0f, 16.0f); - lacunarity = fmaxf(lacunarity, 1e-5f); - - float f = svm_musgrave((NodeMusgraveType)type, - dimension, lacunarity, detail, foffset, 1.0f, gain, co*scale); - - if(stack_valid(fac_offset)) - stack_store_float(stack, fac_offset, f); - if(stack_valid(color_offset)) - stack_store_float3(stack, color_offset, make_float3(f, f, f)); + uint4 node2 = read_node(kg, offset); + uint4 node3 = read_node(kg, offset); + + uint type, co_offset, color_offset, fac_offset; + uint dimension_offset, lacunarity_offset, detail_offset, offset_offset; + uint gain_offset, scale_offset; + + decode_node_uchar4(node.y, &type, &co_offset, &color_offset, &fac_offset); + decode_node_uchar4( + node.z, &dimension_offset, &lacunarity_offset, &detail_offset, &offset_offset); + decode_node_uchar4(node.w, &gain_offset, &scale_offset, NULL, NULL); + + float3 co = stack_load_float3(stack, co_offset); + float dimension = stack_load_float_default(stack, dimension_offset, node2.x); + float lacunarity = stack_load_float_default(stack, lacunarity_offset, node2.y); + float detail = stack_load_float_default(stack, detail_offset, node2.z); + float foffset = stack_load_float_default(stack, offset_offset, node2.w); + float gain = stack_load_float_default(stack, gain_offset, node3.x); + float scale = stack_load_float_default(stack, scale_offset, node3.y); + + dimension = fmaxf(dimension, 1e-5f); + detail = clamp(detail, 0.0f, 16.0f); + lacunarity = fmaxf(lacunarity, 1e-5f); + + float f = svm_musgrave( + (NodeMusgraveType)type, dimension, lacunarity, detail, foffset, 1.0f, gain, co * scale); + + if (stack_valid(fac_offset)) + stack_store_float(stack, fac_offset, f); + if (stack_valid(color_offset)) + stack_store_float3(stack, color_offset, make_float3(f, f, f)); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h index 8c425ecf326..322579ccfe3 100644 --- a/intern/cycles/kernel/svm/svm_noise.h +++ b/intern/cycles/kernel/svm/svm_noise.h @@ -33,280 +33,302 @@ CCL_NAMESPACE_BEGIN #ifdef __KERNEL_SSE2__ -ccl_device_inline ssei quick_floor_sse(const ssef& x) +ccl_device_inline ssei quick_floor_sse(const ssef &x) { - ssei b = truncatei(x); - ssei isneg = cast((x < ssef(0.0f)).m128); - return b + isneg; // unsaturated add 0xffffffff is the same as subtract -1 + ssei b = truncatei(x); + ssei isneg = cast((x < ssef(0.0f)).m128); + return b + isneg; // unsaturated add 0xffffffff is the same as subtract -1 } #endif ccl_device uint hash(uint kx, uint ky, uint kz) { - // define some handy macros -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) -#define final(a,b,c) \ -{ \ - c ^= b; c -= rot(b,14); \ - a ^= c; a -= rot(c,11); \ - b ^= a; b -= rot(a,25); \ - c ^= b; c -= rot(b,16); \ - a ^= c; a -= rot(c,4); \ - b ^= a; b -= rot(a,14); \ - c ^= b; c -= rot(b,24); \ -} - // now hash the data! - uint a, b, c, len = 3; - a = b = c = 0xdeadbeef + (len << 2) + 13; - - c += kz; - b += ky; - a += kx; - final(a, b, c); - - return c; - // macros not needed anymore + // define some handy macros +#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) +#define final(a, b, c) \ + { \ + c ^= b; \ + c -= rot(b, 14); \ + a ^= c; \ + a -= rot(c, 11); \ + b ^= a; \ + b -= rot(a, 25); \ + c ^= b; \ + c -= rot(b, 16); \ + a ^= c; \ + a -= rot(c, 4); \ + b ^= a; \ + b -= rot(a, 14); \ + c ^= b; \ + c -= rot(b, 24); \ + } + // now hash the data! + uint a, b, c, len = 3; + a = b = c = 0xdeadbeef + (len << 2) + 13; + + c += kz; + b += ky; + a += kx; + final(a, b, c); + + return c; + // macros not needed anymore #undef rot #undef final } #ifdef __KERNEL_SSE2__ -ccl_device_inline ssei hash_sse(const ssei& kx, const ssei& ky, const ssei& kz) +ccl_device_inline ssei hash_sse(const ssei &kx, const ssei &ky, const ssei &kz) { -# define rot(x,k) (((x)<<(k)) | (srl(x, 32-(k)))) -# define xor_rot(a, b, c) do {a = a^b; a = a - rot(b, c);} while(0) - - uint len = 3; - ssei magic = ssei(0xdeadbeef + (len << 2) + 13); - ssei a = magic + kx; - ssei b = magic + ky; - ssei c = magic + kz; - - xor_rot(c, b, 14); - xor_rot(a, c, 11); - xor_rot(b, a, 25); - xor_rot(c, b, 16); - xor_rot(a, c, 4); - xor_rot(b, a, 14); - xor_rot(c, b, 24); - - return c; +# define rot(x, k) (((x) << (k)) | (srl(x, 32 - (k)))) +# define xor_rot(a, b, c) \ + do { \ + a = a ^ b; \ + a = a - rot(b, c); \ + } while (0) + + uint len = 3; + ssei magic = ssei(0xdeadbeef + (len << 2) + 13); + ssei a = magic + kx; + ssei b = magic + ky; + ssei c = magic + kz; + + xor_rot(c, b, 14); + xor_rot(a, c, 11); + xor_rot(b, a, 25); + xor_rot(c, b, 16); + xor_rot(a, c, 4); + xor_rot(b, a, 14); + xor_rot(c, b, 24); + + return c; # undef rot # undef xor_rot } #endif -#if 0 // unused +#if 0 // unused ccl_device int imod(int a, int b) { - a %= b; - return a < 0 ? a + b : a; + a %= b; + return a < 0 ? a + b : a; } ccl_device uint phash(int kx, int ky, int kz, int3 p) { - return hash(imod(kx, p.x), imod(ky, p.y), imod(kz, p.z)); + return hash(imod(kx, p.x), imod(ky, p.y), imod(kz, p.z)); } #endif #ifndef __KERNEL_SSE2__ -ccl_device float floorfrac(float x, int* i) +ccl_device float floorfrac(float x, int *i) { - *i = quick_floor_to_int(x); - return x - *i; + *i = quick_floor_to_int(x); + return x - *i; } #else -ccl_device_inline ssef floorfrac_sse(const ssef& x, ssei *i) +ccl_device_inline ssef floorfrac_sse(const ssef &x, ssei *i) { - *i = quick_floor_sse(x); - return x - ssef(*i); + *i = quick_floor_sse(x); + return x - ssef(*i); } #endif #ifndef __KERNEL_SSE2__ ccl_device float fade(float t) { - return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f); + return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f); } #else ccl_device_inline ssef fade_sse(const ssef *t) { - ssef a = madd(*t, ssef(6.0f), ssef(-15.0f)); - ssef b = madd(*t, a, ssef(10.0f)); - return ((*t) * (*t)) * ((*t) * b); + ssef a = madd(*t, ssef(6.0f), ssef(-15.0f)); + ssef b = madd(*t, a, ssef(10.0f)); + return ((*t) * (*t)) * ((*t) * b); } #endif #ifndef __KERNEL_SSE2__ ccl_device float nerp(float t, float a, float b) { - return (1.0f - t) * a + t * b; + return (1.0f - t) * a + t * b; } #else -ccl_device_inline ssef nerp_sse(const ssef& t, const ssef& a, const ssef& b) +ccl_device_inline ssef nerp_sse(const ssef &t, const ssef &a, const ssef &b) { - ssef x1 = (ssef(1.0f) - t) * a; - return madd(t, b, x1); + ssef x1 = (ssef(1.0f) - t) * a; + return madd(t, b, x1); } #endif #ifndef __KERNEL_SSE2__ ccl_device float grad(int hash, float x, float y, float z) { - // use vectors pointing to the edges of the cube - int h = hash & 15; - float u = h<8 ? x : y; - float vt = ((h == 12) | (h == 14)) ? x : z; - float v = h < 4 ? y : vt; - return ((h&1) ? -u : u) + ((h&2) ? -v : v); + // use vectors pointing to the edges of the cube + int h = hash & 15; + float u = h < 8 ? x : y; + float vt = ((h == 12) | (h == 14)) ? x : z; + float v = h < 4 ? y : vt; + return ((h & 1) ? -u : u) + ((h & 2) ? -v : v); } #else -ccl_device_inline ssef grad_sse(const ssei& hash, const ssef& x, const ssef& y, const ssef& z) +ccl_device_inline ssef grad_sse(const ssei &hash, const ssef &x, const ssef &y, const ssef &z) { - ssei c1 = ssei(1); - ssei c2 = ssei(2); + ssei c1 = ssei(1); + ssei c2 = ssei(2); - ssei h = hash & ssei(15); // h = hash & 15 + ssei h = hash & ssei(15); // h = hash & 15 - sseb case_ux = h < ssei(8); // 0xffffffff if h < 8 else 0 + sseb case_ux = h < ssei(8); // 0xffffffff if h < 8 else 0 - ssef u = select(case_ux, x, y); // u = h<8 ? x : y + ssef u = select(case_ux, x, y); // u = h<8 ? x : y - sseb case_vy = h < ssei(4); // 0xffffffff if h < 4 else 0 + sseb case_vy = h < ssei(4); // 0xffffffff if h < 4 else 0 - sseb case_h12 = h == ssei(12); // 0xffffffff if h == 12 else 0 - sseb case_h14 = h == ssei(14); // 0xffffffff if h == 14 else 0 + sseb case_h12 = h == ssei(12); // 0xffffffff if h == 12 else 0 + sseb case_h14 = h == ssei(14); // 0xffffffff if h == 14 else 0 - sseb case_vx = case_h12 | case_h14; // 0xffffffff if h == 12 or h == 14 else 0 + sseb case_vx = case_h12 | case_h14; // 0xffffffff if h == 12 or h == 14 else 0 - ssef v = select(case_vy, y, select(case_vx, x, z)); // v = h<4 ? y : h == 12 || h == 14 ? x : z + ssef v = select(case_vy, y, select(case_vx, x, z)); // v = h<4 ? y : h == 12 || h == 14 ? x : z - ssei case_uneg = (h & c1) << 31; // 1<<31 if h&1 else 0 - ssef case_uneg_mask = cast(case_uneg); // -0.0 if h&1 else +0.0 - ssef ru = u ^ case_uneg_mask; // -u if h&1 else u (copy float sign) + ssei case_uneg = (h & c1) << 31; // 1<<31 if h&1 else 0 + ssef case_uneg_mask = cast(case_uneg); // -0.0 if h&1 else +0.0 + ssef ru = u ^ case_uneg_mask; // -u if h&1 else u (copy float sign) - ssei case_vneg = (h & c2) << 30; // 2<<30 if h&2 else 0 - ssef case_vneg_mask = cast(case_vneg); // -0.0 if h&2 else +0.0 - ssef rv = v ^ case_vneg_mask; // -v if h&2 else v (copy float sign) + ssei case_vneg = (h & c2) << 30; // 2<<30 if h&2 else 0 + ssef case_vneg_mask = cast(case_vneg); // -0.0 if h&2 else +0.0 + ssef rv = v ^ case_vneg_mask; // -v if h&2 else v (copy float sign) - ssef r = ru + rv; // ((h&1) ? -u : u) + ((h&2) ? -v : v) - return r; + ssef r = ru + rv; // ((h&1) ? -u : u) + ((h&2) ? -v : v) + return r; } #endif #ifndef __KERNEL_SSE2__ ccl_device float scale3(float result) { - return 0.9820f * result; + return 0.9820f * result; } #else -ccl_device_inline ssef scale3_sse(const ssef& result) +ccl_device_inline ssef scale3_sse(const ssef &result) { - return ssef(0.9820f) * result; + return ssef(0.9820f) * result; } #endif #ifndef __KERNEL_SSE2__ ccl_device_noinline float perlin(float x, float y, float z) { - int X; float fx = floorfrac(x, &X); - int Y; float fy = floorfrac(y, &Y); - int Z; float fz = floorfrac(z, &Z); - - float u = fade(fx); - float v = fade(fy); - float w = fade(fz); - - float result; - - result = nerp (w, nerp (v, nerp (u, grad (hash (X , Y , Z ), fx , fy , fz ), - grad (hash (X+1, Y , Z ), fx-1.0f, fy , fz )), - nerp (u, grad (hash (X , Y+1, Z ), fx , fy-1.0f, fz ), - grad (hash (X+1, Y+1, Z ), fx-1.0f, fy-1.0f, fz ))), - nerp (v, nerp (u, grad (hash (X , Y , Z+1), fx , fy , fz-1.0f ), - grad (hash (X+1, Y , Z+1), fx-1.0f, fy , fz-1.0f )), - nerp (u, grad (hash (X , Y+1, Z+1), fx , fy-1.0f, fz-1.0f ), - grad (hash (X+1, Y+1, Z+1), fx-1.0f, fy-1.0f, fz-1.0f )))); - float r = scale3(result); - - /* can happen for big coordinates, things even out to 0.0 then anyway */ - return (isfinite(r))? r: 0.0f; + int X; + float fx = floorfrac(x, &X); + int Y; + float fy = floorfrac(y, &Y); + int Z; + float fz = floorfrac(z, &Z); + + float u = fade(fx); + float v = fade(fy); + float w = fade(fz); + + float result; + + result = nerp( + w, + nerp(v, + nerp(u, grad(hash(X, Y, Z), fx, fy, fz), grad(hash(X + 1, Y, Z), fx - 1.0f, fy, fz)), + nerp(u, + grad(hash(X, Y + 1, Z), fx, fy - 1.0f, fz), + grad(hash(X + 1, Y + 1, Z), fx - 1.0f, fy - 1.0f, fz))), + nerp(v, + nerp(u, + grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0f), + grad(hash(X + 1, Y, Z + 1), fx - 1.0f, fy, fz - 1.0f)), + nerp(u, + grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0f, fz - 1.0f), + grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0f, fy - 1.0f, fz - 1.0f)))); + float r = scale3(result); + + /* can happen for big coordinates, things even out to 0.0 then anyway */ + return (isfinite(r)) ? r : 0.0f; } #else ccl_device_noinline float perlin(float x, float y, float z) { - ssef xyz = ssef(x, y, z, 0.0f); - ssei XYZ; + ssef xyz = ssef(x, y, z, 0.0f); + ssei XYZ; - ssef fxyz = floorfrac_sse(xyz, &XYZ); + ssef fxyz = floorfrac_sse(xyz, &XYZ); - ssef uvw = fade_sse(&fxyz); - ssef u = shuffle<0>(uvw), v = shuffle<1>(uvw), w = shuffle<2>(uvw); + ssef uvw = fade_sse(&fxyz); + ssef u = shuffle<0>(uvw), v = shuffle<1>(uvw), w = shuffle<2>(uvw); - ssei XYZ_ofc = XYZ + ssei(1); - ssei vdy = shuffle<1, 1, 1, 1>(XYZ, XYZ_ofc); // +0, +0, +1, +1 - ssei vdz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZ, XYZ_ofc)); // +0, +1, +0, +1 + ssei XYZ_ofc = XYZ + ssei(1); + ssei vdy = shuffle<1, 1, 1, 1>(XYZ, XYZ_ofc); // +0, +0, +1, +1 + ssei vdz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(XYZ, XYZ_ofc)); // +0, +1, +0, +1 - ssei h1 = hash_sse(shuffle<0>(XYZ), vdy, vdz); // hash directions 000, 001, 010, 011 - ssei h2 = hash_sse(shuffle<0>(XYZ_ofc), vdy, vdz); // hash directions 100, 101, 110, 111 + ssei h1 = hash_sse(shuffle<0>(XYZ), vdy, vdz); // hash directions 000, 001, 010, 011 + ssei h2 = hash_sse(shuffle<0>(XYZ_ofc), vdy, vdz); // hash directions 100, 101, 110, 111 - ssef fxyz_ofc = fxyz - ssef(1.0f); - ssef vfy = shuffle<1, 1, 1, 1>(fxyz, fxyz_ofc); - ssef vfz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyz, fxyz_ofc)); + ssef fxyz_ofc = fxyz - ssef(1.0f); + ssef vfy = shuffle<1, 1, 1, 1>(fxyz, fxyz_ofc); + ssef vfz = shuffle<0, 2, 0, 2>(shuffle<2, 2, 2, 2>(fxyz, fxyz_ofc)); - ssef g1 = grad_sse(h1, shuffle<0>(fxyz), vfy, vfz); - ssef g2 = grad_sse(h2, shuffle<0>(fxyz_ofc), vfy, vfz); - ssef n1 = nerp_sse(u, g1, g2); + ssef g1 = grad_sse(h1, shuffle<0>(fxyz), vfy, vfz); + ssef g2 = grad_sse(h2, shuffle<0>(fxyz_ofc), vfy, vfz); + ssef n1 = nerp_sse(u, g1, g2); - ssef n1_half = shuffle<2, 3, 2, 3>(n1); // extract 2 floats to a separate vector - ssef n2 = nerp_sse(v, n1, n1_half); // process nerp([a, b, _, _], [c, d, _, _]) -> [a', b', _, _] + ssef n1_half = shuffle<2, 3, 2, 3>(n1); // extract 2 floats to a separate vector + ssef n2 = nerp_sse( + v, n1, n1_half); // process nerp([a, b, _, _], [c, d, _, _]) -> [a', b', _, _] - ssef n2_second = shuffle<1>(n2); // extract b to a separate vector - ssef result = nerp_sse(w, n2, n2_second); // process nerp([a', _, _, _], [b', _, _, _]) -> [a'', _, _, _] + ssef n2_second = shuffle<1>(n2); // extract b to a separate vector + ssef result = nerp_sse( + w, n2, n2_second); // process nerp([a', _, _, _], [b', _, _, _]) -> [a'', _, _, _] - ssef r = scale3_sse(result); + ssef r = scale3_sse(result); - ssef infmask = cast(ssei(0x7f800000)); - ssef rinfmask = ((r & infmask) == infmask).m128; // 0xffffffff if r is inf/-inf/nan else 0 - ssef rfinite = andnot(rinfmask, r); // 0 if r is inf/-inf/nan else r - return extract<0>(rfinite); + ssef infmask = cast(ssei(0x7f800000)); + ssef rinfmask = ((r & infmask) == infmask).m128; // 0xffffffff if r is inf/-inf/nan else 0 + ssef rfinite = andnot(rinfmask, r); // 0 if r is inf/-inf/nan else r + return extract<0>(rfinite); } #endif /* perlin noise in range 0..1 */ ccl_device float noise(float3 p) { - float r = perlin(p.x, p.y, p.z); - return 0.5f*r + 0.5f; + float r = perlin(p.x, p.y, p.z); + return 0.5f * r + 0.5f; } /* perlin noise in range -1..1 */ ccl_device float snoise(float3 p) { - return perlin(p.x, p.y, p.z); + return perlin(p.x, p.y, p.z); } /* cell noise */ ccl_device float cellnoise(float3 p) { - int3 ip = quick_floor_to_int3(p); - return bits_to_01(hash(ip.x, ip.y, ip.z)); + int3 ip = quick_floor_to_int3(p); + return bits_to_01(hash(ip.x, ip.y, ip.z)); } ccl_device float3 cellnoise3(float3 p) { - int3 ip = quick_floor_to_int3(p); + int3 ip = quick_floor_to_int3(p); #ifndef __KERNEL_SSE__ - float r = bits_to_01(hash(ip.x, ip.y, ip.z)); - float g = bits_to_01(hash(ip.y, ip.x, ip.z)); - float b = bits_to_01(hash(ip.y, ip.z, ip.x)); - return make_float3(r, g, b); + float r = bits_to_01(hash(ip.x, ip.y, ip.z)); + float g = bits_to_01(hash(ip.y, ip.x, ip.z)); + float b = bits_to_01(hash(ip.y, ip.z, ip.x)); + return make_float3(r, g, b); #else - ssei ip_yxz = shuffle<1, 0, 2, 3>(ssei(ip.m128)); - ssei ip_xyy = shuffle<0, 1, 1, 3>(ssei(ip.m128)); - ssei ip_zzx = shuffle<2, 2, 0, 3>(ssei(ip.m128)); - ssei bits = hash_sse(ip_xyy, ip_yxz, ip_zzx); - return float3(uint32_to_float(bits) * ssef(1.0f/(float)0xFFFFFFFF)); + ssei ip_yxz = shuffle<1, 0, 2, 3>(ssei(ip.m128)); + ssei ip_xyy = shuffle<0, 1, 1, 3>(ssei(ip.m128)); + ssei ip_zzx = shuffle<2, 2, 0, 3>(ssei(ip.m128)); + ssei bits = hash_sse(ip_xyy, ip_yxz, ip_zzx); + return float3(uint32_to_float(bits) * ssef(1.0f / (float)0xFFFFFFFF)); #endif } diff --git a/intern/cycles/kernel/svm/svm_noisetex.h b/intern/cycles/kernel/svm/svm_noisetex.h index c02940f96d6..3324e86fcd8 100644 --- a/intern/cycles/kernel/svm/svm_noisetex.h +++ b/intern/cycles/kernel/svm/svm_noisetex.h @@ -18,42 +18,43 @@ CCL_NAMESPACE_BEGIN /* Noise */ -ccl_device void svm_node_tex_noise(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_tex_noise( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint co_offset, scale_offset, detail_offset, distortion_offset, fac_offset, color_offset; + uint co_offset, scale_offset, detail_offset, distortion_offset, fac_offset, color_offset; - decode_node_uchar4(node.y, &co_offset, &scale_offset, &detail_offset, &distortion_offset); - decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL); + decode_node_uchar4(node.y, &co_offset, &scale_offset, &detail_offset, &distortion_offset); + decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL); - uint4 node2 = read_node(kg, offset); + uint4 node2 = read_node(kg, offset); - float scale = stack_load_float_default(stack, scale_offset, node2.x); - float detail = stack_load_float_default(stack, detail_offset, node2.y); - float distortion = stack_load_float_default(stack, distortion_offset, node2.z); - float3 p = stack_load_float3(stack, co_offset) * scale; - int hard = 0; + float scale = stack_load_float_default(stack, scale_offset, node2.x); + float detail = stack_load_float_default(stack, detail_offset, node2.y); + float distortion = stack_load_float_default(stack, distortion_offset, node2.z); + float3 p = stack_load_float3(stack, co_offset) * scale; + int hard = 0; - if(distortion != 0.0f) { - float3 r, offset = make_float3(13.5f, 13.5f, 13.5f); + if (distortion != 0.0f) { + float3 r, offset = make_float3(13.5f, 13.5f, 13.5f); - r.x = noise(p + offset) * distortion; - r.y = noise(p) * distortion; - r.z = noise(p - offset) * distortion; + r.x = noise(p + offset) * distortion; + r.y = noise(p) * distortion; + r.z = noise(p - offset) * distortion; - p += r; - } + p += r; + } - float f = noise_turbulence(p, detail, hard); + float f = noise_turbulence(p, detail, hard); - if(stack_valid(fac_offset)) { - stack_store_float(stack, fac_offset, f); - } - if(stack_valid(color_offset)) { - float3 color = make_float3(f, - noise_turbulence(make_float3(p.y, p.x, p.z), detail, hard), - noise_turbulence(make_float3(p.y, p.z, p.x), detail, hard)); - stack_store_float3(stack, color_offset, color); - } + if (stack_valid(fac_offset)) { + stack_store_float(stack, fac_offset, f); + } + if (stack_valid(color_offset)) { + float3 color = make_float3(f, + noise_turbulence(make_float3(p.y, p.x, p.z), detail, hard), + noise_turbulence(make_float3(p.y, p.z, p.x), detail, hard)); + stack_store_float3(stack, color_offset, color); + } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_normal.h b/intern/cycles/kernel/svm/svm_normal.h index fe46d79fe15..4cd3eab0ed2 100644 --- a/intern/cycles/kernel/svm/svm_normal.h +++ b/intern/cycles/kernel/svm/svm_normal.h @@ -16,23 +16,29 @@ CCL_NAMESPACE_BEGIN -ccl_device void svm_node_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_normal_offset, uint out_normal_offset, uint out_dot_offset, int *offset) +ccl_device void svm_node_normal(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint in_normal_offset, + uint out_normal_offset, + uint out_dot_offset, + int *offset) { - /* read extra data */ - uint4 node1 = read_node(kg, offset); - float3 normal = stack_load_float3(stack, in_normal_offset); + /* read extra data */ + uint4 node1 = read_node(kg, offset); + float3 normal = stack_load_float3(stack, in_normal_offset); - float3 direction; - direction.x = __int_as_float(node1.x); - direction.y = __int_as_float(node1.y); - direction.z = __int_as_float(node1.z); - direction = normalize(direction); + float3 direction; + direction.x = __int_as_float(node1.x); + direction.y = __int_as_float(node1.y); + direction.z = __int_as_float(node1.z); + direction = normalize(direction); - if(stack_valid(out_normal_offset)) - stack_store_float3(stack, out_normal_offset, direction); + if (stack_valid(out_normal_offset)) + stack_store_float3(stack, out_normal_offset, direction); - if(stack_valid(out_dot_offset)) - stack_store_float(stack, out_dot_offset, dot(direction, normalize(normal))); + if (stack_valid(out_dot_offset)) + stack_store_float(stack, out_dot_offset, dot(direction, normalize(normal))); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_ramp.h b/intern/cycles/kernel/svm/svm_ramp.h index 6f39391057e..6084ee35a1f 100644 --- a/intern/cycles/kernel/svm/svm_ramp.h +++ b/intern/cycles/kernel/svm/svm_ramp.h @@ -21,91 +21,84 @@ CCL_NAMESPACE_BEGIN /* NOTE: svm_ramp.h, svm_ramp_util.h and node_ramp_util.h must stay consistent */ -ccl_device_inline float4 rgb_ramp_lookup(KernelGlobals *kg, - int offset, - float f, - bool interpolate, - bool extrapolate, - int table_size) +ccl_device_inline float4 rgb_ramp_lookup( + KernelGlobals *kg, int offset, float f, bool interpolate, bool extrapolate, int table_size) { - if((f < 0.0f || f > 1.0f) && extrapolate) { - float4 t0, dy; - if(f < 0.0f) { - t0 = fetch_node_float(kg, offset); - dy = t0 - fetch_node_float(kg, offset + 1); - f = -f; - } - else { - t0 = fetch_node_float(kg, offset + table_size - 1); - dy = t0 - fetch_node_float(kg, offset + table_size - 2); - f = f - 1.0f; - } - return t0 + dy * f * (table_size-1); - } - - f = saturate(f)*(table_size-1); - - /* clamp int as well in case of NaN */ - int i = clamp(float_to_int(f), 0, table_size-1); - float t = f - (float)i; - - float4 a = fetch_node_float(kg, offset+i); - - if(interpolate && t > 0.0f) - a = (1.0f - t)*a + t*fetch_node_float(kg, offset+i+1); - - return a; + if ((f < 0.0f || f > 1.0f) && extrapolate) { + float4 t0, dy; + if (f < 0.0f) { + t0 = fetch_node_float(kg, offset); + dy = t0 - fetch_node_float(kg, offset + 1); + f = -f; + } + else { + t0 = fetch_node_float(kg, offset + table_size - 1); + dy = t0 - fetch_node_float(kg, offset + table_size - 2); + f = f - 1.0f; + } + return t0 + dy * f * (table_size - 1); + } + + f = saturate(f) * (table_size - 1); + + /* clamp int as well in case of NaN */ + int i = clamp(float_to_int(f), 0, table_size - 1); + float t = f - (float)i; + + float4 a = fetch_node_float(kg, offset + i); + + if (interpolate && t > 0.0f) + a = (1.0f - t) * a + t * fetch_node_float(kg, offset + i + 1); + + return a; } -ccl_device void svm_node_rgb_ramp(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_rgb_ramp( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint fac_offset, color_offset, alpha_offset; - uint interpolate = node.z; + uint fac_offset, color_offset, alpha_offset; + uint interpolate = node.z; - decode_node_uchar4(node.y, &fac_offset, &color_offset, &alpha_offset, NULL); + decode_node_uchar4(node.y, &fac_offset, &color_offset, &alpha_offset, NULL); - uint table_size = read_node(kg, offset).x; + uint table_size = read_node(kg, offset).x; - float fac = stack_load_float(stack, fac_offset); - float4 color = rgb_ramp_lookup(kg, *offset, fac, interpolate, false, table_size); + float fac = stack_load_float(stack, fac_offset); + float4 color = rgb_ramp_lookup(kg, *offset, fac, interpolate, false, table_size); - if(stack_valid(color_offset)) - stack_store_float3(stack, color_offset, float4_to_float3(color)); - if(stack_valid(alpha_offset)) - stack_store_float(stack, alpha_offset, color.w); + if (stack_valid(color_offset)) + stack_store_float3(stack, color_offset, float4_to_float3(color)); + if (stack_valid(alpha_offset)) + stack_store_float(stack, alpha_offset, color.w); - *offset += table_size; + *offset += table_size; } -ccl_device void svm_node_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_curves( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint fac_offset, color_offset, out_offset; - decode_node_uchar4(node.y, - &fac_offset, - &color_offset, - &out_offset, - NULL); + uint fac_offset, color_offset, out_offset; + decode_node_uchar4(node.y, &fac_offset, &color_offset, &out_offset, NULL); - uint table_size = read_node(kg, offset).x; + uint table_size = read_node(kg, offset).x; - float fac = stack_load_float(stack, fac_offset); - float3 color = stack_load_float3(stack, color_offset); + float fac = stack_load_float(stack, fac_offset); + float3 color = stack_load_float3(stack, color_offset); - const float min_x = __int_as_float(node.z), - max_x = __int_as_float(node.w); - const float range_x = max_x - min_x; - const float3 relpos = (color - make_float3(min_x, min_x, min_x)) / range_x; + const float min_x = __int_as_float(node.z), max_x = __int_as_float(node.w); + const float range_x = max_x - min_x; + const float3 relpos = (color - make_float3(min_x, min_x, min_x)) / range_x; - float r = rgb_ramp_lookup(kg, *offset, relpos.x, true, true, table_size).x; - float g = rgb_ramp_lookup(kg, *offset, relpos.y, true, true, table_size).y; - float b = rgb_ramp_lookup(kg, *offset, relpos.z, true, true, table_size).z; + float r = rgb_ramp_lookup(kg, *offset, relpos.x, true, true, table_size).x; + float g = rgb_ramp_lookup(kg, *offset, relpos.y, true, true, table_size).y; + float b = rgb_ramp_lookup(kg, *offset, relpos.z, true, true, table_size).z; - color = (1.0f - fac)*color + fac*make_float3(r, g, b); - stack_store_float3(stack, out_offset, color); + color = (1.0f - fac) * color + fac * make_float3(r, g, b); + stack_store_float3(stack, out_offset, color); - *offset += table_size; + *offset += table_size; } CCL_NAMESPACE_END -#endif /* __SVM_RAMP_H__ */ +#endif /* __SVM_RAMP_H__ */ diff --git a/intern/cycles/kernel/svm/svm_ramp_util.h b/intern/cycles/kernel/svm/svm_ramp_util.h index 847108ff1c2..202596c1fe3 100644 --- a/intern/cycles/kernel/svm/svm_ramp_util.h +++ b/intern/cycles/kernel/svm/svm_ramp_util.h @@ -21,78 +21,70 @@ CCL_NAMESPACE_BEGIN /* NOTE: svm_ramp.h, svm_ramp_util.h and node_ramp_util.h must stay consistent */ -ccl_device_inline float3 rgb_ramp_lookup(const float3 *ramp, - float f, - bool interpolate, - bool extrapolate, - int table_size) +ccl_device_inline float3 +rgb_ramp_lookup(const float3 *ramp, float f, bool interpolate, bool extrapolate, int table_size) { - if((f < 0.0f || f > 1.0f) && extrapolate) { - float3 t0, dy; - if(f < 0.0f) { - t0 = ramp[0]; - dy = t0 - ramp[1], - f = -f; - } - else { - t0 = ramp[table_size - 1]; - dy = t0 - ramp[table_size - 2]; - f = f - 1.0f; - } - return t0 + dy * f * (table_size - 1); - } - - f = clamp(f, 0.0f, 1.0f) * (table_size - 1); - - /* clamp int as well in case of NaN */ - int i = clamp(float_to_int(f), 0, table_size-1); - float t = f - (float)i; - - float3 result = ramp[i]; - - if(interpolate && t > 0.0f) { - result = (1.0f - t) * result + t * ramp[i + 1]; - } - - return result; + if ((f < 0.0f || f > 1.0f) && extrapolate) { + float3 t0, dy; + if (f < 0.0f) { + t0 = ramp[0]; + dy = t0 - ramp[1], f = -f; + } + else { + t0 = ramp[table_size - 1]; + dy = t0 - ramp[table_size - 2]; + f = f - 1.0f; + } + return t0 + dy * f * (table_size - 1); + } + + f = clamp(f, 0.0f, 1.0f) * (table_size - 1); + + /* clamp int as well in case of NaN */ + int i = clamp(float_to_int(f), 0, table_size - 1); + float t = f - (float)i; + + float3 result = ramp[i]; + + if (interpolate && t > 0.0f) { + result = (1.0f - t) * result + t * ramp[i + 1]; + } + + return result; } -ccl_device float float_ramp_lookup(const float *ramp, - float f, - bool interpolate, - bool extrapolate, - int table_size) +ccl_device float float_ramp_lookup( + const float *ramp, float f, bool interpolate, bool extrapolate, int table_size) { - if((f < 0.0f || f > 1.0f) && extrapolate) { - float t0, dy; - if(f < 0.0f) { - t0 = ramp[0]; - dy = t0 - ramp[1], - f = -f; - } - else { - t0 = ramp[table_size - 1]; - dy = t0 - ramp[table_size - 2]; - f = f - 1.0f; - } - return t0 + dy * f * (table_size - 1); - } - - f = clamp(f, 0.0f, 1.0f) * (table_size - 1); - - /* clamp int as well in case of NaN */ - int i = clamp(float_to_int(f), 0, table_size-1); - float t = f - (float)i; - - float result = ramp[i]; - - if(interpolate && t > 0.0f) { - result = (1.0f - t) * result + t * ramp[i + 1]; - } - - return result; + if ((f < 0.0f || f > 1.0f) && extrapolate) { + float t0, dy; + if (f < 0.0f) { + t0 = ramp[0]; + dy = t0 - ramp[1], f = -f; + } + else { + t0 = ramp[table_size - 1]; + dy = t0 - ramp[table_size - 2]; + f = f - 1.0f; + } + return t0 + dy * f * (table_size - 1); + } + + f = clamp(f, 0.0f, 1.0f) * (table_size - 1); + + /* clamp int as well in case of NaN */ + int i = clamp(float_to_int(f), 0, table_size - 1); + float t = f - (float)i; + + float result = ramp[i]; + + if (interpolate && t > 0.0f) { + result = (1.0f - t) * result + t * ramp[i + 1]; + } + + return result; } CCL_NAMESPACE_END -#endif /* __SVM_RAMP_UTIL_H__ */ +#endif /* __SVM_RAMP_UTIL_H__ */ diff --git a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h index 1096aed2d97..f501252062e 100644 --- a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h +++ b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h @@ -16,38 +16,50 @@ CCL_NAMESPACE_BEGIN -ccl_device void svm_node_combine_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint hue_in, uint saturation_in, uint value_in, int *offset) +ccl_device void svm_node_combine_hsv(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint hue_in, + uint saturation_in, + uint value_in, + int *offset) { - uint4 node1 = read_node(kg, offset); - uint color_out = node1.y; + uint4 node1 = read_node(kg, offset); + uint color_out = node1.y; - float hue = stack_load_float(stack, hue_in); - float saturation = stack_load_float(stack, saturation_in); - float value = stack_load_float(stack, value_in); + float hue = stack_load_float(stack, hue_in); + float saturation = stack_load_float(stack, saturation_in); + float value = stack_load_float(stack, value_in); - /* Combine, and convert back to RGB */ - float3 color = hsv_to_rgb(make_float3(hue, saturation, value)); + /* Combine, and convert back to RGB */ + float3 color = hsv_to_rgb(make_float3(hue, saturation, value)); - if(stack_valid(color_out)) - stack_store_float3(stack, color_out, color); + if (stack_valid(color_out)) + stack_store_float3(stack, color_out, color); } -ccl_device void svm_node_separate_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, uint color_in, uint hue_out, uint saturation_out, int *offset) +ccl_device void svm_node_separate_hsv(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint color_in, + uint hue_out, + uint saturation_out, + int *offset) { - uint4 node1 = read_node(kg, offset); - uint value_out = node1.y; + uint4 node1 = read_node(kg, offset); + uint value_out = node1.y; - float3 color = stack_load_float3(stack, color_in); + float3 color = stack_load_float3(stack, color_in); - /* Convert to HSV */ - color = rgb_to_hsv(color); + /* Convert to HSV */ + color = rgb_to_hsv(color); - if(stack_valid(hue_out)) - stack_store_float(stack, hue_out, color.x); - if(stack_valid(saturation_out)) - stack_store_float(stack, saturation_out, color.y); - if(stack_valid(value_out)) - stack_store_float(stack, value_out, color.z); + if (stack_valid(hue_out)) + stack_store_float(stack, hue_out, color.x); + if (stack_valid(saturation_out)) + stack_store_float(stack, saturation_out, color.y); + if (stack_valid(value_out)) + stack_store_float(stack, value_out, color.z); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_sepcomb_vector.h b/intern/cycles/kernel/svm/svm_sepcomb_vector.h index 0d85c0d6f1d..cbf77f1e640 100644 --- a/intern/cycles/kernel/svm/svm_sepcomb_vector.h +++ b/intern/cycles/kernel/svm/svm_sepcomb_vector.h @@ -18,26 +18,28 @@ CCL_NAMESPACE_BEGIN /* Vector combine / separate, used for the RGB and XYZ nodes */ -ccl_device void svm_node_combine_vector(ShaderData *sd, float *stack, uint in_offset, uint vector_index, uint out_offset) +ccl_device void svm_node_combine_vector( + ShaderData *sd, float *stack, uint in_offset, uint vector_index, uint out_offset) { - float vector = stack_load_float(stack, in_offset); + float vector = stack_load_float(stack, in_offset); - if(stack_valid(out_offset)) - stack_store_float(stack, out_offset+vector_index, vector); + if (stack_valid(out_offset)) + stack_store_float(stack, out_offset + vector_index, vector); } -ccl_device void svm_node_separate_vector(ShaderData *sd, float *stack, uint ivector_offset, uint vector_index, uint out_offset) +ccl_device void svm_node_separate_vector( + ShaderData *sd, float *stack, uint ivector_offset, uint vector_index, uint out_offset) { - float3 vector = stack_load_float3(stack, ivector_offset); + float3 vector = stack_load_float3(stack, ivector_offset); - if(stack_valid(out_offset)) { - if(vector_index == 0) - stack_store_float(stack, out_offset, vector.x); - else if(vector_index == 1) - stack_store_float(stack, out_offset, vector.y); - else - stack_store_float(stack, out_offset, vector.z); - } + if (stack_valid(out_offset)) { + if (vector_index == 0) + stack_store_float(stack, out_offset, vector.x); + else if (vector_index == 1) + stack_store_float(stack, out_offset, vector.y); + else + stack_store_float(stack, out_offset, vector.z); + } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h index 092f6e045d6..50fe0c8232f 100644 --- a/intern/cycles/kernel/svm/svm_sky.h +++ b/intern/cycles/kernel/svm/svm_sky.h @@ -20,8 +20,8 @@ CCL_NAMESPACE_BEGIN ccl_device float sky_angle_between(float thetav, float phiv, float theta, float phi) { - float cospsi = sinf(thetav)*sinf(theta)*cosf(phi - phiv) + cosf(thetav)*cosf(theta); - return safe_acosf(cospsi); + float cospsi = sinf(thetav) * sinf(theta) * cosf(phi - phiv) + cosf(thetav) * cosf(theta); + return safe_acosf(cospsi); } /* @@ -30,36 +30,43 @@ ccl_device float sky_angle_between(float thetav, float phiv, float theta, float */ ccl_device float sky_perez_function(float *lam, float theta, float gamma) { - float ctheta = cosf(theta); - float cgamma = cosf(gamma); + float ctheta = cosf(theta); + float cgamma = cosf(gamma); - return (1.0f + lam[0]*expf(lam[1]/ctheta)) * (1.0f + lam[2]*expf(lam[3]*gamma) + lam[4]*cgamma*cgamma); + return (1.0f + lam[0] * expf(lam[1] / ctheta)) * + (1.0f + lam[2] * expf(lam[3] * gamma) + lam[4] * cgamma * cgamma); } -ccl_device float3 sky_radiance_old(KernelGlobals *kg, float3 dir, - float sunphi, float suntheta, - float radiance_x, float radiance_y, float radiance_z, - float *config_x, float *config_y, float *config_z) +ccl_device float3 sky_radiance_old(KernelGlobals *kg, + float3 dir, + float sunphi, + float suntheta, + float radiance_x, + float radiance_y, + float radiance_z, + float *config_x, + float *config_y, + float *config_z) { - /* convert vector to spherical coordinates */ - float2 spherical = direction_to_spherical(dir); - float theta = spherical.x; - float phi = spherical.y; + /* convert vector to spherical coordinates */ + float2 spherical = direction_to_spherical(dir); + float theta = spherical.x; + float phi = spherical.y; - /* angle between sun direction and dir */ - float gamma = sky_angle_between(theta, phi, suntheta, sunphi); + /* angle between sun direction and dir */ + float gamma = sky_angle_between(theta, phi, suntheta, sunphi); - /* clamp theta to horizon */ - theta = min(theta, M_PI_2_F - 0.001f); + /* clamp theta to horizon */ + theta = min(theta, M_PI_2_F - 0.001f); - /* compute xyY color space values */ - float x = radiance_y * sky_perez_function(config_y, theta, gamma); - float y = radiance_z * sky_perez_function(config_z, theta, gamma); - float Y = radiance_x * sky_perez_function(config_x, theta, gamma); + /* compute xyY color space values */ + float x = radiance_y * sky_perez_function(config_y, theta, gamma); + float y = radiance_z * sky_perez_function(config_z, theta, gamma); + float Y = radiance_x * sky_perez_function(config_x, theta, gamma); - /* convert to RGB */ - float3 xyz = xyY_to_xyz(x, y, Y); - return xyz_to_rgb(kg, xyz); + /* convert to RGB */ + float3 xyz = xyY_to_xyz(x, y, Y); + return xyz_to_rgb(kg, xyz); } /* @@ -68,118 +75,142 @@ ccl_device float3 sky_radiance_old(KernelGlobals *kg, float3 dir, */ ccl_device float sky_radiance_internal(float *configuration, float theta, float gamma) { - float ctheta = cosf(theta); - float cgamma = cosf(gamma); - - float expM = expf(configuration[4] * gamma); - float rayM = cgamma * cgamma; - float mieM = (1.0f + rayM) / powf((1.0f + configuration[8]*configuration[8] - 2.0f*configuration[8]*cgamma), 1.5f); - float zenith = sqrtf(ctheta); - - return (1.0f + configuration[0] * expf(configuration[1] / (ctheta + 0.01f))) * - (configuration[2] + configuration[3] * expM + configuration[5] * rayM + configuration[6] * mieM + configuration[7] * zenith); + float ctheta = cosf(theta); + float cgamma = cosf(gamma); + + float expM = expf(configuration[4] * gamma); + float rayM = cgamma * cgamma; + float mieM = (1.0f + rayM) / powf((1.0f + configuration[8] * configuration[8] - + 2.0f * configuration[8] * cgamma), + 1.5f); + float zenith = sqrtf(ctheta); + + return (1.0f + configuration[0] * expf(configuration[1] / (ctheta + 0.01f))) * + (configuration[2] + configuration[3] * expM + configuration[5] * rayM + + configuration[6] * mieM + configuration[7] * zenith); } -ccl_device float3 sky_radiance_new(KernelGlobals *kg, float3 dir, - float sunphi, float suntheta, - float radiance_x, float radiance_y, float radiance_z, - float *config_x, float *config_y, float *config_z) +ccl_device float3 sky_radiance_new(KernelGlobals *kg, + float3 dir, + float sunphi, + float suntheta, + float radiance_x, + float radiance_y, + float radiance_z, + float *config_x, + float *config_y, + float *config_z) { - /* convert vector to spherical coordinates */ - float2 spherical = direction_to_spherical(dir); - float theta = spherical.x; - float phi = spherical.y; + /* convert vector to spherical coordinates */ + float2 spherical = direction_to_spherical(dir); + float theta = spherical.x; + float phi = spherical.y; - /* angle between sun direction and dir */ - float gamma = sky_angle_between(theta, phi, suntheta, sunphi); + /* angle between sun direction and dir */ + float gamma = sky_angle_between(theta, phi, suntheta, sunphi); - /* clamp theta to horizon */ - theta = min(theta, M_PI_2_F - 0.001f); + /* clamp theta to horizon */ + theta = min(theta, M_PI_2_F - 0.001f); - /* compute xyz color space values */ - float x = sky_radiance_internal(config_x, theta, gamma) * radiance_x; - float y = sky_radiance_internal(config_y, theta, gamma) * radiance_y; - float z = sky_radiance_internal(config_z, theta, gamma) * radiance_z; + /* compute xyz color space values */ + float x = sky_radiance_internal(config_x, theta, gamma) * radiance_x; + float y = sky_radiance_internal(config_y, theta, gamma) * radiance_y; + float z = sky_radiance_internal(config_z, theta, gamma) * radiance_z; - /* convert to RGB and adjust strength */ - return xyz_to_rgb(kg, make_float3(x, y, z)) * (M_2PI_F/683); + /* convert to RGB and adjust strength */ + return xyz_to_rgb(kg, make_float3(x, y, z)) * (M_2PI_F / 683); } -ccl_device void svm_node_tex_sky(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_tex_sky( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - /* Define variables */ - float sunphi, suntheta, radiance_x, radiance_y, radiance_z; - float config_x[9], config_y[9], config_z[9]; - - /* Load data */ - uint dir_offset = node.y; - uint out_offset = node.z; - int sky_model = node.w; - - float4 data = read_node_float(kg, offset); - sunphi = data.x; - suntheta = data.y; - radiance_x = data.z; - radiance_y = data.w; - - data = read_node_float(kg, offset); - radiance_z = data.x; - config_x[0] = data.y; - config_x[1] = data.z; - config_x[2] = data.w; - - data = read_node_float(kg, offset); - config_x[3] = data.x; - config_x[4] = data.y; - config_x[5] = data.z; - config_x[6] = data.w; - - data = read_node_float(kg, offset); - config_x[7] = data.x; - config_x[8] = data.y; - config_y[0] = data.z; - config_y[1] = data.w; - - data = read_node_float(kg, offset); - config_y[2] = data.x; - config_y[3] = data.y; - config_y[4] = data.z; - config_y[5] = data.w; - - data = read_node_float(kg, offset); - config_y[6] = data.x; - config_y[7] = data.y; - config_y[8] = data.z; - config_z[0] = data.w; - - data = read_node_float(kg, offset); - config_z[1] = data.x; - config_z[2] = data.y; - config_z[3] = data.z; - config_z[4] = data.w; - - data = read_node_float(kg, offset); - config_z[5] = data.x; - config_z[6] = data.y; - config_z[7] = data.z; - config_z[8] = data.w; - - float3 dir = stack_load_float3(stack, dir_offset); - float3 f; - - /* Compute Sky */ - if(sky_model == 0) { - f = sky_radiance_old(kg, dir, sunphi, suntheta, - radiance_x, radiance_y, radiance_z, - config_x, config_y, config_z); - } - else { - f = sky_radiance_new(kg, dir, sunphi, suntheta, - radiance_x, radiance_y, radiance_z, - config_x, config_y, config_z); - } - - stack_store_float3(stack, out_offset, f); + /* Define variables */ + float sunphi, suntheta, radiance_x, radiance_y, radiance_z; + float config_x[9], config_y[9], config_z[9]; + + /* Load data */ + uint dir_offset = node.y; + uint out_offset = node.z; + int sky_model = node.w; + + float4 data = read_node_float(kg, offset); + sunphi = data.x; + suntheta = data.y; + radiance_x = data.z; + radiance_y = data.w; + + data = read_node_float(kg, offset); + radiance_z = data.x; + config_x[0] = data.y; + config_x[1] = data.z; + config_x[2] = data.w; + + data = read_node_float(kg, offset); + config_x[3] = data.x; + config_x[4] = data.y; + config_x[5] = data.z; + config_x[6] = data.w; + + data = read_node_float(kg, offset); + config_x[7] = data.x; + config_x[8] = data.y; + config_y[0] = data.z; + config_y[1] = data.w; + + data = read_node_float(kg, offset); + config_y[2] = data.x; + config_y[3] = data.y; + config_y[4] = data.z; + config_y[5] = data.w; + + data = read_node_float(kg, offset); + config_y[6] = data.x; + config_y[7] = data.y; + config_y[8] = data.z; + config_z[0] = data.w; + + data = read_node_float(kg, offset); + config_z[1] = data.x; + config_z[2] = data.y; + config_z[3] = data.z; + config_z[4] = data.w; + + data = read_node_float(kg, offset); + config_z[5] = data.x; + config_z[6] = data.y; + config_z[7] = data.z; + config_z[8] = data.w; + + float3 dir = stack_load_float3(stack, dir_offset); + float3 f; + + /* Compute Sky */ + if (sky_model == 0) { + f = sky_radiance_old(kg, + dir, + sunphi, + suntheta, + radiance_x, + radiance_y, + radiance_z, + config_x, + config_y, + config_z); + } + else { + f = sky_radiance_new(kg, + dir, + sunphi, + suntheta, + radiance_x, + radiance_y, + radiance_z, + config_x, + config_y, + config_z); + } + + stack_store_float3(stack, out_offset, f); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index fe61292d0b0..1fb3e20f9e0 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -18,390 +18,381 @@ CCL_NAMESPACE_BEGIN /* Texture Coordinate Node */ -ccl_device void svm_node_tex_coord(KernelGlobals *kg, - ShaderData *sd, - int path_flag, - float *stack, - uint4 node, - int *offset) +ccl_device void svm_node_tex_coord( + KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset) { - float3 data; - uint type = node.y; - uint out_offset = node.z; - - switch(type) { - case NODE_TEXCO_OBJECT: { - data = sd->P; - if(node.w == 0) { - if(sd->object != OBJECT_NONE) { - object_inverse_position_transform(kg, sd, &data); - } - } - else { - Transform tfm; - tfm.x = read_node_float(kg, offset); - tfm.y = read_node_float(kg, offset); - tfm.z = read_node_float(kg, offset); - data = transform_point(&tfm, data); - } - break; - } - case NODE_TEXCO_NORMAL: { - data = sd->N; - object_inverse_normal_transform(kg, sd, &data); - break; - } - case NODE_TEXCO_CAMERA: { - Transform tfm = kernel_data.cam.worldtocamera; - - if(sd->object != OBJECT_NONE) - data = transform_point(&tfm, sd->P); - else - data = transform_point(&tfm, sd->P + camera_position(kg)); - break; - } - case NODE_TEXCO_WINDOW: { - if((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) - data = camera_world_to_ndc(kg, sd, sd->ray_P); - else - data = camera_world_to_ndc(kg, sd, sd->P); - data.z = 0.0f; - break; - } - case NODE_TEXCO_REFLECTION: { - if(sd->object != OBJECT_NONE) - data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I; - else - data = sd->I; - break; - } - case NODE_TEXCO_DUPLI_GENERATED: { - data = object_dupli_generated(kg, sd->object); - break; - } - case NODE_TEXCO_DUPLI_UV: { - data = object_dupli_uv(kg, sd->object); - break; - } - case NODE_TEXCO_VOLUME_GENERATED: { - data = sd->P; + float3 data; + uint type = node.y; + uint out_offset = node.z; + + switch (type) { + case NODE_TEXCO_OBJECT: { + data = sd->P; + if (node.w == 0) { + if (sd->object != OBJECT_NONE) { + object_inverse_position_transform(kg, sd, &data); + } + } + else { + Transform tfm; + tfm.x = read_node_float(kg, offset); + tfm.y = read_node_float(kg, offset); + tfm.z = read_node_float(kg, offset); + data = transform_point(&tfm, data); + } + break; + } + case NODE_TEXCO_NORMAL: { + data = sd->N; + object_inverse_normal_transform(kg, sd, &data); + break; + } + case NODE_TEXCO_CAMERA: { + Transform tfm = kernel_data.cam.worldtocamera; + + if (sd->object != OBJECT_NONE) + data = transform_point(&tfm, sd->P); + else + data = transform_point(&tfm, sd->P + camera_position(kg)); + break; + } + case NODE_TEXCO_WINDOW: { + if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && + kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) + data = camera_world_to_ndc(kg, sd, sd->ray_P); + else + data = camera_world_to_ndc(kg, sd, sd->P); + data.z = 0.0f; + break; + } + case NODE_TEXCO_REFLECTION: { + if (sd->object != OBJECT_NONE) + data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I; + else + data = sd->I; + break; + } + case NODE_TEXCO_DUPLI_GENERATED: { + data = object_dupli_generated(kg, sd->object); + break; + } + case NODE_TEXCO_DUPLI_UV: { + data = object_dupli_uv(kg, sd->object); + break; + } + case NODE_TEXCO_VOLUME_GENERATED: { + data = sd->P; #ifdef __VOLUME__ - if(sd->object != OBJECT_NONE) - data = volume_normalized_position(kg, sd, data); + if (sd->object != OBJECT_NONE) + data = volume_normalized_position(kg, sd, data); #endif - break; - } - } + break; + } + } - stack_store_float3(stack, out_offset, data); + stack_store_float3(stack, out_offset, data); } -ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, - ShaderData *sd, - int path_flag, - float *stack, - uint4 node, - int *offset) +ccl_device void svm_node_tex_coord_bump_dx( + KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset) { #ifdef __RAY_DIFFERENTIALS__ - float3 data; - uint type = node.y; - uint out_offset = node.z; - - switch(type) { - case NODE_TEXCO_OBJECT: { - data = sd->P + sd->dP.dx; - if(node.w == 0) { - if(sd->object != OBJECT_NONE) { - object_inverse_position_transform(kg, sd, &data); - } - } - else { - Transform tfm; - tfm.x = read_node_float(kg, offset); - tfm.y = read_node_float(kg, offset); - tfm.z = read_node_float(kg, offset); - data = transform_point(&tfm, data); - } - break; - } - case NODE_TEXCO_NORMAL: { - data = sd->N; - object_inverse_normal_transform(kg, sd, &data); - break; - } - case NODE_TEXCO_CAMERA: { - Transform tfm = kernel_data.cam.worldtocamera; - - if(sd->object != OBJECT_NONE) - data = transform_point(&tfm, sd->P + sd->dP.dx); - else - data = transform_point(&tfm, sd->P + sd->dP.dx + camera_position(kg)); - break; - } - case NODE_TEXCO_WINDOW: { - if((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) - data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx); - else - data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx); - data.z = 0.0f; - break; - } - case NODE_TEXCO_REFLECTION: { - if(sd->object != OBJECT_NONE) - data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I; - else - data = sd->I; - break; - } - case NODE_TEXCO_DUPLI_GENERATED: { - data = object_dupli_generated(kg, sd->object); - break; - } - case NODE_TEXCO_DUPLI_UV: { - data = object_dupli_uv(kg, sd->object); - break; - } - case NODE_TEXCO_VOLUME_GENERATED: { - data = sd->P + sd->dP.dx; - -#ifdef __VOLUME__ - if(sd->object != OBJECT_NONE) - data = volume_normalized_position(kg, sd, data); -#endif - break; - } - } - - stack_store_float3(stack, out_offset, data); + float3 data; + uint type = node.y; + uint out_offset = node.z; + + switch (type) { + case NODE_TEXCO_OBJECT: { + data = sd->P + sd->dP.dx; + if (node.w == 0) { + if (sd->object != OBJECT_NONE) { + object_inverse_position_transform(kg, sd, &data); + } + } + else { + Transform tfm; + tfm.x = read_node_float(kg, offset); + tfm.y = read_node_float(kg, offset); + tfm.z = read_node_float(kg, offset); + data = transform_point(&tfm, data); + } + break; + } + case NODE_TEXCO_NORMAL: { + data = sd->N; + object_inverse_normal_transform(kg, sd, &data); + break; + } + case NODE_TEXCO_CAMERA: { + Transform tfm = kernel_data.cam.worldtocamera; + + if (sd->object != OBJECT_NONE) + data = transform_point(&tfm, sd->P + sd->dP.dx); + else + data = transform_point(&tfm, sd->P + sd->dP.dx + camera_position(kg)); + break; + } + case NODE_TEXCO_WINDOW: { + if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && + kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) + data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx); + else + data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx); + data.z = 0.0f; + break; + } + case NODE_TEXCO_REFLECTION: { + if (sd->object != OBJECT_NONE) + data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I; + else + data = sd->I; + break; + } + case NODE_TEXCO_DUPLI_GENERATED: { + data = object_dupli_generated(kg, sd->object); + break; + } + case NODE_TEXCO_DUPLI_UV: { + data = object_dupli_uv(kg, sd->object); + break; + } + case NODE_TEXCO_VOLUME_GENERATED: { + data = sd->P + sd->dP.dx; + +# ifdef __VOLUME__ + if (sd->object != OBJECT_NONE) + data = volume_normalized_position(kg, sd, data); +# endif + break; + } + } + + stack_store_float3(stack, out_offset, data); #else - svm_node_tex_coord(kg, sd, path_flag, stack, node, offset); + svm_node_tex_coord(kg, sd, path_flag, stack, node, offset); #endif } -ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, - ShaderData *sd, - int path_flag, - float *stack, - uint4 node, - int *offset) +ccl_device void svm_node_tex_coord_bump_dy( + KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset) { #ifdef __RAY_DIFFERENTIALS__ - float3 data; - uint type = node.y; - uint out_offset = node.z; - - switch(type) { - case NODE_TEXCO_OBJECT: { - data = sd->P + sd->dP.dy; - if(node.w == 0) { - if(sd->object != OBJECT_NONE) { - object_inverse_position_transform(kg, sd, &data); - } - } - else { - Transform tfm; - tfm.x = read_node_float(kg, offset); - tfm.y = read_node_float(kg, offset); - tfm.z = read_node_float(kg, offset); - data = transform_point(&tfm, data); - } - break; - } - case NODE_TEXCO_NORMAL: { - data = sd->N; - object_inverse_normal_transform(kg, sd, &data); - break; - } - case NODE_TEXCO_CAMERA: { - Transform tfm = kernel_data.cam.worldtocamera; - - if(sd->object != OBJECT_NONE) - data = transform_point(&tfm, sd->P + sd->dP.dy); - else - data = transform_point(&tfm, sd->P + sd->dP.dy + camera_position(kg)); - break; - } - case NODE_TEXCO_WINDOW: { - if((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) - data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy); - else - data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy); - data.z = 0.0f; - break; - } - case NODE_TEXCO_REFLECTION: { - if(sd->object != OBJECT_NONE) - data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I; - else - data = sd->I; - break; - } - case NODE_TEXCO_DUPLI_GENERATED: { - data = object_dupli_generated(kg, sd->object); - break; - } - case NODE_TEXCO_DUPLI_UV: { - data = object_dupli_uv(kg, sd->object); - break; - } - case NODE_TEXCO_VOLUME_GENERATED: { - data = sd->P + sd->dP.dy; - -#ifdef __VOLUME__ - if(sd->object != OBJECT_NONE) - data = volume_normalized_position(kg, sd, data); -#endif - break; - } - } - - stack_store_float3(stack, out_offset, data); + float3 data; + uint type = node.y; + uint out_offset = node.z; + + switch (type) { + case NODE_TEXCO_OBJECT: { + data = sd->P + sd->dP.dy; + if (node.w == 0) { + if (sd->object != OBJECT_NONE) { + object_inverse_position_transform(kg, sd, &data); + } + } + else { + Transform tfm; + tfm.x = read_node_float(kg, offset); + tfm.y = read_node_float(kg, offset); + tfm.z = read_node_float(kg, offset); + data = transform_point(&tfm, data); + } + break; + } + case NODE_TEXCO_NORMAL: { + data = sd->N; + object_inverse_normal_transform(kg, sd, &data); + break; + } + case NODE_TEXCO_CAMERA: { + Transform tfm = kernel_data.cam.worldtocamera; + + if (sd->object != OBJECT_NONE) + data = transform_point(&tfm, sd->P + sd->dP.dy); + else + data = transform_point(&tfm, sd->P + sd->dP.dy + camera_position(kg)); + break; + } + case NODE_TEXCO_WINDOW: { + if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE && + kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) + data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy); + else + data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy); + data.z = 0.0f; + break; + } + case NODE_TEXCO_REFLECTION: { + if (sd->object != OBJECT_NONE) + data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I; + else + data = sd->I; + break; + } + case NODE_TEXCO_DUPLI_GENERATED: { + data = object_dupli_generated(kg, sd->object); + break; + } + case NODE_TEXCO_DUPLI_UV: { + data = object_dupli_uv(kg, sd->object); + break; + } + case NODE_TEXCO_VOLUME_GENERATED: { + data = sd->P + sd->dP.dy; + +# ifdef __VOLUME__ + if (sd->object != OBJECT_NONE) + data = volume_normalized_position(kg, sd, data); +# endif + break; + } + } + + stack_store_float3(stack, out_offset, data); #else - svm_node_tex_coord(kg, sd, path_flag, stack, node, offset); + svm_node_tex_coord(kg, sd, path_flag, stack, node, offset); #endif } ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - uint color_offset, strength_offset, normal_offset, space; - decode_node_uchar4(node.y, &color_offset, &strength_offset, &normal_offset, &space); - - float3 color = stack_load_float3(stack, color_offset); - color = 2.0f*make_float3(color.x - 0.5f, color.y - 0.5f, color.z - 0.5f); - - bool is_backfacing = (sd->flag & SD_BACKFACING) != 0; - float3 N; - - if(space == NODE_NORMAL_MAP_TANGENT) { - /* tangent space */ - if(sd->object == OBJECT_NONE) { - stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f)); - return; - } - - /* first try to get tangent attribute */ - const AttributeDescriptor attr = find_attribute(kg, sd, node.z); - const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w); - const AttributeDescriptor attr_normal = find_attribute(kg, sd, ATTR_STD_VERTEX_NORMAL); - - if(attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND || attr_normal.offset == ATTR_STD_NOT_FOUND) { - stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f)); - return; - } - - /* get _unnormalized_ interpolated normal and tangent */ - float3 tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL); - float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL); - float3 normal; - - if(sd->shader & SHADER_SMOOTH_NORMAL) { - normal = primitive_surface_attribute_float3(kg, sd, attr_normal, NULL, NULL); - } - else { - normal = sd->Ng; - - /* the normal is already inverted, which is too soon for the math here */ - if(is_backfacing) { - normal = -normal; - } - - object_inverse_normal_transform(kg, sd, &normal); - } - - /* apply normal map */ - float3 B = sign * cross(normal, tangent); - N = safe_normalize(color.x * tangent + color.y * B + color.z * normal); - - /* transform to world space */ - object_normal_transform(kg, sd, &N); - } - else { - /* strange blender convention */ - if(space == NODE_NORMAL_MAP_BLENDER_OBJECT || space == NODE_NORMAL_MAP_BLENDER_WORLD) { - color.y = -color.y; - color.z = -color.z; - } - - /* object, world space */ - N = color; - - if(space == NODE_NORMAL_MAP_OBJECT || space == NODE_NORMAL_MAP_BLENDER_OBJECT) - object_normal_transform(kg, sd, &N); - else - N = safe_normalize(N); - } - - /* invert normal for backfacing polygons */ - if(is_backfacing) { - N = -N; - } - - float strength = stack_load_float(stack, strength_offset); - - if(strength != 1.0f) { - strength = max(strength, 0.0f); - N = safe_normalize(sd->N + (N - sd->N)*strength); - } - - N = ensure_valid_reflection(sd->Ng, sd->I, N); - - if(is_zero(N)) { - N = sd->N; - } - - stack_store_float3(stack, normal_offset, N); + uint color_offset, strength_offset, normal_offset, space; + decode_node_uchar4(node.y, &color_offset, &strength_offset, &normal_offset, &space); + + float3 color = stack_load_float3(stack, color_offset); + color = 2.0f * make_float3(color.x - 0.5f, color.y - 0.5f, color.z - 0.5f); + + bool is_backfacing = (sd->flag & SD_BACKFACING) != 0; + float3 N; + + if (space == NODE_NORMAL_MAP_TANGENT) { + /* tangent space */ + if (sd->object == OBJECT_NONE) { + stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f)); + return; + } + + /* first try to get tangent attribute */ + const AttributeDescriptor attr = find_attribute(kg, sd, node.z); + const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w); + const AttributeDescriptor attr_normal = find_attribute(kg, sd, ATTR_STD_VERTEX_NORMAL); + + if (attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND || + attr_normal.offset == ATTR_STD_NOT_FOUND) { + stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f)); + return; + } + + /* get _unnormalized_ interpolated normal and tangent */ + float3 tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL); + float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL); + float3 normal; + + if (sd->shader & SHADER_SMOOTH_NORMAL) { + normal = primitive_surface_attribute_float3(kg, sd, attr_normal, NULL, NULL); + } + else { + normal = sd->Ng; + + /* the normal is already inverted, which is too soon for the math here */ + if (is_backfacing) { + normal = -normal; + } + + object_inverse_normal_transform(kg, sd, &normal); + } + + /* apply normal map */ + float3 B = sign * cross(normal, tangent); + N = safe_normalize(color.x * tangent + color.y * B + color.z * normal); + + /* transform to world space */ + object_normal_transform(kg, sd, &N); + } + else { + /* strange blender convention */ + if (space == NODE_NORMAL_MAP_BLENDER_OBJECT || space == NODE_NORMAL_MAP_BLENDER_WORLD) { + color.y = -color.y; + color.z = -color.z; + } + + /* object, world space */ + N = color; + + if (space == NODE_NORMAL_MAP_OBJECT || space == NODE_NORMAL_MAP_BLENDER_OBJECT) + object_normal_transform(kg, sd, &N); + else + N = safe_normalize(N); + } + + /* invert normal for backfacing polygons */ + if (is_backfacing) { + N = -N; + } + + float strength = stack_load_float(stack, strength_offset); + + if (strength != 1.0f) { + strength = max(strength, 0.0f); + N = safe_normalize(sd->N + (N - sd->N) * strength); + } + + N = ensure_valid_reflection(sd->Ng, sd->I, N); + + if (is_zero(N)) { + N = sd->N; + } + + stack_store_float3(stack, normal_offset, N); } ccl_device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - uint tangent_offset, direction_type, axis; - decode_node_uchar4(node.y, &tangent_offset, &direction_type, &axis, NULL); - - float3 tangent; - float3 attribute_value; - const AttributeDescriptor desc = find_attribute(kg, sd, node.z); - if (desc.offset != ATTR_STD_NOT_FOUND) { - if(desc.type == NODE_ATTR_FLOAT2) { - float2 value = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL); - attribute_value.x = value.x; - attribute_value.y = value.y; - attribute_value.z = 0.0f; - } - else { - attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL); - } - } - - - if(direction_type == NODE_TANGENT_UVMAP) { - /* UV map */ - if(desc.offset == ATTR_STD_NOT_FOUND) - tangent = make_float3(0.0f, 0.0f, 0.0f); - else - tangent = attribute_value; - } - else { - /* radial */ - float3 generated; - - if(desc.offset == ATTR_STD_NOT_FOUND) - generated = sd->P; - else - generated = attribute_value; - - if(axis == NODE_TANGENT_AXIS_X) - tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f)); - else if(axis == NODE_TANGENT_AXIS_Y) - tangent = make_float3(-(generated.z - 0.5f), 0.0f, (generated.x - 0.5f)); - else - tangent = make_float3(-(generated.y - 0.5f), (generated.x - 0.5f), 0.0f); - } - - object_normal_transform(kg, sd, &tangent); - tangent = cross(sd->N, normalize(cross(tangent, sd->N))); - stack_store_float3(stack, tangent_offset, tangent); + uint tangent_offset, direction_type, axis; + decode_node_uchar4(node.y, &tangent_offset, &direction_type, &axis, NULL); + + float3 tangent; + float3 attribute_value; + const AttributeDescriptor desc = find_attribute(kg, sd, node.z); + if (desc.offset != ATTR_STD_NOT_FOUND) { + if (desc.type == NODE_ATTR_FLOAT2) { + float2 value = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL); + attribute_value.x = value.x; + attribute_value.y = value.y; + attribute_value.z = 0.0f; + } + else { + attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL); + } + } + + if (direction_type == NODE_TANGENT_UVMAP) { + /* UV map */ + if (desc.offset == ATTR_STD_NOT_FOUND) + tangent = make_float3(0.0f, 0.0f, 0.0f); + else + tangent = attribute_value; + } + else { + /* radial */ + float3 generated; + + if (desc.offset == ATTR_STD_NOT_FOUND) + generated = sd->P; + else + generated = attribute_value; + + if (axis == NODE_TANGENT_AXIS_X) + tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f)); + else if (axis == NODE_TANGENT_AXIS_Y) + tangent = make_float3(-(generated.z - 0.5f), 0.0f, (generated.x - 0.5f)); + else + tangent = make_float3(-(generated.y - 0.5f), (generated.x - 0.5f), 0.0f); + } + + object_normal_transform(kg, sd, &tangent); + tangent = cross(sd->N, normalize(cross(tangent, sd->N))); + stack_store_float3(stack, tangent_offset, tangent); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_texture.h b/intern/cycles/kernel/svm/svm_texture.h index 57729817bdc..290aa85c831 100644 --- a/intern/cycles/kernel/svm/svm_texture.h +++ b/intern/cycles/kernel/svm/svm_texture.h @@ -20,44 +20,44 @@ CCL_NAMESPACE_BEGIN ccl_device_noinline float noise_turbulence(float3 p, float octaves, int hard) { - float fscale = 1.0f; - float amp = 1.0f; - float sum = 0.0f; - int i, n; + float fscale = 1.0f; + float amp = 1.0f; + float sum = 0.0f; + int i, n; - octaves = clamp(octaves, 0.0f, 16.0f); - n = float_to_int(octaves); + octaves = clamp(octaves, 0.0f, 16.0f); + n = float_to_int(octaves); - for(i = 0; i <= n; i++) { - float t = noise(fscale*p); + for (i = 0; i <= n; i++) { + float t = noise(fscale * p); - if(hard) - t = fabsf(2.0f*t - 1.0f); + if (hard) + t = fabsf(2.0f * t - 1.0f); - sum += t*amp; - amp *= 0.5f; - fscale *= 2.0f; - } + sum += t * amp; + amp *= 0.5f; + fscale *= 2.0f; + } - float rmd = octaves - floorf(octaves); + float rmd = octaves - floorf(octaves); - if(rmd != 0.0f) { - float t = noise(fscale*p); + if (rmd != 0.0f) { + float t = noise(fscale * p); - if(hard) - t = fabsf(2.0f*t - 1.0f); + if (hard) + t = fabsf(2.0f * t - 1.0f); - float sum2 = sum + t*amp; + float sum2 = sum + t * amp; - sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1)); - sum2 *= ((float)(1 << (n+1))/(float)((1 << (n+2)) - 1)); + sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1)); + sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1)); - return (1.0f - rmd)*sum + rmd*sum2; - } - else { - sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1)); - return sum; - } + return (1.0f - rmd) * sum + rmd * sum2; + } + else { + sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1)); + return sum; + } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 8b15d7bf9f4..d31e4f93696 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -38,498 +38,505 @@ CCL_NAMESPACE_BEGIN * * Lower the number of group more often the node is used. */ -#define NODE_GROUP_LEVEL_0 0 -#define NODE_GROUP_LEVEL_1 1 -#define NODE_GROUP_LEVEL_2 2 -#define NODE_GROUP_LEVEL_3 3 -#define NODE_GROUP_LEVEL_MAX NODE_GROUP_LEVEL_3 - -#define NODE_FEATURE_VOLUME (1 << 0) -#define NODE_FEATURE_HAIR (1 << 1) -#define NODE_FEATURE_BUMP (1 << 2) +#define NODE_GROUP_LEVEL_0 0 +#define NODE_GROUP_LEVEL_1 1 +#define NODE_GROUP_LEVEL_2 2 +#define NODE_GROUP_LEVEL_3 3 +#define NODE_GROUP_LEVEL_MAX NODE_GROUP_LEVEL_3 + +#define NODE_FEATURE_VOLUME (1 << 0) +#define NODE_FEATURE_HAIR (1 << 1) +#define NODE_FEATURE_BUMP (1 << 2) #define NODE_FEATURE_BUMP_STATE (1 << 3) /* TODO(sergey): Consider using something like ((uint)(-1)). * Need to check carefully operand types around usage of this * define first. */ -#define NODE_FEATURE_ALL (NODE_FEATURE_VOLUME|NODE_FEATURE_HAIR|NODE_FEATURE_BUMP|NODE_FEATURE_BUMP_STATE) +#define NODE_FEATURE_ALL \ + (NODE_FEATURE_VOLUME | NODE_FEATURE_HAIR | NODE_FEATURE_BUMP | NODE_FEATURE_BUMP_STATE) typedef enum ShaderNodeType { - NODE_END = 0, - NODE_CLOSURE_BSDF, - NODE_CLOSURE_EMISSION, - NODE_CLOSURE_BACKGROUND, - NODE_CLOSURE_SET_WEIGHT, - NODE_CLOSURE_WEIGHT, - NODE_MIX_CLOSURE, - NODE_JUMP_IF_ZERO, - NODE_JUMP_IF_ONE, - NODE_TEX_IMAGE, - NODE_TEX_IMAGE_BOX, - NODE_TEX_SKY, - NODE_GEOMETRY, - NODE_GEOMETRY_DUPLI, - NODE_LIGHT_PATH, - NODE_VALUE_F, - NODE_VALUE_V, - NODE_MIX, - NODE_ATTR, - NODE_CONVERT, - NODE_FRESNEL, - NODE_WIREFRAME, - NODE_WAVELENGTH, - NODE_BLACKBODY, - NODE_EMISSION_WEIGHT, - NODE_TEX_GRADIENT, - NODE_TEX_VORONOI, - NODE_TEX_MUSGRAVE, - NODE_TEX_WAVE, - NODE_TEX_MAGIC, - NODE_TEX_NOISE, - NODE_SHADER_JUMP, - NODE_SET_DISPLACEMENT, - NODE_GEOMETRY_BUMP_DX, - NODE_GEOMETRY_BUMP_DY, - NODE_SET_BUMP, - NODE_MATH, - NODE_VECTOR_MATH, - NODE_VECTOR_TRANSFORM, - NODE_MAPPING, - NODE_TEX_COORD, - NODE_TEX_COORD_BUMP_DX, - NODE_TEX_COORD_BUMP_DY, - NODE_ATTR_BUMP_DX, - NODE_ATTR_BUMP_DY, - NODE_TEX_ENVIRONMENT, - NODE_CLOSURE_HOLDOUT, - NODE_LAYER_WEIGHT, - NODE_CLOSURE_VOLUME, - NODE_SEPARATE_VECTOR, - NODE_COMBINE_VECTOR, - NODE_SEPARATE_HSV, - NODE_COMBINE_HSV, - NODE_HSV, - NODE_CAMERA, - NODE_INVERT, - NODE_NORMAL, - NODE_GAMMA, - NODE_TEX_CHECKER, - NODE_BRIGHTCONTRAST, - NODE_RGB_RAMP, - NODE_RGB_CURVES, - NODE_VECTOR_CURVES, - NODE_MIN_MAX, - NODE_LIGHT_FALLOFF, - NODE_OBJECT_INFO, - NODE_PARTICLE_INFO, - NODE_TEX_BRICK, - NODE_CLOSURE_SET_NORMAL, - NODE_AMBIENT_OCCLUSION, - NODE_TANGENT, - NODE_NORMAL_MAP, - NODE_HAIR_INFO, - NODE_UVMAP, - NODE_TEX_VOXEL, - NODE_ENTER_BUMP_EVAL, - NODE_LEAVE_BUMP_EVAL, - NODE_BEVEL, - NODE_DISPLACEMENT, - NODE_VECTOR_DISPLACEMENT, - NODE_PRINCIPLED_VOLUME, - NODE_IES, + NODE_END = 0, + NODE_CLOSURE_BSDF, + NODE_CLOSURE_EMISSION, + NODE_CLOSURE_BACKGROUND, + NODE_CLOSURE_SET_WEIGHT, + NODE_CLOSURE_WEIGHT, + NODE_MIX_CLOSURE, + NODE_JUMP_IF_ZERO, + NODE_JUMP_IF_ONE, + NODE_TEX_IMAGE, + NODE_TEX_IMAGE_BOX, + NODE_TEX_SKY, + NODE_GEOMETRY, + NODE_GEOMETRY_DUPLI, + NODE_LIGHT_PATH, + NODE_VALUE_F, + NODE_VALUE_V, + NODE_MIX, + NODE_ATTR, + NODE_CONVERT, + NODE_FRESNEL, + NODE_WIREFRAME, + NODE_WAVELENGTH, + NODE_BLACKBODY, + NODE_EMISSION_WEIGHT, + NODE_TEX_GRADIENT, + NODE_TEX_VORONOI, + NODE_TEX_MUSGRAVE, + NODE_TEX_WAVE, + NODE_TEX_MAGIC, + NODE_TEX_NOISE, + NODE_SHADER_JUMP, + NODE_SET_DISPLACEMENT, + NODE_GEOMETRY_BUMP_DX, + NODE_GEOMETRY_BUMP_DY, + NODE_SET_BUMP, + NODE_MATH, + NODE_VECTOR_MATH, + NODE_VECTOR_TRANSFORM, + NODE_MAPPING, + NODE_TEX_COORD, + NODE_TEX_COORD_BUMP_DX, + NODE_TEX_COORD_BUMP_DY, + NODE_ATTR_BUMP_DX, + NODE_ATTR_BUMP_DY, + NODE_TEX_ENVIRONMENT, + NODE_CLOSURE_HOLDOUT, + NODE_LAYER_WEIGHT, + NODE_CLOSURE_VOLUME, + NODE_SEPARATE_VECTOR, + NODE_COMBINE_VECTOR, + NODE_SEPARATE_HSV, + NODE_COMBINE_HSV, + NODE_HSV, + NODE_CAMERA, + NODE_INVERT, + NODE_NORMAL, + NODE_GAMMA, + NODE_TEX_CHECKER, + NODE_BRIGHTCONTRAST, + NODE_RGB_RAMP, + NODE_RGB_CURVES, + NODE_VECTOR_CURVES, + NODE_MIN_MAX, + NODE_LIGHT_FALLOFF, + NODE_OBJECT_INFO, + NODE_PARTICLE_INFO, + NODE_TEX_BRICK, + NODE_CLOSURE_SET_NORMAL, + NODE_AMBIENT_OCCLUSION, + NODE_TANGENT, + NODE_NORMAL_MAP, + NODE_HAIR_INFO, + NODE_UVMAP, + NODE_TEX_VOXEL, + NODE_ENTER_BUMP_EVAL, + NODE_LEAVE_BUMP_EVAL, + NODE_BEVEL, + NODE_DISPLACEMENT, + NODE_VECTOR_DISPLACEMENT, + NODE_PRINCIPLED_VOLUME, + NODE_IES, } ShaderNodeType; typedef enum NodeAttributeType { - NODE_ATTR_FLOAT = 0, - NODE_ATTR_FLOAT2, - NODE_ATTR_FLOAT3, - NODE_ATTR_MATRIX + NODE_ATTR_FLOAT = 0, + NODE_ATTR_FLOAT2, + NODE_ATTR_FLOAT3, + NODE_ATTR_MATRIX } NodeAttributeType; typedef enum NodeGeometry { - NODE_GEOM_P = 0, - NODE_GEOM_N, - NODE_GEOM_T, - NODE_GEOM_I, - NODE_GEOM_Ng, - NODE_GEOM_uv + NODE_GEOM_P = 0, + NODE_GEOM_N, + NODE_GEOM_T, + NODE_GEOM_I, + NODE_GEOM_Ng, + NODE_GEOM_uv } NodeGeometry; typedef enum NodeObjectInfo { - NODE_INFO_OB_LOCATION, - NODE_INFO_OB_INDEX, - NODE_INFO_MAT_INDEX, - NODE_INFO_OB_RANDOM + NODE_INFO_OB_LOCATION, + NODE_INFO_OB_INDEX, + NODE_INFO_MAT_INDEX, + NODE_INFO_OB_RANDOM } NodeObjectInfo; typedef enum NodeParticleInfo { - NODE_INFO_PAR_INDEX, - NODE_INFO_PAR_RANDOM, - NODE_INFO_PAR_AGE, - NODE_INFO_PAR_LIFETIME, - NODE_INFO_PAR_LOCATION, - NODE_INFO_PAR_ROTATION, - NODE_INFO_PAR_SIZE, - NODE_INFO_PAR_VELOCITY, - NODE_INFO_PAR_ANGULAR_VELOCITY + NODE_INFO_PAR_INDEX, + NODE_INFO_PAR_RANDOM, + NODE_INFO_PAR_AGE, + NODE_INFO_PAR_LIFETIME, + NODE_INFO_PAR_LOCATION, + NODE_INFO_PAR_ROTATION, + NODE_INFO_PAR_SIZE, + NODE_INFO_PAR_VELOCITY, + NODE_INFO_PAR_ANGULAR_VELOCITY } NodeParticleInfo; typedef enum NodeHairInfo { - NODE_INFO_CURVE_IS_STRAND, - NODE_INFO_CURVE_INTERCEPT, - NODE_INFO_CURVE_THICKNESS, - /*fade for minimum hair width transpency*/ - /*NODE_INFO_CURVE_FADE,*/ - NODE_INFO_CURVE_TANGENT_NORMAL, - NODE_INFO_CURVE_RANDOM, + NODE_INFO_CURVE_IS_STRAND, + NODE_INFO_CURVE_INTERCEPT, + NODE_INFO_CURVE_THICKNESS, + /*fade for minimum hair width transpency*/ + /*NODE_INFO_CURVE_FADE,*/ + NODE_INFO_CURVE_TANGENT_NORMAL, + NODE_INFO_CURVE_RANDOM, } NodeHairInfo; typedef enum NodeLightPath { - NODE_LP_camera = 0, - NODE_LP_shadow, - NODE_LP_diffuse, - NODE_LP_glossy, - NODE_LP_singular, - NODE_LP_reflection, - NODE_LP_transmission, - NODE_LP_volume_scatter, - NODE_LP_backfacing, - NODE_LP_ray_length, - NODE_LP_ray_depth, - NODE_LP_ray_diffuse, - NODE_LP_ray_glossy, - NODE_LP_ray_transparent, - NODE_LP_ray_transmission, + NODE_LP_camera = 0, + NODE_LP_shadow, + NODE_LP_diffuse, + NODE_LP_glossy, + NODE_LP_singular, + NODE_LP_reflection, + NODE_LP_transmission, + NODE_LP_volume_scatter, + NODE_LP_backfacing, + NODE_LP_ray_length, + NODE_LP_ray_depth, + NODE_LP_ray_diffuse, + NODE_LP_ray_glossy, + NODE_LP_ray_transparent, + NODE_LP_ray_transmission, } NodeLightPath; typedef enum NodeLightFalloff { - NODE_LIGHT_FALLOFF_QUADRATIC, - NODE_LIGHT_FALLOFF_LINEAR, - NODE_LIGHT_FALLOFF_CONSTANT + NODE_LIGHT_FALLOFF_QUADRATIC, + NODE_LIGHT_FALLOFF_LINEAR, + NODE_LIGHT_FALLOFF_CONSTANT } NodeLightFalloff; typedef enum NodeTexCoord { - NODE_TEXCO_NORMAL, - NODE_TEXCO_OBJECT, - NODE_TEXCO_CAMERA, - NODE_TEXCO_WINDOW, - NODE_TEXCO_REFLECTION, - NODE_TEXCO_DUPLI_GENERATED, - NODE_TEXCO_DUPLI_UV, - NODE_TEXCO_VOLUME_GENERATED + NODE_TEXCO_NORMAL, + NODE_TEXCO_OBJECT, + NODE_TEXCO_CAMERA, + NODE_TEXCO_WINDOW, + NODE_TEXCO_REFLECTION, + NODE_TEXCO_DUPLI_GENERATED, + NODE_TEXCO_DUPLI_UV, + NODE_TEXCO_VOLUME_GENERATED } NodeTexCoord; typedef enum NodeMix { - NODE_MIX_BLEND = 0, - NODE_MIX_ADD, - NODE_MIX_MUL, - NODE_MIX_SUB, - NODE_MIX_SCREEN, - NODE_MIX_DIV, - NODE_MIX_DIFF, - NODE_MIX_DARK, - NODE_MIX_LIGHT, - NODE_MIX_OVERLAY, - NODE_MIX_DODGE, - NODE_MIX_BURN, - NODE_MIX_HUE, - NODE_MIX_SAT, - NODE_MIX_VAL, - NODE_MIX_COLOR, - NODE_MIX_SOFT, - NODE_MIX_LINEAR, - NODE_MIX_CLAMP /* used for the clamp UI option */ + NODE_MIX_BLEND = 0, + NODE_MIX_ADD, + NODE_MIX_MUL, + NODE_MIX_SUB, + NODE_MIX_SCREEN, + NODE_MIX_DIV, + NODE_MIX_DIFF, + NODE_MIX_DARK, + NODE_MIX_LIGHT, + NODE_MIX_OVERLAY, + NODE_MIX_DODGE, + NODE_MIX_BURN, + NODE_MIX_HUE, + NODE_MIX_SAT, + NODE_MIX_VAL, + NODE_MIX_COLOR, + NODE_MIX_SOFT, + NODE_MIX_LINEAR, + NODE_MIX_CLAMP /* used for the clamp UI option */ } NodeMix; typedef enum NodeMath { - NODE_MATH_ADD, - NODE_MATH_SUBTRACT, - NODE_MATH_MULTIPLY, - NODE_MATH_DIVIDE, - NODE_MATH_SINE, - NODE_MATH_COSINE, - NODE_MATH_TANGENT, - NODE_MATH_ARCSINE, - NODE_MATH_ARCCOSINE, - NODE_MATH_ARCTANGENT, - NODE_MATH_POWER, - NODE_MATH_LOGARITHM, - NODE_MATH_MINIMUM, - NODE_MATH_MAXIMUM, - NODE_MATH_ROUND, - NODE_MATH_LESS_THAN, - NODE_MATH_GREATER_THAN, - NODE_MATH_MODULO, - NODE_MATH_ABSOLUTE, - NODE_MATH_ARCTAN2, - NODE_MATH_FLOOR, - NODE_MATH_CEIL, - NODE_MATH_FRACT, - NODE_MATH_SQRT, - NODE_MATH_CLAMP /* used for the clamp UI option */ + NODE_MATH_ADD, + NODE_MATH_SUBTRACT, + NODE_MATH_MULTIPLY, + NODE_MATH_DIVIDE, + NODE_MATH_SINE, + NODE_MATH_COSINE, + NODE_MATH_TANGENT, + NODE_MATH_ARCSINE, + NODE_MATH_ARCCOSINE, + NODE_MATH_ARCTANGENT, + NODE_MATH_POWER, + NODE_MATH_LOGARITHM, + NODE_MATH_MINIMUM, + NODE_MATH_MAXIMUM, + NODE_MATH_ROUND, + NODE_MATH_LESS_THAN, + NODE_MATH_GREATER_THAN, + NODE_MATH_MODULO, + NODE_MATH_ABSOLUTE, + NODE_MATH_ARCTAN2, + NODE_MATH_FLOOR, + NODE_MATH_CEIL, + NODE_MATH_FRACT, + NODE_MATH_SQRT, + NODE_MATH_CLAMP /* used for the clamp UI option */ } NodeMath; typedef enum NodeVectorMath { - NODE_VECTOR_MATH_ADD, - NODE_VECTOR_MATH_SUBTRACT, - NODE_VECTOR_MATH_AVERAGE, - NODE_VECTOR_MATH_DOT_PRODUCT, - NODE_VECTOR_MATH_CROSS_PRODUCT, - NODE_VECTOR_MATH_NORMALIZE + NODE_VECTOR_MATH_ADD, + NODE_VECTOR_MATH_SUBTRACT, + NODE_VECTOR_MATH_AVERAGE, + NODE_VECTOR_MATH_DOT_PRODUCT, + NODE_VECTOR_MATH_CROSS_PRODUCT, + NODE_VECTOR_MATH_NORMALIZE } NodeVectorMath; typedef enum NodeVectorTransformType { - NODE_VECTOR_TRANSFORM_TYPE_VECTOR, - NODE_VECTOR_TRANSFORM_TYPE_POINT, - NODE_VECTOR_TRANSFORM_TYPE_NORMAL + NODE_VECTOR_TRANSFORM_TYPE_VECTOR, + NODE_VECTOR_TRANSFORM_TYPE_POINT, + NODE_VECTOR_TRANSFORM_TYPE_NORMAL } NodeVectorTransformType; typedef enum NodeVectorTransformConvertSpace { - NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD, - NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT, - NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA + NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD, + NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT, + NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA } NodeVectorTransformConvertSpace; typedef enum NodeConvert { - NODE_CONVERT_FV, - NODE_CONVERT_FI, - NODE_CONVERT_CF, - NODE_CONVERT_CI, - NODE_CONVERT_VF, - NODE_CONVERT_VI, - NODE_CONVERT_IF, - NODE_CONVERT_IV + NODE_CONVERT_FV, + NODE_CONVERT_FI, + NODE_CONVERT_CF, + NODE_CONVERT_CI, + NODE_CONVERT_VF, + NODE_CONVERT_VI, + NODE_CONVERT_IF, + NODE_CONVERT_IV } NodeConvert; typedef enum NodeMusgraveType { - NODE_MUSGRAVE_MULTIFRACTAL, - NODE_MUSGRAVE_FBM, - NODE_MUSGRAVE_HYBRID_MULTIFRACTAL, - NODE_MUSGRAVE_RIDGED_MULTIFRACTAL, - NODE_MUSGRAVE_HETERO_TERRAIN + NODE_MUSGRAVE_MULTIFRACTAL, + NODE_MUSGRAVE_FBM, + NODE_MUSGRAVE_HYBRID_MULTIFRACTAL, + NODE_MUSGRAVE_RIDGED_MULTIFRACTAL, + NODE_MUSGRAVE_HETERO_TERRAIN } NodeMusgraveType; -typedef enum NodeWaveType { - NODE_WAVE_BANDS, - NODE_WAVE_RINGS -} NodeWaveType; +typedef enum NodeWaveType { NODE_WAVE_BANDS, NODE_WAVE_RINGS } NodeWaveType; typedef enum NodeWaveProfiles { - NODE_WAVE_PROFILE_SIN, - NODE_WAVE_PROFILE_SAW, + NODE_WAVE_PROFILE_SIN, + NODE_WAVE_PROFILE_SAW, } NodeWaveProfile; -typedef enum NodeSkyType { - NODE_SKY_OLD, - NODE_SKY_NEW -} NodeSkyType; +typedef enum NodeSkyType { NODE_SKY_OLD, NODE_SKY_NEW } NodeSkyType; typedef enum NodeGradientType { - NODE_BLEND_LINEAR, - NODE_BLEND_QUADRATIC, - NODE_BLEND_EASING, - NODE_BLEND_DIAGONAL, - NODE_BLEND_RADIAL, - NODE_BLEND_QUADRATIC_SPHERE, - NODE_BLEND_SPHERICAL + NODE_BLEND_LINEAR, + NODE_BLEND_QUADRATIC, + NODE_BLEND_EASING, + NODE_BLEND_DIAGONAL, + NODE_BLEND_RADIAL, + NODE_BLEND_QUADRATIC_SPHERE, + NODE_BLEND_SPHERICAL } NodeGradientType; typedef enum NodeVoronoiColoring { - NODE_VORONOI_INTENSITY, - NODE_VORONOI_CELLS + NODE_VORONOI_INTENSITY, + NODE_VORONOI_CELLS } NodeVoronoiColoring; typedef enum NodeVoronoiDistanceMetric { - NODE_VORONOI_DISTANCE, - NODE_VORONOI_MANHATTAN, - NODE_VORONOI_CHEBYCHEV, - NODE_VORONOI_MINKOWSKI + NODE_VORONOI_DISTANCE, + NODE_VORONOI_MANHATTAN, + NODE_VORONOI_CHEBYCHEV, + NODE_VORONOI_MINKOWSKI } NodeVoronoiDistanceMetric; typedef enum NodeVoronoiFeature { - NODE_VORONOI_F1, - NODE_VORONOI_F2, - NODE_VORONOI_F3, - NODE_VORONOI_F4, - NODE_VORONOI_F2F1 + NODE_VORONOI_F1, + NODE_VORONOI_F2, + NODE_VORONOI_F3, + NODE_VORONOI_F4, + NODE_VORONOI_F2F1 } NodeVoronoiFeature; typedef enum NodeBlendWeightType { - NODE_LAYER_WEIGHT_FRESNEL, - NODE_LAYER_WEIGHT_FACING + NODE_LAYER_WEIGHT_FRESNEL, + NODE_LAYER_WEIGHT_FACING } NodeBlendWeightType; typedef enum NodeTangentDirectionType { - NODE_TANGENT_RADIAL, - NODE_TANGENT_UVMAP + NODE_TANGENT_RADIAL, + NODE_TANGENT_UVMAP } NodeTangentDirectionType; typedef enum NodeTangentAxis { - NODE_TANGENT_AXIS_X, - NODE_TANGENT_AXIS_Y, - NODE_TANGENT_AXIS_Z + NODE_TANGENT_AXIS_X, + NODE_TANGENT_AXIS_Y, + NODE_TANGENT_AXIS_Z } NodeTangentAxis; typedef enum NodeNormalMapSpace { - NODE_NORMAL_MAP_TANGENT, - NODE_NORMAL_MAP_OBJECT, - NODE_NORMAL_MAP_WORLD, - NODE_NORMAL_MAP_BLENDER_OBJECT, - NODE_NORMAL_MAP_BLENDER_WORLD, + NODE_NORMAL_MAP_TANGENT, + NODE_NORMAL_MAP_OBJECT, + NODE_NORMAL_MAP_WORLD, + NODE_NORMAL_MAP_BLENDER_OBJECT, + NODE_NORMAL_MAP_BLENDER_WORLD, } NodeNormalMapSpace; typedef enum NodeImageColorSpace { - NODE_COLOR_SPACE_NONE = 0, - NODE_COLOR_SPACE_COLOR = 1, + NODE_COLOR_SPACE_NONE = 0, + NODE_COLOR_SPACE_COLOR = 1, } NodeImageColorSpace; typedef enum NodeImageProjection { - NODE_IMAGE_PROJ_FLAT = 0, - NODE_IMAGE_PROJ_BOX = 1, - NODE_IMAGE_PROJ_SPHERE = 2, - NODE_IMAGE_PROJ_TUBE = 3, + NODE_IMAGE_PROJ_FLAT = 0, + NODE_IMAGE_PROJ_BOX = 1, + NODE_IMAGE_PROJ_SPHERE = 2, + NODE_IMAGE_PROJ_TUBE = 3, } NodeImageProjection; typedef enum NodeEnvironmentProjection { - NODE_ENVIRONMENT_EQUIRECTANGULAR = 0, - NODE_ENVIRONMENT_MIRROR_BALL = 1, + NODE_ENVIRONMENT_EQUIRECTANGULAR = 0, + NODE_ENVIRONMENT_MIRROR_BALL = 1, } NodeEnvironmentProjection; typedef enum NodeBumpOffset { - NODE_BUMP_OFFSET_CENTER, - NODE_BUMP_OFFSET_DX, - NODE_BUMP_OFFSET_DY, + NODE_BUMP_OFFSET_CENTER, + NODE_BUMP_OFFSET_DX, + NODE_BUMP_OFFSET_DY, } NodeBumpOffset; typedef enum NodeTexVoxelSpace { - NODE_TEX_VOXEL_SPACE_OBJECT = 0, - NODE_TEX_VOXEL_SPACE_WORLD = 1, + NODE_TEX_VOXEL_SPACE_OBJECT = 0, + NODE_TEX_VOXEL_SPACE_WORLD = 1, } NodeTexVoxelSpace; typedef enum NodeAO { - NODE_AO_ONLY_LOCAL = (1 << 0), - NODE_AO_INSIDE = (1 << 1), - NODE_AO_GLOBAL_RADIUS = (1 << 2), + NODE_AO_ONLY_LOCAL = (1 << 0), + NODE_AO_INSIDE = (1 << 1), + NODE_AO_GLOBAL_RADIUS = (1 << 2), } NodeAO; typedef enum ShaderType { - SHADER_TYPE_SURFACE, - SHADER_TYPE_VOLUME, - SHADER_TYPE_DISPLACEMENT, - SHADER_TYPE_BUMP, + SHADER_TYPE_SURFACE, + SHADER_TYPE_VOLUME, + SHADER_TYPE_DISPLACEMENT, + SHADER_TYPE_BUMP, } ShaderType; typedef enum NodePrincipledHairParametrization { - NODE_PRINCIPLED_HAIR_REFLECTANCE = 0, - NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION = 1, - NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION = 2, - NODE_PRINCIPLED_HAIR_NUM, + NODE_PRINCIPLED_HAIR_REFLECTANCE = 0, + NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION = 1, + NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION = 2, + NODE_PRINCIPLED_HAIR_NUM, } NodePrincipledHairParametrization; /* Closure */ typedef enum ClosureType { - /* Special type, flags generic node as a non-BSDF. */ - CLOSURE_NONE_ID, - - CLOSURE_BSDF_ID, - - /* Diffuse */ - CLOSURE_BSDF_DIFFUSE_ID, - CLOSURE_BSDF_OREN_NAYAR_ID, - CLOSURE_BSDF_DIFFUSE_RAMP_ID, - CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID, - CLOSURE_BSDF_PRINCIPLED_SHEEN_ID, - CLOSURE_BSDF_DIFFUSE_TOON_ID, - - /* Glossy */ - CLOSURE_BSDF_REFLECTION_ID, - CLOSURE_BSDF_MICROFACET_GGX_ID, - CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID, - CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID, - CLOSURE_BSDF_MICROFACET_BECKMANN_ID, - CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID, - CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID, - CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID, - CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID, - CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID, - CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID, - CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_FRESNEL_ID, - CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID, - CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID, - CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, - CLOSURE_BSDF_PHONG_RAMP_ID, - CLOSURE_BSDF_GLOSSY_TOON_ID, - CLOSURE_BSDF_HAIR_REFLECTION_ID, - - /* Transmission */ - CLOSURE_BSDF_TRANSLUCENT_ID, - CLOSURE_BSDF_REFRACTION_ID, - CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, - CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, - CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID, - CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID, - CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID, - CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID, - CLOSURE_BSDF_SHARP_GLASS_ID, - CLOSURE_BSDF_HAIR_PRINCIPLED_ID, - CLOSURE_BSDF_HAIR_TRANSMISSION_ID, - - /* Special cases */ - CLOSURE_BSDF_BSSRDF_ID, - CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID, - CLOSURE_BSDF_TRANSPARENT_ID, - - /* BSSRDF */ - CLOSURE_BSSRDF_CUBIC_ID, - CLOSURE_BSSRDF_GAUSSIAN_ID, - CLOSURE_BSSRDF_PRINCIPLED_ID, - CLOSURE_BSSRDF_BURLEY_ID, - CLOSURE_BSSRDF_RANDOM_WALK_ID, - CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID, - - /* Other */ - CLOSURE_HOLDOUT_ID, - - /* Volume */ - CLOSURE_VOLUME_ID, - CLOSURE_VOLUME_ABSORPTION_ID, - CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, - - CLOSURE_BSDF_PRINCIPLED_ID, - - NBUILTIN_CLOSURES + /* Special type, flags generic node as a non-BSDF. */ + CLOSURE_NONE_ID, + + CLOSURE_BSDF_ID, + + /* Diffuse */ + CLOSURE_BSDF_DIFFUSE_ID, + CLOSURE_BSDF_OREN_NAYAR_ID, + CLOSURE_BSDF_DIFFUSE_RAMP_ID, + CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID, + CLOSURE_BSDF_PRINCIPLED_SHEEN_ID, + CLOSURE_BSDF_DIFFUSE_TOON_ID, + + /* Glossy */ + CLOSURE_BSDF_REFLECTION_ID, + CLOSURE_BSDF_MICROFACET_GGX_ID, + CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID, + CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID, + CLOSURE_BSDF_MICROFACET_BECKMANN_ID, + CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID, + CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID, + CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID, + CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID, + CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID, + CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID, + CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_FRESNEL_ID, + CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID, + CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID, + CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, + CLOSURE_BSDF_PHONG_RAMP_ID, + CLOSURE_BSDF_GLOSSY_TOON_ID, + CLOSURE_BSDF_HAIR_REFLECTION_ID, + + /* Transmission */ + CLOSURE_BSDF_TRANSLUCENT_ID, + CLOSURE_BSDF_REFRACTION_ID, + CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, + CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, + CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID, + CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID, + CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID, + CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID, + CLOSURE_BSDF_SHARP_GLASS_ID, + CLOSURE_BSDF_HAIR_PRINCIPLED_ID, + CLOSURE_BSDF_HAIR_TRANSMISSION_ID, + + /* Special cases */ + CLOSURE_BSDF_BSSRDF_ID, + CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID, + CLOSURE_BSDF_TRANSPARENT_ID, + + /* BSSRDF */ + CLOSURE_BSSRDF_CUBIC_ID, + CLOSURE_BSSRDF_GAUSSIAN_ID, + CLOSURE_BSSRDF_PRINCIPLED_ID, + CLOSURE_BSSRDF_BURLEY_ID, + CLOSURE_BSSRDF_RANDOM_WALK_ID, + CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID, + + /* Other */ + CLOSURE_HOLDOUT_ID, + + /* Volume */ + CLOSURE_VOLUME_ID, + CLOSURE_VOLUME_ABSORPTION_ID, + CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, + + CLOSURE_BSDF_PRINCIPLED_ID, + + NBUILTIN_CLOSURES } ClosureType; /* watch this, being lazy with memory usage */ #define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_TRANSPARENT_ID) -#define CLOSURE_IS_BSDF_DIFFUSE(type) (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID) -#define CLOSURE_IS_BSDF_GLOSSY(type) ((type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID )|| (type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID)) -#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID) -#define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID || type == CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID) -#define CLOSURE_IS_BSDF_SINGULAR(type) (type == CLOSURE_BSDF_REFLECTION_ID || \ - type == CLOSURE_BSDF_REFRACTION_ID || \ - type == CLOSURE_BSDF_TRANSPARENT_ID) +#define CLOSURE_IS_BSDF_DIFFUSE(type) \ + (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID) +#define CLOSURE_IS_BSDF_GLOSSY(type) \ + ((type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID) || \ + (type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID)) +#define CLOSURE_IS_BSDF_TRANSMISSION(type) \ + (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID) +#define CLOSURE_IS_BSDF_BSSRDF(type) \ + (type == CLOSURE_BSDF_BSSRDF_ID || type == CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID) +#define CLOSURE_IS_BSDF_SINGULAR(type) \ + (type == CLOSURE_BSDF_REFLECTION_ID || type == CLOSURE_BSDF_REFRACTION_ID || \ + type == CLOSURE_BSDF_TRANSPARENT_ID) #define CLOSURE_IS_BSDF_TRANSPARENT(type) (type == CLOSURE_BSDF_TRANSPARENT_ID) -#define CLOSURE_IS_BSDF_MULTISCATTER(type) (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID ||\ - type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID || \ - type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) -#define CLOSURE_IS_BSDF_MICROFACET(type) ((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) ||\ - (type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) ||\ - (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID)) +#define CLOSURE_IS_BSDF_MULTISCATTER(type) \ + (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID || \ + type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID || \ + type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) +#define CLOSURE_IS_BSDF_MICROFACET(type) \ + ((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) || \ + (type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && \ + type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) || \ + (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID)) #define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID) -#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID) -#define CLOSURE_IS_DISK_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_BURLEY_ID) -#define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) +#define CLOSURE_IS_BSSRDF(type) \ + (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID) +#define CLOSURE_IS_DISK_BSSRDF(type) \ + (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_BURLEY_ID) +#define CLOSURE_IS_VOLUME(type) \ + (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) #define CLOSURE_IS_VOLUME_SCATTER(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) #define CLOSURE_IS_VOLUME_ABSORPTION(type) (type == CLOSURE_VOLUME_ABSORPTION_ID) #define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID) #define CLOSURE_IS_PHASE(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) -#define CLOSURE_IS_GLASS(type) (type >= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID && type <= CLOSURE_BSDF_SHARP_GLASS_ID) +#define CLOSURE_IS_GLASS(type) \ + (type >= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID && type <= CLOSURE_BSDF_SHARP_GLASS_ID) #define CLOSURE_IS_PRINCIPLED(type) (type == CLOSURE_BSDF_PRINCIPLED_ID) #define CLOSURE_WEIGHT_CUTOFF 1e-5f CCL_NAMESPACE_END -#endif /* __SVM_TYPES_H__ */ +#endif /* __SVM_TYPES_H__ */ diff --git a/intern/cycles/kernel/svm/svm_value.h b/intern/cycles/kernel/svm/svm_value.h index 062aee2956e..5b76f2c8832 100644 --- a/intern/cycles/kernel/svm/svm_value.h +++ b/intern/cycles/kernel/svm/svm_value.h @@ -18,18 +18,21 @@ CCL_NAMESPACE_BEGIN /* Value Nodes */ -ccl_device void svm_node_value_f(KernelGlobals *kg, ShaderData *sd, float *stack, uint ivalue, uint out_offset) +ccl_device void svm_node_value_f( + KernelGlobals *kg, ShaderData *sd, float *stack, uint ivalue, uint out_offset) { - stack_store_float(stack, out_offset, __uint_as_float(ivalue)); + stack_store_float(stack, out_offset, __uint_as_float(ivalue)); } -ccl_device void svm_node_value_v(KernelGlobals *kg, ShaderData *sd, float *stack, uint out_offset, int *offset) +ccl_device void svm_node_value_v( + KernelGlobals *kg, ShaderData *sd, float *stack, uint out_offset, int *offset) { - /* read extra data */ - uint4 node1 = read_node(kg, offset); - float3 p = make_float3(__uint_as_float(node1.y), __uint_as_float(node1.z), __uint_as_float(node1.w)); + /* read extra data */ + uint4 node1 = read_node(kg, offset); + float3 p = make_float3( + __uint_as_float(node1.y), __uint_as_float(node1.z), __uint_as_float(node1.w)); - stack_store_float3(stack, out_offset, p); + stack_store_float3(stack, out_offset, p); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_vector_transform.h b/intern/cycles/kernel/svm/svm_vector_transform.h index f6ec36ba41f..7ec0f07f2e4 100644 --- a/intern/cycles/kernel/svm/svm_vector_transform.h +++ b/intern/cycles/kernel/svm/svm_vector_transform.h @@ -18,83 +18,90 @@ CCL_NAMESPACE_BEGIN /* Vector Transform */ -ccl_device void svm_node_vector_transform(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) +ccl_device void svm_node_vector_transform(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint4 node) { - uint itype, ifrom, ito; - uint vector_in, vector_out; + uint itype, ifrom, ito; + uint vector_in, vector_out; - decode_node_uchar4(node.y, &itype, &ifrom, &ito, NULL); - decode_node_uchar4(node.z, &vector_in, &vector_out, NULL, NULL); + decode_node_uchar4(node.y, &itype, &ifrom, &ito, NULL); + decode_node_uchar4(node.z, &vector_in, &vector_out, NULL, NULL); - float3 in = stack_load_float3(stack, vector_in); + float3 in = stack_load_float3(stack, vector_in); - NodeVectorTransformType type = (NodeVectorTransformType)itype; - NodeVectorTransformConvertSpace from = (NodeVectorTransformConvertSpace)ifrom; - NodeVectorTransformConvertSpace to = (NodeVectorTransformConvertSpace)ito; + NodeVectorTransformType type = (NodeVectorTransformType)itype; + NodeVectorTransformConvertSpace from = (NodeVectorTransformConvertSpace)ifrom; + NodeVectorTransformConvertSpace to = (NodeVectorTransformConvertSpace)ito; - Transform tfm; - bool is_object = (sd->object != OBJECT_NONE); - bool is_direction = (type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR || type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL); + Transform tfm; + bool is_object = (sd->object != OBJECT_NONE); + bool is_direction = (type == NODE_VECTOR_TRANSFORM_TYPE_VECTOR || + type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL); - /* From world */ - if(from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD) { - if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) { - tfm = kernel_data.cam.worldtocamera; - if(is_direction) - in = transform_direction(&tfm, in); - else - in = transform_point(&tfm, in); - } - else if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT && is_object) { - if(is_direction) - object_inverse_dir_transform(kg, sd, &in); - else - object_inverse_position_transform(kg, sd, &in); - } - } + /* From world */ + if (from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD) { + if (to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) { + tfm = kernel_data.cam.worldtocamera; + if (is_direction) + in = transform_direction(&tfm, in); + else + in = transform_point(&tfm, in); + } + else if (to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT && is_object) { + if (is_direction) + object_inverse_dir_transform(kg, sd, &in); + else + object_inverse_position_transform(kg, sd, &in); + } + } - /* From camera */ - else if(from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) { - if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD || to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT) { - tfm = kernel_data.cam.cameratoworld; - if(is_direction) - in = transform_direction(&tfm, in); - else - in = transform_point(&tfm, in); - } - if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT && is_object) { - if(is_direction) - object_inverse_dir_transform(kg, sd, &in); - else - object_inverse_position_transform(kg, sd, &in); - } - } + /* From camera */ + else if (from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) { + if (to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD || + to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT) { + tfm = kernel_data.cam.cameratoworld; + if (is_direction) + in = transform_direction(&tfm, in); + else + in = transform_point(&tfm, in); + } + if (to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT && is_object) { + if (is_direction) + object_inverse_dir_transform(kg, sd, &in); + else + object_inverse_position_transform(kg, sd, &in); + } + } - /* From object */ - else if(from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT) { - if((to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD || to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) && is_object) { - if(is_direction) - object_dir_transform(kg, sd, &in); - else - object_position_transform(kg, sd, &in); - } - if(to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) { - tfm = kernel_data.cam.worldtocamera; - if(is_direction) - in = transform_direction(&tfm, in); - else - in = transform_point(&tfm, in); - } - } + /* From object */ + else if (from == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT) { + if ((to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD || + to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) && + is_object) { + if (is_direction) + object_dir_transform(kg, sd, &in); + else + object_position_transform(kg, sd, &in); + } + if (to == NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA) { + tfm = kernel_data.cam.worldtocamera; + if (is_direction) + in = transform_direction(&tfm, in); + else + in = transform_point(&tfm, in); + } + } - /* Normalize Normal */ - if(type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL) - in = normalize(in); + /* Normalize Normal */ + if (type == NODE_VECTOR_TRANSFORM_TYPE_NORMAL) + in = normalize(in); - /* Output */ - if(stack_valid(vector_out)) { - stack_store_float3(stack, vector_out, in); - } + /* Output */ + if (stack_valid(vector_out)) { + stack_store_float3(stack, vector_out, in); + } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_voronoi.h b/intern/cycles/kernel/svm/svm_voronoi.h index d661df54ead..c311aefaf38 100644 --- a/intern/cycles/kernel/svm/svm_voronoi.h +++ b/intern/cycles/kernel/svm/svm_voronoi.h @@ -18,143 +18,167 @@ CCL_NAMESPACE_BEGIN /* Voronoi */ -ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, float e, float da[4], float3 pa[4]) +ccl_device void voronoi_neighbors( + float3 p, NodeVoronoiDistanceMetric distance, float e, float da[4], float3 pa[4]) { - /* Compute the distance to and the position of the closest neighbors to p. - * - * The neighbors are randomly placed, 1 each in a 3x3x3 grid (Worley pattern). - * The distances and points are returned in ascending order, i.e. da[0] and pa[0] will - * contain the distance to the closest point and its coordinates respectively. - */ - - da[0] = 1e10f; - da[1] = 1e10f; - da[2] = 1e10f; - da[3] = 1e10f; - - pa[0] = make_float3(0.0f, 0.0f, 0.0f); - pa[1] = make_float3(0.0f, 0.0f, 0.0f); - pa[2] = make_float3(0.0f, 0.0f, 0.0f); - pa[3] = make_float3(0.0f, 0.0f, 0.0f); - - int3 xyzi = quick_floor_to_int3(p); - - for(int xx = -1; xx <= 1; xx++) { - for(int yy = -1; yy <= 1; yy++) { - for(int zz = -1; zz <= 1; zz++) { - int3 ip = xyzi + make_int3(xx, yy, zz); - float3 fp = make_float3(ip.x, ip.y, ip.z); - float3 vp = fp + cellnoise3(fp); - - float d; - switch(distance) { - case NODE_VORONOI_DISTANCE: - d = len_squared(p - vp); - break; - case NODE_VORONOI_MANHATTAN: - d = reduce_add(fabs(vp - p)); - break; - case NODE_VORONOI_CHEBYCHEV: - d = max3(fabs(vp - p)); - break; - case NODE_VORONOI_MINKOWSKI: { - float3 n = fabs(vp - p); - if(e == 0.5f) { - d = sqr(reduce_add(sqrt(n))); - } - else { - d = powf(reduce_add(pow3(n, e)), 1.0f/e); - } - break; - } - } - - /* To keep the shortest four distances and associated points we have to keep them in sorted order. */ - if(d < da[0]) { - da[3] = da[2]; - da[2] = da[1]; - da[1] = da[0]; - da[0] = d; - - pa[3] = pa[2]; - pa[2] = pa[1]; - pa[1] = pa[0]; - pa[0] = vp; - } - else if(d < da[1]) { - da[3] = da[2]; - da[2] = da[1]; - da[1] = d; - - pa[3] = pa[2]; - pa[2] = pa[1]; - pa[1] = vp; - } - else if(d < da[2]) { - da[3] = da[2]; - da[2] = d; - - pa[3] = pa[2]; - pa[2] = vp; - } - else if(d < da[3]) { - da[3] = d; - pa[3] = vp; - } - } - } - } + /* Compute the distance to and the position of the closest neighbors to p. + * + * The neighbors are randomly placed, 1 each in a 3x3x3 grid (Worley pattern). + * The distances and points are returned in ascending order, i.e. da[0] and pa[0] will + * contain the distance to the closest point and its coordinates respectively. + */ + + da[0] = 1e10f; + da[1] = 1e10f; + da[2] = 1e10f; + da[3] = 1e10f; + + pa[0] = make_float3(0.0f, 0.0f, 0.0f); + pa[1] = make_float3(0.0f, 0.0f, 0.0f); + pa[2] = make_float3(0.0f, 0.0f, 0.0f); + pa[3] = make_float3(0.0f, 0.0f, 0.0f); + + int3 xyzi = quick_floor_to_int3(p); + + for (int xx = -1; xx <= 1; xx++) { + for (int yy = -1; yy <= 1; yy++) { + for (int zz = -1; zz <= 1; zz++) { + int3 ip = xyzi + make_int3(xx, yy, zz); + float3 fp = make_float3(ip.x, ip.y, ip.z); + float3 vp = fp + cellnoise3(fp); + + float d; + switch (distance) { + case NODE_VORONOI_DISTANCE: + d = len_squared(p - vp); + break; + case NODE_VORONOI_MANHATTAN: + d = reduce_add(fabs(vp - p)); + break; + case NODE_VORONOI_CHEBYCHEV: + d = max3(fabs(vp - p)); + break; + case NODE_VORONOI_MINKOWSKI: { + float3 n = fabs(vp - p); + if (e == 0.5f) { + d = sqr(reduce_add(sqrt(n))); + } + else { + d = powf(reduce_add(pow3(n, e)), 1.0f / e); + } + break; + } + } + + /* To keep the shortest four distances and associated points we have to keep them in sorted order. */ + if (d < da[0]) { + da[3] = da[2]; + da[2] = da[1]; + da[1] = da[0]; + da[0] = d; + + pa[3] = pa[2]; + pa[2] = pa[1]; + pa[1] = pa[0]; + pa[0] = vp; + } + else if (d < da[1]) { + da[3] = da[2]; + da[2] = da[1]; + da[1] = d; + + pa[3] = pa[2]; + pa[2] = pa[1]; + pa[1] = vp; + } + else if (d < da[2]) { + da[3] = da[2]; + da[2] = d; + + pa[3] = pa[2]; + pa[2] = vp; + } + else if (d < da[3]) { + da[3] = d; + pa[3] = vp; + } + } + } + } } -ccl_device void svm_node_tex_voronoi(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_tex_voronoi( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint4 node2 = read_node(kg, offset); - - uint co_offset, coloring, distance, feature; - uint scale_offset, e_offset, fac_offset, color_offset; - - decode_node_uchar4(node.y, &co_offset, &coloring, &distance, &feature); - decode_node_uchar4(node.z, &scale_offset, &e_offset, &fac_offset, &color_offset); - - float3 co = stack_load_float3(stack, co_offset); - float scale = stack_load_float_default(stack, scale_offset, node2.x); - float exponent = stack_load_float_default(stack, e_offset, node2.y); - - float dist[4]; - float3 neighbor[4]; - voronoi_neighbors(co*scale, (NodeVoronoiDistanceMetric)distance, exponent, dist, neighbor); - - float3 color; - float fac; - if(coloring == NODE_VORONOI_INTENSITY) { - switch(feature) { - case NODE_VORONOI_F1: fac = dist[0]; break; - case NODE_VORONOI_F2: fac = dist[1]; break; - case NODE_VORONOI_F3: fac = dist[2]; break; - case NODE_VORONOI_F4: fac = dist[3]; break; - case NODE_VORONOI_F2F1: fac = dist[1] - dist[0]; break; - } - - color = make_float3(fac, fac, fac); - } - else { - /* NODE_VORONOI_CELLS */ - switch(feature) { - case NODE_VORONOI_F1: color = neighbor[0]; break; - case NODE_VORONOI_F2: color = neighbor[1]; break; - case NODE_VORONOI_F3: color = neighbor[2]; break; - case NODE_VORONOI_F4: color = neighbor[3]; break; - /* Usefulness of this vector is questionable. Note F2 >= F1 but the - * individual vector components might not be. */ - case NODE_VORONOI_F2F1: color = fabs(neighbor[1] - neighbor[0]); break; - } - - color = cellnoise3(color); - fac = average(color); - } - - if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, fac); - if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, color); + uint4 node2 = read_node(kg, offset); + + uint co_offset, coloring, distance, feature; + uint scale_offset, e_offset, fac_offset, color_offset; + + decode_node_uchar4(node.y, &co_offset, &coloring, &distance, &feature); + decode_node_uchar4(node.z, &scale_offset, &e_offset, &fac_offset, &color_offset); + + float3 co = stack_load_float3(stack, co_offset); + float scale = stack_load_float_default(stack, scale_offset, node2.x); + float exponent = stack_load_float_default(stack, e_offset, node2.y); + + float dist[4]; + float3 neighbor[4]; + voronoi_neighbors(co * scale, (NodeVoronoiDistanceMetric)distance, exponent, dist, neighbor); + + float3 color; + float fac; + if (coloring == NODE_VORONOI_INTENSITY) { + switch (feature) { + case NODE_VORONOI_F1: + fac = dist[0]; + break; + case NODE_VORONOI_F2: + fac = dist[1]; + break; + case NODE_VORONOI_F3: + fac = dist[2]; + break; + case NODE_VORONOI_F4: + fac = dist[3]; + break; + case NODE_VORONOI_F2F1: + fac = dist[1] - dist[0]; + break; + } + + color = make_float3(fac, fac, fac); + } + else { + /* NODE_VORONOI_CELLS */ + switch (feature) { + case NODE_VORONOI_F1: + color = neighbor[0]; + break; + case NODE_VORONOI_F2: + color = neighbor[1]; + break; + case NODE_VORONOI_F3: + color = neighbor[2]; + break; + case NODE_VORONOI_F4: + color = neighbor[3]; + break; + /* Usefulness of this vector is questionable. Note F2 >= F1 but the + * individual vector components might not be. */ + case NODE_VORONOI_F2F1: + color = fabs(neighbor[1] - neighbor[0]); + break; + } + + color = cellnoise3(color); + fac = average(color); + } + + if (stack_valid(fac_offset)) + stack_store_float(stack, fac_offset, fac); + if (stack_valid(color_offset)) + stack_store_float3(stack, color_offset, color); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_voxel.h b/intern/cycles/kernel/svm/svm_voxel.h index 43b433683e0..26d8cc71d3b 100644 --- a/intern/cycles/kernel/svm/svm_voxel.h +++ b/intern/cycles/kernel/svm/svm_voxel.h @@ -19,37 +19,34 @@ CCL_NAMESPACE_BEGIN /* TODO(sergey): Think of making it more generic volume-type attribute * sampler. */ -ccl_device void svm_node_tex_voxel(KernelGlobals *kg, - ShaderData *sd, - float *stack, - uint4 node, - int *offset) +ccl_device void svm_node_tex_voxel( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint co_offset, density_out_offset, color_out_offset, space; - decode_node_uchar4(node.z, &co_offset, &density_out_offset, &color_out_offset, &space); + uint co_offset, density_out_offset, color_out_offset, space; + decode_node_uchar4(node.z, &co_offset, &density_out_offset, &color_out_offset, &space); #ifdef __VOLUME__ - int id = node.y; - float3 co = stack_load_float3(stack, co_offset); - if(space == NODE_TEX_VOXEL_SPACE_OBJECT) { - co = volume_normalized_position(kg, sd, co); - } - else { - kernel_assert(space == NODE_TEX_VOXEL_SPACE_WORLD); - Transform tfm; - tfm.x = read_node_float(kg, offset); - tfm.y = read_node_float(kg, offset); - tfm.z = read_node_float(kg, offset); - co = transform_point(&tfm, co); - } + int id = node.y; + float3 co = stack_load_float3(stack, co_offset); + if (space == NODE_TEX_VOXEL_SPACE_OBJECT) { + co = volume_normalized_position(kg, sd, co); + } + else { + kernel_assert(space == NODE_TEX_VOXEL_SPACE_WORLD); + Transform tfm; + tfm.x = read_node_float(kg, offset); + tfm.y = read_node_float(kg, offset); + tfm.z = read_node_float(kg, offset); + co = transform_point(&tfm, co); + } - float4 r = kernel_tex_image_interp_3d(kg, id, co.x, co.y, co.z, INTERPOLATION_NONE); + float4 r = kernel_tex_image_interp_3d(kg, id, co.x, co.y, co.z, INTERPOLATION_NONE); #else - float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f); #endif - if(stack_valid(density_out_offset)) - stack_store_float(stack, density_out_offset, r.w); - if(stack_valid(color_out_offset)) - stack_store_float3(stack, color_out_offset, make_float3(r.x, r.y, r.z)); + if (stack_valid(density_out_offset)) + stack_store_float(stack, density_out_offset, r.w); + if (stack_valid(color_out_offset)) + stack_store_float3(stack, color_out_offset, make_float3(r.x, r.y, r.z)); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_wave.h b/intern/cycles/kernel/svm/svm_wave.h index 80b63dc80cd..003ad7dc63a 100644 --- a/intern/cycles/kernel/svm/svm_wave.h +++ b/intern/cycles/kernel/svm/svm_wave.h @@ -18,48 +18,58 @@ CCL_NAMESPACE_BEGIN /* Wave */ -ccl_device_noinline float svm_wave(NodeWaveType type, NodeWaveProfile profile, float3 p, float detail, float distortion, float dscale) +ccl_device_noinline float svm_wave(NodeWaveType type, + NodeWaveProfile profile, + float3 p, + float detail, + float distortion, + float dscale) { - float n; + float n; - if(type == NODE_WAVE_BANDS) - n = (p.x + p.y + p.z) * 10.0f; - else /* NODE_WAVE_RINGS */ - n = len(p) * 20.0f; + if (type == NODE_WAVE_BANDS) + n = (p.x + p.y + p.z) * 10.0f; + else /* NODE_WAVE_RINGS */ + n = len(p) * 20.0f; - if(distortion != 0.0f) - n += distortion * noise_turbulence(p*dscale, detail, 0); + if (distortion != 0.0f) + n += distortion * noise_turbulence(p * dscale, detail, 0); - if(profile == NODE_WAVE_PROFILE_SIN) { - return 0.5f + 0.5f * sinf(n); - } - else { /* NODE_WAVE_PROFILE_SAW */ - n /= M_2PI_F; - n -= (int) n; - return (n < 0.0f)? n + 1.0f: n; - } + if (profile == NODE_WAVE_PROFILE_SIN) { + return 0.5f + 0.5f * sinf(n); + } + else { /* NODE_WAVE_PROFILE_SAW */ + n /= M_2PI_F; + n -= (int)n; + return (n < 0.0f) ? n + 1.0f : n; + } } -ccl_device void svm_node_tex_wave(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +ccl_device void svm_node_tex_wave( + KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint4 node2 = read_node(kg, offset); + uint4 node2 = read_node(kg, offset); - uint type; - uint co_offset, scale_offset, detail_offset, dscale_offset, distortion_offset, color_offset, fac_offset; + uint type; + uint co_offset, scale_offset, detail_offset, dscale_offset, distortion_offset, color_offset, + fac_offset; - decode_node_uchar4(node.y, &type, &color_offset, &fac_offset, &dscale_offset); - decode_node_uchar4(node.z, &co_offset, &scale_offset, &detail_offset, &distortion_offset); + decode_node_uchar4(node.y, &type, &color_offset, &fac_offset, &dscale_offset); + decode_node_uchar4(node.z, &co_offset, &scale_offset, &detail_offset, &distortion_offset); - float3 co = stack_load_float3(stack, co_offset); - float scale = stack_load_float_default(stack, scale_offset, node2.x); - float detail = stack_load_float_default(stack, detail_offset, node2.y); - float distortion = stack_load_float_default(stack, distortion_offset, node2.z); - float dscale = stack_load_float_default(stack, dscale_offset, node2.w); + float3 co = stack_load_float3(stack, co_offset); + float scale = stack_load_float_default(stack, scale_offset, node2.x); + float detail = stack_load_float_default(stack, detail_offset, node2.y); + float distortion = stack_load_float_default(stack, distortion_offset, node2.z); + float dscale = stack_load_float_default(stack, dscale_offset, node2.w); - float f = svm_wave((NodeWaveType)type, (NodeWaveProfile)node.w, co*scale, detail, distortion, dscale); + float f = svm_wave( + (NodeWaveType)type, (NodeWaveProfile)node.w, co * scale, detail, distortion, dscale); - if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f); - if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, make_float3(f, f, f)); + if (stack_valid(fac_offset)) + stack_store_float(stack, fac_offset, f); + if (stack_valid(color_offset)) + stack_store_float3(stack, color_offset, make_float3(f, f, f)); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_wavelength.h b/intern/cycles/kernel/svm/svm_wavelength.h index e935fd20690..d6144802559 100644 --- a/intern/cycles/kernel/svm/svm_wavelength.h +++ b/intern/cycles/kernel/svm/svm_wavelength.h @@ -10,13 +10,13 @@ * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -35,64 +35,64 @@ CCL_NAMESPACE_BEGIN /* Wavelength to RGB */ // CIE colour matching functions xBar, yBar, and zBar for -// wavelengths from 380 through 780 nanometers, every 5 -// nanometers. For a wavelength lambda in this range: -// cie_colour_match[(lambda - 380) / 5][0] = xBar -// cie_colour_match[(lambda - 380) / 5][1] = yBar -// cie_colour_match[(lambda - 380) / 5][2] = zBar +// wavelengths from 380 through 780 nanometers, every 5 +// nanometers. For a wavelength lambda in this range: +// cie_colour_match[(lambda - 380) / 5][0] = xBar +// cie_colour_match[(lambda - 380) / 5][1] = yBar +// cie_colour_match[(lambda - 380) / 5][2] = zBar ccl_static_constant float cie_colour_match[81][3] = { - {0.0014f,0.0000f,0.0065f}, {0.0022f,0.0001f,0.0105f}, {0.0042f,0.0001f,0.0201f}, - {0.0076f,0.0002f,0.0362f}, {0.0143f,0.0004f,0.0679f}, {0.0232f,0.0006f,0.1102f}, - {0.0435f,0.0012f,0.2074f}, {0.0776f,0.0022f,0.3713f}, {0.1344f,0.0040f,0.6456f}, - {0.2148f,0.0073f,1.0391f}, {0.2839f,0.0116f,1.3856f}, {0.3285f,0.0168f,1.6230f}, - {0.3483f,0.0230f,1.7471f}, {0.3481f,0.0298f,1.7826f}, {0.3362f,0.0380f,1.7721f}, - {0.3187f,0.0480f,1.7441f}, {0.2908f,0.0600f,1.6692f}, {0.2511f,0.0739f,1.5281f}, - {0.1954f,0.0910f,1.2876f}, {0.1421f,0.1126f,1.0419f}, {0.0956f,0.1390f,0.8130f}, - {0.0580f,0.1693f,0.6162f}, {0.0320f,0.2080f,0.4652f}, {0.0147f,0.2586f,0.3533f}, - {0.0049f,0.3230f,0.2720f}, {0.0024f,0.4073f,0.2123f}, {0.0093f,0.5030f,0.1582f}, - {0.0291f,0.6082f,0.1117f}, {0.0633f,0.7100f,0.0782f}, {0.1096f,0.7932f,0.0573f}, - {0.1655f,0.8620f,0.0422f}, {0.2257f,0.9149f,0.0298f}, {0.2904f,0.9540f,0.0203f}, - {0.3597f,0.9803f,0.0134f}, {0.4334f,0.9950f,0.0087f}, {0.5121f,1.0000f,0.0057f}, - {0.5945f,0.9950f,0.0039f}, {0.6784f,0.9786f,0.0027f}, {0.7621f,0.9520f,0.0021f}, - {0.8425f,0.9154f,0.0018f}, {0.9163f,0.8700f,0.0017f}, {0.9786f,0.8163f,0.0014f}, - {1.0263f,0.7570f,0.0011f}, {1.0567f,0.6949f,0.0010f}, {1.0622f,0.6310f,0.0008f}, - {1.0456f,0.5668f,0.0006f}, {1.0026f,0.5030f,0.0003f}, {0.9384f,0.4412f,0.0002f}, - {0.8544f,0.3810f,0.0002f}, {0.7514f,0.3210f,0.0001f}, {0.6424f,0.2650f,0.0000f}, - {0.5419f,0.2170f,0.0000f}, {0.4479f,0.1750f,0.0000f}, {0.3608f,0.1382f,0.0000f}, - {0.2835f,0.1070f,0.0000f}, {0.2187f,0.0816f,0.0000f}, {0.1649f,0.0610f,0.0000f}, - {0.1212f,0.0446f,0.0000f}, {0.0874f,0.0320f,0.0000f}, {0.0636f,0.0232f,0.0000f}, - {0.0468f,0.0170f,0.0000f}, {0.0329f,0.0119f,0.0000f}, {0.0227f,0.0082f,0.0000f}, - {0.0158f,0.0057f,0.0000f}, {0.0114f,0.0041f,0.0000f}, {0.0081f,0.0029f,0.0000f}, - {0.0058f,0.0021f,0.0000f}, {0.0041f,0.0015f,0.0000f}, {0.0029f,0.0010f,0.0000f}, - {0.0020f,0.0007f,0.0000f}, {0.0014f,0.0005f,0.0000f}, {0.0010f,0.0004f,0.0000f}, - {0.0007f,0.0002f,0.0000f}, {0.0005f,0.0002f,0.0000f}, {0.0003f,0.0001f,0.0000f}, - {0.0002f,0.0001f,0.0000f}, {0.0002f,0.0001f,0.0000f}, {0.0001f,0.0000f,0.0000f}, - {0.0001f,0.0000f,0.0000f}, {0.0001f,0.0000f,0.0000f}, {0.0000f,0.0000f,0.0000f} -}; + {0.0014f, 0.0000f, 0.0065f}, {0.0022f, 0.0001f, 0.0105f}, {0.0042f, 0.0001f, 0.0201f}, + {0.0076f, 0.0002f, 0.0362f}, {0.0143f, 0.0004f, 0.0679f}, {0.0232f, 0.0006f, 0.1102f}, + {0.0435f, 0.0012f, 0.2074f}, {0.0776f, 0.0022f, 0.3713f}, {0.1344f, 0.0040f, 0.6456f}, + {0.2148f, 0.0073f, 1.0391f}, {0.2839f, 0.0116f, 1.3856f}, {0.3285f, 0.0168f, 1.6230f}, + {0.3483f, 0.0230f, 1.7471f}, {0.3481f, 0.0298f, 1.7826f}, {0.3362f, 0.0380f, 1.7721f}, + {0.3187f, 0.0480f, 1.7441f}, {0.2908f, 0.0600f, 1.6692f}, {0.2511f, 0.0739f, 1.5281f}, + {0.1954f, 0.0910f, 1.2876f}, {0.1421f, 0.1126f, 1.0419f}, {0.0956f, 0.1390f, 0.8130f}, + {0.0580f, 0.1693f, 0.6162f}, {0.0320f, 0.2080f, 0.4652f}, {0.0147f, 0.2586f, 0.3533f}, + {0.0049f, 0.3230f, 0.2720f}, {0.0024f, 0.4073f, 0.2123f}, {0.0093f, 0.5030f, 0.1582f}, + {0.0291f, 0.6082f, 0.1117f}, {0.0633f, 0.7100f, 0.0782f}, {0.1096f, 0.7932f, 0.0573f}, + {0.1655f, 0.8620f, 0.0422f}, {0.2257f, 0.9149f, 0.0298f}, {0.2904f, 0.9540f, 0.0203f}, + {0.3597f, 0.9803f, 0.0134f}, {0.4334f, 0.9950f, 0.0087f}, {0.5121f, 1.0000f, 0.0057f}, + {0.5945f, 0.9950f, 0.0039f}, {0.6784f, 0.9786f, 0.0027f}, {0.7621f, 0.9520f, 0.0021f}, + {0.8425f, 0.9154f, 0.0018f}, {0.9163f, 0.8700f, 0.0017f}, {0.9786f, 0.8163f, 0.0014f}, + {1.0263f, 0.7570f, 0.0011f}, {1.0567f, 0.6949f, 0.0010f}, {1.0622f, 0.6310f, 0.0008f}, + {1.0456f, 0.5668f, 0.0006f}, {1.0026f, 0.5030f, 0.0003f}, {0.9384f, 0.4412f, 0.0002f}, + {0.8544f, 0.3810f, 0.0002f}, {0.7514f, 0.3210f, 0.0001f}, {0.6424f, 0.2650f, 0.0000f}, + {0.5419f, 0.2170f, 0.0000f}, {0.4479f, 0.1750f, 0.0000f}, {0.3608f, 0.1382f, 0.0000f}, + {0.2835f, 0.1070f, 0.0000f}, {0.2187f, 0.0816f, 0.0000f}, {0.1649f, 0.0610f, 0.0000f}, + {0.1212f, 0.0446f, 0.0000f}, {0.0874f, 0.0320f, 0.0000f}, {0.0636f, 0.0232f, 0.0000f}, + {0.0468f, 0.0170f, 0.0000f}, {0.0329f, 0.0119f, 0.0000f}, {0.0227f, 0.0082f, 0.0000f}, + {0.0158f, 0.0057f, 0.0000f}, {0.0114f, 0.0041f, 0.0000f}, {0.0081f, 0.0029f, 0.0000f}, + {0.0058f, 0.0021f, 0.0000f}, {0.0041f, 0.0015f, 0.0000f}, {0.0029f, 0.0010f, 0.0000f}, + {0.0020f, 0.0007f, 0.0000f}, {0.0014f, 0.0005f, 0.0000f}, {0.0010f, 0.0004f, 0.0000f}, + {0.0007f, 0.0002f, 0.0000f}, {0.0005f, 0.0002f, 0.0000f}, {0.0003f, 0.0001f, 0.0000f}, + {0.0002f, 0.0001f, 0.0000f}, {0.0002f, 0.0001f, 0.0000f}, {0.0001f, 0.0000f, 0.0000f}, + {0.0001f, 0.0000f, 0.0000f}, {0.0001f, 0.0000f, 0.0000f}, {0.0000f, 0.0000f, 0.0000f}}; -ccl_device void svm_node_wavelength(KernelGlobals *kg, ShaderData *sd, float *stack, uint wavelength, uint color_out) +ccl_device void svm_node_wavelength( + KernelGlobals *kg, ShaderData *sd, float *stack, uint wavelength, uint color_out) { - float lambda_nm = stack_load_float(stack, wavelength); - float ii = (lambda_nm-380.0f) * (1.0f/5.0f); // scaled 0..80 - int i = float_to_int(ii); - float3 color; + float lambda_nm = stack_load_float(stack, wavelength); + float ii = (lambda_nm - 380.0f) * (1.0f / 5.0f); // scaled 0..80 + int i = float_to_int(ii); + float3 color; - if(i < 0 || i >= 80) { - color = make_float3(0.0f, 0.0f, 0.0f); - } - else { - ii -= i; - ccl_constant float *c = cie_colour_match[i]; - color = interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii); - } + if (i < 0 || i >= 80) { + color = make_float3(0.0f, 0.0f, 0.0f); + } + else { + ii -= i; + ccl_constant float *c = cie_colour_match[i]; + color = interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii); + } - color = xyz_to_rgb(kg, color); - color *= 1.0f/2.52f; // Empirical scale from lg to make all comps <= 1 + color = xyz_to_rgb(kg, color); + color *= 1.0f / 2.52f; // Empirical scale from lg to make all comps <= 1 - /* Clamp to zero if values are smaller */ - color = max(color, make_float3(0.0f, 0.0f, 0.0f)); + /* Clamp to zero if values are smaller */ + color = max(color, make_float3(0.0f, 0.0f, 0.0f)); - stack_store_float3(stack, color_out, color); + stack_store_float3(stack, color_out, color); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_wireframe.h b/intern/cycles/kernel/svm/svm_wireframe.h index 35df9e8a0e7..55e61d0e8c7 100644 --- a/intern/cycles/kernel/svm/svm_wireframe.h +++ b/intern/cycles/kernel/svm/svm_wireframe.h @@ -34,103 +34,97 @@ CCL_NAMESPACE_BEGIN /* Wireframe Node */ -ccl_device_inline float wireframe(KernelGlobals *kg, - ShaderData *sd, - float size, - int pixel_size, - float3 *P) +ccl_device_inline float wireframe( + KernelGlobals *kg, ShaderData *sd, float size, int pixel_size, float3 *P) { #ifdef __HAIR__ - if(sd->prim != PRIM_NONE && sd->type & PRIMITIVE_ALL_TRIANGLE) + if (sd->prim != PRIM_NONE && sd->type & PRIMITIVE_ALL_TRIANGLE) #else - if(sd->prim != PRIM_NONE) + if (sd->prim != PRIM_NONE) #endif - { - float3 Co[3]; - float pixelwidth = 1.0f; + { + float3 Co[3]; + float pixelwidth = 1.0f; - /* Triangles */ - int np = 3; + /* Triangles */ + int np = 3; - if(sd->type & PRIMITIVE_TRIANGLE) - triangle_vertices(kg, sd->prim, Co); - else - motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, Co); + if (sd->type & PRIMITIVE_TRIANGLE) + triangle_vertices(kg, sd->prim, Co); + else + motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, Co); - if(!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { - object_position_transform(kg, sd, &Co[0]); - object_position_transform(kg, sd, &Co[1]); - object_position_transform(kg, sd, &Co[2]); - } + if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { + object_position_transform(kg, sd, &Co[0]); + object_position_transform(kg, sd, &Co[1]); + object_position_transform(kg, sd, &Co[2]); + } - if(pixel_size) { - // Project the derivatives of P to the viewing plane defined - // by I so we have a measure of how big is a pixel at this point - float pixelwidth_x = len(sd->dP.dx - dot(sd->dP.dx, sd->I) * sd->I); - float pixelwidth_y = len(sd->dP.dy - dot(sd->dP.dy, sd->I) * sd->I); - // Take the average of both axis' length - pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f; - } + if (pixel_size) { + // Project the derivatives of P to the viewing plane defined + // by I so we have a measure of how big is a pixel at this point + float pixelwidth_x = len(sd->dP.dx - dot(sd->dP.dx, sd->I) * sd->I); + float pixelwidth_y = len(sd->dP.dy - dot(sd->dP.dy, sd->I) * sd->I); + // Take the average of both axis' length + pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f; + } - // Use half the width as the neighbor face will render the - // other half. And take the square for fast comparison - pixelwidth *= 0.5f * size; - pixelwidth *= pixelwidth; - for(int i = 0; i < np; i++) { - int i2 = i ? i - 1 : np - 1; - float3 dir = *P - Co[i]; - float3 edge = Co[i] - Co[i2]; - float3 crs = cross(edge, dir); - // At this point dot(crs, crs) / dot(edge, edge) is - // the square of area / length(edge) == square of the - // distance to the edge. - if(dot(crs, crs) < (dot(edge, edge) * pixelwidth)) - return 1.0f; - } - } - return 0.0f; + // Use half the width as the neighbor face will render the + // other half. And take the square for fast comparison + pixelwidth *= 0.5f * size; + pixelwidth *= pixelwidth; + for (int i = 0; i < np; i++) { + int i2 = i ? i - 1 : np - 1; + float3 dir = *P - Co[i]; + float3 edge = Co[i] - Co[i2]; + float3 crs = cross(edge, dir); + // At this point dot(crs, crs) / dot(edge, edge) is + // the square of area / length(edge) == square of the + // distance to the edge. + if (dot(crs, crs) < (dot(edge, edge) * pixelwidth)) + return 1.0f; + } + } + return 0.0f; } -ccl_device void svm_node_wireframe(KernelGlobals *kg, - ShaderData *sd, - float *stack, - uint4 node) +ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - uint in_size = node.y; - uint out_fac = node.z; - uint use_pixel_size, bump_offset; - decode_node_uchar4(node.w, &use_pixel_size, &bump_offset, NULL, NULL); + uint in_size = node.y; + uint out_fac = node.z; + uint use_pixel_size, bump_offset; + decode_node_uchar4(node.w, &use_pixel_size, &bump_offset, NULL, NULL); - /* Input Data */ - float size = stack_load_float(stack, in_size); - int pixel_size = (int)use_pixel_size; + /* Input Data */ + float size = stack_load_float(stack, in_size); + int pixel_size = (int)use_pixel_size; - /* Calculate wireframe */ + /* Calculate wireframe */ #ifdef __SPLIT_KERNEL__ - /* TODO(sergey): This is because sd is actually a global space, - * which makes it difficult to re-use same wireframe() function. - * - * With OpenCL 2.0 it's possible to avoid this change, but for until - * then we'll be living with such an exception. - */ - float3 P = sd->P; - float f = wireframe(kg, sd, size, pixel_size, &P); + /* TODO(sergey): This is because sd is actually a global space, + * which makes it difficult to re-use same wireframe() function. + * + * With OpenCL 2.0 it's possible to avoid this change, but for until + * then we'll be living with such an exception. + */ + float3 P = sd->P; + float f = wireframe(kg, sd, size, pixel_size, &P); #else - float f = wireframe(kg, sd, size, pixel_size, &sd->P); + float f = wireframe(kg, sd, size, pixel_size, &sd->P); #endif - /* TODO(sergey): Think of faster way to calculate derivatives. */ - if(bump_offset == NODE_BUMP_OFFSET_DX) { - float3 Px = sd->P - sd->dP.dx; - f += (f - wireframe(kg, sd, size, pixel_size, &Px)) / len(sd->dP.dx); - } - else if(bump_offset == NODE_BUMP_OFFSET_DY) { - float3 Py = sd->P - sd->dP.dy; - f += (f - wireframe(kg, sd, size, pixel_size, &Py)) / len(sd->dP.dy); - } + /* TODO(sergey): Think of faster way to calculate derivatives. */ + if (bump_offset == NODE_BUMP_OFFSET_DX) { + float3 Px = sd->P - sd->dP.dx; + f += (f - wireframe(kg, sd, size, pixel_size, &Px)) / len(sd->dP.dx); + } + else if (bump_offset == NODE_BUMP_OFFSET_DY) { + float3 Py = sd->P - sd->dP.dy; + f += (f - wireframe(kg, sd, size, pixel_size, &Py)) / len(sd->dP.dy); + } - if(stack_valid(out_fac)) - stack_store_float(stack, out_fac, f); + if (stack_valid(out_fac)) + stack_store_float(stack, out_fac, f); } CCL_NAMESPACE_END -- cgit v1.2.3