Blender V4.5
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}, \
32 { \
33 SOCK_RGBA, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f \
34 }
35
36/* Calls multitex and copies the result to the outputs.
37 * Called by xxx_exec, which handles inputs. */
38static void do_proc(float *result,
39 TexParams *p,
40 const float col1[4],
41 const float col2[4],
42 Tex *tex,
43 const short thread)
44{
45 TexResult texres;
46 int textype;
47
48 textype = multitex_nodes(
49 tex, p->co, p->dxt, p->dyt, p->osatex, &texres, thread, 0, p->mtex, nullptr);
50
51 if (textype & TEX_RGB) {
52 copy_v4_v4(result, texres.trgba);
53 }
54 else {
55 copy_v4_v4(result, col1);
56 ramp_blend(MA_RAMP_BLEND, result, texres.tin, col2);
57 }
58}
59
60using MapFn = void (*)(Tex *tex, bNodeStack **in, TexParams *p, const short thread);
61
62static void texfn(
63 float *result, TexParams *p, bNode *node, bNodeStack **in, MapFn map_inputs, short thread)
64{
65 Tex tex = blender::dna::shallow_copy(*((Tex *)(node->storage)));
66 float col1[4], col2[4];
67 tex_input_rgba(col1, in[0], p, thread);
68 tex_input_rgba(col2, in[1], p, thread);
69
70 map_inputs(&tex, in, p, thread);
71
72 do_proc(result, p, col1, col2, &tex, thread);
73}
74
75static int count_outputs(bNode *node)
76{
77 int num = 0;
78 LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
79 num++;
80 }
81 return num;
82}
83
84/* Boilerplate generators */
85
86#define ProcNoInputs(name) \
87 static void name##_map_inputs( \
88 Tex * /*tex*/, bNodeStack ** /*in*/, TexParams * /*p*/, short /*thread*/) \
89 { \
90 }
91
92#define ProcDef(name) \
93 static void name##_colorfn( \
94 float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
95 { \
96 texfn(result, p, node, in, &name##_map_inputs, thread); \
97 } \
98 static void name##_exec(void *data, \
99 int /*thread*/, \
100 bNode *node, \
101 bNodeExecData *execdata, \
102 bNodeStack **in, \
103 bNodeStack **out) \
104 { \
105 int outs = count_outputs(node); \
106 if (outs >= 1) { \
107 tex_output(node, execdata, in, out[0], &name##_colorfn, static_cast<TexCallData *>(data)); \
108 } \
109 }
110
111/* --- VORONOI -- */
114 {SOCK_FLOAT, N_("W1"), 1.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
115 {SOCK_FLOAT, N_("W2"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
116 {SOCK_FLOAT, N_("W3"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
117 {SOCK_FLOAT, N_("W4"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE},
118
119 {SOCK_FLOAT, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f, PROP_UNSIGNED},
120 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f, PROP_UNSIGNED},
121
122 {-1, ""}};
123static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
124{
125 tex->vn_w1 = tex_input_value(in[I + 0], p, thread);
126 tex->vn_w2 = tex_input_value(in[I + 1], p, thread);
127 tex->vn_w3 = tex_input_value(in[I + 2], p, thread);
128 tex->vn_w4 = tex_input_value(in[I + 3], p, thread);
129
130 tex->ns_outscale = tex_input_value(in[I + 4], p, thread);
131 tex->noisesize = tex_input_value(in[I + 5], p, thread);
132}
133ProcDef(voronoi);
134
135/* --- BLEND -- */
139
140/* -- MAGIC -- */
143 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
144 {-1, ""}};
145static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
146{
147 tex->turbul = tex_input_value(in[I + 0], p, thread);
148}
150
151/* --- MARBLE --- */
154 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
155 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
156 {-1, ""}};
157static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
158{
159 tex->noisesize = tex_input_value(in[I + 0], p, thread);
160 tex->turbul = tex_input_value(in[I + 1], p, thread);
161}
163
164/* --- CLOUDS --- */
167 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
168 {-1, ""}};
169static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
170{
171 tex->noisesize = tex_input_value(in[I + 0], p, thread);
172}
174
175/* --- DISTORTED NOISE --- */
178 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
179 {SOCK_FLOAT, N_("Distortion"), 1.00f, 0.0f, 0.0f, 0.0f, 0.0000f, 10.0f, PROP_UNSIGNED},
180 {-1, ""}};
181static void distnoise_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
182{
183 tex->noisesize = tex_input_value(in[I + 0], p, thread);
184 tex->dist_amount = tex_input_value(in[I + 1], p, thread);
185}
186ProcDef(distnoise);
187
188/* --- WOOD --- */
191 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
192 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
193 {-1, ""}};
194static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
195{
196 tex->noisesize = tex_input_value(in[I + 0], p, thread);
197 tex->turbul = tex_input_value(in[I + 1], p, thread);
198}
200
201/* --- MUSGRAVE --- */
204 {SOCK_FLOAT, N_("H"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
205 {SOCK_FLOAT, N_("Lacunarity"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f, PROP_UNSIGNED},
206 {SOCK_FLOAT, N_("Octaves"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f, PROP_UNSIGNED},
207
208 {SOCK_FLOAT, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f, PROP_UNSIGNED},
209 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
210 {-1, ""}};
211static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
212{
213 tex->mg_H = tex_input_value(in[I + 0], p, thread);
214 tex->mg_lacunarity = tex_input_value(in[I + 1], p, thread);
215 tex->mg_octaves = tex_input_value(in[I + 2], p, thread);
216 tex->ns_outscale = tex_input_value(in[I + 3], p, thread);
217 tex->noisesize = tex_input_value(in[I + 4], p, thread);
218}
219ProcDef(musgrave);
220
221/* --- NOISE --- */
225
226/* --- STUCCI --- */
229 {SOCK_FLOAT, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED},
230 {SOCK_FLOAT, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED},
231 {-1, ""}};
232static void stucci_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
233{
234 tex->noisesize = tex_input_value(in[I + 0], p, thread);
235 tex->turbul = tex_input_value(in[I + 1], p, thread);
236}
238
239/* --- */
240
241static void init(bNodeTree * /*ntree*/, bNode *node)
242{
243 Tex *tex = MEM_callocN<Tex>("Tex");
244 node->storage = tex;
245
247 tex->type = node->type_legacy - TEX_NODE_PROC;
248
249 if (tex->type == TEX_WOOD) {
250 tex->stype = TEX_BANDNOISE;
251 }
252}
253
254/* Node type definitions */
255#define TexDef(TEXTYPE, idname, outputs, name, Name, EnumNameLegacy) \
256 void register_node_type_tex_proc_##name(void) \
257 { \
258 static blender::bke::bNodeType ntype; \
259\
260 tex_node_type_base(&ntype, idname, TEX_NODE_PROC + TEXTYPE); \
261 ntype.ui_name = Name; \
262 ntype.enum_name_legacy = EnumNameLegacy; \
263 ntype.nclass = NODE_CLASS_TEXTURE; \
264 blender::bke::node_type_socket_templates(&ntype, name##_inputs, outputs); \
265 blender::bke::node_type_size_preset(ntype, blender::bke::eNodeSizePreset::Middle); \
266 ntype.initfunc = init; \
267 blender::bke::node_type_storage( \
268 ntype, "Tex", node_free_standard_storage, node_copy_standard_storage); \
269 ntype.exec_fn = name##_exec; \
270 ntype.flag |= NODE_PREVIEW; \
271\
272 blender::bke::node_register_type(ntype); \
273 }
274
275#define C outputs_color_only
276#define CV outputs_both
277
278TexDef(TEX_VORONOI, "TextureNodeTexVoronoi", CV, voronoi, "Voronoi", "TEX_VORONOI");
279TexDef(TEX_BLEND, "TextureNodeTexBlend", C, blend, "Blend", "TEX_BLEND");
280TexDef(TEX_MAGIC, "TextureNodeTexMagic", C, magic, "Magic", "TEX_MAGIC");
281TexDef(TEX_MARBLE, "TextureNodeTexMarble", CV, marble, "Marble", "TEX_MARBLE");
282TexDef(TEX_CLOUDS, "TextureNodeTexClouds", CV, clouds, "Clouds", "TEX_CLOUDS");
283TexDef(TEX_WOOD, "TextureNodeTexWood", CV, wood, "Wood", "TEX_WOOD");
284TexDef(TEX_MUSGRAVE, "TextureNodeTexMusgrave", CV, musgrave, "Musgrave", "TEX_MUSGRAVE");
285TexDef(TEX_NOISE, "TextureNodeTexNoise", C, noise, "Noise", "TEX_NOISE");
286TexDef(TEX_STUCCI, "TextureNodeTexStucci", CV, stucci, "Stucci", "TEX_STUCCI");
288 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:362
#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_BANDNOISE
@ TEX_BLEND
@ TEX_MARBLE
@ TEX_NOISE
@ TEX_WOOD
@ TEX_CLOUDS
@ TEX_DISTNOISE
@ TEX_VORONOI
@ TEX_STUCCI
@ TEX_MAGIC
@ TEX_MUSGRAVE
@ TEX_RGB
@ PROP_NONE
Definition RNA_types.hh:221
@ PROP_UNSIGNED
Definition RNA_types.hh:237
#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:83
float trgba[4]
Definition RE_texture.h:84
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
int16_t type_legacy
void * storage
ListBase outputs
Compact definition of a node socket.
Definition BKE_node.hh:98
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 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)
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)