Blender  V3.3
node_texture_math.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
8 #include "NOD_texture.h"
9 #include "node_texture_util.h"
10 
11 /* **************** SCALAR MATH ******************** */
13  {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE},
14  {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE},
15  {SOCK_FLOAT, N_("Value"), 0.0f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE},
16  {-1, ""},
17 };
18 
20  {SOCK_FLOAT, N_("Value")},
21  {-1, ""},
22 };
23 
24 static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
25 {
26  float in0 = tex_input_value(in[0], p, thread);
27  float in1 = tex_input_value(in[1], p, thread);
28 
29  switch (node->custom1) {
30 
31  case NODE_MATH_ADD:
32  *out = in0 + in1;
33  break;
34  case NODE_MATH_SUBTRACT:
35  *out = in0 - in1;
36  break;
37  case NODE_MATH_MULTIPLY:
38  *out = in0 * in1;
39  break;
40  case NODE_MATH_DIVIDE: {
41  if (in1 == 0) {
42  /* We don't want to divide by zero. */
43  *out = 0.0;
44  }
45  else {
46  *out = in0 / in1;
47  }
48  break;
49  }
50  case NODE_MATH_SINE: {
51  *out = sinf(in0);
52  break;
53  }
54  case NODE_MATH_COSINE: {
55  *out = cosf(in0);
56  break;
57  }
58  case NODE_MATH_TANGENT: {
59  *out = tanf(in0);
60  break;
61  }
62  case NODE_MATH_SINH: {
63  *out = sinhf(in0);
64  break;
65  }
66  case NODE_MATH_COSH: {
67  *out = coshf(in0);
68  break;
69  }
70  case NODE_MATH_TANH: {
71  *out = tanhf(in0);
72  break;
73  }
74  case NODE_MATH_ARCSINE: {
75  /* Can't do the impossible... */
76  if (in0 <= 1 && in0 >= -1) {
77  *out = asinf(in0);
78  }
79  else {
80  *out = 0.0;
81  }
82  break;
83  }
84  case NODE_MATH_ARCCOSINE: {
85  /* Can't do the impossible... */
86  if (in0 <= 1 && in0 >= -1) {
87  *out = acosf(in0);
88  }
89  else {
90  *out = 0.0;
91  }
92  break;
93  }
94  case NODE_MATH_ARCTANGENT: {
95  *out = atan(in0);
96  break;
97  }
98  case NODE_MATH_POWER: {
99  /* Only raise negative numbers by full integers */
100  if (in0 >= 0) {
101  out[0] = pow(in0, in1);
102  }
103  else {
104  float y_mod_1 = fmod(in1, 1);
105  if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
106  *out = pow(in0, floor(in1 + 0.5f));
107  }
108  else {
109  *out = 0.0;
110  }
111  }
112  break;
113  }
114  case NODE_MATH_LOGARITHM: {
115  /* Don't want any imaginary numbers... */
116  if (in0 > 0 && in1 > 0) {
117  *out = log(in0) / log(in1);
118  }
119  else {
120  *out = 0.0;
121  }
122  break;
123  }
124  case NODE_MATH_MINIMUM: {
125  if (in0 < in1) {
126  *out = in0;
127  }
128  else {
129  *out = in1;
130  }
131  break;
132  }
133  case NODE_MATH_MAXIMUM: {
134  if (in0 > in1) {
135  *out = in0;
136  }
137  else {
138  *out = in1;
139  }
140  break;
141  }
142  case NODE_MATH_ROUND: {
143  *out = (in0 < 0) ? (int)(in0 - 0.5f) : (int)(in0 + 0.5f);
144  break;
145  }
146 
147  case NODE_MATH_LESS_THAN: {
148  if (in0 < in1) {
149  *out = 1.0f;
150  }
151  else {
152  *out = 0.0f;
153  }
154  break;
155  }
156 
157  case NODE_MATH_GREATER_THAN: {
158  if (in0 > in1) {
159  *out = 1.0f;
160  }
161  else {
162  *out = 0.0f;
163  }
164  break;
165  }
166 
167  case NODE_MATH_MODULO: {
168  if (in1 == 0.0f) {
169  *out = 0.0f;
170  }
171  else {
172  *out = fmod(in0, in1);
173  }
174  break;
175  }
176 
177  case NODE_MATH_ABSOLUTE: {
178  *out = fabsf(in0);
179  break;
180  }
181 
182  case NODE_MATH_RADIANS: {
183  *out = DEG2RADF(in0);
184  break;
185  }
186 
187  case NODE_MATH_DEGREES: {
188  *out = RAD2DEGF(in0);
189  break;
190  }
191 
192  case NODE_MATH_ARCTAN2: {
193  *out = atan2(in0, in1);
194  break;
195  }
196 
197  case NODE_MATH_SIGN: {
198  *out = compatible_signf(in0);
199  break;
200  }
201 
202  case NODE_MATH_EXPONENT: {
203  *out = expf(in0);
204  break;
205  }
206 
207  case NODE_MATH_FLOOR: {
208  *out = floorf(in0);
209  break;
210  }
211 
212  case NODE_MATH_CEIL: {
213  *out = ceilf(in0);
214  break;
215  }
216 
217  case NODE_MATH_FRACTION: {
218  *out = in0 - floorf(in0);
219  break;
220  }
221 
222  case NODE_MATH_SQRT: {
223  if (in0 > 0.0f) {
224  *out = sqrtf(in0);
225  }
226  else {
227  *out = 0.0f;
228  }
229  break;
230  }
231 
232  case NODE_MATH_INV_SQRT: {
233  if (in0 > 0.0f) {
234  *out = 1.0f / sqrtf(in0);
235  }
236  else {
237  *out = 0.0f;
238  }
239  break;
240  }
241 
242  case NODE_MATH_TRUNC: {
243  if (in0 > 0.0f) {
244  *out = floorf(in0);
245  }
246  else {
247  *out = ceilf(in0);
248  }
249  break;
250  }
251 
252  case NODE_MATH_SNAP: {
253  if (in1 == 0) {
254  *out = 0.0;
255  }
256  else {
257  *out = floorf(in0 / in1) * in1;
258  }
259  break;
260  }
261 
262  case NODE_MATH_WRAP: {
263  float in2 = tex_input_value(in[2], p, thread);
264  *out = wrapf(in0, in1, in2);
265  break;
266  }
267 
268  case NODE_MATH_PINGPONG: {
269  *out = pingpongf(in0, in1);
270  break;
271  }
272 
273  case NODE_MATH_COMPARE: {
274  float in2 = tex_input_value(in[2], p, thread);
275  *out = (fabsf(in0 - in1) <= MAX2(in2, 1e-5f)) ? 1.0f : 0.0f;
276  break;
277  }
278 
279  case NODE_MATH_MULTIPLY_ADD: {
280  float in2 = tex_input_value(in[2], p, thread);
281  *out = in0 * in1 + in2;
282  break;
283  }
284 
285  case NODE_MATH_SMOOTH_MIN: {
286  float in2 = tex_input_value(in[2], p, thread);
287  *out = smoothminf(in0, in1, in2);
288  break;
289  }
290 
291  case NODE_MATH_SMOOTH_MAX: {
292  float in2 = tex_input_value(in[2], p, thread);
293  *out = -smoothminf(-in0, -in1, in2);
294  break;
295  }
296 
297  default: {
298  BLI_assert(0);
299  break;
300  }
301  }
302 
303  if (node->custom2 & SHD_MATH_CLAMP) {
304  CLAMP(*out, 0.0f, 1.0f);
305  }
306 }
307 
308 static void exec(void *data,
309  int UNUSED(thread),
310  bNode *node,
311  bNodeExecData *execdata,
312  bNodeStack **in,
313  bNodeStack **out)
314 {
315  tex_output(node, execdata, in, out[0], &valuefn, data);
316 }
317 
319 {
320  static bNodeType ntype;
321 
324  ntype.labelfunc = node_math_label;
325  node_type_exec(&ntype, NULL, NULL, exec);
327 
328  nodeRegisterType(&ntype);
329 }
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4358
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4443
#define NODE_CLASS_CONVERTER
Definition: BKE_node.h:351
#define TEX_NODE_MATH
Definition: BKE_node.h:1351
void node_type_exec(struct bNodeType *ntype, NodeInitExecFunction init_exec_fn, NodeFreeExecFunction free_exec_fn, NodeExecFunction exec_fn)
Definition: node.cc:4455
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define DEG2RADF(_deg)
#define RAD2DEGF(_rad)
#define UNUSED(x)
#define MAX2(a, b)
@ 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_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
#define SHD_MATH_CLAMP
@ SOCK_FLOAT
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
@ PROP_NONE
Definition: RNA_types.h:126
Definition: thread.h:34
#define sinf(x)
Definition: cuda/compat.h:102
#define cosf(x)
Definition: cuda/compat.h:101
#define expf(x)
Definition: cuda/compat.h:106
#define tanf(x)
Definition: cuda/compat.h:104
OperationNode * node
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 float3 pow(float3 v, float e)
Definition: math_float3.h:533
ccl_device_inline float3 log(float3 v)
Definition: math_float3.h:397
#define asinf(x)
Definition: metal/compat.h:221
#define ceilf(x)
Definition: metal/compat.h:225
#define floorf(x)
Definition: metal/compat.h:224
#define acosf(x)
Definition: metal/compat.h:222
#define tanhf(x)
Definition: metal/compat.h:233
#define sinhf(x)
Definition: metal/compat.h:231
#define coshf(x)
Definition: metal/compat.h:232
#define fabsf(x)
Definition: metal/compat.h:219
#define sqrtf(x)
Definition: metal/compat.h:243
INLINE Rall1d< T, V, S > atan(const Rall1d< T, V, S > &x)
Definition: rall1d.h:375
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
Definition: rall1d.h:429
T floor(const T &a)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
void register_node_type_tex_math(void)
static bNodeSocketTemplate outputs[]
static bNodeSocketTemplate inputs[]
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
float tex_input_value(bNodeStack *in, TexParams *params, short thread)
void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass)
void tex_output(bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *cdata)
void node_math_update(bNodeTree *ntree, bNode *node)
Definition: node_util.c:88
void node_math_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen)
Definition: node_util.c:196
Compact definition of a node socket.
Definition: BKE_node.h:84
Defines a node type.
Definition: BKE_node.h:226
void(* labelfunc)(const struct bNodeTree *ntree, const struct bNode *node, char *label, int maxlen)
Definition: BKE_node.h:256
#define N_(msgid)