diff options
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/kernel/svm/displace.h | 225 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm.h | 20 |
2 files changed, 131 insertions, 114 deletions
diff --git a/intern/cycles/kernel/svm/displace.h b/intern/cycles/kernel/svm/displace.h index eb74e23b1a4..56fb5c3f9b0 100644 --- a/intern/cycles/kernel/svm/displace.h +++ b/intern/cycles/kernel/svm/displace.h @@ -8,159 +8,188 @@ CCL_NAMESPACE_BEGIN /* Bump Node */ - +template<uint node_feature_mask> ccl_device_noinline void svm_node_set_bump(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node) { #ifdef __RAY_DIFFERENTIALS__ - /* get normal input */ - uint normal_offset, scale_offset, invert, use_object_space; - svm_unpack_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; + IF_KERNEL_NODES_FEATURE(BUMP) + { + /* get normal input */ + uint normal_offset, scale_offset, invert, use_object_space; + svm_unpack_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 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); + } - float3 dPdx = sd->dP.dx; - float3 dPdy = sd->dP.dy; + /* get surface tangents from normal */ + float3 Rx = cross(dPdy, normal_in); + float3 Ry = cross(normal_in, dPdx); - 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 bump values */ + uint c_offset, x_offset, y_offset, strength_offset; + svm_unpack_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset); - /* get surface tangents from normal */ - float3 Rx = cross(dPdy, normal_in); - float3 Ry = cross(normal_in, dPdx); + 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); - /* get bump values */ - uint c_offset, x_offset, y_offset, strength_offset; - svm_unpack_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset); + /* compute surface gradient and determinant */ + float det = dot(dPdx, Rx); + float3 surfgrad = (h_x - h_c) * Rx + (h_y - h_c) * Ry; - 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 absdet = fabsf(det); - /* compute surface gradient and determinant */ - float det = dot(dPdx, Rx); - float3 surfgrad = (h_x - h_c) * Rx + (h_y - h_c) * Ry; + float strength = stack_load_float(stack, strength_offset); + float scale = stack_load_float(stack, scale_offset); - float absdet = fabsf(det); + if (invert) + scale *= -1.0f; - float strength = stack_load_float(stack, strength_offset); - float scale = stack_load_float(stack, scale_offset); + strength = max(strength, 0.0f); - if (invert) - scale *= -1.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); + } - strength = max(strength, 0.0f); + if (use_object_space) { + object_normal_transform(kg, sd, &normal_out); + } - /* 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); + normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out); + stack_store_float3(stack, node.w, normal_out); } - - if (use_object_space) { - object_normal_transform(kg, sd, &normal_out); + else + { + stack_store_float3(stack, node.w, zero_float3()); } - - normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out); - - stack_store_float3(stack, node.w, normal_out); #endif } /* Displacement Node */ +template<uint node_feature_mask> ccl_device void svm_node_set_displacement(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint fac_offset) { - float3 dP = stack_load_float3(stack, fac_offset); - sd->P += dP; + IF_KERNEL_NODES_FEATURE(BUMP) + { + float3 dP = stack_load_float3(stack, fac_offset); + sd->P += dP; + } } +template<uint node_feature_mask> ccl_device_noinline void svm_node_displacement(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node) { - uint height_offset, midlevel_offset, scale_offset, normal_offset; - svm_unpack_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); + IF_KERNEL_NODES_FEATURE(BUMP) + { + uint height_offset, midlevel_offset, scale_offset, normal_offset; + svm_unpack_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); } - else { - /* World space. */ - dP *= (height - midlevel) * scale; + else + { + stack_store_float3(stack, node.z, zero_float3()); } - - stack_store_float3(stack, node.z, dP); } +template<uint node_feature_mask> ccl_device_noinline int svm_node_vector_displacement( KernelGlobals kg, ccl_private ShaderData *sd, ccl_private 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; svm_unpack_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); + IF_KERNEL_NODES_FEATURE(BUMP) + { + uint space = data_node.x; + + 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; } - 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; + if (space != NODE_NORMAL_MAP_WORLD) { + /* Tangent or object space. */ + object_dir_transform(kg, sd, &dP); } - dP = tangent * dP.x + normal * dP.y + bitangent * dP.z; + stack_store_float3(stack, displacement_offset, dP); } - - if (space != NODE_NORMAL_MAP_WORLD) { - /* Tangent or object space. */ - object_dir_transform(kg, sd, &dP); + else + { + stack_store_float3(stack, displacement_offset, zero_float3()); } - stack_store_float3(stack, displacement_offset, dP); return offset; } diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 6b969da7e52..08352a6231f 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -304,22 +304,13 @@ ccl_device void svm_eval_nodes(KernelGlobals kg, } break; case NODE_SET_DISPLACEMENT: - IF_KERNEL_NODES_FEATURE(BUMP) - { - svm_node_set_displacement(kg, sd, stack, node.y); - } + svm_node_set_displacement<node_feature_mask>(kg, sd, stack, node.y); break; case NODE_DISPLACEMENT: - IF_KERNEL_NODES_FEATURE(BUMP) - { - svm_node_displacement(kg, sd, stack, node); - } + svm_node_displacement<node_feature_mask>(kg, sd, stack, node); break; case NODE_VECTOR_DISPLACEMENT: - IF_KERNEL_NODES_FEATURE(BUMP) - { - offset = svm_node_vector_displacement(kg, sd, stack, node, offset); - } + offset = svm_node_vector_displacement<node_feature_mask>(kg, sd, stack, node, offset); break; case NODE_TEX_IMAGE: offset = svm_node_tex_image(kg, sd, stack, node, offset); @@ -331,10 +322,7 @@ ccl_device void svm_eval_nodes(KernelGlobals kg, offset = svm_node_tex_noise(kg, sd, stack, node.y, node.z, node.w, offset); break; case NODE_SET_BUMP: - IF_KERNEL_NODES_FEATURE(BUMP) - { - svm_node_set_bump(kg, sd, stack, node); - } + svm_node_set_bump<node_feature_mask>(kg, sd, stack, node); break; case NODE_ATTR_BUMP_DX: IF_KERNEL_NODES_FEATURE(BUMP) |