diff options
Diffstat (limited to 'intern/cycles/kernel/svm/map_range.h')
-rw-r--r-- | intern/cycles/kernel/svm/map_range.h | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/intern/cycles/kernel/svm/map_range.h b/intern/cycles/kernel/svm/map_range.h index fdbfc6531c4..933ea84f939 100644 --- a/intern/cycles/kernel/svm/map_range.h +++ b/intern/cycles/kernel/svm/map_range.h @@ -88,4 +88,78 @@ ccl_device_noinline int svm_node_map_range(KernelGlobals kg, return offset; } +ccl_device_noinline int svm_node_vector_map_range(KernelGlobals kg, + ccl_private ShaderData *sd, + ccl_private float *stack, + uint value_stack_offset, + uint parameters_stack_offsets, + uint results_stack_offsets, + int offset) +{ + uint from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset; + uint steps_stack_offset, clamp_stack_offset, range_type_stack_offset, result_stack_offset; + svm_unpack_node_uchar4(parameters_stack_offsets, + &from_min_stack_offset, + &from_max_stack_offset, + &to_min_stack_offset, + &to_max_stack_offset); + svm_unpack_node_uchar4(results_stack_offsets, + &steps_stack_offset, + &clamp_stack_offset, + &range_type_stack_offset, + &result_stack_offset); + + float3 value = stack_load_float3(stack, value_stack_offset); + float3 from_min = stack_load_float3(stack, from_min_stack_offset); + float3 from_max = stack_load_float3(stack, from_max_stack_offset); + float3 to_min = stack_load_float3(stack, to_min_stack_offset); + float3 to_max = stack_load_float3(stack, to_max_stack_offset); + float3 steps = stack_load_float3(stack, steps_stack_offset); + + int type = range_type_stack_offset; + int use_clamp = (type == NODE_MAP_RANGE_SMOOTHSTEP || type == NODE_MAP_RANGE_SMOOTHERSTEP) ? + 0 : + clamp_stack_offset; + float3 result; + float3 factor = value; + switch (range_type_stack_offset) { + default: + case NODE_MAP_RANGE_LINEAR: + factor = safe_divide_float3_float3((value - from_min), (from_max - from_min)); + break; + case NODE_MAP_RANGE_STEPPED: { + factor = safe_divide_float3_float3((value - from_min), (from_max - from_min)); + factor = make_float3((steps.x > 0.0f) ? floorf(factor.x * (steps.x + 1.0f)) / steps.x : 0.0f, + (steps.y > 0.0f) ? floorf(factor.y * (steps.y + 1.0f)) / steps.y : 0.0f, + (steps.z > 0.0f) ? floorf(factor.z * (steps.z + 1.0f)) / steps.z : + 0.0f); + break; + } + case NODE_MAP_RANGE_SMOOTHSTEP: { + factor = safe_divide_float3_float3((value - from_min), (from_max - from_min)); + factor = clamp(factor, zero_float3(), one_float3()); + factor = (make_float3(3.0f, 3.0f, 3.0f) - 2.0f * factor) * (factor * factor); + break; + } + case NODE_MAP_RANGE_SMOOTHERSTEP: { + factor = safe_divide_float3_float3((value - from_min), (from_max - from_min)); + factor = clamp(factor, zero_float3(), one_float3()); + factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); + break; + } + } + result = to_min + factor * (to_max - to_min); + if (use_clamp > 0) { + result.x = (to_min.x > to_max.x) ? clamp(result.x, to_max.x, to_min.x) : + clamp(result.x, to_min.x, to_max.x); + result.y = (to_min.y > to_max.y) ? clamp(result.y, to_max.y, to_min.y) : + clamp(result.y, to_min.y, to_max.y); + result.z = (to_min.z > to_max.z) ? clamp(result.z, to_max.z, to_min.z) : + clamp(result.z, to_min.z, to_max.z); + } + + stack_store_float3(stack, result_stack_offset, result); + return offset; +} + CCL_NAMESPACE_END |