diff --git a/pxr/imaging/hdSt/materialXFilter.cpp b/pxr/imaging/hdSt/materialXFilter.cpp index f3f38b18b3..f1f8b87b55 100644 --- a/pxr/imaging/hdSt/materialXFilter.cpp +++ b/pxr/imaging/hdSt/materialXFilter.cpp @@ -495,10 +495,9 @@ _UpdatePrimvarNodes( (*mxHdPrimvarDefaultValueMap)[primvarName] = defaultPrimvarValue; } - // Texcoord nodes will have an index parameter set - primvarNameIt = hdPrimvarNode.parameters.find(_tokens->index); - if (primvarNameIt != hdPrimvarNode.parameters.end()) { - // Get the sdr node for the texcoord node + else { + // Other primvar nodes will be either a texcoord node or a + // custom node that uses a texcoord node. SdrRegistry &sdrRegistry = SdrRegistry::GetInstance(); const SdrShaderNodeConstPtr sdrTexCoordNode = sdrRegistry.GetShaderNodeByIdentifierAndType( @@ -511,12 +510,7 @@ _UpdatePrimvarNodes( texCoordName = metadata[SdrNodeMetadata->Primvars]; } - // Figure out the mx typename - mx::NodeDefPtr mxNodeDef = mxDoc->getNodeDef( - hdPrimvarNode.nodeTypeId.GetString()); - if (mxNodeDef) { - (*mxHdPrimvarMap)[texCoordName] = mxNodeDef->getType(); - } + (*mxHdPrimvarMap)[texCoordName] = getVector2Name(); } } } @@ -634,26 +628,41 @@ _GetGlTFSurfaceMaterialTag(HdMaterialNode2 const& terminal) return materialToken.GetString(); } -static const mx::TypeDesc* +static const mx::TypeDesc _GetMxTypeDescription(std::string const& typeName) { +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + using MxTypeDesc = const mx::TypeDesc*; +#else + using MxTypeDesc = const mx::TypeDesc; +#endif + // Add whatever is necessary for current codebase: - static const auto _typeLibrary = - std::map{ - {"float", mx::Type::FLOAT}, - {"color3", mx::Type::COLOR3}, - {"color4", mx::Type::COLOR4}, - {"vector2", mx::Type::VECTOR2}, - {"vector3", mx::Type::VECTOR3}, - {"vector4", mx::Type::VECTOR4}, - {"surfaceshader", mx::Type::SURFACESHADER} - }; + static const auto _typeLibrary = + std::map{ + {"float", mx::Type::FLOAT}, + {"color3", mx::Type::COLOR3}, + {"color4", mx::Type::COLOR4}, + {"vector2", mx::Type::VECTOR2}, + {"vector3", mx::Type::VECTOR3}, + {"vector4", mx::Type::VECTOR4}, + {"surfaceshader", mx::Type::SURFACESHADER} + }; const auto typeDescIt = _typeLibrary.find(typeName); if (typeDescIt != _typeLibrary.end()) { - return typeDescIt->second; - } - return nullptr; +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + return *typeDescIt->second; +#else + return typeDescIt->second; +#endif + } + +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + return *mx::Type::NONE; +#else + return mx::Type::NONE; +#endif } // This function adds a stripped down version of the surfaceshader node to the @@ -678,14 +687,14 @@ _AddStrippedSurfaceNode( if (!mxInputDef) { continue; } - auto const* mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType()); - if (!mxTypeDesc) { + auto const mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType()); + if (mxTypeIsNone(mxTypeDesc)) { continue; } // If hdNode is connected to the surfaceshader node, recursively call // this function to make sure that surfaceshader node is added to // the mxDocument - if (mxTypeDesc == mx::Type::SURFACESHADER) { + if (mxTypeIsSurfaceShader(mxTypeDesc)) { auto const& hdConnectedPath = connIt.second.front().upstreamNode; auto const& hdConnectedNode = hdNetwork.nodes.at(hdConnectedPath); mx::NodePtr mxConnectedNode = @@ -696,14 +705,13 @@ _AddStrippedSurfaceNode( mxInput->setConnectedNode(mxConnectedNode); } // Add the connection as an input with each component set to 0.5 - else if (mxTypeDesc->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT && - mxTypeDesc->getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) { + else if (mxTypeDesc.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT && + mxTypeDesc.getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) { std::string valueStr = "0.5"; - for (size_t i = 1; i < mxTypeDesc->getSize(); ++i) { + for (size_t i = 1; i < mxTypeDesc.getSize(); ++i) { valueStr += ", 0.5"; } - mx::InputPtr mxInput = - mxNode->addInput(mxInputDef->getName(), mxInputDef->getType()); + mx::InputPtr mxInput = mxNode->addInputFromNodeDef(mxInputDef->getName()); mxInput->setValueString(valueStr); } } @@ -715,16 +723,15 @@ _AddStrippedSurfaceNode( if (!mxInputDef) { continue; } - auto const* mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType()); - if (!mxTypeDesc) { + auto const mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType()); + if (mxTypeIsNone(mxTypeDesc)) { continue; } - if (mxTypeDesc->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT && - mxTypeDesc->getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) { + if (mxTypeDesc.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT && + mxTypeDesc.getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) { // Add the parameter as an input to the mxNode in the mx Document - mx::InputPtr mxInput = - mxNode->addInput(mxInputDef->getName(), mxInputDef->getType()); + mx::InputPtr mxInput = mxNode->addInputFromNodeDef(mxInputDef->getName()); mxInput->setValueString(HdMtlxConvertToString(paramIt.second)); } } @@ -787,9 +794,9 @@ _GetMaterialTag( // Outputting anything that is not a surfaceshader will be // considered opaque, unless outputting a color4 or vector4. // XXX This is not fully per USD specs, but is supported by MaterialX. - auto const* typeDesc = + auto const typeDesc = _GetMxTypeDescription(activeOutputs.back()->getType()); - if (typeDesc == mx::Type::COLOR4 || typeDesc == mx::Type::VECTOR4) { + if (typeDesc.isFloat4()) { return HdStMaterialTagTokens->translucent.GetString(); } return HdStMaterialTagTokens->defaultMaterialTag.GetString(); @@ -1100,7 +1107,7 @@ _AddMaterialXParams( // MaterialX parameter Information const auto* variable = paramsBlock[i]; - const auto varType = variable->getType(); + const auto varType = getMxTypeDesc(variable); // Create a corresponding HdSt_MaterialParam HdSt_MaterialParam param; @@ -1111,9 +1118,9 @@ _AddMaterialXParams( const auto paramValueIt = mxParamNameToValue.find(variable->getVariable()); if (paramValueIt != mxParamNameToValue.end()) { - if (varType->getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN || - varType->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT || - varType->getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) { + if (varType.getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN || + varType.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT || + varType.getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) { param.fallbackValue = paramValueIt->second; } } @@ -1124,52 +1131,52 @@ _AddMaterialXParams( const auto varValue = variable->getValue(); std::istringstream valueStream(varValue ? varValue->getValueString() : std::string()); - if (varType->getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN) { + if (varType.getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN) { const bool val = valueStream.str() == "true"; param.fallbackValue = VtValue(val); } - else if (varType->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT) { - if (varType->getSize() == 1) { + else if (varType.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT) { + if (varType.getSize() == 1) { float val; valueStream >> val; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 2) { + else if (varType.getSize() == 2) { GfVec2f val; valueStream >> val[0] >> separator >> val[1]; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 3) { + else if (varType.getSize() == 3) { GfVec3f val; valueStream >> val[0] >> separator >> val[1] >> separator >> val[2]; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 4) { + else if (varType.getSize() == 4) { GfVec4f val; valueStream >> val[0] >> separator >> val[1] >> separator >> val[2] >> separator >> val[3]; param.fallbackValue = VtValue(val); } } - else if (varType->getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) { - if (varType->getSize() == 1) { + else if (varType.getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) { + if (varType.getSize() == 1) { int val; valueStream >> val; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 2) { + else if (varType.getSize() == 2) { GfVec2i val; valueStream >> val[0] >> separator >> val[1]; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 3) { + else if (varType.getSize() == 3) { GfVec3i val; valueStream >> val[0] >> separator >> val[1] >> separator >> val[2]; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 4) { + else if (varType.getSize() == 4) { GfVec4i val; valueStream >> val[0] >> separator >> val[1] >> separator >> val[2] >> separator >> val[3]; @@ -1183,7 +1190,7 @@ _AddMaterialXParams( } // For filename inputs, manage the associated texture node - if (varType->getSemantic() == mx::TypeDesc::SEMANTIC_FILENAME) { + if (varType.getSemantic() == mx::TypeDesc::SEMANTIC_FILENAME) { // Get the anonymized MaterialX node name from the param name // annonNodeName_paramName -> annonNodeName std::string mxNodeName = variable->getVariable(); diff --git a/pxr/imaging/hdSt/materialXShaderGen.cpp b/pxr/imaging/hdSt/materialXShaderGen.cpp index 3de8ae9872..ee7ce074bd 100644 --- a/pxr/imaging/hdSt/materialXShaderGen.cpp +++ b/pxr/imaging/hdSt/materialXShaderGen.cpp @@ -158,13 +158,12 @@ HdStMaterialXShaderGen::_EmitGlslfxHeader(mx::ShaderStage& mxStage) const Base::emitString(R"( "attributes": {)" "\n", mxStage); std::string line = ""; unsigned int i = 0; for (mx::StringMap::const_reference primvarPair : _mxHdPrimvarMap) { - const mx::TypeDesc *mxType = mx::TypeDesc::get(primvarPair.second); - if (mxType == nullptr) { + const mx::TypeDesc mxType = getMxTypeDesc(primvarPair.second); + if (mxTypeIsNone(mxType)) { TF_WARN("MaterialX geomprop '%s' has unknown type '%s'", primvarPair.first.c_str(), primvarPair.second.c_str()); } - const std::string type = mxType - ? Base::_syntax->getTypeName(mxType) : "vec2"; + const std::string type = mxGetTypeString(mxType, Base::_syntax); line += " \"" + primvarPair.first + "\": {\n"; line += " \"type\": \"" + type + "\"\n"; @@ -287,12 +286,15 @@ HdStMaterialXShaderGen::_EmitMxSurfaceShader( if (outputConnection) { std::string finalOutput = outputConnection->getVariable(); +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + // channels feature removed in MaterialX 1.39 const std::string& channels = outputSocket->getChannels(); if (!channels.empty()) { finalOutput = Base::_syntax->getSwizzledVariable( finalOutput, outputConnection->getType(), channels, outputSocket->getType()); } +#endif if (mxGraph.hasClassification( mx::ShaderNode::Classification::SURFACE)) { @@ -313,7 +315,7 @@ HdStMaterialXShaderGen::_EmitMxSurfaceShader( } } else { - if (!outputSocket->getType()->isFloat4()) { + if (!getMxTypeDesc(outputSocket).isFloat4()) { Base::toVec4(outputSocket->getType(), finalOutput); } emitLine(finalOutputReturn + @@ -325,7 +327,7 @@ HdStMaterialXShaderGen::_EmitMxSurfaceShader( ? Base::_syntax->getValue( outputSocket->getType(), *outputSocket->getValue()) : Base::_syntax->getDefaultValue(outputSocket->getType()); - if (!outputSocket->getType()->isFloat4()) { + if (!getMxTypeDesc(outputSocket).isFloat4()) { std::string finalOutput = outputSocket->getVariable() + "_tmp"; emitLine(Base::_syntax->getTypeName(outputSocket->getType()) + " " + finalOutput + " = " + outputValue, mxStage); @@ -417,8 +419,8 @@ HdStMaterialXShaderGen::_EmitMxInitFunction( mxStage.getUniformBlock(mx::HW::PUBLIC_UNIFORMS); for (size_t i = 0; i < paramsBlock.size(); ++i) { const mx::ShaderPort* variable = paramsBlock[i]; - const mx::TypeDesc* variableType = variable->getType(); - if (!_IsHardcodedPublicUniform(*variableType)) { + const mx::TypeDesc variableType = getMxTypeDesc(variable); + if (!_IsHardcodedPublicUniform(variableType)) { emitLine(variable->getVariable() + " = HdGet_" + variable->getVariable() + "()", mxStage); } @@ -624,16 +626,16 @@ HdStMaterialXShaderGen::emitVariableDeclarations( { Base::emitLineBegin(stage); const mx::ShaderPort* variable = block[i]; - const mx::TypeDesc* varType = variable->getType(); + const mx::TypeDesc varType = getMxTypeDesc(variable); // If bindlessTextures are not enabled the Mx Smpler names are mapped // to the Hydra equivalents in HdStMaterialXShaderGen*::_EmitMxFunctions - if (!_bindlessTexturesEnabled && varType == mx::Type::FILENAME) { + if (!_bindlessTexturesEnabled && mxTypeDescIsFilename(varType)) { continue; } // Only declare the variables that we need to initialize with Hd Data - if ( (isPublicUniform && !_IsHardcodedPublicUniform(*varType)) + if ( (isPublicUniform && !_IsHardcodedPublicUniform(varType)) || MxHdVariables.count(variable->getName()) ) { Base::emitVariableDeclaration(variable, mx::EMPTY_STRING, context, stage, false /* assignValue */); @@ -1351,4 +1353,70 @@ HdStMaterialXShaderGenMsl::_EmitMxFunctions( } +bool mxTypeIsNone(mx::TypeDesc typeDesc) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + return typeDesc == *mx::Type::NONE; +#else + return typeDesc == mx::Type::NONE; +#endif +} + +bool mxTypeIsSurfaceShader(mx::TypeDesc typeDesc) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + return typeDesc == *mx::Type::SURFACESHADER; +#else + return typeDesc == mx::Type::SURFACESHADER; +#endif +} + +bool mxTypeDescIsFilename(const mx::TypeDesc typeDesc) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + return typeDesc == *mx::Type::FILENAME; +#else + return typeDesc == mx::Type::FILENAME; +#endif +} + +mx::TypeDesc getMxTypeDesc(const std::string& typeName) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + const mx::TypeDesc* mxType = mx::TypeDesc::get(typeName); + if (mxType) + return *mxType; + return *mx::Type::NONE; +#else + return mx::TypeDesc::get(typeName); +#endif +} + +const MaterialX::TypeDesc getMxTypeDesc(const mx::ShaderPort* port) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + return port->getType() ? *(port->getType()) : *mx::Type::NONE; +#else + return port->getType(); +#endif +} + +const std::string mxGetTypeString(const mx::TypeDesc mxType, mx::SyntaxPtr syntax) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + return (!mxTypeIsNone(mxType)) ? syntax->getTypeName(&mxType) : "vec2"; +#else + return (!mxTypeIsNone(mxType)) ? syntax->getTypeName(mxType) : "vec2"; +#endif +} + +const std::string& getVector2Name() +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38 + return mx::Type::VECTOR2->getName(); +#else + return mx::Type::VECTOR2.getName(); +#endif +} + PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/hdSt/materialXShaderGen.h b/pxr/imaging/hdSt/materialXShaderGen.h index e61bd13a43..46ad7b9160 100644 --- a/pxr/imaging/hdSt/materialXShaderGen.h +++ b/pxr/imaging/hdSt/materialXShaderGen.h @@ -192,6 +192,15 @@ class HdStMaterialXShaderGenMsl MaterialX::ShaderStage& mxStage) const; }; +// helper functions to aid building both MaterialX 1.38.X and 1.39.X +// once MaterialX 1.38.X is no longer required these should likely be removed. +bool mxTypeIsNone(MaterialX::TypeDesc typeDesc); +bool mxTypeIsSurfaceShader(MaterialX::TypeDesc typeDesc); +bool mxTypeDescIsFilename(const MaterialX::TypeDesc typeDesc); +MaterialX::TypeDesc getMxTypeDesc(const std::string& typeName); +const MaterialX::TypeDesc getMxTypeDesc(const MaterialX::ShaderPort* port); +const std::string mxGetTypeString(const MaterialX::TypeDesc mxType, MaterialX::SyntaxPtr syntax); +const std::string& getVector2Name(); PXR_NAMESPACE_CLOSE_SCOPE