Blender V5.0
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
8
9#include "BKE_material.hh"
10#include "BKE_texture.h"
11#include "BLI_listbase.h"
12#include "BLI_math_vector.h"
13#include "DNA_material_types.h"
14#include "node_texture_util.hh"
15#include "node_util.hh"
16
17#include "RE_texture.h"
18
19/*
20 * In this file: wrappers to use procedural textures as nodes
21 */
22
24 {SOCK_RGBA, N_("Color"), 1.0f, 0.0f, 0.0f, 1.0f}, {-1, ""}};
27
28/* Inputs common to all, #defined because nodes will need their own inputs too */
29#define I 2 /* count */
30#define COMMON_INPUTS \
31 {SOCK_RGBA, "Color 1", 0.0f, 0.0f, 0.0f, 1.0f}, {SOCK_RGBA, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f}
32
33/* Calls multitex and copies the result to the outputs.
34 * Called by xxx_exec, which handles inputs. */
35static void do_proc(float *result,
36 TexParams *p,
37 const float col1[4],
38 const float col2[4],
39 Tex *tex,
40 const short thread)
41{
42 TexResult texres;
43 int textype;
44
45 textype = multitex_nodes(tex, p->co, &texres, thread, 0, p->mtex, nullptr);
46
47 if (textype & TEX_RGB) {
48 copy_v4_v4(result, texres.trgba);
49 }
50 else {
51 copy_v4_v4(result, col1);
52 ramp_blend(MA_RAMP_BLEND, result, texres.tin, col2);
53 }
54}
55
56using MapFn = void (*)(Tex *tex, bNodeStack **in, TexParams *p, const short thread);
57
58static void texfn(
59 float *result, TexParams *p, bNode *node, bNodeStack **in, MapFn map_inputs, short thread)
60{
61 Tex tex = blender::dna::shallow_copy(*((Tex *)(node->storage)));
62 float col1[4], col2[4];
63 tex_input_rgba(col1, in[0], p, thread);
64 tex_input_rgba(col2, in[1], p, thread);
65
66 map_inputs(&tex, in, p, thread);
67
68 do_proc(result, p, col1, col2, &tex, thread);
69}
70
71static int count_outputs(bNode *node)
72{
73 int num = 0;
74 LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
75 num++;
76 }
77 return num;
78}
79
80/* Boilerplate generators */
81
82#define ProcNoInputs(name) \
83 static void name##_map_inputs( \
84 Tex * /*tex*/, bNodeStack ** /*in*/, TexParams * /*p*/, short /*thread*/) \
85 { \
86 }
87
88#define ProcDef(name) \
89 static void name##_colorfn( \
90 float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
91 { \
92 texfn(result, p, node, in, &name##_map_inputs, thread); \
93 } \
94 static void name##_exec(void *data, \
95 int /*thread*/, \
96 bNode *node, \
97 bNodeExecData *execdata, \
98 bNodeStack **in, \
99 bNodeStack **out) \
100 { \
101 int outs = count_outputs(node); \
102 if (outs >= 1) { \
103 tex_output(node, execdata, in, out[0], &name##_colorfn, static_cast<TexCallData *>(data)); \
104 } \
105 }
106
107/* --- VORONOI -- */
110 {SOCK_FLOAT, N_("W1"), 1.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
111 {SOCK_FLOAT, N_("W2"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
112 {SOCK_FLOAT, N_("W3"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
113 {SOCK_FLOAT, N_("W4"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
114
115 {SOCK_FLOAT, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f, PROP_UNSIGNED},
116 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f, PROP_UNSIGNED},
117
118 {-1, ""}};
119static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
120{
121 tex->vn_w1 = tex_input_value(in[I + 0], p, thread);
122 tex->vn_w2 = tex_input_value(in[I + 1], p, thread);
123 tex->vn_w3 = tex_input_value(in[I + 2], p, thread);
124 tex->vn_w4 = tex_input_value(in[I + 3], p, thread);
125
126 tex->ns_outscale = tex_input_value(in[I + 4], p, thread);
127 tex->noisesize = tex_input_value(in[I + 5], p, thread);
128}
129ProcDef(voronoi);
130
131/* --- BLEND -- */
135
136/* -- MAGIC -- */
139 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
140 {-1, ""}};
141static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
142{
143 tex->turbul = tex_input_value(in[I + 0], p, thread);
144}
146
147/* --- MARBLE --- */
150 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
151 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
152 {-1, ""}};
153static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
154{
155 tex->noisesize = tex_input_value(in[I + 0], p, thread);
156 tex->turbul = tex_input_value(in[I + 1], p, thread);
157}
159
160/* --- CLOUDS --- */
163 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
164 {-1, ""}};
165static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
166{
167 tex->noisesize = tex_input_value(in[I + 0], p, thread);
168}
170
171/* --- DISTORTED NOISE --- */
174 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
175 {SOCK_FLOAT, N_("Distortion"), 1.00f, 0.0f, 0.0f, 0.0f, 0.0000f, 10.0f, PROP_UNSIGNED},
176 {-1, ""}};
177static void distnoise_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
178{
179 tex->noisesize = tex_input_value(in[I + 0], p, thread);
180 tex->dist_amount = tex_input_value(in[I + 1], p, thread);
181}
182ProcDef(distnoise);
183
184/* --- WOOD --- */
187 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
188 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
189 {-1, ""}};
190static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
191{
192 tex->noisesize = tex_input_value(in[I + 0], p, thread);
193 tex->turbul = tex_input_value(in[I + 1], p, thread);
194}
196
197/* --- MUSGRAVE --- */
200 {SOCK_FLOAT, N_("H"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
201 {SOCK_FLOAT, N_("Lacunarity"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f, PROP_UNSIGNED},
202 {SOCK_FLOAT, N_("Octaves"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f, PROP_UNSIGNED},
203
204 {SOCK_FLOAT, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f, PROP_UNSIGNED},
205 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
206 {-1, ""}};
207static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
208{
209 tex->mg_H = tex_input_value(in[I + 0], p, thread);
210 tex->mg_lacunarity = tex_input_value(in[I + 1], p, thread);
211 tex->mg_octaves = tex_input_value(in[I + 2], p, thread);
212 tex->ns_outscale = tex_input_value(in[I + 3], p, thread);
213 tex->noisesize = tex_input_value(in[I + 4], p, thread);
214}
215ProcDef(musgrave);
216
217/* --- NOISE --- */
221
222/* --- STUCCI --- */
225 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
226 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
227 {-1, ""}};
228static void stucci_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
229{
230 tex->noisesize = tex_input_value(in[I + 0], p, thread);
231 tex->turbul = tex_input_value(in[I + 1], p, thread);
232}
234
235/* --- */
236
237static void init(bNodeTree * /*ntree*/, bNode *node)
238{
239 Tex *tex = MEM_callocN<Tex>("Tex");
240 node->storage = tex;
241
243 tex->type = node->type_legacy - TEX_NODE_PROC;
244
245 if (tex->type == TEX_WOOD) {
246 tex->stype = TEX_BANDNOISE;
247 }
248}
249
250/* Node type definitions */
251#define TexDef(TEXTYPE, idname, outputs, name, Name, EnumNameLegacy) \
252 void register_node_type_tex_proc_##name(void) \
253 { \
254 static blender::bke::bNodeType ntype; \
255\
256 tex_node_type_base(&ntype, idname, TEX_NODE_PROC + TEXTYPE); \
257 ntype.ui_name = Name; \
258 ntype.enum_name_legacy = EnumNameLegacy; \
259 ntype.nclass = 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, "TextureNodeTexVoronoi", CV, voronoi, "Voronoi", "TEX_VORONOI");
275TexDef(TEX_BLEND, "TextureNodeTexBlend", C, blend, "Blend", "TEX_BLEND");
276TexDef(TEX_MAGIC, "TextureNodeTexMagic", C, magic, "Magic", "TEX_MAGIC");
277TexDef(TEX_MARBLE, "TextureNodeTexMarble", CV, marble, "Marble", "TEX_MARBLE");
278TexDef(TEX_CLOUDS, "TextureNodeTexClouds", CV, clouds, "Clouds", "TEX_CLOUDS");
279TexDef(TEX_WOOD, "TextureNodeTexWood", CV, wood, "Wood", "TEX_WOOD");
280TexDef(TEX_MUSGRAVE, "TextureNodeTexMusgrave", CV, musgrave, "Musgrave", "TEX_MUSGRAVE");
281TexDef(TEX_NOISE, "TextureNodeTexNoise", C, noise, "Noise", "TEX_NOISE");
282TexDef(TEX_STUCCI, "TextureNodeTexStucci", CV, stucci, "Stucci", "TEX_STUCCI");
284 TEX_DISTNOISE, "TextureNodeTexDistNoise", CV, distnoise, "Distorted Noise", "TEX_DISTNOISE");
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
void BKE_texture_default(struct Tex *tex)
Definition texture.cc:358
#define LISTBASE_FOREACH(type, var, list)
MINLINE void copy_v4_v4(float r[4], const float a[4])
ATTR_WARN_UNUSED_RESULT const size_t num
@ MA_RAMP_BLEND
@ SOCK_FLOAT
@ SOCK_RGBA
@ TEX_RGB
@ TEX_BANDNOISE
@ TEX_BLEND
@ TEX_MARBLE
@ TEX_NOISE
@ TEX_WOOD
@ TEX_CLOUDS
@ TEX_DISTNOISE
@ TEX_VORONOI
@ TEX_STUCCI
@ TEX_MAGIC
@ TEX_MUSGRAVE
@ PROP_NONE
Definition RNA_types.hh:233
@ PROP_UNSIGNED
Definition RNA_types.hh:249
#define C
Definition RandGen.cpp:29
void init()
#define in
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
static float noise(int n)
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)
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 TexDef(TEXTYPE, idname, outputs, name, Name, EnumNameLegacy)
#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:59
float trgba[4]
Definition RE_texture.h:60
float dist_amount
float noisesize
float vn_w4
float ns_outscale
float vn_w2
float mg_lacunarity
short stype
float mg_octaves
float mg_H
float vn_w3
float vn_w1
float turbul
int16_t type_legacy
void * storage
ListBase outputs
Compact definition of a node socket.
Definition BKE_node.hh:99
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 int wood(const Tex *tex, const float texvec[3], TexResult *texres)
static int magic(const Tex *tex, const float texvec[3], TexResult *texres)
int multitex_nodes(Tex *tex, const float texvec[3], TexResult *texres, const short thread, short which_output, const MTex *mtex, ImagePool *pool)
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
static int clouds(const Tex *tex, const float texvec[3], TexResult *texres)
#define N_(msgid)