Blender V4.5
texture_procedural.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10#include <cmath>
11#include <cstdlib>
12#include <cstring>
13
14#include "BLI_math_geom.h"
15#include "BLI_noise.h"
16#include "BLI_rand.h"
17#include "BLI_utildefines.h"
18
19#include "DNA_material_types.h"
20#include "DNA_node_types.h"
21#include "DNA_texture_types.h"
22
24#include "IMB_imbuf_types.hh"
25
26#include "BKE_colorband.hh"
27#include "BKE_image.hh"
28
29#include "NOD_texture.h"
30
31#include "texture_common.h"
32
33#include "RE_texture.h"
34
36
41
43{
44 if (random_tex_array == nullptr) {
45 return;
46 }
48 random_tex_array = nullptr;
49}
50
51/* ------------------------------------------------------------------------- */
52
53static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
54{
55 float x, y, t;
56
57 if (tex->flag & TEX_FLIPBLEND) {
58 x = texvec[1];
59 y = texvec[0];
60 }
61 else {
62 x = texvec[0];
63 y = texvec[1];
64 }
65
66 if (tex->stype == TEX_LIN) { /* Linear. */
67 texres->tin = (1.0f + x) / 2.0f;
68 }
69 else if (tex->stype == TEX_QUAD) { /* Quadratic. */
70 texres->tin = (1.0f + x) / 2.0f;
71 if (texres->tin < 0.0f) {
72 texres->tin = 0.0f;
73 }
74 else {
75 texres->tin *= texres->tin;
76 }
77 }
78 else if (tex->stype == TEX_EASE) { /* Ease. */
79 texres->tin = (1.0f + x) / 2.0f;
80 if (texres->tin <= 0.0f) {
81 texres->tin = 0.0f;
82 }
83 else if (texres->tin >= 1.0f) {
84 texres->tin = 1.0f;
85 }
86 else {
87 t = texres->tin * texres->tin;
88 texres->tin = (3.0f * t - 2.0f * t * texres->tin);
89 }
90 }
91 else if (tex->stype == TEX_DIAG) { /* Diagonal. */
92 texres->tin = (2.0f + x + y) / 4.0f;
93 }
94 else if (tex->stype == TEX_RAD) { /* Radial. */
95 texres->tin = (atan2f(y, x) / float(2 * M_PI) + 0.5f);
96 }
97 else { /* sphere TEX_SPHERE */
98 texres->tin = 1.0f - sqrtf(x * x + y * y + texvec[2] * texvec[2]);
99 texres->tin = std::max(texres->tin, 0.0f);
100 if (tex->stype == TEX_HALO) {
101 texres->tin *= texres->tin; /* Halo. */
102 }
103 }
104
105 BRICONT;
106
107 return TEX_INT;
108}
109
110/* ------------------------------------------------------------------------- */
111/* ************************************************************************* */
112
113/* newnoise: all noise-based types now have different noise-bases to choose from. */
114
115static int clouds(const Tex *tex, const float texvec[3], TexResult *texres)
116{
117 int rv = TEX_INT;
118
120 texvec[0],
121 texvec[1],
122 texvec[2],
123 tex->noisedepth,
124 (tex->noisetype != TEX_NOISESOFT),
125 tex->noisebasis);
126
127 if (tex->stype == TEX_COLOR) {
128 texres->trgba[0] = texres->tin;
130 texvec[1],
131 texvec[0],
132 texvec[2],
133 tex->noisedepth,
134 (tex->noisetype != TEX_NOISESOFT),
135 tex->noisebasis);
137 texvec[1],
138 texvec[2],
139 texvec[0],
140 tex->noisedepth,
141 (tex->noisetype != TEX_NOISESOFT),
142 tex->noisebasis);
144 texres->trgba[3] = 1.0;
145 return (rv | TEX_RGB);
146 }
147
148 BRICONT;
149
150 return rv;
151}
152
153/* creates a sine wave */
154static float tex_sin(float a)
155{
156 a = 0.5f + 0.5f * sinf(a);
157
158 return a;
159}
160
161/* creates a saw wave */
162static float tex_saw(float a)
163{
164 const float b = 2 * M_PI;
165
166 int n = int(a / b);
167 a -= n * b;
168 if (a < 0) {
169 a += b;
170 }
171 return a / b;
172}
173
174/* creates a triangle wave */
175static float tex_tri(float a)
176{
177 const float b = 2 * M_PI;
178 const float rmax = 1.0;
179
180 a = rmax - 2.0f * fabsf(floorf((a * (1.0f / b)) + 0.5f) - (a * (1.0f / b)));
181
182 return a;
183}
184
185/* computes basic wood intensity value at x,y,z */
186static float wood_int(const Tex *tex, float x, float y, float z)
187{
188 float wi = 0;
189 /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2. */
190 short wf = tex->noisebasis2;
191 /* wood type: TEX_BAND=0, TEX_RING=1, TEX_BANDNOISE=2, TEX_RINGNOISE=3. */
192 short wt = tex->stype;
193
194 float (*waveform[3])(float); /* create array of pointers to waveform functions */
195 waveform[0] = tex_sin; /* assign address of tex_sin() function to pointer array */
196 waveform[1] = tex_saw;
197 waveform[2] = tex_tri;
198
199 if ((wf > TEX_TRI) || (wf < TEX_SIN)) {
200 wf = 0; /* check to be sure noisebasis2 is initialized ahead of time */
201 }
202
203 if (wt == TEX_BAND) {
204 wi = waveform[wf]((x + y + z) * 10.0f);
205 }
206 else if (wt == TEX_RING) {
207 wi = waveform[wf](sqrtf(x * x + y * y + z * z) * 20.0f);
208 }
209 else if (wt == TEX_BANDNOISE) {
210 wi = tex->turbul *
212 tex->noisesize, x, y, z, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
213 wi = waveform[wf]((x + y + z) * 10.0f + wi);
214 }
215 else if (wt == TEX_RINGNOISE) {
216 wi = tex->turbul *
218 tex->noisesize, x, y, z, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis);
219 wi = waveform[wf](sqrtf(x * x + y * y + z * z) * 20.0f + wi);
220 }
221
222 return wi;
223}
224
225static int wood(const Tex *tex, const float texvec[3], TexResult *texres)
226{
227 int rv = TEX_INT;
228
229 texres->tin = wood_int(tex, texvec[0], texvec[1], texvec[2]);
230
231 BRICONT;
232
233 return rv;
234}
235
236/* computes basic marble intensity at x,y,z */
237static float marble_int(const Tex *tex, float x, float y, float z)
238{
239 float n, mi;
240 short wf = tex->noisebasis2; /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2 */
241 short mt = tex->stype; /* marble type: TEX_SOFT=0, TEX_SHARP=1, TEX_SHAPER=2 */
242
243 float (*waveform[3])(float); /* create array of pointers to waveform functions */
244 waveform[0] = tex_sin; /* assign address of tex_sin() function to pointer array */
245 waveform[1] = tex_saw;
246 waveform[2] = tex_tri;
247
248 if ((wf > TEX_TRI) || (wf < TEX_SIN)) {
249 wf = 0; /* check to be sure noisebasis2 isn't initialized ahead of time */
250 }
251
252 n = 5.0f * (x + y + z);
253
254 mi = n + tex->turbul * BLI_noise_generic_turbulence(tex->noisesize,
255 x,
256 y,
257 z,
258 tex->noisedepth,
259 (tex->noisetype != TEX_NOISESOFT),
260 tex->noisebasis);
261
262 if (mt >= TEX_SOFT) { /* TEX_SOFT always true */
263 mi = waveform[wf](mi);
264 if (mt == TEX_SHARP) {
265 mi = sqrtf(mi);
266 }
267 else if (mt == TEX_SHARPER) {
268 mi = sqrtf(sqrtf(mi));
269 }
270 }
271
272 return mi;
273}
274
275static int marble(const Tex *tex, const float texvec[3], TexResult *texres)
276{
277 int rv = TEX_INT;
278
279 texres->tin = marble_int(tex, texvec[0], texvec[1], texvec[2]);
280
281 BRICONT;
282
283 return rv;
284}
285
286/* ------------------------------------------------------------------------- */
287
288static int magic(const Tex *tex, const float texvec[3], TexResult *texres)
289{
290 float x, y, z, turb;
291 int n;
292
293 n = tex->noisedepth;
294 turb = tex->turbul / 5.0f;
295
296 x = sinf((texvec[0] + texvec[1] + texvec[2]) * 5.0f);
297 y = cosf((-texvec[0] + texvec[1] - texvec[2]) * 5.0f);
298 z = -cosf((-texvec[0] - texvec[1] + texvec[2]) * 5.0f);
299 if (n > 0) {
300 x *= turb;
301 y *= turb;
302 z *= turb;
303 y = -cosf(x - y + z);
304 y *= turb;
305 if (n > 1) {
306 x = cosf(x - y - z);
307 x *= turb;
308 if (n > 2) {
309 z = sinf(-x - y - z);
310 z *= turb;
311 if (n > 3) {
312 x = -cosf(-x + y - z);
313 x *= turb;
314 if (n > 4) {
315 y = -sinf(-x + y + z);
316 y *= turb;
317 if (n > 5) {
318 y = -cosf(-x + y + z);
319 y *= turb;
320 if (n > 6) {
321 x = cosf(x + y + z);
322 x *= turb;
323 if (n > 7) {
324 z = sinf(x + y - z);
325 z *= turb;
326 if (n > 8) {
327 x = -cosf(-x - y + z);
328 x *= turb;
329 if (n > 9) {
330 y = -sinf(x - y + z);
331 y *= turb;
332 }
333 }
334 }
335 }
336 }
337 }
338 }
339 }
340 }
341 }
342
343 if (turb != 0.0f) {
344 turb *= 2.0f;
345 x /= turb;
346 y /= turb;
347 z /= turb;
348 }
349 texres->trgba[0] = 0.5f - x;
350 texres->trgba[1] = 0.5f - y;
351 texres->trgba[2] = 0.5f - z;
352
353 texres->tin = (1.0f / 3.0f) * (texres->trgba[0] + texres->trgba[1] + texres->trgba[2]);
354
356 texres->trgba[3] = 1.0f;
357
358 return TEX_RGB;
359}
360
361/* ------------------------------------------------------------------------- */
362
363/* newnoise: stucci also modified to use different noisebasis */
364static int stucci(const Tex *tex, const float texvec[3], TexResult *texres)
365{
366 float b2, ofs;
367 int retval = TEX_INT;
368
370 texvec[0],
371 texvec[1],
372 texvec[2],
373 (tex->noisetype != TEX_NOISESOFT),
374 tex->noisebasis);
375
376 ofs = tex->turbul / 200.0f;
377
378 if (tex->stype) {
379 ofs *= (b2 * b2);
380 }
381
383 texvec[0],
384 texvec[1],
385 texvec[2] + ofs,
386 (tex->noisetype != TEX_NOISESOFT),
387 tex->noisebasis);
388
389 if (tex->stype == TEX_WALLOUT) {
390 texres->tin = 1.0f - texres->tin;
391 }
392
393 texres->tin = std::max(texres->tin, 0.0f);
394
395 return retval;
396}
397
398/* ------------------------------------------------------------------------- */
399/* newnoise: musgrave terrain noise types */
400
401static int mg_mFractalOrfBmTex(const Tex *tex, const float texvec[3], TexResult *texres)
402{
403 int rv = TEX_INT;
404 float (*mgravefunc)(float, float, float, float, float, float, int);
405
406 if (tex->stype == TEX_MFRACTAL) {
407 mgravefunc = BLI_noise_mg_multi_fractal;
408 }
409 else {
410 mgravefunc = BLI_noise_mg_fbm;
411 }
412
413 texres->tin = tex->ns_outscale * mgravefunc(texvec[0],
414 texvec[1],
415 texvec[2],
416 tex->mg_H,
417 tex->mg_lacunarity,
418 tex->mg_octaves,
419 tex->noisebasis);
420
421 BRICONT;
422
423 return rv;
424}
425
426static int mg_ridgedOrHybridMFTex(const Tex *tex, const float texvec[3], TexResult *texres)
427{
428 int rv = TEX_INT;
429 float (*mgravefunc)(float, float, float, float, float, float, float, float, int);
430
431 if (tex->stype == TEX_RIDGEDMF) {
433 }
434 else {
436 }
437
438 texres->tin = tex->ns_outscale * mgravefunc(texvec[0],
439 texvec[1],
440 texvec[2],
441 tex->mg_H,
442 tex->mg_lacunarity,
443 tex->mg_octaves,
444 tex->mg_offset,
445 tex->mg_gain,
446 tex->noisebasis);
447
448 BRICONT;
449
450 return rv;
451}
452
453static int mg_HTerrainTex(const Tex *tex, const float texvec[3], TexResult *texres)
454{
455 int rv = TEX_INT;
456
457 texres->tin = tex->ns_outscale * BLI_noise_mg_hetero_terrain(texvec[0],
458 texvec[1],
459 texvec[2],
460 tex->mg_H,
461 tex->mg_lacunarity,
462 tex->mg_octaves,
463 tex->mg_offset,
464 tex->noisebasis);
465
466 BRICONT;
467
468 return rv;
469}
470
471static int mg_distNoiseTex(const Tex *tex, const float texvec[3], TexResult *texres)
472{
473 int rv = TEX_INT;
474
476 texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
477
478 BRICONT;
479
480 return rv;
481}
482
483/* ------------------------------------------------------------------------- */
484/* newnoise: Voronoi texture type
485 *
486 * probably the slowest, especially with minkovsky, bump-mapping, could be done another way.
487 */
488
489static int voronoiTex(const Tex *tex, const float texvec[3], TexResult *texres)
490{
491 int rv = TEX_INT;
492 float da[4], pa[12]; /* distance and point coordinate arrays of 4 nearest neighbors */
493 float aw1 = fabsf(tex->vn_w1);
494 float aw2 = fabsf(tex->vn_w2);
495 float aw3 = fabsf(tex->vn_w3);
496 float aw4 = fabsf(tex->vn_w4);
497 float sc = (aw1 + aw2 + aw3 + aw4);
498 if (sc != 0.0f) {
499 sc = tex->ns_outscale / sc;
500 }
501
502 BLI_noise_voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm);
503 texres->tin = sc * fabsf(dot_v4v4(&tex->vn_w1, da));
504
505 const bool is_color = ELEM(tex->vn_coltype, TEX_COL1, TEX_COL2, TEX_COL3);
506 if (is_color) {
507 float ca[3]; /* cell color */
508 BLI_noise_cell_v3(pa[0], pa[1], pa[2], ca);
509 texres->trgba[0] = aw1 * ca[0];
510 texres->trgba[1] = aw1 * ca[1];
511 texres->trgba[2] = aw1 * ca[2];
512 BLI_noise_cell_v3(pa[3], pa[4], pa[5], ca);
513 texres->trgba[0] += aw2 * ca[0];
514 texres->trgba[1] += aw2 * ca[1];
515 texres->trgba[2] += aw2 * ca[2];
516 BLI_noise_cell_v3(pa[6], pa[7], pa[8], ca);
517 texres->trgba[0] += aw3 * ca[0];
518 texres->trgba[1] += aw3 * ca[1];
519 texres->trgba[2] += aw3 * ca[2];
520 BLI_noise_cell_v3(pa[9], pa[10], pa[11], ca);
521 texres->trgba[0] += aw4 * ca[0];
522 texres->trgba[1] += aw4 * ca[1];
523 texres->trgba[2] += aw4 * ca[2];
524 if (ELEM(tex->vn_coltype, TEX_COL2, TEX_COL3)) {
525 float t1 = (da[1] - da[0]) * 10;
526 t1 = std::min<float>(t1, 1);
527 if (tex->vn_coltype == TEX_COL3) {
528 t1 *= texres->tin;
529 }
530 else {
531 t1 *= sc;
532 }
533 texres->trgba[0] *= t1;
534 texres->trgba[1] *= t1;
535 texres->trgba[2] *= t1;
536 }
537 else {
538 texres->trgba[0] *= sc;
539 texres->trgba[1] *= sc;
540 texres->trgba[2] *= sc;
541 }
542 }
543
544 if (is_color) {
546 texres->trgba[3] = 1.0;
547 return (rv | TEX_RGB);
548 }
549
550 BRICONT;
551
552 return rv;
553}
554
555/* ------------------------------------------------------------------------- */
556
557static int texnoise(const Tex *tex, TexResult *texres, int thread)
558{
559 float div = 3.0;
560 int val, ran, loop, shift = 29;
561
563
564 loop = tex->noisedepth;
565
566 /* start from top bits since they have more variance */
567 val = ((ran >> shift) & 3);
568
569 while (loop--) {
570 shift -= 2;
571 val *= ((ran >> shift) & 3);
572 div *= 3.0f;
573 }
574
575 texres->tin = float(val) / div;
576
577 BRICONT;
578 return TEX_INT;
579}
580
581/* ------------------------------------------------------------------------- */
582
583static int cubemap_glob(const float n[3], float x, float y, float z, float *adr1, float *adr2)
584{
585 float x1, y1, z1, nor[3];
586 int ret;
587
588 if (n == nullptr) {
589 nor[0] = x;
590 nor[1] = y;
591 nor[2] = z; /* use local render coord */
592 }
593 else {
594 copy_v3_v3(nor, n);
595 }
596
597 x1 = fabsf(nor[0]);
598 y1 = fabsf(nor[1]);
599 z1 = fabsf(nor[2]);
600
601 if (z1 >= x1 && z1 >= y1) {
602 *adr1 = (x + 1.0f) / 2.0f;
603 *adr2 = (y + 1.0f) / 2.0f;
604 ret = 0;
605 }
606 else if (y1 >= x1 && y1 >= z1) {
607 *adr1 = (x + 1.0f) / 2.0f;
608 *adr2 = (z + 1.0f) / 2.0f;
609 ret = 1;
610 }
611 else {
612 *adr1 = (y + 1.0f) / 2.0f;
613 *adr2 = (z + 1.0f) / 2.0f;
614 ret = 2;
615 }
616 return ret;
617}
618
619/* ------------------------------------------------------------------------- */
620
621static void do_2d_mapping(
622 const MTex *mtex, float texvec[3], const float n[3], float dxt[3], float dyt[3])
623{
624 Tex *tex;
625 float fx, fy, fac1, area[8];
626 int ok, proj, areaflag = 0, wrap;
627
628 /* #MTex variables localized, only cube-map doesn't cooperate yet. */
629 wrap = mtex->mapping;
630 tex = mtex->tex;
631
632 if (!(dxt && dyt)) {
633
634 if (wrap == MTEX_FLAT) {
635 fx = (texvec[0] + 1.0f) / 2.0f;
636 fy = (texvec[1] + 1.0f) / 2.0f;
637 }
638 else if (wrap == MTEX_TUBE) {
639 map_to_tube(&fx, &fy, texvec[0], texvec[1], texvec[2]);
640 }
641 else if (wrap == MTEX_SPHERE) {
642 map_to_sphere(&fx, &fy, texvec[0], texvec[1], texvec[2]);
643 }
644 else {
645 cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy);
646 }
647
648 /* repeat */
649 if (tex->extend == TEX_REPEAT) {
650 if (tex->xrepeat > 1) {
651 float origf = fx *= tex->xrepeat;
652
653 if (fx > 1.0f) {
654 fx -= int(fx);
655 }
656 else if (fx < 0.0f) {
657 fx += 1 - int(fx);
658 }
659
660 if (tex->flag & TEX_REPEAT_XMIR) {
661 int orig = int(floor(origf));
662 if (orig & 1) {
663 fx = 1.0f - fx;
664 }
665 }
666 }
667 if (tex->yrepeat > 1) {
668 float origf = fy *= tex->yrepeat;
669
670 if (fy > 1.0f) {
671 fy -= int(fy);
672 }
673 else if (fy < 0.0f) {
674 fy += 1 - int(fy);
675 }
676
677 if (tex->flag & TEX_REPEAT_YMIR) {
678 int orig = int(floor(origf));
679 if (orig & 1) {
680 fy = 1.0f - fy;
681 }
682 }
683 }
684 }
685 /* crop */
686 if (tex->cropxmin != 0.0f || tex->cropxmax != 1.0f) {
687 fac1 = tex->cropxmax - tex->cropxmin;
688 fx = tex->cropxmin + fx * fac1;
689 }
690 if (tex->cropymin != 0.0f || tex->cropymax != 1.0f) {
691 fac1 = tex->cropymax - tex->cropymin;
692 fy = tex->cropymin + fy * fac1;
693 }
694
695 texvec[0] = fx;
696 texvec[1] = fy;
697 }
698 else {
699
700 if (wrap == MTEX_FLAT) {
701 fx = (texvec[0] + 1.0f) / 2.0f;
702 fy = (texvec[1] + 1.0f) / 2.0f;
703 dxt[0] /= 2.0f;
704 dxt[1] /= 2.0f;
705 dxt[2] /= 2.0f;
706 dyt[0] /= 2.0f;
707 dyt[1] /= 2.0f;
708 dyt[2] /= 2.0f;
709 }
710 else if (ELEM(wrap, MTEX_TUBE, MTEX_SPHERE)) {
711 /* exception: the seam behind (y<0.0) */
712 ok = 1;
713 if (texvec[1] <= 0.0f) {
714 fx = texvec[0] + dxt[0];
715 fy = texvec[0] + dyt[0];
716 if (fx >= 0.0f && fy >= 0.0f && texvec[0] >= 0.0f) {
717 /* pass */
718 }
719 else if (fx <= 0.0f && fy <= 0.0f && texvec[0] <= 0.0f) {
720 /* pass */
721 }
722 else {
723 ok = 0;
724 }
725 }
726
727 if (ok) {
728 if (wrap == MTEX_TUBE) {
729 map_to_tube(area, area + 1, texvec[0], texvec[1], texvec[2]);
731 area + 2, area + 3, texvec[0] + dxt[0], texvec[1] + dxt[1], texvec[2] + dxt[2]);
733 area + 4, area + 5, texvec[0] + dyt[0], texvec[1] + dyt[1], texvec[2] + dyt[2]);
734 }
735 else {
736 map_to_sphere(area, area + 1, texvec[0], texvec[1], texvec[2]);
738 area + 2, area + 3, texvec[0] + dxt[0], texvec[1] + dxt[1], texvec[2] + dxt[2]);
740 area + 4, area + 5, texvec[0] + dyt[0], texvec[1] + dyt[1], texvec[2] + dyt[2]);
741 }
742 areaflag = 1;
743 }
744 else {
745 if (wrap == MTEX_TUBE) {
746 map_to_tube(&fx, &fy, texvec[0], texvec[1], texvec[2]);
747 }
748 else {
749 map_to_sphere(&fx, &fy, texvec[0], texvec[1], texvec[2]);
750 }
751 dxt[0] /= 2.0f;
752 dxt[1] /= 2.0f;
753 dyt[0] /= 2.0f;
754 dyt[1] /= 2.0f;
755 }
756 }
757 else {
758
759 proj = cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy);
760
761 if (proj == 1) {
762 std::swap(dxt[1], dxt[2]);
763 std::swap(dyt[1], dyt[2]);
764 }
765 else if (proj == 2) {
766 float f1 = dxt[0], f2 = dyt[0];
767 dxt[0] = dxt[1];
768 dyt[0] = dyt[1];
769 dxt[1] = dxt[2];
770 dyt[1] = dyt[2];
771 dxt[2] = f1;
772 dyt[2] = f2;
773 }
774
775 dxt[0] *= 0.5f;
776 dxt[1] *= 0.5f;
777 dxt[2] *= 0.5f;
778
779 dyt[0] *= 0.5f;
780 dyt[1] *= 0.5f;
781 dyt[2] *= 0.5f;
782 }
783
784 /* If area, then recalculate `dxt[]` and `dyt[]` */
785 if (areaflag) {
786 fx = area[0];
787 fy = area[1];
788 dxt[0] = area[2] - fx;
789 dxt[1] = area[3] - fy;
790 dyt[0] = area[4] - fx;
791 dyt[1] = area[5] - fy;
792 }
793
794 /* repeat */
795 if (tex->extend == TEX_REPEAT) {
796 float max = 1.0f;
797 if (tex->xrepeat > 1) {
798 float origf = fx *= tex->xrepeat;
799
800 /* TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call */
801 if (tex->texfilter == TXF_BOX) {
802 if (fx > 1.0f) {
803 fx -= int(fx);
804 }
805 else if (fx < 0.0f) {
806 fx += 1 - int(fx);
807 }
808
809 if (tex->flag & TEX_REPEAT_XMIR) {
810 int orig = int(floor(origf));
811 if (orig & 1) {
812 fx = 1.0f - fx;
813 }
814 }
815 }
816
817 max = tex->xrepeat;
818
819 dxt[0] *= tex->xrepeat;
820 dyt[0] *= tex->xrepeat;
821 }
822 if (tex->yrepeat > 1) {
823 float origf = fy *= tex->yrepeat;
824
825 /* TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call */
826 if (tex->texfilter == TXF_BOX) {
827 if (fy > 1.0f) {
828 fy -= int(fy);
829 }
830 else if (fy < 0.0f) {
831 fy += 1 - int(fy);
832 }
833
834 if (tex->flag & TEX_REPEAT_YMIR) {
835 int orig = int(floor(origf));
836 if (orig & 1) {
837 fy = 1.0f - fy;
838 }
839 }
840 }
841
842 max = std::max<float>(max, tex->yrepeat);
843
844 dxt[1] *= tex->yrepeat;
845 dyt[1] *= tex->yrepeat;
846 }
847 if (max != 1.0f) {
848 dxt[2] *= max;
849 dyt[2] *= max;
850 }
851 }
852 /* crop */
853 if (tex->cropxmin != 0.0f || tex->cropxmax != 1.0f) {
854 fac1 = tex->cropxmax - tex->cropxmin;
855 fx = tex->cropxmin + fx * fac1;
856 dxt[0] *= fac1;
857 dyt[0] *= fac1;
858 }
859 if (tex->cropymin != 0.0f || tex->cropymax != 1.0f) {
860 fac1 = tex->cropymax - tex->cropymin;
861 fy = tex->cropymin + fy * fac1;
862 dxt[1] *= fac1;
863 dyt[1] *= fac1;
864 }
865
866 texvec[0] = fx;
867 texvec[1] = fy;
868 }
869}
870
871/* ************************************** */
872
873static int multitex(Tex *tex,
874 const float texvec[3],
875 float dxt[3],
876 float dyt[3],
877 int osatex,
878 TexResult *texres,
879 const short thread,
880 const short which_output,
881 ImagePool *pool,
882 const bool skip_load_image,
883 const bool texnode_preview,
884 const bool use_nodes)
885{
886 float tmpvec[3];
887 int retval = 0; /* return value, TEX_INT or TEX_RGB. */
888
889 texres->talpha = false; /* Is set when image texture returns alpha (considered pre-multiplied) */
890
891 if (use_nodes && tex->use_nodes && tex->nodetree) {
892 const float cfra = 1.0f; /* This was only set for Blender Internal render before. */
893 retval = ntreeTexExecTree(tex->nodetree,
894 texres,
895 texvec,
896 dxt,
897 dyt,
898 osatex,
899 thread,
900 tex,
901 which_output,
902 cfra,
903 texnode_preview,
904 nullptr);
905 }
906 else {
907 switch (tex->type) {
908 case 0:
909 texres->tin = 0.0f;
910 return 0;
911 case TEX_CLOUDS:
912 retval = clouds(tex, texvec, texres);
913 break;
914 case TEX_WOOD:
915 retval = wood(tex, texvec, texres);
916 break;
917 case TEX_MARBLE:
918 retval = marble(tex, texvec, texres);
919 break;
920 case TEX_MAGIC:
921 retval = magic(tex, texvec, texres);
922 break;
923 case TEX_BLEND:
924 retval = blend(tex, texvec, texres);
925 break;
926 case TEX_STUCCI:
927 retval = stucci(tex, texvec, texres);
928 break;
929 case TEX_NOISE:
930 retval = texnoise(tex, texres, thread);
931 break;
932 case TEX_IMAGE:
933 if (osatex) {
934 retval = imagewraposa(
935 tex, tex->ima, nullptr, texvec, dxt, dyt, texres, pool, skip_load_image);
936 }
937 else {
938 retval = imagewrap(tex, tex->ima, texvec, texres, pool, skip_load_image);
939 }
940 if (tex->ima) {
942 }
943 break;
944 case TEX_MUSGRAVE:
945 /* newnoise: musgrave types */
946
947 /* NOTE(@ton): added this, for Blender convention reason.
948 * NOTE(@artificer): added the use of tmpvec to avoid scaling texvec. */
949 copy_v3_v3(tmpvec, texvec);
950 mul_v3_fl(tmpvec, 1.0f / tex->noisesize);
951
952 switch (tex->stype) {
953 case TEX_MFRACTAL:
954 case TEX_FBM:
955 retval = mg_mFractalOrfBmTex(tex, tmpvec, texres);
956 break;
957 case TEX_RIDGEDMF:
958 case TEX_HYBRIDMF:
959 retval = mg_ridgedOrHybridMFTex(tex, tmpvec, texres);
960 break;
961 case TEX_HTERRAIN:
962 retval = mg_HTerrainTex(tex, tmpvec, texres);
963 break;
964 }
965 break;
966 /* newnoise: voronoi type */
967 case TEX_VORONOI:
968 /* NOTE(@ton): added this, for Blender convention reason.
969 * NOTE(@artificer): added the use of tmpvec to avoid scaling texvec. */
970 copy_v3_v3(tmpvec, texvec);
971 mul_v3_fl(tmpvec, 1.0f / tex->noisesize);
972
973 retval = voronoiTex(tex, tmpvec, texres);
974 break;
975 case TEX_DISTNOISE:
976 /* NOTE(@ton): added this, for Blender convention reason.
977 * NOTE(@artificer): added the use of tmpvec to avoid scaling texvec. */
978 copy_v3_v3(tmpvec, texvec);
979 mul_v3_fl(tmpvec, 1.0f / tex->noisesize);
980
981 retval = mg_distNoiseTex(tex, tmpvec, texres);
982 break;
983 }
984 }
985
986 if (tex->flag & TEX_COLORBAND) {
987 float col[4];
988 if (BKE_colorband_evaluate(tex->coba, texres->tin, col)) {
989 texres->talpha = true;
990 copy_v4_v4(texres->trgba, col);
991 retval |= TEX_RGB;
992 }
993 }
994 return retval;
995}
996
998 const float texvec[3],
999 float dxt[3],
1000 float dyt[3],
1001 int osatex,
1002 TexResult *texres,
1003 const short thread,
1004 short which_output,
1005 const MTex *mtex,
1006 ImagePool *pool,
1007 const bool scene_color_manage,
1008 const bool skip_load_image,
1009 const bool texnode_preview,
1010 const bool use_nodes)
1011{
1012 if (tex == nullptr) {
1013 memset(texres, 0, sizeof(TexResult));
1014 return 0;
1015 }
1016
1017 if (mtex) {
1018 which_output = mtex->which_output;
1019 }
1020
1021 if (tex->type == TEX_IMAGE) {
1022 int retval;
1023
1024 if (mtex) {
1025 float texvec_l[3];
1026 copy_v3_v3(texvec_l, texvec);
1027 /* we have mtex, use it for 2d mapping images only */
1028 do_2d_mapping(mtex, texvec_l, nullptr, dxt, dyt);
1029 retval = multitex(tex,
1030 texvec_l,
1031 dxt,
1032 dyt,
1033 osatex,
1034 texres,
1035 thread,
1036 which_output,
1037 pool,
1038 skip_load_image,
1039 texnode_preview,
1040 use_nodes);
1041
1042 if (mtex->mapto & MAP_COL) {
1043 ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
1044
1045 /* don't linearize float buffers, assumed to be linear */
1046 if (ibuf != nullptr && ibuf->float_buffer.data == nullptr && (retval & TEX_RGB) &&
1047 scene_color_manage)
1048 {
1050 ibuf->byte_buffer.colorspace);
1051 }
1052
1053 BKE_image_pool_release_ibuf(tex->ima, ibuf, pool);
1054 }
1055 }
1056 else {
1057 /* we don't have mtex, do default flat 2d projection */
1058 MTex localmtex;
1059 float texvec_l[3], dxt_l[3], dyt_l[3];
1060
1061 localmtex.mapping = MTEX_FLAT;
1062 localmtex.tex = tex;
1063 localmtex.object = nullptr;
1064 localmtex.texco = TEXCO_ORCO;
1065
1066 copy_v3_v3(texvec_l, texvec);
1067 if (dxt && dyt) {
1068 copy_v3_v3(dxt_l, dxt);
1069 copy_v3_v3(dyt_l, dyt);
1070 }
1071 else {
1072 zero_v3(dxt_l);
1073 zero_v3(dyt_l);
1074 }
1075
1076 do_2d_mapping(&localmtex, texvec_l, nullptr, dxt_l, dyt_l);
1077 retval = multitex(tex,
1078 texvec_l,
1079 dxt_l,
1080 dyt_l,
1081 osatex,
1082 texres,
1083 thread,
1084 which_output,
1085 pool,
1086 skip_load_image,
1087 texnode_preview,
1088 use_nodes);
1089
1090 {
1091 ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
1092
1093 /* don't linearize float buffers, assumed to be linear */
1094 if (ibuf != nullptr && ibuf->float_buffer.data == nullptr && (retval & TEX_RGB) &&
1095 scene_color_manage)
1096 {
1098 ibuf->byte_buffer.colorspace);
1099 }
1100
1101 BKE_image_pool_release_ibuf(tex->ima, ibuf, pool);
1102 }
1103 }
1104
1105 return retval;
1106 }
1107
1108 return multitex(tex,
1109 texvec,
1110 dxt,
1111 dyt,
1112 osatex,
1113 texres,
1114 thread,
1115 which_output,
1116 pool,
1117 skip_load_image,
1118 texnode_preview,
1119 use_nodes);
1120}
1121
1123 const float texvec[3],
1124 float dxt[3],
1125 float dyt[3],
1126 int osatex,
1127 TexResult *texres,
1128 const short thread,
1129 short which_output,
1130 const MTex *mtex,
1131 ImagePool *pool)
1132{
1133 return multitex_nodes_intern(tex,
1134 texvec,
1135 dxt,
1136 dyt,
1137 osatex,
1138 texres,
1139 thread,
1140 which_output,
1141 mtex,
1142 pool,
1143 true,
1144 false,
1145 false,
1146 true);
1147}
1148
1150 const float texvec[3],
1151 float dxt[3],
1152 float dyt[3],
1153 int osatex,
1154 TexResult *texres,
1155 const short thread,
1156 ImagePool *pool,
1157 bool scene_color_manage,
1158 const bool skip_load_image)
1159{
1160 return multitex_nodes_intern(tex,
1161 texvec,
1162 dxt,
1163 dyt,
1164 osatex,
1165 texres,
1166 thread,
1167 0,
1168 nullptr,
1169 pool,
1170 scene_color_manage,
1171 skip_load_image,
1172 false,
1173 true);
1174}
1175
1177 const float texvec[3],
1178 TexResult *texres,
1179 ImagePool *pool,
1180 bool scene_color_manage,
1181 const bool skip_load_image)
1182{
1183 return multitex_nodes_intern(tex,
1184 texvec,
1185 nullptr,
1186 nullptr,
1187 0,
1188 texres,
1189 0,
1190 0,
1191 nullptr,
1192 pool,
1193 scene_color_manage,
1194 skip_load_image,
1195 false,
1196 false);
1197}
1198
1199/* ------------------------------------------------------------------------- */
1200
1201float texture_value_blend(float tex, float out, float fact, float facg, int blendtype)
1202{
1203 float in = 0.0, facm, scf;
1204 int flip = (facg < 0.0f);
1205
1206 facg = fabsf(facg);
1207
1208 fact *= facg;
1209 facm = 1.0f - fact;
1210 if (flip) {
1211 std::swap(fact, facm);
1212 }
1213
1214 switch (blendtype) {
1215 case MTEX_BLEND:
1216 in = fact * tex + facm * out;
1217 break;
1218
1219 case MTEX_MUL:
1220 facm = 1.0f - facg;
1221 in = (facm + fact * tex) * out;
1222 break;
1223
1224 case MTEX_SCREEN:
1225 facm = 1.0f - facg;
1226 in = 1.0f - (facm + fact * (1.0f - tex)) * (1.0f - out);
1227 break;
1228
1229 case MTEX_OVERLAY:
1230 facm = 1.0f - facg;
1231 if (out < 0.5f) {
1232 in = out * (facm + 2.0f * fact * tex);
1233 }
1234 else {
1235 in = 1.0f - (facm + 2.0f * fact * (1.0f - tex)) * (1.0f - out);
1236 }
1237 break;
1238
1239 case MTEX_SUB:
1240 fact = -fact;
1242 case MTEX_ADD:
1243 in = fact * tex + out;
1244 break;
1245
1246 case MTEX_DIV:
1247 if (tex != 0.0f) {
1248 in = facm * out + fact * out / tex;
1249 }
1250 break;
1251
1252 case MTEX_DIFF:
1253 in = facm * out + fact * fabsf(tex - out);
1254 break;
1255
1256 case MTEX_DARK:
1257 in = min_ff(out, tex) * fact + out * facm;
1258 break;
1259
1260 case MTEX_LIGHT:
1261 in = max_ff(out, tex) * fact + out * facm;
1262 break;
1263
1264 case MTEX_SOFT_LIGHT:
1265 scf = 1.0f - (1.0f - tex) * (1.0f - out);
1266 in = facm * out + fact * ((1.0f - out) * tex * out) + (out * scf);
1267 break;
1268
1269 case MTEX_LIN_LIGHT:
1270 if (tex > 0.5f) {
1271 in = out + fact * (2.0f * (tex - 0.5f));
1272 }
1273 else {
1274 in = out + fact * (2.0f * tex - 1.0f);
1275 }
1276 break;
1277 }
1278
1279 return in;
1280}
1281
1282/* ------------------------------------------------------------------------- */
1283
1284bool RE_texture_evaluate(const MTex *mtex,
1285 const float vec[3],
1286 const int thread,
1287 ImagePool *pool,
1288 const bool skip_load_image,
1289 const bool texnode_preview,
1290 /* Return arguments. */
1291 float *r_intensity,
1292 float r_rgba[4])
1293{
1294 Tex *tex;
1295 TexResult texr;
1296 float dxt[3], dyt[3], texvec[3];
1297 int rgb;
1298
1299 tex = mtex->tex;
1300 if (tex == nullptr) {
1301 return false;
1302 }
1303
1304 /* placement */
1305 if (mtex->projx) {
1306 texvec[0] = mtex->size[0] * (vec[mtex->projx - 1] + mtex->ofs[0]);
1307 }
1308 else {
1309 texvec[0] = mtex->size[0] * (mtex->ofs[0]);
1310 }
1311
1312 if (mtex->projy) {
1313 texvec[1] = mtex->size[1] * (vec[mtex->projy - 1] + mtex->ofs[1]);
1314 }
1315 else {
1316 texvec[1] = mtex->size[1] * (mtex->ofs[1]);
1317 }
1318
1319 if (mtex->projz) {
1320 texvec[2] = mtex->size[2] * (vec[mtex->projz - 1] + mtex->ofs[2]);
1321 }
1322 else {
1323 texvec[2] = mtex->size[2] * (mtex->ofs[2]);
1324 }
1325
1326 /* texture */
1327 if (tex->type == TEX_IMAGE) {
1328 do_2d_mapping(mtex, texvec, nullptr, dxt, dyt);
1329 }
1330
1331 rgb = multitex(tex,
1332 texvec,
1333 dxt,
1334 dyt,
1335 0,
1336 &texr,
1337 thread,
1338 mtex->which_output,
1339 pool,
1340 skip_load_image,
1341 texnode_preview,
1342 true);
1343
1344 if (rgb) {
1346 }
1347 else {
1348 copy_v3_fl3(texr.trgba, mtex->r, mtex->g, mtex->b);
1349 }
1350
1351 *r_intensity = texr.tin;
1352 copy_v4_v4(r_rgba, texr.trgba);
1353
1354 return (rgb != 0);
1355}
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
Definition colorband.cc:395
void BKE_image_tag_time(Image *ima)
ImBuf * BKE_image_pool_acquire_ibuf(Image *ima, ImageUser *iuser, ImagePool *pool)
void BKE_image_pool_release_ibuf(Image *ima, ImBuf *ibuf, ImagePool *pool)
#define ATTR_FALLTHROUGH
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
#define M_PI
bool map_to_sphere(float *r_u, float *r_v, float x, float y, float z)
bool map_to_tube(float *r_u, float *r_v, float x, float y, float z)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v4v4(const float a[4], const float b[4]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE void zero_v3(float r[3])
float BLI_noise_mg_hetero_terrain(float x, float y, float z, float H, float lacunarity, float octaves, float offset, int noisebasis)
Definition noise_c.cc:1391
float BLI_noise_mg_multi_fractal(float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis)
Definition noise_c.cc:1332
float BLI_noise_mg_ridged_multi_fractal(float x, float y, float z, float H, float lacunarity, float octaves, float offset, float gain, int noisebasis)
Definition noise_c.cc:1535
float BLI_noise_mg_variable_lacunarity(float x, float y, float z, float distortion, int nbas1, int nbas2)
Definition noise_c.cc:1606
float BLI_noise_generic_noise(float noisesize, float x, float y, float z, bool hard, int noisebasis)
Definition noise_c.cc:1153
void BLI_noise_voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype)
Definition noise_c.cc:915
float BLI_noise_mg_fbm(float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis)
Definition noise_c.cc:1272
void BLI_noise_cell_v3(float x, float y, float z, float r_ca[3])
Definition noise_c.cc:1131
float BLI_noise_mg_hybrid_multi_fractal(float x, float y, float z, float H, float lacunarity, float octaves, float offset, float gain, int noisebasis)
Definition noise_c.cc:1461
float BLI_noise_generic_turbulence(float noisesize, float x, float y, float z, int oct, bool hard, int noisebasis)
Definition noise_c.cc:1210
Random number functions.
void BLI_rng_threaded_free(struct RNG_THREAD_ARRAY *rngarr) ATTR_NONNULL(1)
Definition rand.cc:190
RNG_THREAD_ARRAY * BLI_rng_threaded_new(void)
Definition rand.cc:178
int BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread) ATTR_WARN_UNUSED_RESULT
Definition rand.cc:195
#define ELEM(...)
@ TEXCO_ORCO
@ TEX_COLOR
@ TEX_NOISESOFT
@ TEX_BANDNOISE
@ TEX_RINGNOISE
@ TEX_RING
@ TEX_BAND
@ TEX_SHARPER
@ TEX_SOFT
@ TEX_SHARP
@ TXF_BOX
@ TEX_REPEAT_YMIR
@ TEX_FLIPBLEND
@ TEX_COLORBAND
@ TEX_REPEAT_XMIR
@ TEX_DIAG
@ TEX_EASE
@ TEX_HALO
@ TEX_QUAD
@ TEX_RAD
@ TEX_LIN
@ TEX_WALLOUT
@ TEX_BLEND
@ TEX_MARBLE
@ TEX_NOISE
@ TEX_IMAGE
@ TEX_WOOD
@ TEX_CLOUDS
@ TEX_DISTNOISE
@ TEX_VORONOI
@ TEX_STUCCI
@ TEX_MAGIC
@ TEX_MUSGRAVE
@ TEX_COL2
@ TEX_COL1
@ TEX_COL3
@ TEX_REPEAT
@ MTEX_DIFF
@ MTEX_DIV
@ MTEX_MUL
@ MTEX_DARK
@ MTEX_LIGHT
@ MTEX_BLEND
@ MTEX_SOFT_LIGHT
@ MTEX_LIN_LIGHT
@ MTEX_SUB
@ MTEX_ADD
@ MTEX_OVERLAY
@ MTEX_SCREEN
@ TEX_INT
@ TEX_RGB
@ TEX_SIN
@ TEX_TRI
@ MTEX_FLAT
@ MTEX_SPHERE
@ MTEX_TUBE
@ TEX_HYBRIDMF
@ TEX_MFRACTAL
@ TEX_HTERRAIN
@ TEX_FBM
@ TEX_RIDGEDMF
void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], const ColorSpace *colorspace)
BLI_INLINE float IMB_colormanagement_get_luminance(const float rgb[3])
int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, const float co[3], float dxt[3], float dyt[3], int osatex, short thread, const struct Tex *tex, short which_output, int cfra, int preview, struct MTex *mtex)
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
#define sinf(x)
#define cosf(x)
#define atan2f(x, y)
#define floorf(x)
#define fabsf(x)
#define sqrtf(x)
uint nor
uint col
#define in
#define floor
#define out
static float turb(float x, float y, float z, int oct, int hard, int nb, float ampscale, float freqscale)
float wrap(float value, float max, float min)
Definition node_math.h:71
return ret
const ColorSpace * colorspace
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
short texco
short which_output
float ofs[3]
short mapto
struct Object * object
float size[3]
struct Tex * tex
float tin
Definition RE_texture.h:83
float trgba[4]
Definition RE_texture.h:84
float cropymin
float dist_amount
float noisesize
short xrepeat
float vn_w4
short noisedepth
float ns_outscale
short noisetype
float vn_w2
float cropxmax
float cropymax
float mg_lacunarity
float mg_offset
char use_nodes
float vn_mexp
float mg_gain
short noisebasis2
short vn_coltype
short stype
float mg_octaves
struct ImageUser iuser
struct ColorBand * coba
short vn_distm
float cropxmin
float vn_w3
struct bNodeTree * nodetree
short noisebasis
float vn_w1
struct Image * ima
short extend
short yrepeat
float turbul
max
Definition text_draw.cc:251
#define BRICONT
#define BRICONTRGB
int imagewrap(struct Tex *tex, struct Image *ima, const float texvec[3], struct TexResult *texres, struct ImagePool *pool, bool skip_load_image)
int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], const float DXT[2], const float DYT[2], struct TexResult *texres, struct ImagePool *pool, bool skip_load_image)
static float tex_sin(float a)
int multitex_nodes(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, short which_output, const MTex *mtex, ImagePool *pool)
static int mg_mFractalOrfBmTex(const Tex *tex, const float texvec[3], TexResult *texres)
static int marble(const Tex *tex, const float texvec[3], TexResult *texres)
static int stucci(const Tex *tex, const float texvec[3], TexResult *texres)
static void do_2d_mapping(const MTex *mtex, float texvec[3], const float n[3], float dxt[3], float dyt[3])
static int voronoiTex(const Tex *tex, const float texvec[3], TexResult *texres)
static RNG_THREAD_ARRAY * random_tex_array
static int multitex_nodes_intern(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, short which_output, const MTex *mtex, ImagePool *pool, const bool scene_color_manage, const bool skip_load_image, const bool texnode_preview, const bool use_nodes)
static float tex_saw(float a)
static int mg_distNoiseTex(const Tex *tex, const float texvec[3], TexResult *texres)
static float wood_int(const Tex *tex, float x, float y, float z)
static int mg_ridgedOrHybridMFTex(const Tex *tex, const float texvec[3], TexResult *texres)
static int wood(const Tex *tex, const float texvec[3], TexResult *texres)
void RE_texture_rng_init()
static int mg_HTerrainTex(const Tex *tex, const float texvec[3], TexResult *texres)
bool RE_texture_evaluate(const MTex *mtex, const float vec[3], const int thread, ImagePool *pool, const bool skip_load_image, const bool texnode_preview, float *r_intensity, float r_rgba[4])
static int multitex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, const short which_output, ImagePool *pool, const bool skip_load_image, const bool texnode_preview, const bool use_nodes)
static int cubemap_glob(const float n[3], float x, float y, float z, float *adr1, float *adr2)
static int magic(const Tex *tex, const float texvec[3], TexResult *texres)
int multitex_ext(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, ImagePool *pool, bool scene_color_manage, const bool skip_load_image)
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
static float marble_int(const Tex *tex, float x, float y, float z)
static int texnoise(const Tex *tex, TexResult *texres, int thread)
void RE_texture_rng_exit()
int multitex_ext_safe(Tex *tex, const float texvec[3], TexResult *texres, ImagePool *pool, bool scene_color_manage, const bool skip_load_image)
float texture_value_blend(float tex, float out, float fact, float facg, int blendtype)
static float tex_tri(float a)
static int clouds(const Tex *tex, const float texvec[3], TexResult *texres)