MaterialX 1.39.5
Loading...
Searching...
No Matches
ShaderGraph.h
Go to the documentation of this file.
1//
2// Copyright Contributors to the MaterialX Project
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#ifndef MATERIALX_SHADERGRAPH_H
7#define MATERIALX_SHADERGRAPH_H
8
11
13
19
21#include <MaterialXCore/Node.h>
22
23MATERIALX_NAMESPACE_BEGIN
24
25class Syntax;
26class ShaderGraphEdge;
28class GenOptions;
30
34
38
40using ShaderGraphPtr = shared_ptr<class ShaderGraph>;
41
44class MX_GENSHADER_API ShaderGraph : public ShaderNode
45{
46 public:
48 ShaderGraph(const ShaderGraph* parent, const string& name, ConstDocumentPtr document,
49 GenContext& context);
50
52 virtual ~ShaderGraph() { }
53
56 static ShaderGraphPtr create(const ShaderGraph* parent, const string& name, ElementPtr element,
57 GenContext& context);
58
60 static ShaderGraphPtr create(const ShaderGraph* parent, const NodeGraph& nodeGraph,
61 GenContext& context);
62
64 bool isAGraph() const override { return true; }
65
67 ShaderNode* getNode(const string& uniqueId);
68
70 const ShaderNode* getNode(const string& uniqueId) const;
71
73 const vector<ShaderNode*>& getNodes() const { return _nodeOrder; }
74
76 size_t numInputSockets() const { return numOutputs(); }
77
79 size_t numOutputSockets() const { return numInputs(); }
80
82 ShaderGraphInputSocket* getInputSocket(size_t index) { return getOutput(index); }
83 ShaderGraphOutputSocket* getOutputSocket(size_t index = 0) { return getInput(index); }
84 const ShaderGraphInputSocket* getInputSocket(size_t index) const { return getOutput(index); }
85 const ShaderGraphOutputSocket* getOutputSocket(size_t index = 0) const { return getInput(index); }
86
88 ShaderGraphInputSocket* getInputSocket(const string& name) { return getOutput(name); }
89 ShaderGraphOutputSocket* getOutputSocket(const string& name) { return getInput(name); }
90 const ShaderGraphInputSocket* getInputSocket(const string& name) const { return getOutput(name); }
91 const ShaderGraphOutputSocket* getOutputSocket(const string& name) const { return getInput(name); }
92
94 const vector<ShaderGraphInputSocket*>& getInputSockets() const { return _outputOrder; }
95 const vector<ShaderGraphOutputSocket*>& getOutputSockets() const { return _inputOrder; }
96
98 void applyInputTransforms(ConstNodePtr node, ShaderNode* shaderNode, GenContext& context);
99
102
103 ShaderNode* inlineNodeBeforeOutput(ShaderGraphOutputSocket* output,
104 const std::string& newNodeName,
105 const std::string& nodeDefName,
106 const std::string& inputName,
107 const std::string& outputName,
108 GenContext& context);
109
112 [[deprecated]] ShaderGraphInputSocket* addInputSocket(const string& name, const TypeDesc* type) { return addInputSocket(name, *type); }
113
116 [[deprecated]] ShaderGraphOutputSocket* addOutputSocket(const string& name, const TypeDesc* type) { return addOutputSocket(name, *type); }
117
119 void addDefaultGeomNode(ShaderInput* input, const GeomPropDef& geomprop, GenContext& context);
120
123
126
128 IdentifierMap& getIdentifierMap() { return _identifiers; }
129
131 ConstDocumentPtr getDocument() const { return _document; }
132
134 ShaderNode* createNode(const string& name, const string& uniqueId, ConstNodeDefPtr nodeDef, GenContext& context);
135
139 void bypass(ShaderNode* node, size_t inputIndex, size_t outputIndex = 0);
140
143
145 void replaceOutput(ShaderOutput* oldOutput, ShaderOutput* newOutput);
146
147 protected:
153 void createConnectedNodes(const ElementPtr& downstreamElement,
154 const ElementPtr& upstreamElement,
155 ElementPtr connectingElement,
156 GenContext& context);
157
160
162 void addInputSockets(const InterfaceElement& elem, GenContext& context);
163
165 void addOutputSockets(const InterfaceElement& elem, GenContext& context);
166
170 void addUpstreamDependencies(const Element& root, GenContext& context);
171
173 void addColorTransformNode(ShaderInput* input, const ColorSpaceTransform& transform, GenContext& context);
174
176 void addColorTransformNode(ShaderOutput* output, const ColorSpaceTransform& transform, GenContext& context);
177
179 void addUnitTransformNode(ShaderInput* input, const UnitTransform& transform, GenContext& context);
180
182 void addUnitTransformNode(ShaderOutput* output, const UnitTransform& transform, GenContext& context);
183
185 void finalize(GenContext& context);
186
191
194 void populateColorTransformMap(ColorManagementSystemPtr colorManagementSystem, ShaderPort* shaderPort,
195 const string& sourceColorSpace, const string& targetColorSpace, bool asInput);
196
199 void populateUnitTransformMap(UnitSystemPtr unitSystem, ShaderPort* shaderPort, ValueElementPtr element, const string& targetUnitSpace, bool asInput);
200
202 void disconnect(ShaderNode* node) const;
203
204 ConstDocumentPtr _document;
205 std::unordered_map<string, ShaderNodePtr> _nodeMap;
206 std::vector<ShaderNode*> _nodeOrder;
207 IdentifierMap _identifiers;
208
209 // Temporary storage for inputs that require color transformations
210 std::vector<std::pair<ShaderInput*, ColorSpaceTransform>> _inputColorTransformMap;
211 // Temporary storage for inputs that require unit transformations
212 std::vector<std::pair<ShaderInput*, UnitTransform>> _inputUnitTransformMap;
213
214 // Temporary storage for outputs that require color transformations
215 std::vector<std::pair<ShaderOutput*, ColorSpaceTransform>> _outputColorTransformMap;
216 // Temporary storage for outputs that require unit transformations
217 std::vector<std::pair<ShaderOutput*, UnitTransform>> _outputUnitTransformMap;
218};
219
222class MX_GENSHADER_API ShaderGraphEdge
223{
224 public:
225 ShaderGraphEdge(ShaderOutput* up, ShaderInput* down) :
226 upstream(up),
227 downstream(down)
228 {
229 }
230
231 bool operator==(const ShaderGraphEdge& rhs) const
232 {
233 return upstream == rhs.upstream && downstream == rhs.downstream;
234 }
235
236 bool operator!=(const ShaderGraphEdge& rhs) const
237 {
238 return !(*this == rhs);
239 }
240
241 bool operator<(const ShaderGraphEdge& rhs) const
242 {
243 return std::tie(upstream, downstream) < std::tie(rhs.upstream, rhs.downstream);
244 }
245
246 ShaderOutput* upstream;
247 ShaderInput* downstream;
248};
249
252class MX_GENSHADER_API ShaderGraphEdgeIterator
253{
254 public:
255 ShaderGraphEdgeIterator(ShaderOutput* output);
256 ~ShaderGraphEdgeIterator() = default;
257
258 bool operator==(const ShaderGraphEdgeIterator& rhs) const
259 {
260 return _upstream == rhs._upstream &&
261 _downstream == rhs._downstream &&
262 _stack == rhs._stack;
263 }
264 bool operator!=(const ShaderGraphEdgeIterator& rhs) const
265 {
266 return !(*this == rhs);
267 }
268
271 {
272 return ShaderGraphEdge(_upstream, _downstream);
273 }
274
277 ShaderGraphEdgeIterator& operator++();
278
280 ShaderGraphEdgeIterator& begin()
281 {
282 return *this;
283 }
284
286 static const ShaderGraphEdgeIterator& end();
287
288 private:
289 void extendPathUpstream(ShaderOutput* upstream, ShaderInput* downstream);
290 void returnPathDownstream(ShaderOutput* upstream);
291 bool skipOrMarkAsVisited(ShaderGraphEdge);
292
293 ShaderOutput* _upstream;
294 ShaderInput* _downstream;
295 using StackFrame = std::pair<ShaderOutput*, size_t>;
296 std::vector<StackFrame> _stack;
297 std::set<ShaderOutput*> _path;
298 std::set<ShaderGraphEdge> _visitedEdges;
299};
300
301MATERIALX_NAMESPACE_END
302
303#endif
Color management system classes.
shared_ptr< class ColorManagementSystem > ColorManagementSystemPtr
A shared pointer to a ColorManagementSystem.
Definition ColorManagementSystem.h:25
shared_ptr< const NodeDef > ConstNodeDefPtr
A shared pointer to a const NodeDef.
Definition Definition.h:34
The top-level Document class.
shared_ptr< const Document > ConstDocumentPtr
A shared pointer to a const Document.
Definition Document.h:24
shared_ptr< Element > ElementPtr
A shared pointer to an Element.
Definition Element.h:31
shared_ptr< ValueElement > ValueElementPtr
A shared pointer to a ValueElement.
Definition Element.h:41
Macros for declaring imported and exported symbols.
Node element subclasses.
shared_ptr< const Node > ConstNodePtr
A shared pointer to a const Node.
Definition Node.h:26
ShaderInput ShaderGraphOutputSocket
An internal output socket in a shader graph, used for connecting internal nodes to the outside.
Definition ShaderGraph.h:37
ShaderOutput ShaderGraphInputSocket
An internal input socket in a shader graph, used for connecting internal nodes to the outside.
Definition ShaderGraph.h:33
shared_ptr< class ShaderGraph > ShaderGraphPtr
A shared pointer to a shader graph.
Definition ShaderGraph.h:40
Classes for nodes created during shader generation.
shared_ptr< class ShaderNode > ShaderNodePtr
Shared pointer to a ShaderNode.
Definition ShaderNode.h:35
Base class for syntax handling for shader generators.
std::unordered_map< string, size_t > IdentifierMap
Map holding identifier names and a counter for creating unique names from them.
Definition Syntax.h:38
Type descriptor for a MaterialX data type.
Unit system classes.
shared_ptr< class UnitSystem > UnitSystemPtr
A shared pointer to a UnitSystem.
Definition UnitSystem.h:26
The base class for MaterialX elements.
Definition Element.h:85
A context class for shader generation.
Definition GenContext.h:30
Class holding options to configure shader generation.
Definition GenOptions.h:76
An element representing a declaration of geometric property data.
Definition Geom.h:352
The base class for interface elements such as Node, NodeDef, and NodeGraph.
Definition Interface.h:312
A node graph element within a Document.
Definition Node.h:332
An edge returned during shader graph traversal.
Definition ShaderGraph.h:223
Iterator class for traversing edges between nodes in a shader graph.
Definition ShaderGraph.h:253
ShaderGraphEdgeIterator & operator++()
Iterate to the next edge in the traversal.
ShaderGraphEdge operator*() const
Dereference this iterator, returning the current output in the traversal.
Definition ShaderGraph.h:270
static const ShaderGraphEdgeIterator & end()
Return the end iterator.
ShaderGraphEdgeIterator & begin()
Return a reference to this iterator to begin traversal.
Definition ShaderGraph.h:280
void addUnitTransformNode(ShaderOutput *output, const UnitTransform &transform, GenContext &context)
Add a unit transform node and connect to the given output.
virtual ~ShaderGraph()
Destructor.
Definition ShaderGraph.h:52
void addUnitTransformNode(ShaderInput *input, const UnitTransform &transform, GenContext &context)
Add a unit transform node and connect to the given input.
bool isAGraph() const override
Return true if this node is a graph.
Definition ShaderGraph.h:64
ShaderGraphInputSocket * addInputSocket(const string &name, TypeDesc type)
Add input sockets.
void addInputSockets(const InterfaceElement &elem, GenContext &context)
Add input sockets from an interface element (nodedef, nodegraph or node)
size_t numInputSockets() const
Get number of input sockets.
Definition ShaderGraph.h:76
void setVariableNames(GenContext &context)
For inputs and outputs in the graph set the variable names to be used in generated code.
static ShaderGraphEdgeIterator traverseUpstream(ShaderOutput *output)
Return an iterator for traversal upstream from the given output.
void addColorTransformNode(ShaderInput *input, const ColorSpaceTransform &transform, GenContext &context)
Add a color transform node and connect to the given input.
ShaderGraph(const ShaderGraph *parent, const string &name, ConstDocumentPtr document, GenContext &context)
Constructor.
void topologicalSort()
Sort the nodes in topological order.
void replaceOutput(ShaderOutput *oldOutput, ShaderOutput *newOutput)
Rewire all downstream connections from one output to another.
ShaderNode * createNode(ConstNodePtr node, GenContext &context)
Create a new node in the graph.
void removeUnusedNodes()
Remove nodes that are no longer connected to any output.
void applyInputTransforms(ConstNodePtr node, ShaderNode *shaderNode, GenContext &context)
Apply color and unit transforms to each input of a node.
void disconnect(ShaderNode *node) const
Break all connections on a node.
const vector< ShaderGraphInputSocket * > & getInputSockets() const
Get vector of sockets.
Definition ShaderGraph.h:94
void addOutputSockets(const InterfaceElement &elem, GenContext &context)
Add output sockets from an interface element (nodedef, nodegraph or node)
ShaderGraphInputSocket * getInputSocket(size_t index)
Get socket by index.
Definition ShaderGraph.h:82
void bypass(ShaderNode *node, size_t inputIndex, size_t outputIndex=0)
Bypass a node for a particular input and output, effectively connecting the input's upstream connecti...
void addColorTransformNode(ShaderOutput *output, const ColorSpaceTransform &transform, GenContext &context)
Add a color transform node and connect to the given output.
IdentifierMap & getIdentifierMap()
Return the map of unique identifiers used in the scope of this graph.
Definition ShaderGraph.h:128
ShaderNode * getNode(const string &uniqueId)
Get an internal node by its unique identifier.
static ShaderGraphPtr create(const ShaderGraph *parent, const string &name, ElementPtr element, GenContext &context)
Create a new shader graph from an element.
static ShaderGraphPtr create(const ShaderGraph *parent, const NodeGraph &nodeGraph, GenContext &context)
Create a new shader graph from a nodegraph.
size_t numOutputSockets() const
Get number of output sockets.
Definition ShaderGraph.h:79
void populateColorTransformMap(ColorManagementSystemPtr colorManagementSystem, ShaderPort *shaderPort, const string &sourceColorSpace, const string &targetColorSpace, bool asInput)
Populate the color transform map for the given shader port, if the provided combination of source and...
void addDefaultGeomNode(ShaderInput *input, const GeomPropDef &geomprop, GenContext &context)
Add a default geometric node and connect to the given input.
void addUpstreamDependencies(const Element &root, GenContext &context)
Traverse from the given root element and add all dependencies upstream.
void addNode(ShaderNodePtr node)
Add a node to the graph, keyed by the node's unique identifier.
ShaderGraphOutputSocket * addOutputSocket(const string &name, TypeDesc type)
Add output sockets.
ShaderNode * createNode(const string &name, const string &uniqueId, ConstNodeDefPtr nodeDef, GenContext &context)
Create a new node in the graph from a node definition.
void populateUnitTransformMap(UnitSystemPtr unitSystem, ShaderPort *shaderPort, ValueElementPtr element, const string &targetUnitSpace, bool asInput)
Populates the appropriate unit transform map if the provided input/parameter or output has a unit att...
void createConnectedNodes(const ElementPtr &downstreamElement, const ElementPtr &upstreamElement, ElementPtr connectingElement, GenContext &context)
Create node connections corresponding to the connection between a pair of elements.
const ShaderNode * getNode(const string &uniqueId) const
Get an internal node by its unique identifier.
ConstDocumentPtr getDocument() const
Return the document associated with this graph.
Definition ShaderGraph.h:131
const vector< ShaderNode * > & getNodes() const
Get a vector of all nodes in order.
Definition ShaderGraph.h:73
ShaderGraphInputSocket * getInputSocket(const string &name)
Get socket by name.
Definition ShaderGraph.h:88
void finalize(GenContext &context)
Perform all post-build operations on the graph.
Base class for shader graph refactoring passes.
Definition ShaderGraphRefactor.h:28
An input on a ShaderNode.
Definition ShaderNode.h:272
ShaderInput * getInput(size_t index)
Get inputs/outputs by index.
Definition ShaderNode.h:460
ShaderNode(const ShaderGraph *parent, const string &name)
Constructor.
size_t numInputs() const
Get number of inputs/outputs.
Definition ShaderNode.h:456
An output on a ShaderNode.
Definition ShaderNode.h:303
An input or output port on a ShaderNode.
Definition ShaderNode.h:124
Base class for syntax objects used by shader generators to emit code with correct syntax for each lan...
Definition Syntax.h:44
A type descriptor for MaterialX data types.
Definition TypeDesc.h:40
Structure that represents color space transform information.
Definition ColorManagementSystem.h:30
Structure that represents unit transform information.
Definition UnitSystem.h:31