@@ -41,6 +41,12 @@ const auto kLayerPbrNodes = std::set<std::string> {
4141 " dielectric_bsdf" , " generalized_schlick_bsdf" , " sheen_bsdf" ,
4242 " dielectric_tf_bsdf" , " generalized_schlick_tf_82_bsdf" , " sheen_zeltner_bsdf"
4343};
44+
45+ // All the types that have a "multiply" node taking a float as input (FA nodes):
46+ const auto kZeroMultiplyValueMap = std::map<std::string, std::string> {
47+ { " float" , " 0" }, { " color3" , " 0, 0, 0" }, { " color4" , " 0, 0, 0, 0" },
48+ { " vector2" , " 0, 0" }, { " vector3" , " 0, 0, 0" }, { " vector4" , " 0, 0, 0, 0" }
49+ };
4450} // namespace
4551
4652class LobePrunerImpl
@@ -102,14 +108,27 @@ class LobePrunerImpl
102108 void
103109 ensureLibraryHasOptimizedShader (const PXR_NS::TfToken& nodeDefName, const std::string& flags);
104110 void optimizeZeroValue (
105- mx::NodeGraphPtr& newNg ,
111+ mx::NodeGraphPtr& optimizedNodeGraph ,
106112 const OptimizableValueMap& optimizationMap,
107113 ReverseCnxMap& reverseMap);
108114 void optimizeOneValue (
109- mx::NodeGraphPtr& newNg ,
115+ mx::NodeGraphPtr& optimizedNodeGraph ,
110116 const OptimizableValueMap& optimizationMap,
111117 ReverseCnxMap& reverseMap);
112118 void addDarkShaders ();
119+ void optimizeMixNode (
120+ const std::string& promotedInputName,
121+ mx::NodePtr& mixNode,
122+ mx::NodeGraphPtr& optimizedNodeGraph,
123+ ReverseCnxMap& reverseMap) const ;
124+ void optimizeMultiplyNode (
125+ mx::NodePtr& node,
126+ mx::NodeGraphPtr& optimizedNodeGraph,
127+ ReverseCnxMap& reverseMap) const ;
128+ void optimizePbrNode (
129+ mx::NodePtr& node,
130+ const std::string& darkNodeName,
131+ const std::string& darkNodeDefName) const ;
113132
114133 std::unordered_map<PXR_NS::TfToken, NodeDefData, PXR_NS::TfToken::HashFunctor> _prunerData;
115134 mx::DocumentPtr _library;
@@ -243,19 +262,19 @@ bool LobePrunerImpl::getOptimizedNodeCategory(const mx::Node& node, std::string&
243262 auto attrIt = ndIt->second ._attributeData .cbegin ();
244263 for (size_t i = 0 ; attrIt != ndIt->second ._attributeData .cend (); ++attrIt, ++i) {
245264 const auto nodeinput = node.getActiveInput (attrIt->first );
246- // Can not optimize if connected in any way.
247- if (nodeinput
248- && (nodeinput->hasNodeName () || nodeinput->hasOutputString ()
249- || nodeinput->hasInterfaceName ())) {
250- continue ;
251- }
252- float inputValue = 0 .5F ;
265+ float inputValue = 0 .5F ;
253266 if (nodeinput) {
267+ // Can not optimize if connected in any way.
268+ if (nodeinput->hasNodeName () || nodeinput->hasOutputString ()
269+ || nodeinput->hasInterfaceName ()) {
270+ continue ;
271+ }
254272 inputValue = nodeinput->getValue ()->asA <float >();
255273 } else {
256274 const auto defInput = nd->getActiveInput (attrIt->first );
257275 inputValue = defInput->getValue ()->asA <float >();
258276 }
277+
259278 for (const auto & optimizableValue : attrIt->second ) {
260279 if (optimizableValue.first == inputValue) {
261280 if (inputValue == 0 .0F ) {
@@ -354,27 +373,28 @@ void LobePrunerImpl::ensureLibraryHasOptimizedShader(
354373 return ;
355374 }
356375
357- const auto nd = _library->getNodeDef (nodeDefName.GetString ());
358- const auto ng = _library->getNodeGraph (ndIt->second ._nodeGraphName );
359- const std::string nodeName = nd ->getNodeString () + " _" + flags;
360- const std::string ndName = ND_PREFIX + nodeName + " _surfaceshader" ;
361- if (_library->getNodeDef (ndName )) {
376+ const auto originalNodeDef = _library->getNodeDef (nodeDefName.GetString ());
377+ const auto originalNodeGraph = _library->getNodeGraph (ndIt->second ._nodeGraphName );
378+ const std::string optimizedNodeName = originalNodeDef ->getNodeString () + " _" + flags;
379+ const std::string optimizedNodeDefName = ND_PREFIX + optimizedNodeName + " _surfaceshader" ;
380+ if (_library->getNodeDef (optimizedNodeDefName )) {
362381 // Already there
363382 return ;
364383 }
365384
366- auto newNd = _library->addNodeDef (ndName, " surfaceshader" , nodeName);
367- newNd->copyContentFrom (nd);
368- newNd->setSourceUri (" " );
369- newNd->setNodeString (nodeName);
385+ auto optimizedNodeDef
386+ = _library->addNodeDef (optimizedNodeDefName, " surfaceshader" , optimizedNodeName);
387+ optimizedNodeDef->copyContentFrom (originalNodeDef);
388+ optimizedNodeDef->setSourceUri (" " );
389+ optimizedNodeDef->setNodeString (optimizedNodeName);
370390
371- auto newNg = _library->addNodeGraph (" NG_" + nodeName + " _surfaceshader" );
372- newNg ->copyContentFrom (ng );
373- newNg ->setSourceUri (" " );
374- newNg ->setNodeDefString (ndName );
391+ auto optimizedNodeGraph = _library->addNodeGraph (" NG_" + optimizedNodeName + " _surfaceshader" );
392+ optimizedNodeGraph ->copyContentFrom (originalNodeGraph );
393+ optimizedNodeGraph ->setSourceUri (" " );
394+ optimizedNodeGraph ->setNodeDefString (optimizedNodeDefName );
375395
376396 ReverseCnxMap reverseMap;
377- for (const auto & node : newNg ->getNodes ()) {
397+ for (const auto & node : optimizedNodeGraph ->getNodes ()) {
378398 for (const auto & input : node->getActiveInputs ()) {
379399 if (input->hasNodeName ()) {
380400 const auto & sourceNodeName = input->getNodeName ();
@@ -389,97 +409,31 @@ void LobePrunerImpl::ensureLibraryHasOptimizedShader(
389409 auto attrIt = ndIt->second ._attributeData .cbegin ();
390410 for (size_t i = 0 ; attrIt != ndIt->second ._attributeData .cend (); ++attrIt, ++i) {
391411 switch (flags[i]) {
392- case ' 0' : optimizeZeroValue (newNg , attrIt->second , reverseMap); break ;
393- case ' 1' : optimizeOneValue (newNg , attrIt->second , reverseMap); break ;
412+ case ' 0' : optimizeZeroValue (optimizedNodeGraph , attrIt->second , reverseMap); break ;
413+ case ' 1' : optimizeOneValue (optimizedNodeGraph , attrIt->second , reverseMap); break ;
394414 default : continue ;
395415 }
396416 }
397417}
398418
399419void LobePrunerImpl::optimizeZeroValue (
400- mx::NodeGraphPtr& newNg ,
420+ mx::NodeGraphPtr& optimizedNodeGraph ,
401421 const OptimizableValueMap& optimizationMap,
402422 ReverseCnxMap& reverseMap)
403423{
404424 for (const auto & nodeName : optimizationMap.find (0 .0F )->second ) {
405- auto node = newNg ->getNode (nodeName);
425+ auto node = optimizedNodeGraph ->getNode (nodeName);
406426 if (!node) {
407427 continue ;
408428 }
409429 if (node->getCategory () == " mix" ) {
410- auto bgInput = node->getInput (" bg" );
411- if (!bgInput) {
412- continue ;
413- }
414- for (const auto & destNodeName : reverseMap.find (node->getName ())->second ) {
415- auto destNode = newNg->getNode (destNodeName);
416- if (!destNode) {
417- continue ;
418- }
419- for (auto input : destNode->getInputs ()) {
420- if (input->getNodeName () == node->getName ()) {
421- input->removeAttribute (mx::PortElement::NODE_NAME_ATTRIBUTE);
422- if (bgInput->hasNodeName ()) {
423- input->setNodeName (bgInput->getNodeName ());
424- auto & nodeVector = reverseMap.find (bgInput->getNodeName ())->second ;
425- nodeVector.push_back (destNodeName);
426- nodeVector.erase (
427- std::remove_if (
428- nodeVector.begin (),
429- nodeVector.end (),
430- [node](const std::string& s) { return s == node->getName (); }),
431- nodeVector.end ());
432- }
433- if (bgInput->hasInterfaceName ()) {
434- input->setInterfaceName (bgInput->getInterfaceName ());
435- }
436- if (bgInput->hasOutputString ()) {
437- input->setOutputString (bgInput->getOutputString ());
438- }
439- if (bgInput->hasValueString ()) {
440- input->setValueString (bgInput->getValueString ());
441- }
442- }
443- }
444- }
445- newNg->removeNode (node->getName ());
430+ optimizeMixNode (" bg" , node, optimizedNodeGraph, reverseMap);
446431 } else if (node->getCategory () == " multiply" ) {
447- // Result will be a zero value of the type it requests:
448- for (const auto & destNodeName : reverseMap.find (node->getName ())->second ) {
449- auto destNode = newNg->getNode (destNodeName);
450- for (auto input : destNode->getInputs ()) {
451- if (input->getNodeName () == node->getName ()) {
452- input->removeAttribute (mx::PortElement::NODE_NAME_ATTRIBUTE);
453- if (input->getType () == " float" ) {
454- input->setValueString (" 0" );
455- } else if (input->getType () == " color3" ) {
456- input->setValueString (" 0, 0, 0" );
457- }
458- // TODO: Pad all remaining types
459- }
460- }
461- }
462- newNg->removeNode (node->getName ());
432+ optimizeMultiplyNode (node, optimizedNodeGraph, reverseMap);
463433 } else if (kBasePbrNodes .count (node->getCategory ())) {
464- // Prune all inputs.
465- for (const auto & input : node->getInputs ()) {
466- node->removeInput (input->getName ());
467- }
468- // Change node category:
469- node->setCategory (DARK_BASE);
470- if (node->hasNodeDefString ()) {
471- node->setNodeDefString (ND_DARK_BASE);
472- }
434+ optimizePbrNode (node, DARK_BASE, ND_DARK_BASE);
473435 } else if (kLayerPbrNodes .count (node->getCategory ())) {
474- // Prune all inputs.
475- for (const auto & input : node->getInputs ()) {
476- node->removeInput (input->getName ());
477- }
478- // Change node category:
479- node->setCategory (DARK_LAYER);
480- if (node->hasNodeDefString ()) {
481- node->setNodeDefString (ND_DARK_LAYER);
482- }
436+ optimizePbrNode (node, DARK_LAYER, ND_DARK_LAYER);
483437 }
484438 }
485439}
@@ -491,68 +445,114 @@ void LobePrunerImpl::addDarkShaders()
491445 return ;
492446 }
493447
494- auto nd = _library->addNodeDef (ND_DARK_BASE, " BSDF" , DARK_BASE);
495- nd ->setAttribute (" bsdf" , " R" );
496- nd ->setNodeGroup (" pbr" );
497- nd ->setDocString (" A completely dark base BSDF node." );
448+ auto darkNodeDef = _library->addNodeDef (ND_DARK_BASE, " BSDF" , DARK_BASE);
449+ darkNodeDef ->setAttribute (" bsdf" , " R" );
450+ darkNodeDef ->setNodeGroup (" pbr" );
451+ darkNodeDef ->setDocString (" A completely dark base BSDF node." );
498452
499- auto im = _library->addImplementation (IM_DARK_BASE);
500- im ->setNodeDef (nd );
453+ auto darkImplementation = _library->addImplementation (IM_DARK_BASE);
454+ darkImplementation ->setNodeDef (darkNodeDef );
501455
502- nd = _library->addNodeDef (ND_DARK_LAYER, " BSDF" , DARK_LAYER);
503- nd ->setNodeGroup (" pbr" );
504- nd ->setDocString (" A completely dark layer BSDF node." );
456+ darkNodeDef = _library->addNodeDef (ND_DARK_LAYER, " BSDF" , DARK_LAYER);
457+ darkNodeDef ->setNodeGroup (" pbr" );
458+ darkNodeDef ->setDocString (" A completely dark layer BSDF node." );
505459
506- im = _library->addImplementation (IM_DARK_LAYER);
507- im ->setNodeDef (nd );
460+ darkImplementation = _library->addImplementation (IM_DARK_LAYER);
461+ darkImplementation ->setNodeDef (darkNodeDef );
508462}
509463
510464void LobePrunerImpl::optimizeOneValue (
511- mx::NodeGraphPtr& newNg ,
465+ mx::NodeGraphPtr& optimizedNodeGraph ,
512466 const OptimizableValueMap& optimizationMap,
513467 ReverseCnxMap& reverseMap)
514468{
515469 for (const auto & nodeName : optimizationMap.find (1 .0F )->second ) {
516- auto node = newNg ->getNode (nodeName);
517- if (! node) {
518- continue ;
470+ auto node = optimizedNodeGraph ->getNode (nodeName);
471+ if (node && node-> getCategory () == " mix " ) {
472+ optimizeMixNode ( " fg " , node, optimizedNodeGraph, reverseMap) ;
519473 }
520- if (node->getCategory () == " mix" ) {
521- auto fgInput = node->getInput (" fg" );
522- if (!fgInput) {
523- continue ;
474+ }
475+ }
476+
477+ void LobePrunerImpl::optimizeMixNode (
478+ const std::string& promotedInputName,
479+ mx::NodePtr& mixNode,
480+ mx::NodeGraphPtr& optimizedNodeGraph,
481+ ReverseCnxMap& reverseMap) const
482+ {
483+ auto bgInput = mixNode->getInput (promotedInputName);
484+ if (!bgInput) {
485+ return ;
486+ }
487+ for (const auto & destNodeName : reverseMap.find (mixNode->getName ())->second ) {
488+ auto destNode = optimizedNodeGraph->getNode (destNodeName);
489+ if (!destNode) {
490+ return ;
491+ }
492+ for (auto input : destNode->getInputs ()) {
493+ if (input->getNodeName () == mixNode->getName ()) {
494+ input->removeAttribute (mx::PortElement::NODE_NAME_ATTRIBUTE);
495+ if (bgInput->hasNodeName ()) {
496+ input->setNodeName (bgInput->getNodeName ());
497+ auto & nodeVector = reverseMap.find (bgInput->getNodeName ())->second ;
498+ nodeVector.push_back (destNodeName);
499+ nodeVector.erase (
500+ std::remove_if (
501+ nodeVector.begin (),
502+ nodeVector.end (),
503+ [mixNode](const std::string& s) { return s == mixNode->getName (); }),
504+ nodeVector.end ());
505+ }
506+ if (bgInput->hasInterfaceName ()) {
507+ input->setInterfaceName (bgInput->getInterfaceName ());
508+ }
509+ if (bgInput->hasOutputString ()) {
510+ input->setOutputString (bgInput->getOutputString ());
511+ }
512+ if (bgInput->hasValueString ()) {
513+ input->setValueString (bgInput->getValueString ());
514+ }
524515 }
525- for (const auto & destNodeName : reverseMap.find (node->getName ())->second ) {
526- auto destNode = newNg->getNode (destNodeName);
527- for (auto input : destNode->getInputs ()) {
528- if (input->getNodeName () == node->getName ()) {
529- input->removeAttribute (mx::PortElement::NODE_NAME_ATTRIBUTE);
530- if (fgInput->hasNodeName ()) {
531- input->setNodeName (fgInput->getNodeName ());
532- auto & nodeVector = reverseMap.find (fgInput->getNodeName ())->second ;
533- nodeVector.push_back (destNodeName);
534- nodeVector.erase (
535- std::remove_if (
536- nodeVector.begin (),
537- nodeVector.end (),
538- [node](const std::string& s) { return s == node->getName (); }),
539- nodeVector.end ());
540- }
541- if (fgInput->hasInterfaceName ()) {
542- input->setInterfaceName (fgInput->getInterfaceName ());
543- }
544- if (fgInput->hasOutputString ()) {
545- input->setOutputString (fgInput->getOutputString ());
546- }
547- if (fgInput->hasValueString ()) {
548- input->setValueString (fgInput->getValueString ());
549- }
550- }
516+ }
517+ }
518+ optimizedNodeGraph->removeNode (mixNode->getName ());
519+ }
520+
521+ void LobePrunerImpl::optimizeMultiplyNode (
522+ mx::NodePtr& node,
523+ mx::NodeGraphPtr& optimizedNodeGraph,
524+ ReverseCnxMap& reverseMap) const
525+ {
526+ // Result will be a zero value of the type it requests:
527+ for (const auto & destNodeName : reverseMap.find (node->getName ())->second ) {
528+ auto destNode = optimizedNodeGraph->getNode (destNodeName);
529+ for (auto input : destNode->getInputs ()) {
530+ if (input->getNodeName () == node->getName ()) {
531+ input->removeAttribute (mx::PortElement::NODE_NAME_ATTRIBUTE);
532+ const auto defaultValueIt = kZeroMultiplyValueMap .find (input->getType ());
533+ if (defaultValueIt != kZeroMultiplyValueMap .end ()) {
534+ input->setValueString (defaultValueIt->second );
551535 }
552536 }
553- newNg->removeNode (node->getName ());
554537 }
555538 }
539+ optimizedNodeGraph->removeNode (node->getName ());
540+ }
541+
542+ void LobePrunerImpl::optimizePbrNode (
543+ mx::NodePtr& node,
544+ const std::string& darkNodeName,
545+ const std::string& darkNodeDefName) const
546+ {
547+ // Prune all inputs.
548+ for (const auto & input : node->getInputs ()) {
549+ node->removeInput (input->getName ());
550+ }
551+ // Change node category:
552+ node->setCategory (darkNodeName);
553+ if (node->hasNodeDefString ()) {
554+ node->setNodeDefString (darkNodeDefName);
555+ }
556556}
557557
558558LobePruner::Ptr LobePruner::create () { return std::make_shared<LobePruner>(); }
0 commit comments