@@ -359,6 +359,10 @@ struct _MaterialXData
359359 mx::loadLibraries ({}, _mtlxSearchPath, _mtlxLibrary);
360360#endif
361361
362+ #if MX_COMBINED_VERSION >= 13900
363+ _RemovePreviewSurfaceEmbeddedNormalmap (_mtlxLibrary);
364+ #endif
365+
362366 _FixLibraryTangentInputs (_mtlxLibrary);
363367
364368 mx::OgsXmlGenerator::setUseLightAPI (MAYA_LIGHTAPI_VERSION_2);
@@ -396,6 +400,9 @@ struct _MaterialXData
396400
397401private:
398402 void _FixLibraryTangentInputs (MaterialX::DocumentPtr& mtlxLibrary);
403+ #if MX_COMBINED_VERSION >= 13900
404+ void _RemovePreviewSurfaceEmbeddedNormalmap (MaterialX::DocumentPtr& mtlxLibrary);
405+ #endif
399406};
400407
401408_MaterialXData& _GetMaterialXData ()
@@ -682,6 +689,73 @@ mx::NodePtr _RecursiveFindNode(const mx::NodePtr& node, const TfToken& target)
682689 return retVal;
683690}
684691
692+ #if MX_COMBINED_VERSION >= 13900
693+ void _MaterialXData::_RemovePreviewSurfaceEmbeddedNormalmap (mx::DocumentPtr& mtlxDoc)
694+ {
695+ // The embedded "normalmap" node inside ND_UsdPreviewSurface_surfaceshader started causing
696+ // issues in 1.39.4. We will temporarily remove it from the surface shader and patch the
697+ // NodeGraph to use the "normal" input as a true normal input.
698+
699+ // Fetch everything as seen in 1.39.4 and bail out if any change is detected:
700+ auto psNodeDef = mtlxDoc->getNodeDef (" ND_UsdPreviewSurface_surfaceshader" );
701+ if (!psNodeDef) {
702+ return ;
703+ }
704+
705+ auto normalInput = psNodeDef->getInput (" normal" );
706+ if (!normalInput) {
707+ return ;
708+ }
709+
710+ auto psNodeGraph = mtlxDoc->getNodeGraph (" IMP_UsdPreviewSurface_surfaceshader" );
711+ if (!psNodeGraph) {
712+ return ;
713+ }
714+
715+ auto normalmap = psNodeGraph->getNode (" surface_normal" );
716+ if (!normalmap || normalmap->getInputs ().size () != 1 ) {
717+ // Fully unconnected normalmap requires DCC help to provide data for the normal, tangent,
718+ // and bitangent inputs of the normalmap node.
719+ return ;
720+ }
721+
722+ const auto normalClientNamess
723+ = mx::StringVec { " diffuse_bsdf" , " transmission_bsdf" , " specular_bsdf1" ,
724+ " specular_bsdf2" , " metalness_metal_bsdf" , " coat_dielectric_bsdf" };
725+ std::vector<mx::NodePtr> normalClients;
726+ for (const auto & clientName : normalClientNamess) {
727+ auto client = psNodeGraph->getNode (clientName);
728+ if (!client) {
729+ return ;
730+ }
731+ auto clientNormalInput = client->getInput (" normal" );
732+ if (!clientNormalInput || clientNormalInput->getNodeName () != " surface_normal" ) {
733+ return ;
734+ }
735+ normalClients.push_back (client);
736+ }
737+
738+ // If we reached here, we have gathered all the items that needed fixes in 1.39.4 without
739+ // noticing any difference. Proceed:
740+
741+ // Expose a regular normal input:
742+ normalInput->removeAttribute (" value" );
743+ normalInput->removeAttribute (" uimin" );
744+ normalInput->removeAttribute (" uimax" );
745+ normalInput->removeAttribute (" uistep" );
746+ normalInput->setAttribute (" defaultgeomprop" , " Nworld" );
747+
748+ // Each client gets that regular normal instead of a normalmap computation:
749+ for (auto & client : normalClients) {
750+ auto clientNormalInput = client->getInput (" normal" );
751+ if (clientNormalInput) {
752+ clientNormalInput->removeAttribute (" nodename" );
753+ clientNormalInput->setAttribute (" interfacename" , " normal" );
754+ }
755+ }
756+ }
757+ #endif
758+
685759// We have a few library surface nodes that require tangent inputs, but since the tangent input is
686760// not expressed in the interface, we will miss it in the _AddMissingTangents function. This
687761// function goes thru the NodeGraphs in the library and fixes the issue by adding the missing input.
0 commit comments