Blender  V2.93
node_shader_util.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "DNA_node_types.h"
25 
26 #include "node_shader_util.h"
27 
28 #include "node_exec.h"
29 
30 bool sh_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree, const char **r_disabled_hint)
31 {
32  if (!STREQ(ntree->idname, "ShaderNodeTree")) {
33  *r_disabled_hint = "Not a shader node tree";
34  return false;
35  }
36  return true;
37 }
38 
39 static bool sh_fn_poll_default(bNodeType *UNUSED(ntype),
41  const char **r_disabled_hint)
42 {
43  if (!STREQ(ntree->idname, "ShaderNodeTree") && !STREQ(ntree->idname, "GeometryNodeTree")) {
44  *r_disabled_hint = "Not a shader or geometry node tree";
45  return false;
46  }
47  return true;
48 }
49 
51  struct bNodeType *ntype, int type, const char *name, short nclass, short flag)
52 {
53  node_type_base(ntype, type, name, nclass, flag);
54 
55  ntype->poll = sh_node_poll_default;
58 }
59 
60 void sh_fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
61 {
62  sh_node_type_base(ntype, type, name, nclass, flag);
63  ntype->poll = sh_fn_poll_default;
64 }
65 
66 /* ****** */
67 
68 void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
69 {
70  const float *from = ns->vec;
71 
72  if (type_in == SOCK_FLOAT) {
73  if (ns->sockettype == SOCK_FLOAT) {
74  *in = *from;
75  }
76  else {
77  *in = (from[0] + from[1] + from[2]) / 3.0f;
78  }
79  }
80  else if (type_in == SOCK_VECTOR) {
81  if (ns->sockettype == SOCK_FLOAT) {
82  in[0] = from[0];
83  in[1] = from[0];
84  in[2] = from[0];
85  }
86  else {
87  copy_v3_v3(in, from);
88  }
89  }
90  else { /* type_in==SOCK_RGBA */
91  if (ns->sockettype == SOCK_RGBA) {
92  copy_v4_v4(in, from);
93  }
94  else if (ns->sockettype == SOCK_FLOAT) {
95  in[0] = from[0];
96  in[1] = from[0];
97  in[2] = from[0];
98  in[3] = 1.0f;
99  }
100  else {
101  copy_v3_v3(in, from);
102  in[3] = 1.0f;
103  }
104  }
105 }
106 
108 {
109  memset(gs, 0, sizeof(*gs));
110 
111  if (ns == NULL) {
112  /* node_get_stack() will generate NULL bNodeStack pointers
113  * for unknown/unsupported types of sockets. */
114  zero_v4(gs->vec);
115  gs->link = NULL;
116  gs->type = GPU_NONE;
117  gs->hasinput = false;
118  gs->hasoutput = false;
119  gs->sockettype = type;
120  }
121  else {
122  nodestack_get_vec(gs->vec, type, ns);
123  gs->link = ns->data;
124 
125  if (type == SOCK_FLOAT) {
126  gs->type = GPU_FLOAT;
127  }
128  else if (type == SOCK_INT) {
129  gs->type = GPU_FLOAT; /* HACK: Support as float. */
130  }
131  else if (type == SOCK_VECTOR) {
132  gs->type = GPU_VEC3;
133  }
134  else if (type == SOCK_RGBA) {
135  gs->type = GPU_VEC4;
136  }
137  else if (type == SOCK_SHADER) {
138  gs->type = GPU_CLOSURE;
139  }
140  else {
141  gs->type = GPU_NONE;
142  }
143 
144  gs->hasinput = ns->hasinput && ns->data;
145  /* XXX Commented out the ns->data check here, as it seems it's not always set,
146  * even though there *is* a valid connection/output... But that might need
147  * further investigation.
148  */
149  gs->hasoutput = ns->hasoutput /*&& ns->data*/;
150  gs->sockettype = ns->sockettype;
151  }
152 }
153 
155 {
156  copy_v4_v4(ns->vec, gs->vec);
157  ns->data = gs->link;
158  ns->sockettype = gs->sockettype;
159 }
160 
162 {
163  bNodeSocket *sock;
164  int i;
165 
166  for (sock = sockets->first, i = 0; sock; sock = sock->next, i++) {
167  node_gpu_stack_from_data(&gs[i], sock->type, ns[i]);
168  }
169 
170  gs[i].end = true;
171 }
172 
174 {
175  bNodeSocket *sock;
176  int i;
177 
178  for (sock = sockets->first, i = 0; sock; sock = sock->next, i++) {
179  node_data_from_gpu_stack(ns[i], &gs[i]);
180  }
181 }
182 
184 {
185  /* this is the node we texture paint and draw in textured draw */
186  bNode *node, *tnode, *inactivenode = NULL, *activetexnode = NULL, *activegroup = NULL;
187  bool hasgroup = false;
188 
189  if (!ntree) {
190  return NULL;
191  }
192 
193  for (node = ntree->nodes.first; node; node = node->next) {
194  if (node->flag & NODE_ACTIVE_TEXTURE) {
195  activetexnode = node;
196  /* if active we can return immediately */
197  if (node->flag & NODE_ACTIVE) {
198  return node;
199  }
200  }
201  else if (!inactivenode && node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
202  inactivenode = node;
203  }
204  else if (node->type == NODE_GROUP) {
205  if (node->flag & NODE_ACTIVE) {
206  activegroup = node;
207  }
208  else {
209  hasgroup = true;
210  }
211  }
212  }
213 
214  /* first, check active group for textures */
215  if (activegroup) {
216  tnode = nodeGetActiveTexture((bNodeTree *)activegroup->id);
217  /* active node takes priority, so ignore any other possible nodes here */
218  if (tnode) {
219  return tnode;
220  }
221  }
222 
223  if (activetexnode) {
224  return activetexnode;
225  }
226 
227  if (hasgroup) {
228  /* node active texture node in this tree, look inside groups */
229  for (node = ntree->nodes.first; node; node = node->next) {
230  if (node->type == NODE_GROUP) {
231  tnode = nodeGetActiveTexture((bNodeTree *)node->id);
232  if (tnode && ((tnode->flag & NODE_ACTIVE_TEXTURE) || !inactivenode)) {
233  return tnode;
234  }
235  }
236  }
237  }
238 
239  return inactivenode;
240 }
241 
243 {
244  bNodeExec *nodeexec;
245  bNode *node;
246  int n;
247  bNodeStack *stack;
248  bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */
249  bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
250  GPUNodeStack gpuin[MAX_SOCKET + 1], gpuout[MAX_SOCKET + 1];
251  bool do_it;
252 
253  stack = exec->stack;
254 
255  for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; n++, nodeexec++) {
256  node = nodeexec->node;
257 
258  do_it = false;
259  /* for groups, only execute outputs for edited group */
260  if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
261  if ((output_node != NULL) && (node == output_node)) {
262  do_it = true;
263  }
264  }
265  else {
266  do_it = true;
267  }
268 
269  if (do_it) {
270  if (node->typeinfo->gpu_fn) {
271  node_get_stack(node, stack, nsin, nsout);
272  gpu_stack_from_data_list(gpuin, &node->inputs, nsin);
273  gpu_stack_from_data_list(gpuout, &node->outputs, nsout);
274  if (node->typeinfo->gpu_fn(mat, node, &nodeexec->data, gpuin, gpuout)) {
275  data_from_gpu_stack_list(&node->outputs, nsout, gpuout);
276  }
277  }
278  }
279  }
280 }
281 
283 {
284  if (node->branch_tag == 1) {
285  /* Add one time the value fo derivative to the input vector. */
286  GPU_link(mat, "dfdx_v3", *link, link);
287  }
288  else if (node->branch_tag == 2) {
289  /* Add one time the value fo derivative to the input vector. */
290  GPU_link(mat, "dfdy_v3", *link, link);
291  }
292  else {
293  /* nothing to do, reference center value. */
294  }
295 }
296 
298 {
299  if (!*link) {
300  *link = GPU_attribute(mat, CD_ORCO, "");
301  GPU_link(mat, "generated_texco", GPU_builtin(GPU_VIEW_POSITION), *link, link);
303  }
304 }
305 
307  bNode *node,
308  GPUNodeStack *in,
309  GPUNodeStack *UNUSED(out))
310 {
311  NodeTexBase *base = node->storage;
312  TexMapping *texmap = &base->tex_mapping;
313  float domin = (texmap->flag & TEXMAP_CLIP_MIN) != 0;
314  float domax = (texmap->flag & TEXMAP_CLIP_MAX) != 0;
315 
316  if (domin || domax || !(texmap->flag & TEXMAP_UNIT_MATRIX)) {
317  static float max[3] = {FLT_MAX, FLT_MAX, FLT_MAX};
318  static float min[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
319  GPUNodeLink *tmin, *tmax, *tmat0, *tmat1, *tmat2, *tmat3;
320 
321  tmin = GPU_uniform((domin) ? texmap->min : min);
322  tmax = GPU_uniform((domax) ? texmap->max : max);
323  tmat0 = GPU_uniform((float *)texmap->mat[0]);
324  tmat1 = GPU_uniform((float *)texmap->mat[1]);
325  tmat2 = GPU_uniform((float *)texmap->mat[2]);
326  tmat3 = GPU_uniform((float *)texmap->mat[3]);
327 
328  GPU_link(mat, "mapping_mat4", in[0].link, tmat0, tmat1, tmat2, tmat3, tmin, tmax, &in[0].link);
329 
330  if (texmap->type == TEXMAP_TYPE_NORMAL) {
331  GPU_link(mat, "vector_normalize", in[0].link, &in[0].link);
332  }
333  }
334 }
#define NODE_CLASS_OUTPUT
Definition: BKE_node.h:335
void node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag)
Definition: node.cc:4443
#define MAX_SOCKET
Definition: BKE_node.h:41
#define NODE_CLASS_TEXTURE
Definition: BKE_node.h:346
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v4(float r[4])
#define UNUSED(x)
#define STREQ(a, b)
#define NODE_ACTIVE_TEXTURE
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_SHADER
@ SOCK_FLOAT
@ SOCK_RGBA
#define NODE_ACTIVE
#define TEXMAP_TYPE_NORMAL
#define TEXMAP_UNIT_MATRIX
#define TEXMAP_CLIP_MIN
#define TEXMAP_CLIP_MAX
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
GPUNodeLink * GPU_builtin(eGPUBuiltin builtin)
GPUNodeLink * GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name)
@ GPU_VIEW_POSITION
Definition: GPU_material.h:91
GPUNodeLink * GPU_uniform(const float *num)
@ GPU_VEC4
Definition: GPU_material.h:66
@ GPU_NONE
Definition: GPU_material.h:62
@ GPU_CLOSURE
Definition: GPU_material.h:80
@ GPU_VEC3
Definition: GPU_material.h:65
@ GPU_FLOAT
Definition: GPU_material.h:63
bool GPU_link(GPUMaterial *mat, const char *name,...)
NODE_GROUP
OperationNode * node
StackEntry * from
bNodeTree * ntree
void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out)
Definition: node_exec.cc:53
bNode * nodeGetActiveTexture(bNodeTree *ntree)
void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *UNUSED(out))
bool sh_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree, const char **r_disabled_hint)
void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag)
void node_shader_gpu_default_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink **link)
void node_data_from_gpu_stack(bNodeStack *ns, GPUNodeStack *gs)
void node_shader_gpu_bump_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink **link)
void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
static bool sh_fn_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree, const char **r_disabled_hint)
void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, bNode *output_node)
void sh_fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
static void gpu_stack_from_data_list(GPUNodeStack *gs, ListBase *sockets, bNodeStack **ns)
static void data_from_gpu_stack_list(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs)
void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link)
Definition: node_util.c:305
void node_update_internal_links_default(bNodeTree *ntree, bNode *node)
Definition: node_util.c:503
#define min(a, b)
Definition: sort.c:51
struct GPUNodeLink * link
Definition: GPU_material.h:119
eGPUType type
Definition: GPU_material.h:117
float vec[4]
Definition: GPU_material.h:118
short sockettype
Definition: GPU_material.h:122
void * first
Definition: DNA_listBase.h:47
TexMapping tex_mapping
float mat[4][4]
bNodeExecData data
Definition: node_exec.h:48
struct bNode * node
Definition: node_exec.h:47
struct bNodeSocket * next
short hasoutput
short hasinput
short sockettype
float vec[4]
char idname[64]
ListBase nodes
Defines a node type.
Definition: BKE_node.h:221
bool(* poll)(struct bNodeType *ntype, struct bNodeTree *nodetree, const char **r_disabled_hint)
Definition: BKE_node.h:301
void(* update_internal_links)(struct bNodeTree *, struct bNode *node)
Definition: BKE_node.h:312
void(* insert_link)(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link)
Definition: BKE_node.h:310
float max