From 62055fdafa988197a358be9da7a48b17a006248d Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Mon, 29 Jul 2024 11:28:43 -0400 Subject: [PATCH 1/3] Add hints support. --- libraries/bxdf/open_pbr_surface.mtlx | 4 +-- .../surfaceshader/transparency_hints.mtlx | 15 +++++++++ source/MaterialXCore/Definition.cpp | 13 ++++++++ source/MaterialXCore/Definition.h | 7 ++++ source/MaterialXCore/Interface.cpp | 4 +++ source/MaterialXCore/Interface.h | 26 +++++++++++++++ source/MaterialXGenShader/Util.cpp | 33 ++++++++++++++----- 7 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 resources/Materials/TestSuite/pbrlib/surfaceshader/transparency_hints.mtlx diff --git a/libraries/bxdf/open_pbr_surface.mtlx b/libraries/bxdf/open_pbr_surface.mtlx index 8186482cf8..f80bc652e4 100644 --- a/libraries/bxdf/open_pbr_surface.mtlx +++ b/libraries/bxdf/open_pbr_surface.mtlx @@ -24,7 +24,7 @@ + doc="Mixture weight between the transparent and opaque dielectric base. The greater the value the more transparent the material." hint="transparency"/> + doc="The opacity of the entire material." hint="opacity"/> + + + + + + + + + + + + + + diff --git a/source/MaterialXCore/Definition.cpp b/source/MaterialXCore/Definition.cpp index 842330c95c..9bbaefb16a 100644 --- a/source/MaterialXCore/Definition.cpp +++ b/source/MaterialXCore/Definition.cpp @@ -100,6 +100,19 @@ InterfaceElementPtr NodeDef::getImplementation(const string& target) const return InterfaceElementPtr(); } +const StringMap NodeDef::getInputHints() const +{ + StringMap hints; + for (InputPtr input : getActiveInputs()) + { + if (input->hasHint()) + { + hints[input->getName()] = input->getHint(); + } + } + return hints; +} + bool NodeDef::validate(string* message) const { bool res = true; diff --git a/source/MaterialXCore/Definition.h b/source/MaterialXCore/Definition.h index 9ec7251221..e3aecbe24a 100644 --- a/source/MaterialXCore/Definition.h +++ b/source/MaterialXCore/Definition.h @@ -146,6 +146,13 @@ class MX_CORE_API NodeDef : public InterfaceElement /// an Implementation element or a NodeGraph element. InterfaceElementPtr getImplementation(const string& target = EMPTY_STRING) const; + /// @} + /// @name Hints + /// @{ + + /// Return list of input hint pairs of the form { input_name, hint_string } + const StringMap getInputHints() const; + /// @} /// @name Validation /// @{ diff --git a/source/MaterialXCore/Interface.cpp b/source/MaterialXCore/Interface.cpp index 6b200a8dcf..24d3ccfe0d 100644 --- a/source/MaterialXCore/Interface.cpp +++ b/source/MaterialXCore/Interface.cpp @@ -20,6 +20,10 @@ const string InterfaceElement::TARGET_ATTRIBUTE = "target"; const string InterfaceElement::VERSION_ATTRIBUTE = "version"; const string InterfaceElement::DEFAULT_VERSION_ATTRIBUTE = "isdefaultversion"; const string Input::DEFAULT_GEOM_PROP_ATTRIBUTE = "defaultgeomprop"; +const string Input::HINT_ATTRIBUTE = "hint"; +const string Input::TRANSPARENCY_HINT = "transparency"; +const string Input::OPACITY_HINT = "opacity"; +const string Input::ANISOTROPY_HINT = "anisotropy"; const string Output::DEFAULT_INPUT_ATTRIBUTE = "defaultinput"; // diff --git a/source/MaterialXCore/Interface.h b/source/MaterialXCore/Interface.h index 39fd888b94..599f85ed9d 100644 --- a/source/MaterialXCore/Interface.h +++ b/source/MaterialXCore/Interface.h @@ -219,6 +219,28 @@ class MX_CORE_API Input : public PortElement /// for this input. InputPtr getInterfaceInput() const; + /// @} + /// @name Hints + /// @{ + + /// Return true if the input has a hint + bool hasHint() const + { + return hasAttribute(HINT_ATTRIBUTE); + } + + /// Return the code generation hint + const string& getHint() const + { + return getAttribute(HINT_ATTRIBUTE); + } + + // Set the code generation hint + void setHint(const string& hint) + { + setAttribute(HINT_ATTRIBUTE, hint); + } + /// @} /// @name Validation /// @{ @@ -232,6 +254,10 @@ class MX_CORE_API Input : public PortElement public: static const string CATEGORY; static const string DEFAULT_GEOM_PROP_ATTRIBUTE; + static const string HINT_ATTRIBUTE; + static const string TRANSPARENCY_HINT; + static const string OPACITY_HINT; + static const string ANISOTROPY_HINT; }; /// @class Output diff --git a/source/MaterialXGenShader/Util.cpp b/source/MaterialXGenShader/Util.cpp index 9722952390..bda7dafb5b 100644 --- a/source/MaterialXGenShader/Util.cpp +++ b/source/MaterialXGenShader/Util.cpp @@ -16,10 +16,10 @@ using OpaqueTestPair = std::pair; using OpaqueTestPairList = vector; // Inputs on a surface shader which are checked for transparency -const OpaqueTestPairList inputPairList = { { "opacity", 1.0f }, - { "existence", 1.0f }, - { "alpha", 1.0f }, - { "transmission", 0.0f } }; +const OpaqueTestPairList DEFAULT_INPUT_PAIR_LIST = { { "opacity", 1.0f }, + { "existence", 1.0f }, + { "alpha", 1.0f }, + { "transmission", 0.0f } }; const string MIX_CATEGORY("mix"); const string MIX_FG_INPUT("fg"); @@ -116,11 +116,28 @@ bool isTransparentShaderNode(NodePtr node, NodePtr interfaceNode) return false; } + // Check against nodedef input hints + OpaqueTestPairList testList = DEFAULT_INPUT_PAIR_LIST; + NodeDefPtr nodeDef = node->getNodeDef(); + StringMap nodeDefList = nodeDef ? nodeDef->getInputHints() : StringMap(); + for (auto &item : nodeDefList) + { + string inputName = item.first; + if (item.second == Input::TRANSPARENCY_HINT) + { + testList.push_back(std::make_pair(inputName, 0.0f) ); + } + else if (item.second == Input::OPACITY_HINT) + { + testList.push_back(std::make_pair(inputName, 1.0f)); + } + } + // Check against the interface if a node is passed in to check against OpaqueTestPairList interfaceNames; if (interfaceNode) { - for (auto inputPair : inputPairList) + for (auto inputPair : testList) { InputPtr checkInput = node->getActiveInput(inputPair.first); if (checkInput) @@ -144,7 +161,7 @@ bool isTransparentShaderNode(NodePtr node, NodePtr interfaceNode) // Check against the child input or the corresponding // functional nodegraph's interface if the input is mapped // via an interface name. - for (auto inputPair : inputPairList) + for (auto inputPair : testList) { InputPtr checkInput = node->getActiveInput(inputPair.first); if (checkInput) @@ -167,8 +184,8 @@ bool isTransparentShaderNode(NodePtr node, NodePtr interfaceNode) NodePtr inputNode = checkInput->getConnectedNode(); if (inputNode) { - NodeDefPtr nodeDef = inputNode->getNodeDef(); - string nodeGroup = nodeDef ? nodeDef->getAttribute(NodeDef::NODE_GROUP_ATTRIBUTE) : EMPTY_STRING; + NodeDefPtr inputNodeDef = inputNode->getNodeDef(); + string nodeGroup = inputNodeDef ? inputNodeDef->getAttribute(NodeDef::NODE_GROUP_ATTRIBUTE) : EMPTY_STRING; if (nodeGroup != NodeDef::ADJUSTMENT_NODE_GROUP && nodeGroup != NodeDef::CHANNEL_NODE_GROUP) { From c3bd2d929db9f64e367716ff84596e880e440e9a Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Thu, 1 Aug 2024 08:47:16 -0700 Subject: [PATCH 2/3] Minor formatting update --- libraries/bxdf/open_pbr_surface.mtlx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/bxdf/open_pbr_surface.mtlx b/libraries/bxdf/open_pbr_surface.mtlx index f80bc652e4..87084bf7fe 100644 --- a/libraries/bxdf/open_pbr_surface.mtlx +++ b/libraries/bxdf/open_pbr_surface.mtlx @@ -23,8 +23,8 @@ doc="Index of refraction of the dielectric base." /> - + - + Date: Thu, 1 Aug 2024 08:52:11 -0700 Subject: [PATCH 3/3] Restore variable name --- source/MaterialXGenShader/Util.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/MaterialXGenShader/Util.cpp b/source/MaterialXGenShader/Util.cpp index bda7dafb5b..af34fa1b2a 100644 --- a/source/MaterialXGenShader/Util.cpp +++ b/source/MaterialXGenShader/Util.cpp @@ -117,7 +117,7 @@ bool isTransparentShaderNode(NodePtr node, NodePtr interfaceNode) } // Check against nodedef input hints - OpaqueTestPairList testList = DEFAULT_INPUT_PAIR_LIST; + OpaqueTestPairList inputPairList = DEFAULT_INPUT_PAIR_LIST; NodeDefPtr nodeDef = node->getNodeDef(); StringMap nodeDefList = nodeDef ? nodeDef->getInputHints() : StringMap(); for (auto &item : nodeDefList) @@ -125,11 +125,11 @@ bool isTransparentShaderNode(NodePtr node, NodePtr interfaceNode) string inputName = item.first; if (item.second == Input::TRANSPARENCY_HINT) { - testList.push_back(std::make_pair(inputName, 0.0f) ); + inputPairList.push_back(std::make_pair(inputName, 0.0f) ); } else if (item.second == Input::OPACITY_HINT) { - testList.push_back(std::make_pair(inputName, 1.0f)); + inputPairList.push_back(std::make_pair(inputName, 1.0f)); } } @@ -137,7 +137,7 @@ bool isTransparentShaderNode(NodePtr node, NodePtr interfaceNode) OpaqueTestPairList interfaceNames; if (interfaceNode) { - for (auto inputPair : testList) + for (auto inputPair : inputPairList) { InputPtr checkInput = node->getActiveInput(inputPair.first); if (checkInput) @@ -161,7 +161,7 @@ bool isTransparentShaderNode(NodePtr node, NodePtr interfaceNode) // Check against the child input or the corresponding // functional nodegraph's interface if the input is mapped // via an interface name. - for (auto inputPair : testList) + for (auto inputPair : inputPairList) { InputPtr checkInput = node->getActiveInput(inputPair.first); if (checkInput)