Blender V4.3
node_texture_proc.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BKE_material.h"
10#include "BKE_texture.h"
11#include "BLI_math_vector.h"
12#include "DNA_material_types.h"
13#include "node_texture_util.hh"
14#include "node_util.hh"
15
16#include "RE_texture.h"
17
18/*
19 * In this file: wrappers to use procedural textures as nodes
20 */
21
23 {SOCK_RGBA, N_("Color"), 1.0f, 0.0f, 0.0f, 1.0f}, {-1, ""}};
26
27/* Inputs common to all, #defined because nodes will need their own inputs too */
28#define I 2 /* count */
29#define COMMON_INPUTS \
30 {SOCK_RGBA, "Color 1", 0.0f, 0.0f, 0.0f, 1.0f}, \
31 { \
32 SOCK_RGBA, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f \
33 }
34
35/* Calls multitex and copies the result to the outputs.
36 * Called by xxx_exec, which handles inputs. */
37static void do_proc(float *result,
38 TexParams *p,
39 const float col1[4],
40 const float col2[4],
41 Tex *tex,
42 const short thread)
43{
44 TexResult texres;
45 int textype;
46
47 textype = multitex_nodes(
48 tex, p->co, p->dxt, p->dyt, p->osatex, &texres, thread, 0, p->mtex, nullptr);
49
50 if (textype & TEX_RGB) {
51 copy_v4_v4(result, texres.trgba);
52 }
53 else {
54 copy_v4_v4(result, col1);
55 ramp_blend(MA_RAMP_BLEND, result, texres.tin, col2);
56 }
57}
58
59using MapFn = void (*)(Tex *tex, bNodeStack **in, TexParams *p, const short thread);
60
61static void texfn(
62 float *result, TexParams *p, bNode *node, bNodeStack **in, MapFn map_inputs, short thread)
63{
64 Tex tex = blender::dna::shallow_copy(*((Tex *)(node->storage)));
65 float col1[4], col2[4];
66 tex_input_rgba(col1, in[0], p, thread);
67 tex_input_rgba(col2, in[1], p, thread);
68
69 map_inputs(&tex, in, p, thread);
70
71 do_proc(result, p, col1, col2, &tex, thread);
72}
73
74static int count_outputs(bNode *node)
75{
76 int num = 0;
77 LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
78 num++;
79 }
80 return num;
81}
82
83/* Boilerplate generators */
84
85#define ProcNoInputs(name) \
86 static void name##_map_inputs( \
87 Tex * /*tex*/, bNodeStack ** /*in*/, TexParams * /*p*/, short /*thread*/) \
88 { \
89 }
90
91#define ProcDef(name) \
92 static void name##_colorfn( \
93 float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
94 { \
95 texfn(result, p, node, in, &name##_map_inputs, thread); \
96 } \
97 static void name##_exec(void *data, \
98 int /*thread*/, \
99 bNode *node, \
100 bNodeExecData *execdata, \
101 bNodeStack **in, \
102 bNodeStack **out) \
103 { \
104 int outs = count_outputs(node); \
105 if (outs >= 1) { \
106 tex_output(node, execdata, in, out[0], &name##_colorfn, static_cast<TexCallData *>(data)); \
107 } \
108 }
109
110/* --- VORONOI -- */
113 {SOCK_FLOAT, N_("W1"), 1.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
114 {SOCK_FLOAT, N_("W2"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
115 {SOCK_FLOAT, N_("W3"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
116 {SOCK_FLOAT, N_("W4"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
117
118 {SOCK_FLOAT, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f, PROP_UNSIGNED},
119 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f, PROP_UNSIGNED},
120
121 {-1, ""}};
122static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
123{
124 tex->vn_w1 = tex_input_value(in[I + 0], p, thread);
125 tex->vn_w2 = tex_input_value(in[I + 1], p, thread);
126 tex->vn_w3 = tex_input_value(in[I + 2], p, thread);
127 tex->vn_w4 = tex_input_value(in[I + 3], p, thread);
128
129 tex->ns_outscale = tex_input_value(in[I + 4], p, thread);
130 tex->noisesize = tex_input_value(in[I + 5], p, thread);
131}
132ProcDef(voronoi);
133
134/* --- BLEND -- */
138
139/* -- MAGIC -- */
142 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
143 {-1, ""}};
144static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
145{
146 tex->turbul = tex_input_value(in[I + 0], p, thread);
147}
149
150/* --- MARBLE --- */
153 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
154 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
155 {-1, ""}};
156static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
157{
158 tex->noisesize = tex_input_value(in[I + 0], p, thread);
159 tex->turbul = tex_input_value(in[I + 1], p, thread);
160}
161ProcDef(marble);
162
163/* --- CLOUDS --- */
166 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
167 {-1, ""}};
168static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
169{
170 tex->noisesize = tex_input_value(in[I + 0], p, thread);
171}
173
174/* --- DISTORTED NOISE --- */
177 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
178 {SOCK_FLOAT, N_("Distortion"), 1.00f, 0.0f, 0.0f, 0.0f, 0.0000f, 10.0f, PROP_UNSIGNED},
179 {-1, ""}};
181{
182 tex->noisesize = tex_input_value(in[I + 0], p, thread);
183 tex->dist_amount = tex_input_value(in[I + 1], p, thread);
184}
185ProcDef(distnoise);
186
187/* --- WOOD --- */
190 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
191 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
192 {-1, ""}};
193static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
194{
195 tex->noisesize = tex_input_value(in[I + 0], p, thread);
196 tex->turbul = tex_input_value(in[I + 1], p, thread);
197}
199
200/* --- MUSGRAVE --- */
203 {SOCK_FLOAT, N_("H"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
204 {SOCK_FLOAT, N_("Lacunarity"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f, PROP_UNSIGNED},
205 {SOCK_FLOAT, N_("Octaves"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f, PROP_UNSIGNED},
206
207 {SOCK_FLOAT, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f, PROP_UNSIGNED},
208 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
209 {-1, ""}};
210static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
211{
212 tex->mg_H = tex_input_value(in[I + 0], p, thread);
213 tex->mg_lacunarity = tex_input_value(in[I + 1], p, thread);
214 tex->mg_octaves = tex_input_value(in[I + 2], p, thread);
215 tex->ns_outscale = tex_input_value(in[I + 3], p, thread);
216 tex->noisesize = tex_input_value(in[I + 4], p, thread);
217}
218ProcDef(musgrave);
219
220/* --- NOISE --- */
223ProcDef(noise);
224
225/* --- STUCCI --- */
228 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
229 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
230 {-1, ""}};
231static void stucci_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
232{
233 tex->noisesize = tex_input_value(in[I + 0], p, thread);
234 tex->turbul = tex_input_value(in[I + 1], p, thread);
235}
237
238/* --- */
239
240static void init(bNodeTree * /*ntree*/, bNode *node)
241{
242 Tex *tex = static_cast<Tex *>(MEM_callocN(sizeof(Tex), "Tex"));
243 node->storage = tex;
244
246 tex->type = node->type - TEX_NODE_PROC;
247
248 if (tex->type == TEX_WOOD) {
250 }
251}
252
253/* Node type definitions */
254#define TexDef(TEXTYPE, outputs, name, Name) \
255 void register_node_type_tex_proc_##name(void) \
256 { \
257 static blender::bke::bNodeType ntype; \
258\
259 tex_node_type_base(&ntype, TEX_NODE_PROC + TEXTYPE, Name, NODE_CLASS_TEXTURE); \
260 blender::bke::node_type_socket_templates(&ntype, name##_inputs, outputs); \
261 blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::Middle); \
262 ntype.initfunc = init; \
263 blender::bke::node_type_storage( \
264 &ntype, "Tex", node_free_standard_storage, node_copy_standard_storage); \
265 ntype.exec_fn = name##_exec; \
266 ntype.flag |= NODE_PREVIEW; \
267\
268 blender::bke::node_register_type(&ntype); \
269 }
270
271#define C outputs_color_only
272#define CV outputs_both
273
274TexDef(TEX_VORONOI, CV, voronoi, "Voronoi") TexDef(TEX_BLEND, C, blend, "Blend");
275TexDef(TEX_MAGIC, C, magic, "Magic") TexDef(TEX_MARBLE, CV, marble, "Marble");
276TexDef(TEX_CLOUDS, CV, clouds, "Clouds") TexDef(TEX_WOOD, CV, wood, "Wood");
277TexDef(TEX_MUSGRAVE, CV, musgrave, "Musgrave") TexDef(TEX_NOISE, C, noise, "Noise");
278TexDef(TEX_STUCCI, CV, stucci, "Stucci");
279TexDef(TEX_DISTNOISE, CV, distnoise, "Distorted Noise");
General operations, lookup, etc. for materials.
void ramp_blend(int type, float r_col[3], float fac, const float col[3])
#define TEX_NODE_PROC
Definition BKE_node.hh:1162
void BKE_texture_default(struct Tex *tex)
Definition texture.cc:371
#define LISTBASE_FOREACH(type, var, list)
MINLINE void copy_v4_v4(float r[4], const float a[4])
@ MA_RAMP_BLEND
@ SOCK_FLOAT
@ SOCK_RGBA
@ TEX_RGB
@ TEX_BANDNOISE
@ PROP_NONE
Definition RNA_types.hh:136
@ PROP_UNSIGNED
Definition RNA_types.hh:152
void init()
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
static blender::bke::bNodeSocketTemplate blend_inputs[]
static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void distnoise_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static blender::bke::bNodeSocketTemplate marble_inputs[]
static void texfn(float *result, TexParams *p, bNode *node, bNodeStack **in, MapFn map_inputs, short thread)
static blender::bke::bNodeSocketTemplate magic_inputs[]
static int count_outputs(bNode *node)
static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static blender::bke::bNodeSocketTemplate musgrave_inputs[]
#define I
#define ProcNoInputs(name)
#define TexDef(TEXTYPE, outputs, name, Name)
static void do_proc(float *result, TexParams *p, const float col1[4], const float col2[4], Tex *tex, const short thread)
#define CV
static blender::bke::bNodeSocketTemplate outputs_color_only[]
static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static blender::bke::bNodeSocketTemplate clouds_inputs[]
#define COMMON_INPUTS
static blender::bke::bNodeSocketTemplate wood_inputs[]
static blender::bke::bNodeSocketTemplate distnoise_inputs[]
static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
void(*)(Tex *tex, bNodeStack **in, TexParams *p, const short thread) MapFn
static void stucci_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
static blender::bke::bNodeSocketTemplate voronoi_inputs[]
static blender::bke::bNodeSocketTemplate noise_inputs[]
static blender::bke::bNodeSocketTemplate stucci_inputs[]
#define ProcDef(name)
static blender::bke::bNodeSocketTemplate outputs_both[]
float tex_input_value(bNodeStack *in, TexParams *params, short thread)
void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread)
const MTex * mtex
const float * co
float tin
Definition RE_texture.h:87
float trgba[4]
Definition RE_texture.h:88
float dist_amount
float noisesize
float vn_w4
float ns_outscale
float vn_w2
float mg_lacunarity
short stype
float mg_octaves
float vn_w3
float vn_w1
float turbul
Compact definition of a node socket.
Definition BKE_node.hh:103
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 stucci(const Tex *tex, const float texvec[3], TexResult *texres)
static int magic(const Tex *tex, const float texvec[3], TexResult *texres)
static int clouds(const Tex *tex, const float texvec[3], TexResult *texres)
#define N_(msgid)