Blender V4.3
shader_graph.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#ifndef __GRAPH_H__
6#define __GRAPH_H__
7
8#include "graph/node.h"
9#include "graph/node_type.h"
10
11#include "kernel/types.h"
12
13#include "util/list.h"
14#include "util/map.h"
15#include "util/param.h"
16#include "util/set.h"
17#include "util/types.h"
18#include "util/vector.h"
19
21
23class Scene;
24class Shader;
25class ShaderInput;
26class ShaderOutput;
27class ShaderNode;
28class ShaderGraph;
29class SVMCompiler;
30class OSLCompiler;
31class OutputNode;
32class ConstantFolder;
33class MD5Hash;
34
35/* Bump
36 *
37 * For bump mapping, a node may be evaluated multiple times, using different
38 * samples to reconstruct the normal, this indicates the sample position */
39
41
42/* Identifiers for some special node types.
43 *
44 * The graph needs to identify these in the clean function.
45 * Cannot use dynamic_cast, as this is disabled for OSL. */
46
60
61/* Input
62 *
63 * Input socket for a shader node. May be linked to an output or not. If not
64 * linked, it will either get a fixed default value, or e.g. a texture
65 * coordinate. */
66
68 public:
69 ShaderInput(const SocketType &socket_type_, ShaderNode *parent_)
70 : socket_type(socket_type_),
71 parent(parent_),
72 link(NULL),
75 {
76 }
77
78 ustring name() const
79 {
80 return socket_type.ui_name;
81 }
82 int flags() const
83 {
84 return socket_type.flags;
85 }
87 {
88 return socket_type.type;
89 }
90
91 void set(float f)
92 {
93 ((Node *)parent)->set(socket_type, f);
94 }
95 void set(float3 f)
96 {
97 ((Node *)parent)->set(socket_type, f);
98 }
99 void set(int f)
100 {
101 ((Node *)parent)->set(socket_type, f);
102 }
103
104 void disconnect();
105
109 int stack_offset; /* for SVM compiler */
110
111 /* Keeps track of whether a constant was folded in this socket, to avoid over-optimizing when the
112 * link is null. */
114};
115
116/* Output
117 *
118 * Output socket for a shader node. */
119
121 public:
122 ShaderOutput(const SocketType &socket_type_, ShaderNode *parent_)
123 : socket_type(socket_type_), parent(parent_), stack_offset(SVM_STACK_INVALID)
124 {
125 }
126
127 ustring name() const
128 {
129 return socket_type.ui_name;
130 }
132 {
133 return socket_type.type;
134 }
135
136 void disconnect();
137
141 int stack_offset; /* for SVM compiler */
142};
143
144/* Node
145 *
146 * Shader node in graph, with input and output sockets. This is the virtual
147 * base class for all node types. */
148
149class ShaderNode : public Node {
150 public:
151 explicit ShaderNode(const NodeType *type);
152 virtual ~ShaderNode();
153
154 void create_inputs_outputs(const NodeType *type);
155 void remove_input(ShaderInput *input);
156
157 ShaderInput *input(const char *name);
158 ShaderOutput *output(const char *name);
159 ShaderInput *input(ustring name);
160 ShaderOutput *output(ustring name);
161
162 virtual ShaderNode *clone(ShaderGraph *graph) const = 0;
163 virtual void attributes(Shader *shader, AttributeRequestSet *attributes);
164 virtual void compile(SVMCompiler &compiler) = 0;
165 virtual void compile(OSLCompiler &compiler) = 0;
166
167 /* Expand node into additional nodes. */
168 virtual void expand(ShaderGraph * /* graph */) {}
169
170 /* ** Node optimization ** */
171 /* Check whether the node can be replaced with single constant. */
172 virtual void constant_fold(const ConstantFolder & /*folder*/) {}
173
174 /* Simplify settings used by artists to the ones which are simpler to
175 * evaluate in the kernel but keep the final result unchanged.
176 */
177 virtual void simplify_settings(Scene * /*scene*/){};
178
179 virtual bool has_surface_emission()
180 {
181 return false;
182 }
184 {
185 return false;
186 }
187 virtual bool has_surface_bssrdf()
188 {
189 return false;
190 }
191 virtual bool has_bump()
192 {
193 return false;
194 }
195 virtual bool has_bssrdf_bump()
196 {
197 return false;
198 }
199 virtual bool has_spatial_varying()
200 {
201 return false;
202 }
204 {
205 return false;
206 }
207 virtual bool has_volume_support()
208 {
209 return false;
210 }
213
214 int id; /* index in graph node array */
215 ShaderBump bump; /* for bump mapping utility */
216
217 ShaderNodeSpecialType special_type; /* special node type */
218
219 /* ** Selective nodes compilation ** */
220
221 /* TODO(sergey): More explicitly mention in the function names
222 * that those functions are for selective compilation only?
223 */
224
225 /* Node feature are used to disable huge nodes inside the group,
226 * so it's possible to disable huge nodes inside of the required
227 * nodes group.
228 */
229 virtual int get_feature()
230 {
232 }
233
234 /* Get closure ID to which the node compiles into. */
236 {
237 return CLOSURE_NONE_ID;
238 }
239
240 /* Check whether settings of the node equals to another one.
241 *
242 * This is mainly used to check whether two nodes can be merged
243 * together. Meaning, runtime stuff like node id and unbound slots
244 * will be ignored for comparison.
245 *
246 * NOTE: If some node can't be de-duplicated for whatever reason it
247 * is to be handled in the subclass.
248 */
249 virtual bool equals(const ShaderNode &other);
250};
251
252/* Node definition utility macros */
253
254#define SHADER_NODE_CLASS(type) \
255 NODE_DECLARE \
256 type(); \
257 virtual ShaderNode *clone(ShaderGraph *graph) const \
258 { \
259 return graph->create_node<type>(*this); \
260 } \
261 virtual void compile(SVMCompiler &compiler); \
262 virtual void compile(OSLCompiler &compiler);
263
264#define SHADER_NODE_NO_CLONE_CLASS(type) \
265 NODE_DECLARE \
266 type(); \
267 virtual void compile(SVMCompiler &compiler); \
268 virtual void compile(OSLCompiler &compiler);
269
270#define SHADER_NODE_BASE_CLASS(type) \
271 virtual ShaderNode *clone(ShaderGraph *graph) const \
272 { \
273 return graph->create_node<type>(*this); \
274 } \
275 virtual void compile(SVMCompiler &compiler); \
276 virtual void compile(OSLCompiler &compiler);
277
279 public:
280 bool operator()(const ShaderNode *n1, const ShaderNode *n2) const
281 {
282 return n1->id < n2->id;
283 }
284};
285
286typedef set<ShaderNode *, ShaderNodeIDComparator> ShaderNodeSet;
287typedef map<ShaderNode *, ShaderNode *, ShaderNodeIDComparator> ShaderNodeMap;
288
289/* Graph
290 *
291 * Shader graph of nodes. Also does graph manipulations for default inputs,
292 * bump mapping from displacement, and possibly other things in the future. */
293
294class ShaderGraph : public NodeOwner {
295 public:
296 list<ShaderNode *> nodes;
301
302 ShaderGraph();
303 ~ShaderGraph();
304
305 ShaderNode *add(ShaderNode *node);
307
308 void connect(ShaderOutput *from, ShaderInput *to);
309 void disconnect(ShaderOutput *from);
310 void disconnect(ShaderInput *to);
311 void relink(ShaderInput *from, ShaderInput *to);
312 void relink(ShaderOutput *from, ShaderOutput *to);
313 void relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to);
314
315 void remove_proxy_nodes();
317 void simplify(Scene *scene);
318 void finalize(Scene *scene, bool do_bump = false, bool bump_in_object_space = false);
319
320 int get_num_closures();
321
322 void dump_graph(const char *filename);
323
324 /* This function is used to create a node of a specified type instead of
325 * calling 'new', and sets the graph as the owner of the node.
326 */
327 template<typename T, typename... Args> T *create_node(Args &&...args)
328 {
329 T *node = new T(args...);
330 node->set_owner(this);
331 return node;
332 }
333
334 /* This function is used to delete a node created and owned by the graph.
335 */
336 template<typename T> void delete_node(T *node)
337 {
338 assert(node->get_owner() == this);
339 delete node;
340 }
341
342 protected:
343 typedef pair<ShaderNode *const, ShaderNode *> NodePair;
344
345 void find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input);
346 void clear_nodes();
347 void copy_nodes(ShaderNodeSet &nodes, ShaderNodeMap &nnodemap);
348
350 void bump_from_displacement(bool use_object_space);
351 void refine_bump_nodes();
352 void expand();
353 void default_inputs(bool do_osl);
354 void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
355
356 /* Graph simplification routines. */
357 void clean(Scene *scene);
358 void constant_fold(Scene *scene);
359 void simplify_settings(Scene *scene);
360 void deduplicate_nodes();
362};
363
365
366#endif /* __GRAPH_H__ */
#define output
Definition md5.h:21
void find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input)
string displacement_hash
list< ShaderNode * > nodes
OutputNode * output()
void verify_volume_output()
void simplify(Scene *scene)
T * create_node(Args &&...args)
void disconnect(ShaderOutput *from)
void delete_node(T *node)
size_t num_node_ids
void break_cycles(ShaderNode *node, vector< bool > &visited, vector< bool > &on_stack)
void copy_nodes(ShaderNodeSet &nodes, ShaderNodeMap &nnodemap)
void clean(Scene *scene)
pair< ShaderNode *const, ShaderNode * > NodePair
void finalize(Scene *scene, bool do_bump=false, bool bump_in_object_space=false)
void compute_displacement_hash()
void default_inputs(bool do_osl)
void connect(ShaderOutput *from, ShaderInput *to)
void relink(ShaderInput *from, ShaderInput *to)
void constant_fold(Scene *scene)
void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume)
void deduplicate_nodes()
void remove_proxy_nodes()
void simplify_settings(Scene *scene)
void bump_from_displacement(bool use_object_space)
ShaderNode * add(ShaderNode *node)
void refine_bump_nodes()
void dump_graph(const char *filename)
ustring name() const
ShaderInput(const SocketType &socket_type_, ShaderNode *parent_)
void set(float f)
SocketType::Type type() const
void set(int f)
ShaderOutput * link
bool constant_folded_in
void disconnect()
ShaderNode * parent
void set(float3 f)
int flags() const
const SocketType & socket_type
bool operator()(const ShaderNode *n1, const ShaderNode *n2) const
ShaderInput * input(const char *name)
virtual bool has_surface_transparent()
vector< ShaderOutput * > outputs
virtual bool has_surface_emission()
void remove_input(ShaderInput *input)
ShaderNodeSpecialType special_type
virtual void simplify_settings(Scene *)
virtual bool has_bssrdf_bump()
virtual bool has_spatial_varying()
vector< ShaderInput * > inputs
virtual bool has_volume_support()
virtual ~ShaderNode()
virtual ClosureType get_closure_type()
virtual ShaderNode * clone(ShaderGraph *graph) const =0
virtual bool equals(const ShaderNode &other)
virtual int get_feature()
virtual bool has_attribute_dependency()
virtual void constant_fold(const ConstantFolder &)
virtual bool has_bump()
virtual void expand(ShaderGraph *)
ShaderNode(const NodeType *type)
void create_inputs_outputs(const NodeType *type)
ShaderBump bump
virtual bool has_surface_bssrdf()
virtual void compile(OSLCompiler &compiler)=0
virtual void compile(SVMCompiler &compiler)=0
virtual void attributes(Shader *shader, AttributeRequestSet *attributes)
vector< ShaderInput * > links
ShaderOutput(const SocketType &socket_type_, ShaderNode *parent_)
ustring name() const
const SocketType & socket_type
ShaderNode * parent
SocketType::Type type() const
OperationNode * node
Set< ComponentNode * > visited
#define CCL_NAMESPACE_END
#define NULL
#define SVM_STACK_INVALID
ClosureType
@ CLOSURE_NONE_ID
#define KERNEL_FEATURE_NODE_BUMP
#define T
ShaderNodeSpecialType
@ SHADER_SPECIAL_TYPE_PROXY
@ SHADER_SPECIAL_TYPE_IMAGE_SLOT
@ SHADER_SPECIAL_TYPE_GEOMETRY
@ SHADER_SPECIAL_TYPE_OUTPUT_AOV
@ SHADER_SPECIAL_TYPE_COMBINE_CLOSURE
@ SHADER_SPECIAL_TYPE_BUMP
@ SHADER_SPECIAL_TYPE_AUTOCONVERT
@ SHADER_SPECIAL_TYPE_NONE
@ SHADER_SPECIAL_TYPE_OUTPUT
@ SHADER_SPECIAL_TYPE_CLOSURE
@ SHADER_SPECIAL_TYPE_OSL
set< ShaderNode *, ShaderNodeIDComparator > ShaderNodeSet
ShaderBump
@ SHADER_BUMP_CENTER
@ SHADER_BUMP_DX
@ SHADER_BUMP_DY
@ SHADER_BUMP_NONE
map< ShaderNode *, ShaderNode *, ShaderNodeIDComparator > ShaderNodeMap
ustring ui_name
Definition node_type.h:86
Type type
Definition node_type.h:80