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