Blender V5.0
math_util.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/types.h"
8#include "kernel/tables.h"
9
10#include "util/math.h"
11#include "util/types.h"
12
14
18 const float3 a,
19 const float3 b,
20 const float3 c,
21 float param1)
22{
23 switch (type) {
25 *vector = a + b;
26 break;
28 *vector = a - b;
29 break;
31 *vector = a * b;
32 break;
34 *vector = safe_divide(a, b);
35 break;
37 *vector = cross(a, b);
38 break;
40 *vector = project(a, b);
41 break;
44 break;
46 *vector = refract(a, safe_normalize(b), param1);
47 break;
49 *vector = faceforward(a, b, c);
50 break;
52 *vector = a * b + c;
53 break;
55 *value = dot(a, b);
56 break;
58 *value = distance(a, b);
59 break;
61 *value = len(a);
62 break;
64 *vector = a * param1;
65 break;
68 break;
70 *vector = floor(safe_divide(a, b)) * b;
71 break;
73 *vector = floor(a);
74 break;
76 *vector = ceil(a);
77 break;
79 *vector = safe_fmod(a, b);
80 break;
82 *vector = wrap(a, b, c);
83 break;
85 *vector = a - floor(a);
86 break;
88 *vector = fabs(a);
89 break;
91 *vector = safe_pow(a, b);
92 break;
95 break;
97 *vector = min(a, b);
98 break;
100 *vector = max(a, b);
101 break;
103 *vector = sin(a);
104 break;
106 *vector = cos(a);
107 break;
109 *vector = tan(a);
110 break;
111 default:
112 *vector = zero_float3();
113 *value = 0.0f;
114 }
115}
116
117ccl_device float svm_math(NodeMathType type, const float a, float b, const float c)
118{
119 switch (type) {
120 case NODE_MATH_ADD:
121 return a + b;
123 return a - b;
125 return a * b;
126 case NODE_MATH_DIVIDE:
127 return safe_divide(a, b);
128 case NODE_MATH_POWER:
129 return safe_powf(a, b);
131 return safe_logf(a, b);
132 case NODE_MATH_SQRT:
133 return safe_sqrtf(a);
135 return inversesqrtf(a);
137 return fabsf(a);
139 return a * (M_PI_F / 180.0f);
141 return a * (180.0f / M_PI_F);
143 return fminf(a, b);
145 return fmaxf(a, b);
147 return a < b;
149 return a > b;
150 case NODE_MATH_ROUND:
151 return floorf(a + 0.5f);
152 case NODE_MATH_FLOOR:
153 return floorf(a);
154 case NODE_MATH_CEIL:
155 return ceilf(a);
157 return a - floorf(a);
158 case NODE_MATH_MODULO:
159 return safe_modulo(a, b);
161 return safe_floored_modulo(a, b);
162 case NODE_MATH_TRUNC:
163 return a >= 0.0f ? floorf(a) : ceilf(a);
164 case NODE_MATH_SNAP:
165 return floorf(safe_divide(a, b)) * b;
166 case NODE_MATH_WRAP:
167 return wrapf(a, b, c);
169 return pingpongf(a, b);
170 case NODE_MATH_SINE:
171 return sinf(a);
172 case NODE_MATH_COSINE:
173 return cosf(a);
175 return tanf(a);
176 case NODE_MATH_SINH:
177 return sinhf(a);
178 case NODE_MATH_COSH:
179 return coshf(a);
180 case NODE_MATH_TANH:
181 return tanhf(a);
183 return safe_asinf(a);
185 return safe_acosf(a);
187 return atanf(a);
189 return compatible_atan2(a, b);
190 case NODE_MATH_SIGN:
191 return compatible_signf(a);
193 return expf(a);
195 return ((a == b) || (fabsf(a - b) <= fmaxf(c, FLT_EPSILON))) ? 1.0f : 0.0f;
197 return a * b + c;
199 return smoothminf(a, b, c);
201 return -smoothminf(-a, -b, c);
202 default:
203 return 0.0f;
204 }
205}
206
208{
209 /* Calculate color in range 800..12000 using an approximation
210 * a/x+bx+c for R and G and ((at + b)t + c)t + d) for B.
211 *
212 * The result of this can be negative to support gamut wider than
213 * than rec.709, just needs to be clamped. */
214
215 if (t >= 12000.0f) {
216 return make_float3(0.8262954810464208f, 0.9945080501520986f, 1.566307710274283f);
217 }
218 if (t < 800.0f) {
219 /* Arbitrary lower limit where light is very dim, matching OSL. */
220 return make_float3(5.413294490189271f, -0.20319390035873933f, -0.0822535242887164f);
221 }
222
223 const int i = (t >= 6365.0f) ? 6 :
224 (t >= 3315.0f) ? 5 :
225 (t >= 1902.0f) ? 4 :
226 (t >= 1449.0f) ? 3 :
227 (t >= 1167.0f) ? 2 :
228 (t >= 965.0f) ? 1 :
229 0;
230
231 ccl_constant float *r = blackbody_table_r[i];
232 ccl_constant float *g = blackbody_table_g[i];
234
235 const float t_inv = 1.0f / t;
236 return make_float3(r[0] * t_inv + r[1] * t + r[2],
237 g[0] * t_inv + g[1] * t + g[2],
238 ((b[0] * t + b[1]) * t + b[2]) * t + b[3]);
239}
240
242{
243 if (gamma == 0.0f) {
244 return make_float3(1.0f, 1.0f, 1.0f);
245 }
246
247 if (color.x > 0.0f) {
248 color.x = powf(color.x, gamma);
249 }
250 if (color.y > 0.0f) {
251 color.y = powf(color.y, gamma);
252 }
253 if (color.z > 0.0f) {
254 color.z = powf(color.z, gamma);
255 }
256
257 return color;
258}
259
261{
262 float ii = (lambda_nm - 380.0f) * (1.0f / 5.0f); // scaled 0..80
263 const int i = float_to_int(ii);
264 float3 color;
265
266 if (i < 0 || i >= 80) {
267 color = make_float3(0.0f, 0.0f, 0.0f);
268 }
269 else {
270 ii -= i;
271 ccl_constant float *c = cie_color_match[i];
272 color = interp(make_float3(c[0], c[1], c[2]), make_float3(c[3], c[4], c[5]), ii);
273 }
274
275 return color;
276}
277
MINLINE float safe_sqrtf(float a)
MINLINE float safe_logf(float a, float base)
MINLINE float safe_acosf(float a)
MINLINE float safe_powf(float base, float exponent)
MINLINE float safe_divide(float a, float b)
MINLINE float safe_asinf(float a)
@ NODE_VECTOR_MATH_NORMALIZE
@ NODE_VECTOR_MATH_LENGTH
@ NODE_VECTOR_MATH_SIGN
@ NODE_VECTOR_MATH_CROSS_PRODUCT
@ NODE_VECTOR_MATH_CEIL
@ NODE_VECTOR_MATH_MODULO
@ NODE_VECTOR_MATH_ADD
@ NODE_VECTOR_MATH_COSINE
@ NODE_VECTOR_MATH_REFLECT
@ NODE_VECTOR_MATH_WRAP
@ NODE_VECTOR_MATH_REFRACT
@ NODE_VECTOR_MATH_POWER
@ NODE_VECTOR_MATH_DOT_PRODUCT
@ NODE_VECTOR_MATH_ABSOLUTE
@ NODE_VECTOR_MATH_DIVIDE
@ NODE_VECTOR_MATH_TANGENT
@ NODE_VECTOR_MATH_DISTANCE
@ NODE_VECTOR_MATH_FLOOR
@ NODE_VECTOR_MATH_SNAP
@ NODE_VECTOR_MATH_SINE
@ NODE_VECTOR_MATH_FRACTION
@ NODE_VECTOR_MATH_PROJECT
@ NODE_VECTOR_MATH_MULTIPLY
@ NODE_VECTOR_MATH_SCALE
@ NODE_VECTOR_MATH_MAXIMUM
@ NODE_VECTOR_MATH_FACEFORWARD
@ NODE_VECTOR_MATH_SUBTRACT
@ NODE_VECTOR_MATH_MULTIPLY_ADD
@ NODE_VECTOR_MATH_MINIMUM
@ NODE_MATH_SINH
@ NODE_MATH_SMOOTH_MIN
@ NODE_MATH_TRUNC
@ NODE_MATH_COSH
@ NODE_MATH_SIGN
@ NODE_MATH_DEGREES
@ NODE_MATH_MODULO
@ NODE_MATH_ABSOLUTE
@ NODE_MATH_DIVIDE
@ NODE_MATH_SINE
@ NODE_MATH_FLOORED_MODULO
@ NODE_MATH_ARCTAN2
@ NODE_MATH_ARCCOSINE
@ NODE_MATH_MULTIPLY_ADD
@ NODE_MATH_POWER
@ NODE_MATH_WRAP
@ NODE_MATH_ARCTANGENT
@ NODE_MATH_MINIMUM
@ NODE_MATH_SQRT
@ NODE_MATH_CEIL
@ NODE_MATH_TANH
@ NODE_MATH_GREATER_THAN
@ NODE_MATH_ADD
@ NODE_MATH_FRACTION
@ NODE_MATH_EXPONENT
@ NODE_MATH_LESS_THAN
@ NODE_MATH_ARCSINE
@ NODE_MATH_MAXIMUM
@ NODE_MATH_LOGARITHM
@ NODE_MATH_COMPARE
@ NODE_MATH_INV_SQRT
@ NODE_MATH_MULTIPLY
@ NODE_MATH_PINGPONG
@ NODE_MATH_ROUND
@ NODE_MATH_FLOOR
@ NODE_MATH_SUBTRACT
@ NODE_MATH_COSINE
@ NODE_MATH_SNAP
@ NODE_MATH_TANGENT
@ NODE_MATH_SMOOTH_MAX
@ NODE_MATH_RADIANS
static const float blackbody_table_r[7][3]
static float cie_color_match[81][3]
static const float blackbody_table_g[7][3]
static const float blackbody_table_b[7][4]
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define ccl_constant
#define ccl_private
#define ccl_device_inline
#define expf(x)
#define powf(x, y)
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define tanhf(x)
#define sinhf(x)
#define coshf(x)
#define tan
#define sin
VecBase< T, D > refract(VecOp< T, D >, VecOp< T, D >, float) RET
VecBase< T, D > reflect(VecOp< T, D >, VecOp< T, D >) RET
#define cos
VecBase< T, D > faceforward(VecOp< T, D >, VecOp< T, D >, VecOp< T, D >) RET
#define floor
#define ceil
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
NodeMathType
NodeVectorMathType
ccl_device_inline float inversesqrtf(const float f)
Definition math_base.h:529
ccl_device_inline float compatible_atan2(const float y, const float x)
Definition math_base.h:471
ccl_device_inline int float_to_int(const float f)
Definition math_base.h:407
ccl_device_inline float interp(const float a, const float b, const float t)
Definition math_base.h:502
MINLINE float smoothminf(float a, float b, float c)
MINLINE float pingpongf(float value, float scale)
MINLINE float compatible_signf(float f)
MINLINE float wrapf(float value, float max, float min)
ccl_device_inline float2 safe_normalize(const float2 a)
ccl_device_inline float2 fabs(const float2 a)
ccl_device_inline float3 safe_fmod(const float3 a, const float3 b)
ccl_device_inline float3 compatible_sign(const float3 v)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:17
ccl_device_inline float3 safe_pow(const float3 a, const float3 b)
CCL_NAMESPACE_BEGIN ccl_device void svm_vector_math(ccl_private float *value, ccl_private float3 *vector, NodeVectorMathType type, const float3 a, const float3 b, const float3 c, float param1)
Definition math_util.h:15
ccl_device float svm_math(NodeMathType type, const float a, float b, const float c)
Definition math_util.h:117
ccl_device float3 svm_math_wavelength_color_xyz(const float lambda_nm)
Definition math_util.h:260
ccl_device float3 svm_math_blackbody_color_rec709(const float t)
Definition math_util.h:207
ccl_device_inline float3 svm_math_gamma_color(float3 color, const float gamma)
Definition math_util.h:241
float safe_floored_modulo(float a, float b)
Definition node_math.h:27
float wrap(float value, float max, float min)
Definition node_math.h:103
vector project(vector v, vector v_proj)
Definition node_math.h:91
float safe_modulo(float a, float b)
Definition node_math.h:22
#define floorf
#define fabsf
#define ccl_device
#define atanf
#define fmaxf
#define sinf
#define tanf
#define fminf
#define M_PI_F
#define cosf
#define ceilf
#define min(a, b)
Definition sort.cc:36
float z
Definition sky_math.h:136
float y
Definition sky_math.h:136
float x
Definition sky_math.h:136
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
uint len