Skip to content

Commit

Permalink
[hdMtlx, hdSt] Save the geomprop/primvar default value for use in HdS…
Browse files Browse the repository at this point in the history
…t MaterialXShaderGen

Fixes #1880

(Internal change: 2244565)
  • Loading branch information
klucknav authored and pixar-oss committed Aug 16, 2022
1 parent 59cb83a commit dc27ead
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 86 deletions.
73 changes: 27 additions & 46 deletions pxr/imaging/hdMtlx/hdMtlx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,12 @@ HdMtlxConvertToString(VtValue const& hdParameterValue)
static mx::NodePtr
_AddMaterialXNode(
HdMaterialNetworkInterface *netInterface,
TfToken const &hdNodeName,
TfToken const& hdNodeName,
mx::DocumentPtr const& mxDoc,
mx::NodeGraphPtr const& mxNodeGraph,
mx::StringSet * addedNodeNames,
std::set<SdfPath> * hdTextureNodes,
mx::StringSet *addedNodeNames,
std::string const& connectionName,
mx::StringMap * mxHdTextureMap,
std::set<SdfPath> * hdPrimvarNodes)
HdMtlxTexturePrimvarData *mxHdData)
{
// Get the mxNode information
TfToken hdNodeType = netInterface->GetNodeType(hdNodeName);
Expand Down Expand Up @@ -233,43 +231,40 @@ _AddMaterialXNode(
}
std::string mxInputValue = HdMtlxConvertToString(
netInterface->GetNodeParameterValue(hdNodeName, paramName));

mxNode->setInputValue(mxInputName, mxInputValue, mxInputType);
}

// Stdlib MaterialX Texture node or a custom node that uses a texture
if (mxNodeCategory == "image" || mxNodeCategory == "tiledimage" ||
mxNodeGroup == "textureuser") {
// Save the corresponding MaterialX and Hydra names for ShaderGen
if (mxHdTextureMap) {
(*mxHdTextureMap)[mxNodeName] = connectionName;
}

// Save the path to adjust the parameters after traversing the network
if (hdTextureNodes) {
hdTextureNodes->insert(hdNodePath);
if (mxHdData) {
// Save the corresponding MaterialX and Hydra names for ShaderGen
mxHdData->mxHdTextureMap[mxNodeName] = connectionName;
// Save the path to adjust parameters after traversing the network
mxHdData->hdTextureNodes.insert(hdNodePath);
}
}

// MaterialX primvar node
if (mxNodeCategory == "geompropvalue") {
// Save the path to have the primvarName declared in ShaderGen
if (hdPrimvarNodes) {
hdPrimvarNodes->insert(hdNodePath);
if (mxHdData) {
// Save the path to have the primvarName declared in ShaderGen
mxHdData->hdPrimvarNodes.insert(hdNodePath);
}
}
// Stdlib MaterialX texture coordinate node or a custom node that
// uses texture coordinates
if (mxNodeCategory == "texcoord" || mxNodeGroup == "texcoorduser") {
if (hdPrimvarNodes) {
if (mxHdData) {
// Make sure it has the index parameter set.
if (std::find(hdNodeParamNames.begin(), hdNodeParamNames.end(),
_tokens->index) == hdNodeParamNames.end()) {
netInterface->SetNodeParameterValue(
hdNodeName, _tokens->index, VtValue(0));
}
// Save the path to have the textureCoord name declared in ShaderGen
hdPrimvarNodes->insert(hdNodePath);
mxHdData->hdPrimvarNodes.insert(hdNodePath);
}
}
return mxNode;
Expand Down Expand Up @@ -340,13 +335,11 @@ _GatherUpstreamNodes(
HdMaterialNetworkInterface *netInterface,
HdMaterialNetworkInterface::InputConnection const& hdConnection,
mx::DocumentPtr const& mxDoc,
mx::NodeGraphPtr * mxNodeGraph,
mx::StringSet * addedNodeNames,
mx::NodePtr * mxUpstreamNode,
std::set<SdfPath> * hdTextureNodes,
mx::NodeGraphPtr *mxNodeGraph,
mx::StringSet *addedNodeNames,
mx::NodePtr *mxUpstreamNode,
std::string const& connectionName,
mx::StringMap * mxHdTextureMap,
std::set<SdfPath> * hdPrimvarNodes)
HdMtlxTexturePrimvarData *mxHdData)
{
TfToken const &hdNodeName = hdConnection.upstreamNodeName;
if (netInterface->GetNodeType(hdNodeName).IsEmpty()) {
Expand All @@ -364,10 +357,8 @@ _GatherUpstreamNodes(

// Add the node to the mxNodeGraph/mxDoc.
mx::NodePtr mxCurrNode =
_AddMaterialXNode(netInterface, hdNodeName, mxDoc,
*mxNodeGraph, addedNodeNames, hdTextureNodes,
connectionName, mxHdTextureMap,
hdPrimvarNodes);
_AddMaterialXNode(netInterface, hdNodeName, mxDoc, *mxNodeGraph,
addedNodeNames, connectionName, mxHdData);

if (!mxCurrNode) {
return;
Expand All @@ -384,8 +375,7 @@ _GatherUpstreamNodes(
// Gather the nodes uptream from the mxCurrNode
_GatherUpstreamNodes(
netInterface, currConnection, mxDoc, mxNodeGraph,
addedNodeNames, mxUpstreamNode, hdTextureNodes,
connName.GetString(), mxHdTextureMap, hdPrimvarNodes);
addedNodeNames, mxUpstreamNode, connName.GetString(), mxHdData);

// Connect mxCurrNode to the mxUpstreamNode
mx::NodePtr mxNextNode = *mxUpstreamNode;
Expand Down Expand Up @@ -414,9 +404,7 @@ HdMtlxCreateMtlxDocumentFromHdNetwork(
SdfPath const& hdMaterialXNodePath,
SdfPath const& materialPath,
mx::DocumentPtr const& libraries,
std::set<SdfPath> * hdTextureNodes, // Paths to the Hd Texture Nodes
mx::StringMap * mxHdTextureMap, // Mx-Hd texture name counterparts
std::set<SdfPath> * hdPrimvarNodes) // Paths to the Hd primvar nodes
HdMtlxTexturePrimvarData* mxHdData)
{
// XXX Unfortunate but necessary to cast away constness even though
// hdNetwork isn't modified.
Expand All @@ -430,9 +418,7 @@ HdMtlxCreateMtlxDocumentFromHdNetwork(
terminalNodeName,
netInterface.GetNodeInputConnectionNames(terminalNodeName),
libraries,
hdTextureNodes,
mxHdTextureMap,
hdPrimvarNodes);
mxHdData);
}

// Add parameter inputs for the terminal node (which is a StandardSurface or
Expand Down Expand Up @@ -476,9 +462,7 @@ _CreateMtlxNodeGraphFromTerminalNodeConnections(
TfTokenVector const& terminalNodeConnectionNames,
mx::DocumentPtr const& mxDoc,
mx::NodePtr const& mxShaderNode,
std::set<SdfPath> * hdTextureNodes,
MaterialX::StringMap * mxHdTextureMap,
std::set<SdfPath> * hdPrimvarNodes)
HdMtlxTexturePrimvarData * mxHdData)
{
mx::NodeGraphPtr mxNodeGraph;
mx::StringSet addedNodeNames; // Set of NodeNames in the mxNodeGraph
Expand All @@ -492,8 +476,7 @@ _CreateMtlxNodeGraphFromTerminalNodeConnections(

_GatherUpstreamNodes(
netInterface, currConnection, mxDoc, &mxNodeGraph,
&addedNodeNames, &mxUpstreamNode, hdTextureNodes,
mxNodeGraphOutput, mxHdTextureMap, hdPrimvarNodes);
&addedNodeNames, &mxUpstreamNode, mxNodeGraphOutput, mxHdData);

if (!mxUpstreamNode) {
continue;
Expand Down Expand Up @@ -522,9 +505,7 @@ HdMtlxCreateMtlxDocumentFromHdMaterialNetworkInterface(
TfToken const& terminalNodeName,
TfTokenVector const& terminalNodeConnectionNames,
MaterialX::DocumentPtr const& libraries,
std::set<SdfPath> * hdTextureNodes,
MaterialX::StringMap * mxHdTextureMap,
std::set<SdfPath> * hdPrimvarNodes)
HdMtlxTexturePrimvarData *mxHdData)
{
if (!netInterface) {
return nullptr;
Expand All @@ -546,7 +527,7 @@ HdMtlxCreateMtlxDocumentFromHdMaterialNetworkInterface(

_CreateMtlxNodeGraphFromTerminalNodeConnections(
netInterface, terminalNodeName, terminalNodeConnectionNames,
mxDoc, mxShaderNode, hdTextureNodes, mxHdTextureMap, hdPrimvarNodes);
mxDoc, mxShaderNode, mxHdData);

_AddParameterInputsToTerminalNode(
netInterface,
Expand Down
23 changes: 15 additions & 8 deletions pxr/imaging/hdMtlx/hdMtlx.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,20 @@ HDMTLX_API
std::string
HdMtlxConvertToString(VtValue const& hdParameterValue);

// Storing MaterialX-Hydra texture and primvar information
struct HdMtlxTexturePrimvarData {
HdMtlxTexturePrimvarData()
: mxHdTextureMap(MaterialX::StringMap()), // Mx-Hd texture name mapping
hdTextureNodes(std::set<SdfPath>()), // Paths to HdTexture Nodes
hdPrimvarNodes(std::set<SdfPath>()) {} // Paths to HdPrimvar nodes
MaterialX::StringMap mxHdTextureMap;
std::set<SdfPath> hdTextureNodes;
std::set<SdfPath> hdPrimvarNodes;
};

/// Creates and returns a MaterialX Document from the given HdMaterialNetwork2
/// Collecting the hdTextureNodes as the HdMaterialNetwork2 is traversed as
/// well as the Texture name mapping between MaterialX and Hydra
/// Collecting the hdTextureNodes and hdPrimvarNodes as the network is
/// traversed as well as the Texture name mapping between MaterialX and Hydra.
HDMTLX_API
MaterialX::DocumentPtr
HdMtlxCreateMtlxDocumentFromHdNetwork(
Expand All @@ -71,9 +82,7 @@ HdMtlxCreateMtlxDocumentFromHdNetwork(
SdfPath const& hdMaterialXNodePath,
SdfPath const& materialPath,
MaterialX::DocumentPtr const& libraries,
std::set<SdfPath> * hdTextureNodes = nullptr,
MaterialX::StringMap * mxHdTextureMap = nullptr,
std::set<SdfPath> * hdPrimvarNodes = nullptr);
HdMtlxTexturePrimvarData *mxHdData = nullptr);

/// Implementation that uses the material network interface.
HDMTLX_API
Expand All @@ -83,9 +92,7 @@ HdMtlxCreateMtlxDocumentFromHdMaterialNetworkInterface(
TfToken const& terminalNodeName,
TfTokenVector const& terminalNodeConnectionNames,
MaterialX::DocumentPtr const& libraries,
std::set<SdfPath> * hdTextureNodes = nullptr,
MaterialX::StringMap * mxHdTextureMap = nullptr,
std::set<SdfPath> * hdPrimvarNodes = nullptr);
HdMtlxTexturePrimvarData *mxHdData = nullptr);

PXR_NAMESPACE_CLOSE_SCOPE

Expand Down
43 changes: 27 additions & 16 deletions pxr/imaging/hdSt/materialXFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ TF_DEFINE_PRIVATE_TOKENS(
(texcoord)
(geomprop)
(index)
((defaultInput, "default"))

// Opacity Parameters
(opacity)
Expand Down Expand Up @@ -106,7 +107,7 @@ mx::ShaderPtr
HdSt_GenMaterialXShader(
mx::DocumentPtr const& mxDoc,
mx::FileSearchPath const& searchPath,
MxHdInfo const& mxHdInfo)
HdSt_MxShaderGenInfo const& mxHdInfo)
{
// Initialize the Context for shaderGen.
mx::GenContext mxContext = HdStMaterialXShaderGen::create(mxHdInfo);
Expand Down Expand Up @@ -386,6 +387,7 @@ _UpdateTextureNodes(
HdMaterialNetwork2* hdNetwork,
SdfPath const& hdTerminalNodePath,
std::set<SdfPath> const& hdTextureNodes,
mx::StringMap const& hdMtlxTextureInfo,
mx::StringMap* mxHdTextureMap,
mx::StringMap* mxHdPrimvarMap,
std::string* defaultTexcoordName)
Expand Down Expand Up @@ -415,11 +417,11 @@ _UpdateTextureNodes(
}

// Connect the texture node to the terminal node for HdStMaterialNetwork
// Create a unique name for the new connection, and update the
// mxHdTextureMap with this connection name so Hydra's codegen and
// HdStMaterialXShaderGen match up correctly
// Create a unique name for the new connection, and store in the
// mxHdTextureMap so Hydra's codegen and HdStMaterialXShaderGen
// match up correctly.
std::string newConnName = texturePath.GetName() + "_" +
(*mxHdTextureMap)[texturePath.GetName()];
hdMtlxTextureInfo.find(texturePath.GetName())->second;

// Replace the texturePath.GetName() in the textureMap to the variable
// name used in the shader: textureName_fileInputName
Expand All @@ -433,7 +435,6 @@ _UpdateTextureNodes(
}
}
}
mxHdTextureMap->erase(texturePath.GetName());
mxHdTextureMap->insert(std::pair<std::string, std::string>(
texturePath.GetName() + "_" + fileInputName, newConnName));

Expand All @@ -449,11 +450,12 @@ _UpdateTextureNodes(
// Connect the primvar nodes to the terminal node
static void
_UpdatePrimvarNodes(
mx::DocumentPtr const &mxDoc,
mx::DocumentPtr const& mxDoc,
HdMaterialNetwork2* hdNetwork,
SdfPath const& hdTerminalNodePath,
std::set<SdfPath> const& hdPrimvarNodes,
mx::StringMap* mxHdPrimvarMap)
mx::StringMap* mxHdPrimvarMap,
mx::StringMap* mxHdPrimvarDefaultValueMap)
{
for (auto const& primvarPath : hdPrimvarNodes) {
HdMaterialNode2 hdPrimvarNode = hdNetwork->nodes[primvarPath];
Expand All @@ -470,6 +472,16 @@ _UpdatePrimvarNodes(
if (mxNodeDef) {
(*mxHdPrimvarMap)[primvarName] = mxNodeDef->getType();
}

// Get the Default value if authored
std::string defaultPrimvarValue;
const auto defaultPrimvarValueIt =
hdPrimvarNode.parameters.find(_tokens->defaultInput);
if (hdPrimvarNode.parameters.end() != defaultPrimvarValueIt) {
defaultPrimvarValue =
HdMtlxConvertToString(defaultPrimvarValueIt->second);
}
(*mxHdPrimvarDefaultValueMap)[primvarName] = defaultPrimvarValue;
}

// Texcoord nodes will have an index parameter set
Expand Down Expand Up @@ -679,31 +691,30 @@ HdSt_ApplyMaterialXFilter(
mx::loadLibraries(libraryFolders, searchPath, stdLibraries);

// Create the MaterialX Document from the HdMaterialNetwork
MxHdInfo mxHdInfo; // Hydra information for MaterialX glslfx shaderGen
std::set<SdfPath> hdTextureNodes;
std::set<SdfPath> hdPrimvarNodes;
HdSt_MxShaderGenInfo mxHdInfo;
HdMtlxTexturePrimvarData hdMtlxData;
mx::DocumentPtr mtlxDoc = HdMtlxCreateMtlxDocumentFromHdNetwork(
*hdNetwork,
terminalNode, // MaterialX HdNode
terminalNodePath,
materialPath,
stdLibraries,
&hdTextureNodes,
&mxHdInfo.textureMap,
&hdPrimvarNodes);
&hdMtlxData);

// Add a Fallback DomeLight texture node to make sure the indirect
// light computations always has a texture to sample from
_AddFallbackDomeLightTextureNode(
hdNetwork, terminalNodePath, &mxHdInfo.textureMap);

// Add Hydra parameters for each of the Texture nodes
_UpdateTextureNodes(mtlxDoc, hdNetwork, terminalNodePath, hdTextureNodes,
_UpdateTextureNodes(mtlxDoc, hdNetwork, terminalNodePath,
hdMtlxData.hdTextureNodes, hdMtlxData.mxHdTextureMap,
&mxHdInfo.textureMap, &mxHdInfo.primvarMap,
&mxHdInfo.defaultTexcoordName);

_UpdatePrimvarNodes(mtlxDoc, hdNetwork, terminalNodePath,
hdPrimvarNodes, &mxHdInfo.primvarMap);
hdMtlxData.hdPrimvarNodes, &mxHdInfo.primvarMap,
&mxHdInfo.primvarDefaultValueMap);

mxHdInfo.materialTag = _GetMaterialTag(terminalNode);
mxHdInfo.bindlessTexturesEnabled = bindlessTexturesEnabled;
Expand Down
8 changes: 5 additions & 3 deletions pxr/imaging/hdSt/materialXFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,17 @@
PXR_NAMESPACE_OPEN_SCOPE

// Storing MaterialX-Hydra counterparts and other Hydra specific information
struct MxHdInfo {
MxHdInfo()
struct HdSt_MxShaderGenInfo {
HdSt_MxShaderGenInfo()
: textureMap(MaterialX::StringMap()),
primvarMap(MaterialX::StringMap()),
primvarDefaultValueMap(MaterialX::StringMap()),
defaultTexcoordName("st"),
materialTag(HdStMaterialTagTokens->defaultMaterialTag.GetString()),
bindlessTexturesEnabled(false) {}
MaterialX::StringMap textureMap;
MaterialX::StringMap primvarMap;
MaterialX::StringMap primvarDefaultValueMap;
std::string defaultTexcoordName;
std::string materialTag;
bool bindlessTexturesEnabled;
Expand All @@ -64,7 +66,7 @@ void HdSt_ApplyMaterialXFilter(
MaterialX::ShaderPtr HdSt_GenMaterialXShader(
MaterialX::DocumentPtr const& mxDoc,
MaterialX::FileSearchPath const& searchPath,
MxHdInfo const& mxHdInfo=MxHdInfo());
HdSt_MxShaderGenInfo const& mxHdInfo=HdSt_MxShaderGenInfo());

PXR_NAMESPACE_CLOSE_SCOPE

Expand Down
Loading

0 comments on commit dc27ead

Please sign in to comment.