From 376dd1fdc570668ccdd6b2b21022760f1ea28642 Mon Sep 17 00:00:00 2001 From: Alex Fuller Date: Sun, 23 Feb 2025 19:10:35 +1100 Subject: [PATCH] MaterialX 1.39.x support --- .../GlslFragmentGenerator.cpp | 56 ++++++++++++++++++- .../GlslFragmentGenerator.h | 10 ++++ .../Nodes/MayaShaderGraph.cpp | 5 ++ .../render/MaterialXGenOgsXml/OgsFragment.cpp | 8 +++ .../MaterialXGenOgsXml/OgsXmlGenerator.cpp | 48 ++++++++++++++++ .../MaterialXGenOgsXml/ShaderGenUtil.cpp | 34 +++++++++-- .../render/MaterialXGenOgsXml/ShaderGenUtil.h | 7 +++ 7 files changed, 159 insertions(+), 9 deletions(-) diff --git a/lib/mayaUsd/render/MaterialXGenOgsXml/GlslFragmentGenerator.cpp b/lib/mayaUsd/render/MaterialXGenOgsXml/GlslFragmentGenerator.cpp index 62c63af725..c94836da46 100644 --- a/lib/mayaUsd/render/MaterialXGenOgsXml/GlslFragmentGenerator.cpp +++ b/lib/mayaUsd/render/MaterialXGenOgsXml/GlslFragmentGenerator.cpp @@ -161,7 +161,11 @@ const string& HwSpecularEnvironmentSamples::name() string GlslFragmentSyntax::getVariableName( const string& name, +#if MX_COMBINED_VERSION < 13900 const TypeDesc* type, +#else + TypeDesc type, +#endif IdentifierMap& identifiers) const { string variable = GlslSyntax::getVariableName(name, type, identifiers); @@ -445,7 +449,11 @@ ShaderPtr GlslFragmentGenerator::createShader( for (ShaderNode* node : g->getNodes()) { if (node->hasClassification(ShaderNode::Classification::FILETEXTURE)) { for (ShaderInput* input : node->getInputs()) { +#if MX_COMBINED_VERSION < 13900 if (!input->getConnection() && *input->getType() == *Type::FILENAME) { +#else + if (!input->getConnection() && input->getType() == Type::FILENAME) { +#endif // Create the uniform using the filename type to make this uniform into a // texture sampler. ShaderPort* filename = psPublicUniforms->add( @@ -782,12 +790,13 @@ ShaderPtr GlslFragmentGenerator::generate( // if (const ShaderOutput* const outputConnection = outputSocket->getConnection()) { string finalOutput = outputConnection->getVariable(); +#if MX_COMBINED_VERSION < 13900 const string& channels = outputSocket->getChannels(); if (!channels.empty()) { finalOutput = _syntax->getSwizzledVariable( finalOutput, outputConnection->getType(), channels, outputSocket->getType()); } - +#endif if (graph.hasClassification(ShaderNode::Classification::SURFACE)) { if (context.getOptions().hwTransparency) { emitLine( @@ -798,12 +807,21 @@ ShaderPtr GlslFragmentGenerator::generate( emitLine("return " + finalOutput + ".color", pixelStage); } } else { +#if MX_COMBINED_VERSION < 13900 if (context.getOptions().hwTransparency && !outputSocket->getType()->isFloat4()) { toVec4(outputSocket->getType(), finalOutput); } else if ( !context.getOptions().hwTransparency && !outputSocket->getType()->isFloat3()) { toVec3(outputSocket->getType(), finalOutput); } +#else + if (context.getOptions().hwTransparency && !outputSocket->getType().isFloat4()) { + toVec4(outputSocket->getType(), finalOutput); + } else if ( + !context.getOptions().hwTransparency && !outputSocket->getType().isFloat3()) { + toVec3(outputSocket->getType(), finalOutput); + } +#endif emitLine("return " + finalOutput, pixelStage); } } else { @@ -811,7 +829,12 @@ ShaderPtr GlslFragmentGenerator::generate( ? _syntax->getValue(outputSocket->getType(), *outputSocket->getValue()) : _syntax->getDefaultValue(outputSocket->getType()); - if (!context.getOptions().hwTransparency && !outputSocket->getType()->isFloat3()) { + if (!context.getOptions().hwTransparency && +#if MX_COMBINED_VERSION < 13900 + !outputSocket->getType()->isFloat3()) { +#else + !outputSocket->getType().isFloat3()) { +#endif string finalOutput = outputSocket->getVariable() + "_tmp"; emitLine( _syntax->getTypeName(outputSocket->getType()) + " " + finalOutput + " = " @@ -820,7 +843,12 @@ ShaderPtr GlslFragmentGenerator::generate( toVec3(outputSocket->getType(), finalOutput); emitLine("return " + finalOutput, pixelStage); } else if ( - context.getOptions().hwTransparency && !outputSocket->getType()->isFloat4()) { + context.getOptions().hwTransparency && +#if MX_COMBINED_VERSION < 13900 + !outputSocket->getType()->isFloat4()) { +#else + !outputSocket->getType().isFloat4()) { +#endif string finalOutput = outputSocket->getVariable() + "_tmp"; emitLine( _syntax->getTypeName(outputSocket->getType()) + " " + finalOutput + " = " @@ -896,12 +924,21 @@ ShaderPtr GlslFragmentGenerator::generate( return shader; } +#if MX_COMBINED_VERSION < 13900 void GlslFragmentGenerator::toVec3(const TypeDesc* type, string& variable) { if (type->isFloat2()) { variable = "vec3(" + variable + ", 0.0)"; } else if (type->isFloat4()) { variable = variable + ".xyz"; +#else +void GlslFragmentGenerator::toVec3(const TypeDesc& type, string& variable) +{ + if (type.isFloat2()) { + variable = "vec3(" + variable + ", 0.0)"; + } else if (type.isFloat4()) { + variable = variable + ".xyz"; +#endif } else if (type == Type::FLOAT || type == Type::INTEGER) { variable = "vec3(" + variable + ", " + variable + ", " + variable + ")"; } else if (type == Type::BSDF || type == Type::EDF) { @@ -954,10 +991,19 @@ GlslFragmentGenerator::getImplementation(const NodeDef& nodedef, GenContext& con throw ExceptionShaderGenError("NodeDef '" + nodedef.getName() + "' has no outputs defined"); } +#if MX_COMBINED_VERSION < 13900 const TypeDesc* outputType = TypeDesc::get(outputs[0]->getType()); +#else + const TypeDesc outputType = TypeDesc::get(outputs[0]->getType()); +#endif +#if MX_COMBINED_VERSION < 13900 if (implElement->isA() && outputType->getName() != Type::LIGHTSHADER->getName() && !outputType->isClosure()) { +#else + if (implElement->isA() && outputType.getName() != Type::LIGHTSHADER.getName() + && !outputType.isClosure()) { +#endif // Use a compound implementation that can propagate UDIM inputs: impl = MayaCompoundNode::create(); impl->initialize(*implElement, context); @@ -968,7 +1014,11 @@ GlslFragmentGenerator::getImplementation(const NodeDef& nodedef, GenContext& con return impl; } else if ( implElement->isA() && !_implFactory.classRegistered(name) +#if MX_COMBINED_VERSION < 13900 && !outputType->isClosure()) { +#else + && !outputType.isClosure()) { +#endif // Backporting 1.39 fix done in // https://github.com/AcademySoftwareFoundation/MaterialX/pull/1754 impl = MayaSourceCodeNode::create(); diff --git a/lib/mayaUsd/render/MaterialXGenOgsXml/GlslFragmentGenerator.h b/lib/mayaUsd/render/MaterialXGenOgsXml/GlslFragmentGenerator.h index 1e72dc60df..ec624e778a 100644 --- a/lib/mayaUsd/render/MaterialXGenOgsXml/GlslFragmentGenerator.h +++ b/lib/mayaUsd/render/MaterialXGenOgsXml/GlslFragmentGenerator.h @@ -9,6 +9,8 @@ /// @file /// GLSL fragment generator +#include + #include #include #include @@ -50,7 +52,11 @@ class HwSpecularEnvironmentSamples : public GenUserData class GlslFragmentSyntax : public GlslSyntax { public: +#if MX_COMBINED_VERSION < 13900 string getVariableName(const string& name, const TypeDesc* type, IdentifierMap& identifiers) +#else + string getVariableName(const string& name, TypeDesc type, IdentifierMap& identifiers) +#endif const override; }; @@ -84,7 +90,11 @@ class GlslFragmentGenerator : public GlslShaderGenerator #endif protected: +#if MX_COMBINED_VERSION < 13900 static void toVec3(const TypeDesc* type, string& variable); +#else + static void toVec3(const TypeDesc& type, string& variable); +#endif }; MATERIALX_NAMESPACE_END diff --git a/lib/mayaUsd/render/MaterialXGenOgsXml/Nodes/MayaShaderGraph.cpp b/lib/mayaUsd/render/MaterialXGenOgsXml/Nodes/MayaShaderGraph.cpp index b397e97930..7836996a89 100644 --- a/lib/mayaUsd/render/MaterialXGenOgsXml/Nodes/MayaShaderGraph.cpp +++ b/lib/mayaUsd/render/MaterialXGenOgsXml/Nodes/MayaShaderGraph.cpp @@ -133,8 +133,13 @@ MayaShaderGraph::MayaShaderGraph( ValuePtr value = nodeInput->getResolvedValue(); if (value) { const string& valueString = value->getValueString(); +#if MX_COMBINED_VERSION < 13900 std::pair enumResult; const TypeDesc* type = TypeDesc::get(nodedefInput->getType()); +#else + std::pair enumResult; + TypeDesc type = TypeDesc::get(nodedefInput->getType()); +#endif const string& enumNames = nodedefInput->getAttribute(ValueElement::ENUM_ATTRIBUTE); if (context.getShaderGenerator().getSyntax().remapEnumeration( diff --git a/lib/mayaUsd/render/MaterialXGenOgsXml/OgsFragment.cpp b/lib/mayaUsd/render/MaterialXGenOgsXml/OgsFragment.cpp index cc42249bbf..67ae16eab9 100644 --- a/lib/mayaUsd/render/MaterialXGenOgsXml/OgsFragment.cpp +++ b/lib/mayaUsd/render/MaterialXGenOgsXml/OgsFragment.cpp @@ -647,7 +647,11 @@ OgsFragment::OgsFragment(mx::ElementPtr element, GLSL_GENERATOR_WRAPPER&& glslGe for (size_t i = 0; i < uniforms.size(); ++i) { const mx::ShaderPort* const port = uniforms[i]; if (!port->getNode()) { +#if MX_COMBINED_VERSION < 13900 if (port->getType()->getSemantic() == mx::TypeDesc::SEMANTIC_FILENAME) { +#else + if (port->getType().getSemantic() == mx::TypeDesc::SEMANTIC_FILENAME) { +#endif // Might be an embedded texture. Retrieve the filename. std::string textureName = mx::OgsXmlGenerator::samplerToTextureName(port->getVariable()); @@ -675,7 +679,11 @@ OgsFragment::OgsFragment(mx::ElementPtr element, GLSL_GENERATOR_WRAPPER&& glslGe path += originalName; } if (!path.empty()) { +#if MX_COMBINED_VERSION < 13900 if (port->getType()->getSemantic() == mx::TypeDesc::SEMANTIC_FILENAME) { +#else + if (port->getType().getSemantic() == mx::TypeDesc::SEMANTIC_FILENAME) { +#endif std::string textureName = mx::OgsXmlGenerator::samplerToTextureName(variableName); if (!textureName.empty()) { diff --git a/lib/mayaUsd/render/MaterialXGenOgsXml/OgsXmlGenerator.cpp b/lib/mayaUsd/render/MaterialXGenOgsXml/OgsXmlGenerator.cpp index 0315d77f04..13fe1e64ac 100644 --- a/lib/mayaUsd/render/MaterialXGenOgsXml/OgsXmlGenerator.cpp +++ b/lib/mayaUsd/render/MaterialXGenOgsXml/OgsXmlGenerator.cpp @@ -20,6 +20,7 @@ MATERIALX_NAMESPACE_BEGIN namespace { typedef std::unordered_map OGS_TYPE_MAP_T; +#if MX_COMBINED_VERSION < 13900 const OGS_TYPE_MAP_T& getOgsTypeMap() { // Data types used by OGS @@ -34,6 +35,22 @@ const OGS_TYPE_MAP_T& getOgsTypeMap() { Type::MATRIX44->getName(), "float4x4" } }; return OGS_TYPE_MAP; } +#else +const OGS_TYPE_MAP_T& getOgsTypeMap() +{ + // Data types used by OGS + // Delayed initialization to survive C++ init order fiasco. + // Keyed by string to survive multiple redefinitions of global symbols. + static const OGS_TYPE_MAP_T OGS_TYPE_MAP + = { { Type::BOOLEAN.getName(), "bool" }, { Type::FLOAT.getName(), "float" }, + { Type::INTEGER.getName(), "int" }, { Type::STRING.getName(), "int" }, + { Type::COLOR3.getName(), "float3" }, { Type::COLOR4.getName(), "float4" }, + { Type::VECTOR2.getName(), "float2" }, { Type::VECTOR3.getName(), "float3" }, + { Type::VECTOR4.getName(), "float4" }, { Type::MATRIX33.getName(), "float4x4" }, + { Type::MATRIX44.getName(), "float4x4" } }; + return OGS_TYPE_MAP; +} +#endif // Semantics used by OGS static const std::unordered_map OGS_SEMANTICS_MAP = { @@ -230,7 +247,11 @@ void xmlAddProperties( sampler, shaderPort->getName(), samplerName, parameterFlags, refNode); } } else { +#if MX_COMBINED_VERSION < 13900 const auto type = getOgsTypeMap().find(shaderPort->getType()->getName()); +#else + const auto type = getOgsTypeMap().find(shaderPort->getType().getName()); +#endif if (type != getOgsTypeMap().end()) { pugi::xml_node prop = parent.append_child(type->second); if (shaderPort->getType() == Type::MATRIX33) { @@ -262,7 +283,11 @@ void xmlAddValues(pugi::xml_node& parent, const VariableBlock& block, bool skipL continue; } if (p->getValue()) { +#if MX_COMBINED_VERSION < 13900 auto type = getOgsTypeMap().find(p->getType()->getName()); +#else + auto type = getOgsTypeMap().find(p->getType().getName()); +#endif if (type != getOgsTypeMap().end()) { pugi::xml_node val = parent.append_child(type->second); if (p->getType() == Type::MATRIX33) { @@ -415,8 +440,13 @@ string OgsXmlGenerator::generate( throw ExceptionShaderGenError("Shader stage has no output"); } pugi::xml_node xmlOutputs = xmlRoot.append_child(OUTPUTS); +#if MX_COMBINED_VERSION < 13900 pugi::xml_node xmlOut = xmlOutputs.append_child( getOgsTypeMap().at(hwTransparency ? Type::COLOR4->getName() : Type::COLOR3->getName())); +#else + pugi::xml_node xmlOut = xmlOutputs.append_child( + getOgsTypeMap().at(hwTransparency ? Type::COLOR4.getName() : Type::COLOR3.getName())); +#endif xmlOut.append_attribute(NAME) = OUTPUT_NAME.c_str(); // Add implementations @@ -499,15 +529,24 @@ string OgsXmlGenerator::generateLightRig( baseShaderName.c_str()); // Add Light Rig properties: +#if MX_COMBINED_VERSION < 13900 auto vec3OGSType = getOgsTypeMap().find(Type::VECTOR3->getName())->second; auto intOGSType = getOgsTypeMap().find(Type::INTEGER->getName())->second; +#else + auto vec3OGSType = getOgsTypeMap().find(Type::VECTOR3.getName())->second; + auto intOGSType = getOgsTypeMap().find(Type::INTEGER.getName())->second; +#endif pugi::xml_node xmlLightProp = xmlProperties.append_child(vec3OGSType); xmlLightProp.append_attribute(NAME) = IRRADIANCEENV; xmlLightProp.append_attribute(REF) = DOT_COMBINE(baseShaderName.c_str(), DIFFUSEI).c_str(); xmlLightProp = xmlProperties.append_child(vec3OGSType); xmlLightProp.append_attribute(NAME) = SPECULARENV; xmlLightProp.append_attribute(REF) = DOT_COMBINE(baseShaderName.c_str(), SPECULARI).c_str(); +#if MX_COMBINED_VERSION < 13900 xmlLightProp = xmlProperties.append_child(Type::STRING->getName().c_str()); +#else + xmlLightProp = xmlProperties.append_child(Type::STRING.getName().c_str()); +#endif xmlLightProp.append_attribute(NAME) = SELECTOR; xmlLightProp.append_attribute(REF) = DOT_COMBINE(LIGHT_ACCUM, SELECTOR).c_str(); xmlLightProp = xmlProperties.append_child(intOGSType); @@ -536,7 +575,11 @@ string OgsXmlGenerator::generateLightRig( xmlLightValue = xmlValues.append_child(vec3OGSType); xmlLightValue.append_attribute(NAME) = SPECULARI; xmlLightValue.append_attribute(VALUE) = "0, 0, 0"; +#if MX_COMBINED_VERSION < 13900 xmlLightValue = xmlValues.append_child(Type::STRING->getName().c_str()); +#else + xmlLightValue = xmlValues.append_child(Type::STRING.getName().c_str()); +#endif xmlLightValue.append_attribute(NAME) = SELECTOR; xmlLightValue.append_attribute(VALUE) = LIGHT_SELECTOR; @@ -547,8 +590,13 @@ string OgsXmlGenerator::generateLightRig( } pugi::xml_node xmlOutputs = xmlRoot.append_child(OUTPUTS); const bool hwTransparency = glslShader.hasAttribute(HW::ATTR_TRANSPARENT); +#if MX_COMBINED_VERSION < 13900 pugi::xml_node xmlOut = xmlOutputs.append_child( getOgsTypeMap().at(hwTransparency ? Type::COLOR4->getName() : Type::COLOR3->getName())); +#else + pugi::xml_node xmlOut = xmlOutputs.append_child( + getOgsTypeMap().at(hwTransparency ? Type::COLOR4.getName() : Type::COLOR3.getName())); +#endif xmlOut.append_attribute(NAME) = OUTPUT_NAME.c_str(); xmlOut.append_attribute(REF) = DOT_COMBINE(baseShaderName.c_str(), OgsXmlGenerator::OUTPUT_NAME.c_str()).c_str(); diff --git a/lib/mayaUsd/render/MaterialXGenOgsXml/ShaderGenUtil.cpp b/lib/mayaUsd/render/MaterialXGenOgsXml/ShaderGenUtil.cpp index a011413211..2a1e52ec74 100644 --- a/lib/mayaUsd/render/MaterialXGenOgsXml/ShaderGenUtil.cpp +++ b/lib/mayaUsd/render/MaterialXGenOgsXml/ShaderGenUtil.cpp @@ -3,8 +3,6 @@ #include "LobePruner.h" #include "MaterialXCore/Types.h" -#include - #include #include @@ -178,15 +176,25 @@ void TopoNeutralGraph::computeGraph(const mx::ElementPtr& material, bool texture nodesToTraverse.push_back(connectedNode); } +#if MX_COMBINED_VERSION < 13900 const std::string channelInfo = gatherChannels(*sourceInput); +#endif const std::string outputString = gatherOutput(*sourceInput); if (sourceNode != surfaceShader) { cloneConnection( - *sourceInput, *destNode, destConnectedNode, channelInfo, outputString); + *sourceInput, *destNode, destConnectedNode, +#if MX_COMBINED_VERSION < 13900 + channelInfo, +#endif + outputString); } else { cloneNodeGraphConnection( - *sourceInput, *destNode, destConnectedNode, channelInfo, outputString); + *sourceInput, *destNode, destConnectedNode, +#if MX_COMBINED_VERSION < 13900 + channelInfo, +#endif + outputString); } } else if (isTopological) { std::string valueString = sourceInput->getValueString(); @@ -305,6 +313,7 @@ TopoNeutralGraph::findNodeGraphOutput(const mx::Input& input, const std::string& return nodeGraph->getOutput(outputName); } +#if MX_COMBINED_VERSION < 13900 std::string TopoNeutralGraph::gatherChannels(const mx::Input& input) { // The info we seek might be on the interface of a standalone NodeGraph: @@ -378,6 +387,7 @@ std::string TopoNeutralGraph::gatherChannels(const mx::Input& input) } return combinedChannels; } +#endif std::string TopoNeutralGraph::gatherDefaultGeomProp(const mx::Input& input) { @@ -419,14 +429,18 @@ void TopoNeutralGraph::cloneConnection( const mx::Input& sourceInput, mx::Node& destNode, mx::NodePtr& destConnectedNode, +#if MX_COMBINED_VERSION < 13900 const std::string& channelInfo, +#endif const std::string& output) { auto destInput = destNode.addInput(sourceInput.getName(), sourceInput.getType()); destInput->setConnectedNode(destConnectedNode); +#if MX_COMBINED_VERSION < 13900 if (!channelInfo.empty()) { destInput->setChannels(channelInfo); } +#endif if (!output.empty()) { destInput->setOutputString(output); } @@ -436,11 +450,17 @@ void TopoNeutralGraph::cloneNodeGraphConnection( const mx::Input& sourceInput, mx::Node& destNode, mx::NodePtr& destConnectedNode, +#if MX_COMBINED_VERSION < 13900 const std::string& channelInfo, +#endif const std::string& output) { - std::string outputKey = destConnectedNode->getName() + "(t)" + sourceInput.getType() + "(c)" - + channelInfo + "(o)" + output; + std::string outputKey = destConnectedNode->getName() + "(t)" + sourceInput.getType() +#if MX_COMBINED_VERSION < 13900 + + "(c)" + channelInfo + "(o)" + output; +#else + + "(o)" + output; +#endif mx::OutputPtr graphOutput; auto outputIt = _outputMap.find(outputKey); if (outputIt != _outputMap.end()) { @@ -448,9 +468,11 @@ void TopoNeutralGraph::cloneNodeGraphConnection( } else { graphOutput = getNodeGraph()->addOutput("O" + std::to_string(_outputIndex), sourceInput.getType()); +#if MX_COMBINED_VERSION < 13900 if (!channelInfo.empty()) { graphOutput->setChannels(channelInfo); } +#endif if (!output.empty()) { graphOutput->setOutputString(output); } diff --git a/lib/mayaUsd/render/MaterialXGenOgsXml/ShaderGenUtil.h b/lib/mayaUsd/render/MaterialXGenOgsXml/ShaderGenUtil.h index bc9c9c0026..4733ddd62e 100644 --- a/lib/mayaUsd/render/MaterialXGenOgsXml/ShaderGenUtil.h +++ b/lib/mayaUsd/render/MaterialXGenOgsXml/ShaderGenUtil.h @@ -5,6 +5,7 @@ /// Helpers #include +#include #include #include @@ -86,20 +87,26 @@ class MAYAUSD_CORE_PUBLIC TopoNeutralGraph void computeGraph(const mx::ElementPtr& material, bool textured); mx::NodePtr cloneNode(const mx::Node& node, mx::GraphElement& container); mx::OutputPtr findNodeGraphOutput(const mx::Input& input, const std::string& outputName); +#if MX_COMBINED_VERSION < 13900 std::string gatherChannels(const mx::Input& input); +#endif std::string gatherOutput(const mx::Input& input); std::string gatherDefaultGeomProp(const mx::Input& input); void cloneConnection( const mx::Input& sourceInput, mx::Node& destNode, mx::NodePtr& destConnectedNode, +#if MX_COMBINED_VERSION < 13900 const std::string& channelInfo, +#endif const std::string& output); void cloneNodeGraphConnection( const mx::Input& sourceInput, mx::Node& destNode, mx::NodePtr& destConnectedNode, +#if MX_COMBINED_VERSION < 13900 const std::string& channelInfo, +#endif const std::string& output); // The topo neutral document we are trying to create.