Blender V4.3
map_range.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
8
9/* Map Range Node */
10
11ccl_device_inline float smootherstep(float edge0, float edge1, float x)
12{
13 x = clamp(safe_divide((x - edge0), (edge1 - edge0)), 0.0f, 1.0f);
14 return x * x * x * (x * (x * 6.0f - 15.0f) + 10.0f);
15}
16
19 ccl_private float *stack,
20 uint value_stack_offset,
21 uint parameters_stack_offsets,
22 uint results_stack_offsets,
23 int offset)
24{
25 uint from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset;
26 uint type_stack_offset, steps_stack_offset, result_stack_offset;
27 svm_unpack_node_uchar4(parameters_stack_offsets,
28 &from_min_stack_offset,
29 &from_max_stack_offset,
30 &to_min_stack_offset,
31 &to_max_stack_offset);
33 results_stack_offsets, &type_stack_offset, &steps_stack_offset, &result_stack_offset);
34
35 uint4 defaults = read_node(kg, &offset);
36 uint4 defaults2 = read_node(kg, &offset);
37
38 float value = stack_load_float(stack, value_stack_offset);
39 float from_min = stack_load_float_default(stack, from_min_stack_offset, defaults.x);
40 float from_max = stack_load_float_default(stack, from_max_stack_offset, defaults.y);
41 float to_min = stack_load_float_default(stack, to_min_stack_offset, defaults.z);
42 float to_max = stack_load_float_default(stack, to_max_stack_offset, defaults.w);
43 float steps = stack_load_float_default(stack, steps_stack_offset, defaults2.x);
44
45 float result;
46
47 if (from_max != from_min) {
48 float factor = value;
49 switch (type_stack_offset) {
50 default:
52 factor = (value - from_min) / (from_max - from_min);
53 break;
55 factor = (value - from_min) / (from_max - from_min);
56 factor = (steps > 0.0f) ? floorf(factor * (steps + 1.0f)) / steps : 0.0f;
57 break;
58 }
60 factor = (from_min > from_max) ? 1.0f - smoothstep(from_max, from_min, factor) :
61 smoothstep(from_min, from_max, factor);
62 break;
63 }
65 factor = (from_min > from_max) ? 1.0f - smootherstep(from_max, from_min, factor) :
66 smootherstep(from_min, from_max, factor);
67 break;
68 }
69 }
70 result = to_min + factor * (to_max - to_min);
71 }
72 else {
73 result = 0.0f;
74 }
75 stack_store_float(stack, result_stack_offset, result);
76 return offset;
77}
78
81 ccl_private float *stack,
82 uint value_stack_offset,
83 uint parameters_stack_offsets,
84 uint results_stack_offsets,
85 int offset)
86{
87 uint from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset;
88 uint steps_stack_offset, clamp_stack_offset, range_type_stack_offset, result_stack_offset;
89 svm_unpack_node_uchar4(parameters_stack_offsets,
90 &from_min_stack_offset,
91 &from_max_stack_offset,
92 &to_min_stack_offset,
93 &to_max_stack_offset);
94 svm_unpack_node_uchar4(results_stack_offsets,
95 &steps_stack_offset,
96 &clamp_stack_offset,
97 &range_type_stack_offset,
98 &result_stack_offset);
99
100 float3 value = stack_load_float3(stack, value_stack_offset);
101 float3 from_min = stack_load_float3(stack, from_min_stack_offset);
102 float3 from_max = stack_load_float3(stack, from_max_stack_offset);
103 float3 to_min = stack_load_float3(stack, to_min_stack_offset);
104 float3 to_max = stack_load_float3(stack, to_max_stack_offset);
105 float3 steps = stack_load_float3(stack, steps_stack_offset);
106
107 int type = range_type_stack_offset;
108 int use_clamp = (type == NODE_MAP_RANGE_SMOOTHSTEP || type == NODE_MAP_RANGE_SMOOTHERSTEP) ?
109 0 :
110 clamp_stack_offset;
112 float3 factor = value;
113 switch (range_type_stack_offset) {
114 default:
116 factor = safe_divide((value - from_min), (from_max - from_min));
117 break;
119 factor = safe_divide((value - from_min), (from_max - from_min));
120 factor = make_float3((steps.x > 0.0f) ? floorf(factor.x * (steps.x + 1.0f)) / steps.x : 0.0f,
121 (steps.y > 0.0f) ? floorf(factor.y * (steps.y + 1.0f)) / steps.y : 0.0f,
122 (steps.z > 0.0f) ? floorf(factor.z * (steps.z + 1.0f)) / steps.z :
123 0.0f);
124 break;
125 }
127 factor = safe_divide((value - from_min), (from_max - from_min));
128 factor = clamp(factor, zero_float3(), one_float3());
129 factor = (make_float3(3.0f, 3.0f, 3.0f) - 2.0f * factor) * (factor * factor);
130 break;
131 }
133 factor = safe_divide((value - from_min), (from_max - from_min));
134 factor = clamp(factor, zero_float3(), one_float3());
135 factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f);
136 break;
137 }
138 }
139 result = to_min + factor * (to_max - to_min);
140 if (use_clamp > 0) {
141 result.x = (to_min.x > to_max.x) ? clamp(result.x, to_max.x, to_min.x) :
142 clamp(result.x, to_min.x, to_max.x);
143 result.y = (to_min.y > to_max.y) ? clamp(result.y, to_max.y, to_min.y) :
144 clamp(result.y, to_min.y, to_max.y);
145 result.z = (to_min.z > to_max.z) ? clamp(result.z, to_max.z, to_min.z) :
146 clamp(result.z, to_min.z, to_max.z);
147 }
148
149 stack_store_float3(stack, result_stack_offset, result);
150 return offset;
151}
152
MINLINE float safe_divide(float a, float b)
unsigned int uint
@ NODE_MAP_RANGE_STEPPED
@ NODE_MAP_RANGE_SMOOTHERSTEP
@ NODE_MAP_RANGE_SMOOTHSTEP
@ NODE_MAP_RANGE_LINEAR
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define ccl_private
#define ccl_device_inline
#define ccl_device_noinline
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define floorf(x)
ccl_device_inline void stack_store_float3(ccl_private float *stack, uint a, float3 f)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(ccl_private float *stack, uint a)
ccl_device_inline uint4 read_node(KernelGlobals kg, ccl_private int *offset)
ccl_device_forceinline void svm_unpack_node_uchar3(uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z)
ccl_device_inline float stack_load_float_default(ccl_private float *stack, uint a, uint value)
ccl_device_inline void stack_store_float(ccl_private float *stack, uint a, float f)
ccl_device_inline float stack_load_float(ccl_private float *stack, uint a)
ccl_device_forceinline void svm_unpack_node_uchar4(uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z, ccl_private uint *w)
ShaderData
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)
Definition map_range.h:79
ccl_device_noinline int svm_node_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)
Definition map_range.h:17
CCL_NAMESPACE_BEGIN ccl_device_inline float smootherstep(float edge0, float edge1, float x)
Definition map_range.h:11
MINLINE float smoothstep(float edge0, float edge1, float x)
ccl_device_inline float3 one_float3()
Definition math_float3.h:24
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
static const int steps
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
uint x
Definition types_uint4.h:15
uint y
Definition types_uint4.h:15
uint z
Definition types_uint4.h:15
uint w
Definition types_uint4.h:15
ccl_device_inline int clamp(int a, int mn, int mx)
Definition util/math.h:379