Blender V5.0
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
7#include "kernel/svm/util.h"
8
10
11/* Map Range Node */
12
13ccl_device_inline float smootherstep(const float edge0, const float edge1, float x)
14{
15 x = clamp(safe_divide((x - edge0), (edge1 - edge0)), 0.0f, 1.0f);
16 return x * x * x * (x * (x * 6.0f - 15.0f) + 10.0f);
17}
18
20 ccl_private float *stack,
21 const uint value_stack_offset,
22 const uint parameters_stack_offsets,
23 const uint results_stack_offsets,
24 int offset)
25{
26 uint from_min_stack_offset;
27 uint from_max_stack_offset;
28 uint to_min_stack_offset;
29 uint to_max_stack_offset;
30 uint type_stack_offset;
31 uint steps_stack_offset;
32 uint result_stack_offset;
33 svm_unpack_node_uchar4(parameters_stack_offsets,
34 &from_min_stack_offset,
35 &from_max_stack_offset,
36 &to_min_stack_offset,
37 &to_max_stack_offset);
39 results_stack_offsets, &type_stack_offset, &steps_stack_offset, &result_stack_offset);
40
41 const uint4 defaults = read_node(kg, &offset);
42 const uint4 defaults2 = read_node(kg, &offset);
43
44 const float value = stack_load_float(stack, value_stack_offset);
45 const float from_min = stack_load_float_default(stack, from_min_stack_offset, defaults.x);
46 const float from_max = stack_load_float_default(stack, from_max_stack_offset, defaults.y);
47 const float to_min = stack_load_float_default(stack, to_min_stack_offset, defaults.z);
48 const float to_max = stack_load_float_default(stack, to_max_stack_offset, defaults.w);
49 const float steps = stack_load_float_default(stack, steps_stack_offset, defaults2.x);
50
51 float result;
52
53 if (from_max != from_min) {
54 float factor = value;
55 switch (type_stack_offset) {
56 default:
58 factor = (value - from_min) / (from_max - from_min);
59 break;
61 factor = (value - from_min) / (from_max - from_min);
62 factor = (steps > 0.0f) ? floorf(factor * (steps + 1.0f)) / steps : 0.0f;
63 break;
64 }
66 factor = (from_min > from_max) ? 1.0f - smoothstep(from_max, from_min, factor) :
67 smoothstep(from_min, from_max, factor);
68 break;
69 }
71 factor = (from_min > from_max) ? 1.0f - smootherstep(from_max, from_min, factor) :
72 smootherstep(from_min, from_max, factor);
73 break;
74 }
75 }
76 result = to_min + factor * (to_max - to_min);
77 }
78 else {
79 result = 0.0f;
80 }
81 stack_store_float(stack, result_stack_offset, result);
82 return offset;
83}
84
86 const uint value_stack_offset,
87 const uint parameters_stack_offsets,
88 const uint results_stack_offsets,
89 const int offset)
90{
91 uint from_min_stack_offset;
92 uint from_max_stack_offset;
93 uint to_min_stack_offset;
94 uint to_max_stack_offset;
95 uint steps_stack_offset;
96 uint clamp_stack_offset;
97 uint range_type_stack_offset;
98 uint result_stack_offset;
99 svm_unpack_node_uchar4(parameters_stack_offsets,
100 &from_min_stack_offset,
101 &from_max_stack_offset,
102 &to_min_stack_offset,
103 &to_max_stack_offset);
104 svm_unpack_node_uchar4(results_stack_offsets,
105 &steps_stack_offset,
106 &clamp_stack_offset,
107 &range_type_stack_offset,
108 &result_stack_offset);
109
110 const float3 value = stack_load_float3(stack, value_stack_offset);
111 const float3 from_min = stack_load_float3(stack, from_min_stack_offset);
112 const float3 from_max = stack_load_float3(stack, from_max_stack_offset);
113 const float3 to_min = stack_load_float3(stack, to_min_stack_offset);
114 const float3 to_max = stack_load_float3(stack, to_max_stack_offset);
115 const float3 steps = stack_load_float3(stack, steps_stack_offset);
116
117 const int type = range_type_stack_offset;
118 const int use_clamp = (type == NODE_MAP_RANGE_SMOOTHSTEP ||
120 0 :
121 clamp_stack_offset;
123 float3 factor = value;
124 switch (range_type_stack_offset) {
125 default:
127 factor = safe_divide((value - from_min), (from_max - from_min));
128 break;
130 factor = safe_divide((value - from_min), (from_max - from_min));
131 factor = make_float3((steps.x > 0.0f) ? floorf(factor.x * (steps.x + 1.0f)) / steps.x : 0.0f,
132 (steps.y > 0.0f) ? floorf(factor.y * (steps.y + 1.0f)) / steps.y : 0.0f,
133 (steps.z > 0.0f) ? floorf(factor.z * (steps.z + 1.0f)) / steps.z :
134 0.0f);
135 break;
136 }
138 factor = safe_divide((value - from_min), (from_max - from_min));
139 factor = clamp(factor, zero_float3(), one_float3());
140 factor = (make_float3(3.0f, 3.0f, 3.0f) - 2.0f * factor) * (factor * factor);
141 break;
142 }
144 factor = safe_divide((value - from_min), (from_max - from_min));
145 factor = clamp(factor, zero_float3(), one_float3());
146 factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f);
147 break;
148 }
149 }
150 result = to_min + factor * (to_max - to_min);
151 if (use_clamp > 0) {
152 result.x = (to_min.x > to_max.x) ? clamp(result.x, to_max.x, to_min.x) :
153 clamp(result.x, to_min.x, to_max.x);
154 result.y = (to_min.y > to_max.y) ? clamp(result.y, to_max.y, to_min.y) :
155 clamp(result.y, to_min.y, to_max.y);
156 result.z = (to_min.z > to_max.z) ? clamp(result.z, to_max.z, to_min.z) :
157 clamp(result.z, to_min.z, to_max.z);
158 }
159
160 stack_store_float3(stack, result_stack_offset, result);
161 return offset;
162}
163
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
ccl_device_inline float stack_load_float(const ccl_private float *stack, const uint a)
ccl_device_inline void stack_store_float(ccl_private float *stack, const uint a, const float f)
ccl_device_inline uint4 read_node(KernelGlobals kg, ccl_private int *const offset)
ccl_device_inline void stack_store_float3(ccl_private float *stack, const uint a, const float3 f)
ccl_device_inline float stack_load_float_default(const ccl_private float *stack, const uint a, const uint value)
ccl_device_forceinline void svm_unpack_node_uchar3(const uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z)
ccl_device_forceinline void svm_unpack_node_uchar4(const uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z, ccl_private uint *w)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(const ccl_private float *stack, const uint a)
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#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)
constexpr T clamp(T, U, U) RET
ccl_device_noinline int svm_node_vector_map_range(ccl_private float *stack, const uint value_stack_offset, const uint parameters_stack_offsets, const uint results_stack_offsets, const int offset)
Definition map_range.h:85
CCL_NAMESPACE_BEGIN ccl_device_inline float smootherstep(const float edge0, const float edge1, float x)
Definition map_range.h:13
ccl_device_noinline int svm_node_map_range(KernelGlobals kg, ccl_private float *stack, const uint value_stack_offset, const uint parameters_stack_offsets, const uint results_stack_offsets, int offset)
Definition map_range.h:19
MINLINE float smoothstep(float edge0, float edge1, float x)
ccl_device_inline float3 one_float3()
Definition math_float3.h:26
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:17
#define floorf
float z
Definition sky_math.h:136
float y
Definition sky_math.h:136
float x
Definition sky_math.h:136
uint x
Definition types_uint4.h:13
uint y
Definition types_uint4.h:13
uint z
Definition types_uint4.h:13
uint w
Definition types_uint4.h:13