Skip to content

Commit 82a2f3f

Browse files
klucknavpixar-oss
authored andcommitted
Allow for USD to be run with either MaterialX 1.38 or 1.39
MaterialX 1.39 introduced API changes, this change allows USD to be built against either MaterialX 1.38 or 1.39. Most of the changed arise from an API change around `MaterialX::TypeDesc` being passed by value instead of pointer. The other change is the complete removal of the `channels` attribute. This change also includes a fix for v1.39 and adds a calculation of the bitangent vector used in preview surface materials in v1.39. Additionaly when running v1.38 nodes with v1.39 there were some nodes that changed either their input names or nodedef name between these two versions. This change has fixes to make sure those nodes are still accurately rendered. (based on github pull request #3159) Fixes #3159 (Internal change: 2352303)
1 parent 4c880b5 commit 82a2f3f

12 files changed

+240
-89
lines changed

pxr/imaging/hdSt/materialXFilter.cpp

Lines changed: 72 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ TF_DEFINE_PRIVATE_TOKENS(
107107
(convert)
108108
// Constants: they get inlined in the source.
109109
(constant)
110+
111+
// Atan2 Nodes are Not topological but their inputs change between v1.38
112+
// and v1.39 so we need to include them in the the annonymize network
113+
// otherwise the generated shader will not have the correct values.
114+
(atan2)
110115
);
111116

112117
TF_DEFINE_PRIVATE_TOKENS(
@@ -510,7 +515,8 @@ _UpdatePrimvarNodes(
510515
texCoordName = metadata[SdrNodeMetadata->Primvars];
511516
}
512517

513-
(*mxHdPrimvarMap)[texCoordName] = mx::Type::VECTOR2->getName();
518+
(*mxHdPrimvarMap)[texCoordName] =
519+
HdStMaterialXHelpers::GetVector2Name();
514520
}
515521
}
516522
}
@@ -628,26 +634,41 @@ _GetGlTFSurfaceMaterialTag(HdMaterialNode2 const& terminal)
628634
return materialToken.GetString();
629635
}
630636

631-
static const mx::TypeDesc*
637+
static const mx::TypeDesc
632638
_GetMxTypeDescription(std::string const& typeName)
633639
{
640+
#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38
641+
using MxTypeDesc = const mx::TypeDesc*;
642+
#else
643+
using MxTypeDesc = const mx::TypeDesc;
644+
#endif
645+
634646
// Add whatever is necessary for current codebase:
635-
static const auto _typeLibrary =
636-
std::map<std::string, const mx::TypeDesc*>{
637-
{"float", mx::Type::FLOAT},
638-
{"color3", mx::Type::COLOR3},
639-
{"color4", mx::Type::COLOR4},
640-
{"vector2", mx::Type::VECTOR2},
641-
{"vector3", mx::Type::VECTOR3},
642-
{"vector4", mx::Type::VECTOR4},
643-
{"surfaceshader", mx::Type::SURFACESHADER}
644-
};
647+
static const auto _typeLibrary =
648+
std::map<std::string, MxTypeDesc>{
649+
{"float", mx::Type::FLOAT},
650+
{"color3", mx::Type::COLOR3},
651+
{"color4", mx::Type::COLOR4},
652+
{"vector2", mx::Type::VECTOR2},
653+
{"vector3", mx::Type::VECTOR3},
654+
{"vector4", mx::Type::VECTOR4},
655+
{"surfaceshader", mx::Type::SURFACESHADER}
656+
};
645657

646658
const auto typeDescIt = _typeLibrary.find(typeName);
647659
if (typeDescIt != _typeLibrary.end()) {
648-
return typeDescIt->second;
649-
}
650-
return nullptr;
660+
#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38
661+
return *typeDescIt->second;
662+
#else
663+
return typeDescIt->second;
664+
#endif
665+
}
666+
667+
#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION <= 38
668+
return *mx::Type::NONE;
669+
#else
670+
return mx::Type::NONE;
671+
#endif
651672
}
652673

653674
// This function adds a stripped down version of the surfaceshader node to the
@@ -672,14 +693,14 @@ _AddStrippedSurfaceNode(
672693
if (!mxInputDef) {
673694
continue;
674695
}
675-
auto const* mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType());
676-
if (!mxTypeDesc) {
696+
auto const mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType());
697+
if (HdStMaterialXHelpers::MxTypeIsNone(mxTypeDesc)) {
677698
continue;
678699
}
679700
// If hdNode is connected to the surfaceshader node, recursively call
680701
// this function to make sure that surfaceshader node is added to
681702
// the mxDocument
682-
if (mxTypeDesc == mx::Type::SURFACESHADER) {
703+
if (HdStMaterialXHelpers::MxTypeIsSurfaceShader(mxTypeDesc)) {
683704
auto const& hdConnectedPath = connIt.second.front().upstreamNode;
684705
auto const& hdConnectedNode = hdNetwork.nodes.at(hdConnectedPath);
685706
mx::NodePtr mxConnectedNode =
@@ -690,14 +711,14 @@ _AddStrippedSurfaceNode(
690711
mxInput->setConnectedNode(mxConnectedNode);
691712
}
692713
// Add the connection as an input with each component set to 0.5
693-
else if (mxTypeDesc->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT &&
694-
mxTypeDesc->getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) {
714+
else if (mxTypeDesc.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT &&
715+
mxTypeDesc.getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) {
695716
std::string valueStr = "0.5";
696-
for (size_t i = 1; i < mxTypeDesc->getSize(); ++i) {
717+
for (size_t i = 1; i < mxTypeDesc.getSize(); ++i) {
697718
valueStr += ", 0.5";
698719
}
699720
mx::InputPtr mxInput =
700-
mxNode->addInput(mxInputDef->getName(), mxInputDef->getType());
721+
mxNode->addInputFromNodeDef(mxInputDef->getName());
701722
mxInput->setValueString(valueStr);
702723
}
703724
}
@@ -709,16 +730,16 @@ _AddStrippedSurfaceNode(
709730
if (!mxInputDef) {
710731
continue;
711732
}
712-
auto const* mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType());
713-
if (!mxTypeDesc) {
733+
auto const mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType());
734+
if (HdStMaterialXHelpers::MxTypeIsNone(mxTypeDesc)) {
714735
continue;
715736
}
716737

717-
if (mxTypeDesc->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT &&
718-
mxTypeDesc->getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) {
738+
if (mxTypeDesc.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT &&
739+
mxTypeDesc.getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) {
719740
// Add the parameter as an input to the mxNode in the mx Document
720741
mx::InputPtr mxInput =
721-
mxNode->addInput(mxInputDef->getName(), mxInputDef->getType());
742+
mxNode->addInputFromNodeDef(mxInputDef->getName());
722743
mxInput->setValueString(HdMtlxConvertToString(paramIt.second));
723744
}
724745
}
@@ -781,9 +802,9 @@ _GetMaterialTag(
781802
// Outputting anything that is not a surfaceshader will be
782803
// considered opaque, unless outputting a color4 or vector4.
783804
// XXX This is not fully per USD specs, but is supported by MaterialX.
784-
auto const* typeDesc =
805+
auto const typeDesc =
785806
_GetMxTypeDescription(activeOutputs.back()->getType());
786-
if (typeDesc == mx::Type::COLOR4 || typeDesc == mx::Type::VECTOR4) {
807+
if (typeDesc.isFloat4()) {
787808
return HdStMaterialTagTokens->translucent.GetString();
788809
}
789810
return HdStMaterialTagTokens->defaultMaterialTag.GetString();
@@ -1094,7 +1115,7 @@ _AddMaterialXParams(
10941115

10951116
// MaterialX parameter Information
10961117
const auto* variable = paramsBlock[i];
1097-
const auto varType = variable->getType();
1118+
const auto varType = HdStMaterialXHelpers::GetMxTypeDesc(variable);
10981119

10991120
// Create a corresponding HdSt_MaterialParam
11001121
HdSt_MaterialParam param;
@@ -1105,65 +1126,69 @@ _AddMaterialXParams(
11051126
const auto paramValueIt =
11061127
mxParamNameToValue.find(variable->getVariable());
11071128
if (paramValueIt != mxParamNameToValue.end()) {
1108-
if (varType->getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN ||
1109-
varType->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT ||
1110-
varType->getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) {
1129+
if (varType.getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN ||
1130+
varType.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT ||
1131+
varType.getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) {
11111132
param.fallbackValue = paramValueIt->second;
11121133
}
11131134
}
11141135
// If it was not found in the mapping use the value from the MaterialX
11151136
// variable to get the value.
1137+
// Note that if the network was upgraded in Hdmtlx, and the node's
1138+
// parameter names changed they will not be found through the above
1139+
// mapping and instead need to be found from the variables in the
1140+
// MaterialX glslfxShader.
11161141
else {
11171142
std::string separator;
11181143
const auto varValue = variable->getValue();
11191144
std::istringstream valueStream(varValue
11201145
? varValue->getValueString() : std::string());
1121-
if (varType->getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN) {
1146+
if (varType.getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN) {
11221147
const bool val = valueStream.str() == "true";
11231148
param.fallbackValue = VtValue(val);
11241149
}
1125-
else if (varType->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT) {
1126-
if (varType->getSize() == 1) {
1150+
else if (varType.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT) {
1151+
if (varType.getSize() == 1) {
11271152
float val;
11281153
valueStream >> val;
11291154
param.fallbackValue = VtValue(val);
11301155
}
1131-
else if (varType->getSize() == 2) {
1156+
else if (varType.getSize() == 2) {
11321157
GfVec2f val;
11331158
valueStream >> val[0] >> separator >> val[1];
11341159
param.fallbackValue = VtValue(val);
11351160
}
1136-
else if (varType->getSize() == 3) {
1161+
else if (varType.getSize() == 3) {
11371162
GfVec3f val;
11381163
valueStream >> val[0] >> separator >> val[1] >> separator
11391164
>> val[2];
11401165
param.fallbackValue = VtValue(val);
11411166
}
1142-
else if (varType->getSize() == 4) {
1167+
else if (varType.getSize() == 4) {
11431168
GfVec4f val;
11441169
valueStream >> val[0] >> separator >> val[1] >> separator
11451170
>> val[2] >> separator >> val[3];
11461171
param.fallbackValue = VtValue(val);
11471172
}
11481173
}
1149-
else if (varType->getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) {
1150-
if (varType->getSize() == 1) {
1174+
else if (varType.getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) {
1175+
if (varType.getSize() == 1) {
11511176
int val;
11521177
valueStream >> val;
11531178
param.fallbackValue = VtValue(val);
11541179
}
1155-
else if (varType->getSize() == 2) {
1180+
else if (varType.getSize() == 2) {
11561181
GfVec2i val;
11571182
valueStream >> val[0] >> separator >> val[1];
11581183
param.fallbackValue = VtValue(val);
11591184
}
1160-
else if (varType->getSize() == 3) {
1185+
else if (varType.getSize() == 3) {
11611186
GfVec3i val;
11621187
valueStream >> val[0] >> separator >> val[1] >> separator
11631188
>> val[2];
11641189
param.fallbackValue = VtValue(val);
11651190
}
1166-
else if (varType->getSize() == 4) {
1191+
else if (varType.getSize() == 4) {
11671192
GfVec4i val;
11681193
valueStream >> val[0] >> separator >> val[1] >> separator
11691194
>> val[2] >> separator >> val[3];
@@ -1177,7 +1202,7 @@ _AddMaterialXParams(
11771202
}
11781203

11791204
// For filename inputs, manage the associated texture node
1180-
if (varType->getSemantic() == mx::TypeDesc::SEMANTIC_FILENAME) {
1205+
if (varType.getSemantic() == mx::TypeDesc::SEMANTIC_FILENAME) {
11811206
// Get the anonymized MaterialX node name from the param name
11821207
// annonNodeName_paramName -> annonNodeName
11831208
std::string mxNodeName = variable->getVariable();
@@ -1335,11 +1360,11 @@ size_t _BuildEquivalentMaterialNetwork(
13351360
// Parameters that are color managed are also topological as they
13361361
// result in different nodes being added in the MaterialX graph
13371362
for (const auto& param: inNode.parameters) {
1363+
// If this parameter is used to indicate a colorspace on a
1364+
// color managed input, find and add that corresponding input
13381365
const auto colorManagedInput =
13391366
SdfPath::StripPrefixNamespace(param.first.GetString(),
13401367
SdfFieldKeys->ColorSpace);
1341-
// If this parameter is to indicate a colorspace on a color
1342-
// managed input, find and add that corresponding input
13431368
if (colorManagedInput.second) {
13441369
outNode.parameters.insert(param);
13451370

0 commit comments

Comments
 (0)