1313#include < MaterialXGenShader/Nodes/SourceCodeNode.h>
1414
1515#include < MaterialXGenOsl/Nodes/BlurNodeOsl.h>
16- #include < MaterialXGenOsl/Nodes/MaterialNodeOsl.h>
1716
1817MATERIALX_NAMESPACE_BEGIN
1918
@@ -35,12 +34,6 @@ OslShaderGenerator::OslShaderGenerator(TypeSystemPtr typeSystem) :
3534 registerImplementation (" IM_blur_vector2_" + OslShaderGenerator::TARGET, BlurNodeOsl::create);
3635 registerImplementation (" IM_blur_vector3_" + OslShaderGenerator::TARGET, BlurNodeOsl::create);
3736 registerImplementation (" IM_blur_vector4_" + OslShaderGenerator::TARGET, BlurNodeOsl::create);
38-
39- // <!-- <surface> -->
40- registerImplementation (" IM_surface_" + OslShaderGenerator::TARGET, SourceCodeNode::create);
41-
42- // <!-- <surfacematerial> -->
43- registerImplementation (" IM_surfacematerial_" + OslShaderGenerator::TARGET, MaterialNodeOsl::create);
4437}
4538
4639ShaderPtr OslShaderGenerator::generate (const string& name, ElementPtr element, GenContext& context) const
@@ -58,6 +51,7 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G
5851 // Add global constants and type definitions
5952 emitTypeDefinitions (context, stage);
6053 emitLine (" #define M_FLOAT_EPS 1e-8" , stage, false );
54+ emitLine (" closure color null_closure() { closure color null_closure = 0; return null_closure; } " , stage, false );
6155 emitLineBreak (stage);
6256
6357 // Set the include file to use for uv transformations,
@@ -180,22 +174,16 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G
180174 }
181175 }
182176
183- // Emit all texturing nodes. These are inputs to any
184- // closure/shader nodes and need to be emitted first.
185- emitFunctionCalls (graph, context, stage, ShaderNode::Classification::TEXTURE);
186-
187- // Emit function calls for "root" closure/shader nodes.
188- // These will internally emit function calls for any dependent closure nodes upstream.
177+ // Emit function calls for all nodes in the graph, starting each output
178+ // port and walking backwards along the incoming connections
189179 for (ShaderGraphOutputSocket* socket : graph.getOutputSockets ())
190180 {
191181 if (socket->getConnection ())
192182 {
193183 const ShaderNode* upstream = socket->getConnection ()->getNode ();
194- if (upstream->getParent () == &graph &&
195- (upstream->hasClassification (ShaderNode::Classification::CLOSURE) ||
196- upstream->hasClassification (ShaderNode::Classification::SHADER)))
184+ if (upstream->getParent () == &graph)
197185 {
198- emitFunctionCall (*upstream, context, stage);
186+ emitAllDependentFunctionCalls (*upstream, context, stage);
199187 }
200188 }
201189 }
@@ -304,38 +292,21 @@ ShaderPtr OslShaderGenerator::createShader(const string& name, ElementPtr elemen
304292 return shader;
305293}
306294
307- void OslShaderGenerator::emitFunctionCalls (const ShaderGraph& graph, GenContext& context, ShaderStage& stage, uint32_t classification) const
295+ // TODO - determine it's better if this lives in ShaderGenerator as a useful API function
296+ void OslShaderGenerator::emitAllDependentFunctionCalls (const ShaderNode& node, GenContext& context, ShaderStage& stage) const
308297{
309- // Special handling for closures functions .
310- if ((classification & ShaderNode::Classification::CLOSURE) != 0 )
298+ // Check if it's emitted already .
299+ if (!stage. isEmitted (node, context) )
311300 {
312- // Emit function calls for closures connected to the outputs.
313- // These will internally emit other closure function calls
314- // for upstream nodes if needed.
315- for (ShaderGraphOutputSocket* outputSocket : graph.getOutputSockets ())
301+ // Emit function calls for upstream connected nodes
302+ for (const auto & input : node.getInputs ())
316303 {
317- const ShaderNode* upstream = outputSocket->getConnection () ? outputSocket->getConnection ()->getNode () : nullptr ;
318- if (upstream && upstream->hasClassification (classification))
304+ if (const auto & upstream = input->getConnectedSibling ())
319305 {
320- emitFunctionCall (*upstream, context, stage);
306+ emitAllDependentFunctionCalls (*upstream, context, stage);
321307 }
322308 }
323- }
324- else
325- {
326- // Not a closures graph so just generate all
327- // function calls in order.
328- ShaderGenerator::emitFunctionCalls (graph, context, stage, classification);
329- }
330- }
331-
332- void OslShaderGenerator::emitFunctionBodyBegin (const ShaderNode& node, GenContext&, ShaderStage& stage, Syntax::Punctuation punc) const
333- {
334- emitScopeBegin (stage, punc);
335-
336- if (node.hasClassification (ShaderNode::Classification::SHADER) || node.hasClassification (ShaderNode::Classification::CLOSURE))
337- {
338- emitLine (" closure color null_closure = 0" , stage);
309+ stage.addFunctionCall (node, context);
339310 }
340311}
341312
0 commit comments