From 65dbd3937db8093011b825e9e5bf0b9ae9757abf Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Thu, 14 Nov 2024 10:31:09 -0500 Subject: [PATCH 1/9] Skip comments in functional equivalence tests (#2110) Skip `comment` blocks when checking for functional equivalency as they should not affect the comparison. --- source/MaterialXCore/Element.cpp | 22 ++++++++++++++++--- .../MaterialXTest/MaterialXCore/Document.cpp | 8 +++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/source/MaterialXCore/Element.cpp b/source/MaterialXCore/Element.cpp index 648d7df000..043d6f4092 100644 --- a/source/MaterialXCore/Element.cpp +++ b/source/MaterialXCore/Element.cpp @@ -426,9 +426,25 @@ bool Element::isEquivalent(ConstElementPtr rhs, const ElementEquivalenceOptions& } } - // Compare children. - const vector& children = getChildren(); - const vector& rhsChildren = rhs->getChildren(); + // Compare all child elements that affect functional equivalence. + vector children; + for (ElementPtr child : getChildren()) + { + if (child->getCategory() == CommentElement::CATEGORY) + { + continue; + } + children.push_back(child); + } + vector rhsChildren; + for (ElementPtr child : rhs->getChildren()) + { + if (child->getCategory() == CommentElement::CATEGORY) + { + continue; + } + rhsChildren.push_back(child); + } if (children.size() != rhsChildren.size()) { if (results) diff --git a/source/MaterialXTest/MaterialXCore/Document.cpp b/source/MaterialXTest/MaterialXCore/Document.cpp index ae7623084e..f3a207fc84 100644 --- a/source/MaterialXTest/MaterialXCore/Document.cpp +++ b/source/MaterialXTest/MaterialXCore/Document.cpp @@ -150,6 +150,9 @@ TEST_CASE("Document equivalence", "[document]") unsigned int index = 0; mx::ElementPtr child = doc->addNodeGraph("mygraph"); mx::NodeGraphPtr graph = child->asA(); + // Add comment block at the start of the first doc to check skipping + mx::ElementPtr comment = doc->addChildOfCategory(mx::CommentElement::CATEGORY); + comment->setDocString("Comment 1"); for (auto it = inputMap.begin(); it != inputMap.end(); ++it) { const std::string inputType = (*it).first; @@ -205,6 +208,11 @@ TEST_CASE("Document equivalence", "[document]") input->setName("input_" + inputType); } } + // Add comment blocks at end of second doc to check value and count checks + comment = doc2->addChildOfCategory(mx::CommentElement::CATEGORY); + comment->setDocString("Comment 2"); + comment = doc2->addChildOfCategory(mx::CommentElement::CATEGORY); + comment->setDocString("Comment 3"); mx::ElementEquivalenceOptions options; mx::ElementEquivalenceResultVec results; From a368aac8ccc4f8cf7a9d1d5189826b040eced893 Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Sat, 16 Nov 2024 18:27:38 -0500 Subject: [PATCH 2/9] Cleanup options for equivalence testing (#2115) User facing naming changes for the functional equivalence API. There are no logic changes. --- source/MaterialXCore/Element.cpp | 12 +++--- source/MaterialXCore/Element.h | 37 +++++++++---------- .../MaterialXTest/MaterialXCore/Document.cpp | 12 +++--- .../PyMaterialX/PyMaterialXCore/PyElement.cpp | 8 ++-- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/source/MaterialXCore/Element.cpp b/source/MaterialXCore/Element.cpp index 043d6f4092..3bede2fe74 100644 --- a/source/MaterialXCore/Element.cpp +++ b/source/MaterialXCore/Element.cpp @@ -396,14 +396,14 @@ bool Element::isEquivalent(ConstElementPtr rhs, const ElementEquivalenceOptions& StringVec rhsAttributeNames = rhs->getAttributeNames(); // Filter out any attributes specified in the options. - const StringSet& skipAttributes = options.skipAttributes; - if (!skipAttributes.empty()) + const StringSet& attributeExclusionList = options.attributeExclusionList; + if (!attributeExclusionList.empty()) { attributeNames.erase(std::remove_if(attributeNames.begin(), attributeNames.end(), - [&skipAttributes](const string& attr) { return skipAttributes.find(attr) != skipAttributes.end(); }), + [&attributeExclusionList](const string& attr) { return attributeExclusionList.find(attr) != attributeExclusionList.end(); }), attributeNames.end()); rhsAttributeNames.erase(std::remove_if(rhsAttributeNames.begin(), rhsAttributeNames.end(), - [&skipAttributes](const string& attr) { return skipAttributes.find(attr) != skipAttributes.end(); }), + [&attributeExclusionList](const string& attr) { return attributeExclusionList.find(attr) != attributeExclusionList.end(); }), rhsAttributeNames.end()); } @@ -714,7 +714,7 @@ bool ValueElement::isAttributeEquivalent(ConstElementPtr rhs, const string& attr { // Perform value comparisons bool performedValueComparison = false; - if (!options.skipValueComparisons) + if (options.performValueComparisons) { const StringSet uiAttributes = { @@ -724,7 +724,7 @@ bool ValueElement::isAttributeEquivalent(ConstElementPtr rhs, const string& attr }; // Get precision and format options - ScopedFloatFormatting fmt(options.format, options.precision); + ScopedFloatFormatting fmt(options.floatFormat, options.floatPrecision); ConstValueElementPtr rhsValueElement = rhs->asA(); diff --git a/source/MaterialXCore/Element.h b/source/MaterialXCore/Element.h index fb4bbe07ce..05eb2235f3 100644 --- a/source/MaterialXCore/Element.h +++ b/source/MaterialXCore/Element.h @@ -1389,34 +1389,33 @@ class MX_CORE_API ElementEquivalenceOptions public: ElementEquivalenceOptions() { - format = Value::getFloatFormat(); - precision = Value::getFloatPrecision(); - skipAttributes = {}; - skipValueComparisons = false; + performValueComparisons = true; + floatFormat = Value::getFloatFormat(); + floatPrecision = Value::getFloatPrecision(); + attributeExclusionList = {}; }; ~ElementEquivalenceOptions() { } - /// Floating point format option for floating point value comparisons - Value::FloatFormat format; + /// Perform value comparisons as opposed to literal string comparisons. + /// Default is true. + bool performValueComparisons; - /// Floating point precision option for floating point value comparisons - int precision; + /// Floating point format to use for floating point value comparisons + Value::FloatFormat floatFormat; - /// Attribute filtering options. By default all attributes are considered. - /// Name, category attributes cannot be skipped. + /// Floating point precision to use for floating point value comparisons + int floatPrecision; + + /// Specifies the set of attributes that should be excluded when performing a comparison. + /// By default all attributes are considered. Name and category attributes cannot be excluded. /// - /// For example UI attribute comparision be skipped by setting: - /// skipAttributes = { + /// For example, to exclude UI and documentation attributes from consideration the follow may be set: + /// attributeExclusionList = { /// ValueElement::UI_MIN_ATTRIBUTE, ValueElement::UI_MAX_ATTRIBUTE, /// ValueElement::UI_SOFT_MIN_ATTRIBUTE, ValueElement::UI_SOFT_MAX_ATTRIBUTE, /// ValueElement::UI_STEP_ATTRIBUTE, Element::XPOS_ATTRIBUTE, - /// Element::YPOS_ATTRIBUTE }; - StringSet skipAttributes; - - /// Do not perform any value comparisions. Instead perform exact string comparisons for attributes - /// Default is false. The operator==() method can be used instead as it always performs - /// a strict comparison. Default is false. - bool skipValueComparisons; + /// Element::YPOS_ATTRIBUTE, Element::DOC_ATTRIBUTE }; + StringSet attributeExclusionList; }; /// @class ExceptionOrphanedElement diff --git a/source/MaterialXTest/MaterialXCore/Document.cpp b/source/MaterialXTest/MaterialXCore/Document.cpp index f3a207fc84..b593969ccb 100644 --- a/source/MaterialXTest/MaterialXCore/Document.cpp +++ b/source/MaterialXTest/MaterialXCore/Document.cpp @@ -217,27 +217,27 @@ TEST_CASE("Document equivalence", "[document]") mx::ElementEquivalenceOptions options; mx::ElementEquivalenceResultVec results; - // Check skipping all value compares - options.skipValueComparisons = true; + // Check that this fails when not performing value comparisons + options.performValueComparisons = false; bool equivalent = doc->isEquivalent(doc2, options, &results); REQUIRE(!equivalent); // Check attibute values - options.skipValueComparisons = false; + options.performValueComparisons = true; results.clear(); equivalent = doc->isEquivalent(doc2, options, &results); REQUIRE(equivalent); unsigned int currentPrecision = mx::Value::getFloatPrecision(); // This will compare 0.012345608 versus: 1, 0.012345611 for input10 - options.precision = 8; + options.floatPrecision = 8; equivalent = doc->isEquivalent(doc2, options); REQUIRE(!equivalent); - options.precision = currentPrecision; + options.floatPrecision = currentPrecision; // Check attribute filtering of inputs results.clear(); - options.skipAttributes = { mx::ValueElement::UI_MIN_ATTRIBUTE, mx::ValueElement::UI_MAX_ATTRIBUTE }; + options.attributeExclusionList = { mx::ValueElement::UI_MIN_ATTRIBUTE, mx::ValueElement::UI_MAX_ATTRIBUTE }; for (mx::InputPtr floatInput : floatInputs) { floatInput->setAttribute(mx::ValueElement::UI_MIN_ATTRIBUTE, "0.9"); diff --git a/source/PyMaterialX/PyMaterialXCore/PyElement.cpp b/source/PyMaterialX/PyMaterialXCore/PyElement.cpp index cb70d04704..004fa0a670 100644 --- a/source/PyMaterialX/PyMaterialXCore/PyElement.cpp +++ b/source/PyMaterialX/PyMaterialXCore/PyElement.cpp @@ -224,10 +224,10 @@ void bindPyElement(py::module& mod) .def_readwrite("attributeName", &mx::ElementEquivalenceResult::attributeName); py::class_(mod, "ElementEquivalenceOptions") - .def_readwrite("format", &mx::ElementEquivalenceOptions::format) - .def_readwrite("precision", &mx::ElementEquivalenceOptions::precision) - .def_readwrite("skipAttributes", &mx::ElementEquivalenceOptions::skipAttributes) - .def_readwrite("skipValueComparisons", &mx::ElementEquivalenceOptions::skipValueComparisons) + .def_readwrite("performValueComparisons", &mx::ElementEquivalenceOptions::performValueComparisons) + .def_readwrite("floatFormat", &mx::ElementEquivalenceOptions::floatFormat) + .def_readwrite("floatPrecision", &mx::ElementEquivalenceOptions::floatPrecision) + .def_readwrite("attributeExclusionList", &mx::ElementEquivalenceOptions::attributeExclusionList) .def(py::init<>()); py::class_(mod, "StringResolver") From a3a7744f3e7a290b4d029ea60452f4bab8a9496f Mon Sep 17 00:00:00 2001 From: krohmerNV <42233792+krohmerNV@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:48:00 +0100 Subject: [PATCH 3/9] MDL 1.9 updates (#2102) add new version to GenMDL and remove uniform restriction from material IOR Minor updates: - improve MDL printing by adding named parameters - handle 1-element mixes (basically scale) above layers - improve blur and height to normal to return something meaningful (before totally broken) - improve non-material outputs that can be rendered, e.g. float3x3 and float4x4 - preparations for MDL 1.10 - remove shader parameters from the public MDL material interface. backsurfaceshader and displacementshader showed up with default values only after recent upstream changes --- .../pbrlib/genmdl/pbrlib_genmdl_impl.mtlx | 6 +- .../stdlib/genmdl/stdlib_genmdl_impl.mtlx | 2 +- source/MaterialXGenMdl/MdlShaderGenerator.cpp | 89 +++- source/MaterialXGenMdl/MdlShaderGenerator.h | 9 +- .../Nodes/ClosureLayerNodeMdl.cpp | 45 ++ .../Nodes/ClosureLayerNodeMdl.h | 7 + .../MaterialXGenMdl/Nodes/SurfaceNodeMdl.cpp | 13 +- .../MaterialXGenMdl/mdl/materialx/pbrlib.mdl | 10 +- .../mdl/materialx/pbrlib_1_6.mdl | 34 +- .../mdl/materialx/pbrlib_1_9.mdl | 372 +++++++++++++++++ .../mdl/materialx/sampling.mdl | 19 +- .../MaterialXGenMdl/mdl/materialx/stdlib.mdl | 10 +- .../mdl/materialx/stdlib_1_9.mdl | 387 ++++++++++++++++++ .../MaterialXTest/MaterialXGenMdl/GenMdl.cpp | 22 +- 14 files changed, 961 insertions(+), 64 deletions(-) create mode 100644 source/MaterialXGenMdl/mdl/materialx/pbrlib_1_9.mdl create mode 100644 source/MaterialXGenMdl/mdl/materialx/stdlib_1_9.mdl diff --git a/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx b/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx index c8f23958ae..45f83f164a 100644 --- a/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx +++ b/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx @@ -2,7 +2,7 @@ - + @@ -11,13 +11,13 @@ - + - + diff --git a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx index 51566463aa..b190937c41 100644 --- a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx +++ b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx @@ -695,7 +695,7 @@ - + diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.cpp b/source/MaterialXGenMdl/MdlShaderGenerator.cpp index 76cd7587fd..71db0d7cf4 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.cpp +++ b/source/MaterialXGenMdl/MdlShaderGenerator.cpp @@ -52,9 +52,11 @@ const string IMPORT_ALL = " import *"; const string MDL_VERSION_1_6 = "1.6"; const string MDL_VERSION_1_7 = "1.7"; const string MDL_VERSION_1_8 = "1.8"; +const string MDL_VERSION_1_9 = "1.9"; const string MDL_VERSION_SUFFIX_1_6 = "1_6"; const string MDL_VERSION_SUFFIX_1_7 = "1_7"; const string MDL_VERSION_SUFFIX_1_8 = "1_8"; +const string MDL_VERSION_SUFFIX_1_9 = "1_9"; } // anonymous namespace @@ -191,6 +193,27 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G emitLineBreak(stage); } + // Emit shader inputs that have been filtered during printing of the public interface + const string uniformPrefix = _syntax->getUniformQualifier() + " "; + for (ShaderGraphInputSocket* inputSocket : graph.getInputSockets()) + { + if (inputSocket->getConnections().size() && + (inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_SHADER || + inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_CLOSURE || + inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_MATERIAL)) + { + const string& qualifier = inputSocket->isUniform() || inputSocket->getType() == Type::FILENAME + ? uniformPrefix + : EMPTY_STRING; + const string& type = _syntax->getTypeName(inputSocket->getType()); + + emitLineBegin(stage); + emitString(qualifier + type + " " + inputSocket->getVariable() + " = ", stage); + emitString(_syntax->getDefaultValue(inputSocket->getType(), true), stage); + emitLineEnd(stage, true); + } + } + // Emit all texturing nodes. These are inputs to any // closure/shader nodes and need to be emitted first. emitFunctionCalls(graph, context, stage, ShaderNode::Classification::TEXTURE); @@ -215,6 +238,7 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G const string result = getUpstreamResult(outputSocket, context); const TypeDesc outputType = outputSocket->getType(); + // Try to return some meaningful color in case the output is not a material if (graph.hasClassification(ShaderNode::Classification::TEXTURE)) { if (outputType == Type::DISPLACEMENTSHADER) @@ -229,7 +253,25 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G else { emitLine("float3 displacement__ = float3(0.0)", stage); - emitLine("color finalOutput__ = mk_color3(" + result + ")", stage); + std::string finalOutput = "mk_color3(0.0)"; + if (outputType == Type::BOOLEAN) + finalOutput = result + " ? mk_color3(0.0, 1.0, 0.0) : mk_color3(1.0, 0.0, 0.0)"; + else if (outputType == Type::INTEGER) + finalOutput = "mk_color3(" + result + " / 100)"; // arbitrary + else if (outputType == Type::FLOAT) + finalOutput = "mk_color3(" + result + ")"; + else if (outputType == Type::VECTOR2) + finalOutput = "mk_color3(" + result + ".x, " + result + ".y, 0.0)"; + else if (outputType == Type::VECTOR3) + finalOutput = "mk_color3(" + result + ")"; + else if (outputType == Type::COLOR3) + finalOutput = result; + else if (outputType == Type::COLOR4) + finalOutput = result + ".rgb"; + else if (outputType == Type::MATRIX33 || outputType == Type::MATRIX44) + finalOutput = "mk_color3(" + result + "[0][0], " + result + "[1][1], " + result + "[2][2])"; + + emitLine("color finalOutput__ = " + finalOutput, stage); } // End shader body @@ -527,6 +569,13 @@ ShaderPtr MdlShaderGenerator::createShader(const string& name, ElementPtr elemen // and are editable by users. if (inputSocket->getConnections().size() && graph->isEditable(*inputSocket)) { + if (inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_SHADER || + inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_CLOSURE || + inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_MATERIAL) + { + continue; + } + inputs->add(inputSocket->getSelf()); } } @@ -537,7 +586,7 @@ ShaderPtr MdlShaderGenerator::createShader(const string& name, ElementPtr elemen outputs->add(outputSocket->getSelf()); } - // MDL does not allow varying data connected to transmission IOR. + // MDL does not allow varying data connected to transmission IOR until MDL 1.9. // We must find all uses of transmission IOR and make sure we don't // have a varying connection to it. If a varying connection is found // we break that connection and revert to using default value on that @@ -552,8 +601,14 @@ ShaderPtr MdlShaderGenerator::createShader(const string& name, ElementPtr elemen // this fix will disconnect the transmission IOR on the inside, but // still support the connection to reflection IOR. // - if (graph->hasClassification(ShaderNode::Classification::SHADER) || - graph->hasClassification(ShaderNode::Classification::CLOSURE)) + GenMdlOptions::MdlVersion version = getMdlVersion(context); + bool uniformIorRequired = + version == GenMdlOptions::MdlVersion::MDL_1_6 || + version == GenMdlOptions::MdlVersion::MDL_1_7 || + version == GenMdlOptions::MdlVersion::MDL_1_8; + if (uniformIorRequired && ( + graph->hasClassification(ShaderNode::Classification::SHADER) || + graph->hasClassification(ShaderNode::Classification::CLOSURE))) { // Find dependencies on transmission IOR. std::set graphsWithIorDependency; @@ -641,10 +696,15 @@ void MdlShaderGenerator::emitShaderInputs(const DocumentPtr doc, const VariableB } } -void MdlShaderGenerator::emitMdlVersionNumber(GenContext& context, ShaderStage& stage) const +GenMdlOptions::MdlVersion MdlShaderGenerator::getMdlVersion(GenContext& context) const { GenMdlOptionsPtr options = context.getUserData(GenMdlOptions::GEN_CONTEXT_USER_DATA_KEY); - GenMdlOptions::MdlVersion version = options ? options->targetVersion : GenMdlOptions::MdlVersion::MDL_LATEST; + return options ? options->targetVersion : GenMdlOptions::MdlVersion::MDL_LATEST; +} + +void MdlShaderGenerator::emitMdlVersionNumber(GenContext& context, ShaderStage& stage) const +{ + GenMdlOptions::MdlVersion version = getMdlVersion(context); emitLineBegin(stage); emitString("mdl ", stage); @@ -656,19 +716,22 @@ void MdlShaderGenerator::emitMdlVersionNumber(GenContext& context, ShaderStage& case GenMdlOptions::MdlVersion::MDL_1_7: emitString(MDL_VERSION_1_7, stage); break; + case GenMdlOptions::MdlVersion::MDL_1_8: + emitString(MDL_VERSION_1_8, stage); + break; default: - // GenMdlOptions::MdlVersion::MDL_1_8 + // GenMdlOptions::MdlVersion::MDL_1_9 // GenMdlOptions::MdlVersion::MDL_LATEST - emitString(MDL_VERSION_1_8, stage); + emitString(MDL_VERSION_1_9, stage); break; } emitLineEnd(stage, true); } + const string& MdlShaderGenerator::getMdlVersionFilenameSuffix(GenContext& context) const { - GenMdlOptionsPtr options = context.getUserData(GenMdlOptions::GEN_CONTEXT_USER_DATA_KEY); - GenMdlOptions::MdlVersion version = options ? options->targetVersion : GenMdlOptions::MdlVersion::MDL_LATEST; + GenMdlOptions::MdlVersion version = getMdlVersion(context); switch (version) { @@ -676,10 +739,12 @@ const string& MdlShaderGenerator::getMdlVersionFilenameSuffix(GenContext& contex return MDL_VERSION_SUFFIX_1_6; case GenMdlOptions::MdlVersion::MDL_1_7: return MDL_VERSION_SUFFIX_1_7; + case GenMdlOptions::MdlVersion::MDL_1_8: + return MDL_VERSION_SUFFIX_1_8; default: - // GenMdlOptions::MdlVersion::MDL_1_8 + // GenMdlOptions::MdlVersion::MDL_1_9 // GenMdlOptions::MdlVersion::MDL_LATEST - return MDL_VERSION_SUFFIX_1_8; + return MDL_VERSION_SUFFIX_1_9; } } diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.h b/source/MaterialXGenMdl/MdlShaderGenerator.h index 3a24bcf87d..ef88fbc453 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.h +++ b/source/MaterialXGenMdl/MdlShaderGenerator.h @@ -25,7 +25,8 @@ class MX_GENMDL_API GenMdlOptions : public GenUserData MDL_1_6, MDL_1_7, MDL_1_8, - MDL_LATEST = MDL_1_8 + MDL_1_9, + MDL_LATEST = MDL_1_9 }; /// Create MDL code generator options with default values. @@ -76,7 +77,11 @@ class MX_GENMDL_API MdlShaderGenerator : public ShaderGenerator /// Map of code snippets for geomprops in MDL. static const std::unordered_map GEOMPROP_DEFINITIONS; - /// Add the MDL file header containing the version number of the generated module.. + /// Get the selected MDL target language version number from the context option. + /// If not set, the latest version supported by GenMdl is returned. + GenMdlOptions::MdlVersion getMdlVersion(GenContext& context) const; + + /// Add the MDL file header containing the version number of the generated module. void emitMdlVersionNumber(GenContext& context, ShaderStage& stage) const; /// Add the version number suffix appended to MDL modules that use versions. diff --git a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp index e3484b0171..8949ae6cc0 100644 --- a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp @@ -16,6 +16,10 @@ MATERIALX_NAMESPACE_BEGIN const string StringConstantsMdl::TOP = "top"; const string StringConstantsMdl::BASE = "base"; +const string StringConstantsMdl::FG = "fg"; +const string StringConstantsMdl::BG = "bg"; +const string StringConstantsMdl::MIX = "mix"; +const string StringConstantsMdl::TOP_WEIGHT = "top_weight"; ShaderNodeImplPtr ClosureLayerNodeMdl::create() { @@ -101,6 +105,7 @@ void ClosureLayerNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext& // Transport the base bsdf further than one layer ShaderNode* baseReceiverNode = top; + ShaderNode* mixTopWeightNode = nullptr; while (true) { // If the top node is again a layer, we don't want to override the base @@ -111,6 +116,26 @@ void ClosureLayerNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext& } else { + // TODO is there a more efficient way to check if the node is a mix_bsdf? + std::string name = top->getImplementation().getName(); + if (name == "IM_mix_bsdf_genmdl") + { + // handle one special case: the top node is a mix where either fg or bg is empty + // so basically a scale factor + ShaderOutput* fgOutput = top->getInput(StringConstantsMdl::FG)->getConnection(); + ShaderOutput* bgOutput = top->getInput(StringConstantsMdl::BG)->getConnection(); + ShaderOutput* mixOutput = top->getInput(StringConstantsMdl::MIX)->getConnection(); + ShaderNode* fg = fgOutput ? fgOutput->getNode() : nullptr; + ShaderNode* bg = bgOutput ? bgOutput->getNode() : nullptr; + ShaderNode* mix = mixOutput ? mixOutput->getNode() : nullptr; + if ((fg && !bg) || (!fg && bg)) + { + baseReceiverNode = fg ? fg : bg; // take the node that is valid + top = baseReceiverNode; + mixTopWeightNode = mix; + } + break; + } // we stop at elemental bsdfs // TODO handle mix, add, and multiply break; @@ -150,6 +175,11 @@ void ClosureLayerNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext& // base BSDF connection and output variable name from the // layer operator itself. topNodeBaseInput->makeConnection(base->getOutput()); + if (mixTopWeightNode) + { + ShaderInput* topNodeTopWeightInput = baseReceiverNode->getInput(StringConstantsMdl::TOP_WEIGHT); + topNodeTopWeightInput->makeConnection(mixTopWeightNode->getOutput()); + } ScopedSetVariableName setVariable(output->getVariable(), top->getOutput()); // Make the call. @@ -171,6 +201,21 @@ void LayerableNodeMdl::addInputs(ShaderNode& node, GenContext& /*context*/) cons { // Add the input to hold base layer BSDF. node.addInput(StringConstantsMdl::BASE, Type::BSDF); + + // Set the top level weight default to 1.0 + ShaderInput* topWeightNode = node.addInput(StringConstantsMdl::TOP_WEIGHT, Type::FLOAT); + ValuePtr value = TypedValue::createValue(1.0f); + topWeightNode->setValue(value); +} + +bool LayerableNodeMdl::isEditable(const ShaderInput& input) const +{ + if (input.getName() == StringConstantsMdl::BASE || + input.getName() == StringConstantsMdl::TOP_WEIGHT) + { + return false; + } + return BASE::isEditable(input); } MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h index bced5cfac1..8b6f987287 100644 --- a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h +++ b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h @@ -23,6 +23,10 @@ class MX_GENMDL_API StringConstantsMdl /// String constants static const string TOP; ///< layer parameter name of the top component static const string BASE; ///< layer parameter name of the base component + static const string FG; ///< mix parameter name of the foreground + static const string BG; ///< mix parameter name of the background + static const string MIX; ///< mix parameter name of the amount + static const string TOP_WEIGHT; ///< mix amount forwarded into layer top component }; /// Closure layer node implementation for MDL. @@ -40,11 +44,14 @@ class MX_GENMDL_API ClosureLayerNodeMdl : public ShaderNodeImpl /// Note, not all elemental bsdfs support this kind of transformation. class MX_GENMDL_API LayerableNodeMdl : public SourceCodeNodeMdl { + using BASE = SourceCodeNodeMdl; + public: virtual ~LayerableNodeMdl() = default; static ShaderNodeImplPtr create(); void addInputs(ShaderNode& node, GenContext&) const override; + bool isEditable(const ShaderInput& input) const override; }; MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMdl/Nodes/SurfaceNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/SurfaceNodeMdl.cpp index 6477cd9ae8..dd0444d129 100644 --- a/source/MaterialXGenMdl/Nodes/SurfaceNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/SurfaceNodeMdl.cpp @@ -59,12 +59,17 @@ void SurfaceNodeMdl::emitFunctionCall(const ShaderNode& node, GenContext& contex // Emit calls for the closure dependencies upstream from this node. shadergen.emitDependentFunctionCalls(node, context, stage, ShaderNode::Classification::CLOSURE); - // Check if transmission IOR is used for this shader. + // Check if transmission IOR is used for this shader for MDL versions before 1.9. // MDL only supports a single transmission IOR per material and // it is given as an input on the 'material' constructor. // So if used we must forward this value/connection to the surface // constructor. It's set as an extra input below. - const ShaderInput* ior = findTransmissionIOR(node); + GenMdlOptions::MdlVersion version = shadergen.getMdlVersion(context); + bool uniformIorRequired = + version == GenMdlOptions::MdlVersion::MDL_1_6 || + version == GenMdlOptions::MdlVersion::MDL_1_7 || + version == GenMdlOptions::MdlVersion::MDL_1_8; + const ShaderInput* ior = uniformIorRequired ? findTransmissionIOR(node) : nullptr; shadergen.emitLineBegin(stage); @@ -79,6 +84,9 @@ void SurfaceNodeMdl::emitFunctionCall(const ShaderNode& node, GenContext& contex for (ShaderInput* input : node.getInputs()) { shadergen.emitString(delim, stage); + shadergen.emitString("mxp_", stage); + shadergen.emitString(input->getName(), stage); + shadergen.emitString(": ", stage); shadergen.emitInput(input, context, stage); delim = ", "; } @@ -87,6 +95,7 @@ void SurfaceNodeMdl::emitFunctionCall(const ShaderNode& node, GenContext& contex { // Emit the extra input for transmission IOR. shadergen.emitString(delim, stage); + shadergen.emitString("mxp_transmission_ior: ", stage); shadergen.emitInput(ior, context, stage); } diff --git a/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl b/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl index 0c11ce3744..789b4cfa77 100644 --- a/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl @@ -16,15 +16,15 @@ // MDL implementation of all types and nodes of // MaterialX Physically-Based Shading Nodes -// Document v1.37 REV2, July 16, 2019 (Revised October 17, 2019) +// Document version 1.39, June 29, 2024 // see www.materialx.org // in -// NVIDIA Material Definition Language 1.8 +// NVIDIA Material Definition Language 1.9 // Language Specification -// Document version 1.8.2, May 24, 2023 +// Document version 1.9.2, September 16, 2024 // www.nvidia.com/mdl -mdl 1.8; +mdl 1.9; // forward the latest version -export using .::pbrlib_1_8 import *; +export using .::pbrlib_1_9 import *; diff --git a/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl index e70f849920..64102d6c27 100644 --- a/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl @@ -82,7 +82,8 @@ export material mx_oren_nayar_diffuse_bsdf( float mxp_weight = 1.0, color mxp_color = color(0.18), float mxp_roughness = 0.0, - float3 mxp_normal = state::normal() + float3 mxp_normal = state::normal(), + uniform bool mxp_energy_compensation = false [[ anno::unused() ]] // MDL 1.10 ) [[ anno::usage( "materialx:bsdf") ]] @@ -152,7 +153,8 @@ export material mx_dielectric_bsdf( float3 mxp_tangent = state::texture_tangent_u(0), uniform core::mx_distribution_type mxp_distribution = core::mx_distribution_type_ggx [[ anno::unused() ]], uniform mx_scatter_mode mxp_scatter_mode = mx_scatter_mode_R, - material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]], + material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]], // layering + float mxp_top_weight = 1.0, // layering for cases where top is scaled using a mix float mxp_thinfilm_thickness = 0.0, float mxp_thinfilm_ior = 1.0 ) [[ @@ -174,8 +176,8 @@ export material mx_dielectric_bsdf( layer: df::microfacet_ggx_smith_bsdf( roughness_u: mxp_roughness.x, roughness_v: mxp_roughness.y, - tint: mxp_tint, - multiscatter_tint: mxp_tint, + tint: mxp_tint * mxp_top_weight, + multiscatter_tint: mxp_tint * mxp_top_weight, tangent_u: mxp_tangent, mode: df::scatter_reflect), base: mxp_base.surface.scattering, @@ -186,8 +188,8 @@ export material mx_dielectric_bsdf( layer: df::microfacet_ggx_smith_bsdf( roughness_u: mxp_roughness.x, roughness_v: mxp_roughness.y, - tint: mxp_tint, - multiscatter_tint: mxp_tint, + tint: mxp_tint * mxp_top_weight, + multiscatter_tint: mxp_tint * mxp_top_weight, tangent_u: mxp_tangent, mode: df::scatter_transmit), normal: mxp_normal); @@ -200,8 +202,8 @@ export material mx_dielectric_bsdf( base: df::microfacet_ggx_smith_bsdf( roughness_u: mxp_roughness.x, roughness_v: mxp_roughness.y, - tint: mxp_tint, - multiscatter_tint: mxp_tint, + tint: mxp_tint * mxp_top_weight, + multiscatter_tint: mxp_tint * mxp_top_weight, tangent_u: mxp_tangent, mode: df::scatter_reflect_transmit)), normal: mxp_normal); @@ -258,12 +260,13 @@ export material mx_conductor_bsdf( ) ); -// TODO MDL 1.8 +// MDL 1.8 // * will add support for thin film above a color_custom_curve_layer node until then, thin_film will have no effect // * thin_film(thickness: 0.0, ior: < 1.0) will be handled properly export material mx_generalized_schlick_bsdf( float mxp_weight = 1.0, color mxp_color0 = color(1.0), + color mxp_color82 = color(1.0), // MDL 1.10 color mxp_color90 = color(1.0), float mxp_exponent = 5.0, float2 mxp_roughness = float2(0.05), @@ -271,7 +274,8 @@ export material mx_generalized_schlick_bsdf( float3 mxp_tangent = state::texture_tangent_u(0), uniform core::mx_distribution_type mxp_distribution = core::mx_distribution_type_ggx [[ anno::unused() ]], uniform mx_scatter_mode mxp_scatter_mode = mx_scatter_mode_R, - material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]], + material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]], // layering + float mxp_top_weight = 1.0, // layering for cases where top is scaled using a mix float mxp_thinfilm_thickness = 0.0, float mxp_thinfilm_ior = 1.0 ) [[ @@ -283,8 +287,8 @@ export material mx_generalized_schlick_bsdf( bsdf ggx_model_R = df::microfacet_ggx_smith_bsdf( roughness_u: mxp_roughness.x, roughness_v: mxp_roughness.y, - tint: color(1.0), - multiscatter_tint: color(1.0), + tint: color(1.0) * mxp_top_weight, + multiscatter_tint: color(1.0) * mxp_top_weight, tangent_u: mxp_tangent, mode: df::scatter_reflect); @@ -302,7 +306,7 @@ export material mx_generalized_schlick_bsdf( layer: mxp_scatter_mode == mx_scatter_mode_T ? df::color_custom_curve_layer( normal_reflectivity: mxp_color0, - grazing_reflectivity: mxp_color90, + grazing_reflectivity: mxp_color82 * mxp_color90, exponent: mxp_exponent, layer: bsdf(), base: ggx_model_T, @@ -312,7 +316,7 @@ export material mx_generalized_schlick_bsdf( ior: color(coatIor), base: df::color_custom_curve_layer( normal_reflectivity: mxp_color0, - grazing_reflectivity: mxp_color90, + grazing_reflectivity: mxp_color82 * mxp_color90, exponent: mxp_exponent, layer: ggx_model_R, base: mxp_scatter_mode == mx_scatter_mode_R @@ -440,7 +444,7 @@ export material mx_chiang_hair_bsdf( float mxp_cuticle_angle = 0.5, float3 mxp_absorption_coefficient = float3(0.0), // TODO: MDL's chiang_hair BSDF has no support user tangent vector - float3 mxp_curve_direction = state::texture_tangent_u(0) + float3 mxp_curve_direction = state::texture_tangent_u(0) [[ anno::unused() ]] ) [[ anno::usage( "materialx:bsdf") ]] diff --git a/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_9.mdl b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_9.mdl new file mode 100644 index 0000000000..e8654380d3 --- /dev/null +++ b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_9.mdl @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// MDL implementation of all types and nodes of +// MaterialX Physically-Based Shading Nodes +// Document version 1.39, June 29, 2024 +// see www.materialx.org +// in +// NVIDIA Material Definition Language 1.9 +// Language Specification +// Document version 1.9.2, September 16, 2024 +// www.nvidia.com/mdl + +mdl 1.9; + +import ::anno::*; +import ::df::*; +import ::math::*; +import ::state::*; + +import .::core::*; + +// Changes since MDL 1.8 +// - lift the restriction of uniform IORs + +// forward unchanged definitions from the previous versions +export using .::pbrlib_1_6 import mx_scatter_mode; +export using .::pbrlib_1_6 import mx_map_scatter_mode; +export using .::pbrlib_1_6 import mx_oren_nayar_diffuse_bsdf; +export using .::pbrlib_1_6 import mx_burley_diffuse_bsdf; +export using .::pbrlib_1_6 import mx_translucent_bsdf; +export using .::pbrlib_1_6 import mx_subsurface_bsdf; +export using .::pbrlib_1_6 import mx_thin_film_bsdf; +export using .::pbrlib_1_6 import mx_chiang_hair_bsdf; +export using .::pbrlib_1_6 import mx_uniform_edf; +export using .::pbrlib_1_6 import mx_conical_edf; +export using .::pbrlib_1_6 import mx_measured_edf; +export using .::pbrlib_1_6 import mx_absorption_vdf; +export using .::pbrlib_1_6 import mx_anisotropic_vdf; +export using .::pbrlib_1_6 import mx_light; +export using .::pbrlib_1_6 import mx_displacement_float; +export using .::pbrlib_1_6 import mx_displacement_vector3; +export using .::pbrlib_1_6 import volume_mix_return; +export using .::pbrlib_1_6 import volume_mix; +export using .::pbrlib_1_6 import mx_multiply_bsdf_color3; +export using .::pbrlib_1_6 import mx_multiply_bsdf_float; +export using .::pbrlib_1_6 import mx_multiply_edf_color3; +export using .::pbrlib_1_6 import mx_multiply_edf_float; +export using .::pbrlib_1_6 import mx_multiply_vdf_color3; +export using .::pbrlib_1_6 import mx_multiply_vdf_float; +export using .::pbrlib_1_6 import mx_roughness_anisotropy; +export using .::pbrlib_1_6 import mx_roughness_dual; +export using .::pbrlib_1_6 import mx_blackbody; +export using .::pbrlib_1_6 import mx_artistic_ior__result; +export using .::pbrlib_1_6 import mx_artistic_ior; +export using .::pbrlib_1_6 import mx_deon_hair_absorption_from_melanin; +export using .::pbrlib_1_6 import mx_chiang_hair_absorption_from_color; +export using .::pbrlib_1_6 import mx_chiang_hair_roughness__result; +export using .::pbrlib_1_6 import mx_chiang_hair_roughness; + +export using .::pbrlib_1_7 import mx_sheen_bsdf; +export using .::pbrlib_1_7 import mx_add_bsdf; +export using .::pbrlib_1_7 import mx_add_edf; +export using .::pbrlib_1_7 import mx_mix_edf; +export using .::pbrlib_1_7 import mx_add_vdf; +export using .::pbrlib_1_7 import mx_generalized_schlick_edf; +export using .::pbrlib_1_7 import mx_volume; + +export material mx_mix_bsdf( + material mxp_fg = material() [[ anno::usage( "materialx:bsdf") ]], + material mxp_bg = material() [[ anno::usage( "materialx:bsdf") ]], + float mxp_mix = 0.0 +) [[ + anno::usage( "materialx:bsdf") +]] += let { + float mix = math::saturate(mxp_mix); + volume_mix_return v = volume_mix( + mxp_fg.volume.scattering_coefficient, mix, + mxp_bg.volume.scattering_coefficient, (1.0f - mix)); +} in material( + surface: material_surface( + scattering: df::weighted_layer( + weight: mix, + layer: mxp_fg.surface.scattering, + base: mxp_bg.surface.scattering + ) + ), + // we need to carry volume properties along for SSS + ior: mix * mxp_fg.ior + (1.0f - mix) * mxp_bg.ior, + volume: material_volume( + scattering: df::clamped_mix( + df::vdf_component[]( + df::vdf_component(v.mix_weight1, mxp_fg.volume.scattering), + df::vdf_component(1.0 - v.mix_weight1, mxp_bg.volume.scattering)) + ), + absorption_coefficient: mix * mxp_fg.volume.absorption_coefficient + + (1.0 - mix) * mxp_bg.volume.absorption_coefficient, + scattering_coefficient: v.scattering_coefficient + ) +); + +export material mx_mix_vdf( + material mxp_fg = material() [[ anno::usage( "materialx:vdf") ]], + material mxp_bg = material() [[ anno::usage( "materialx:vdf") ]], + float mxp_mix = 0.0 +) [[ + anno::usage( "materialx:vdf") +]] += let { + float mix = math::saturate(mxp_mix); + volume_mix_return v = volume_mix( + mxp_fg.volume.scattering_coefficient, mix, + mxp_bg.volume.scattering_coefficient, (1.0f - mix)); +} in material( + ior: mix * mxp_fg.ior + (1.0f - mix) * mxp_bg.ior, + volume: material_volume( + scattering: df::clamped_mix( + df::vdf_component[]( + df::vdf_component( v.mix_weight1, mxp_fg.volume.scattering), + df::vdf_component( 1.0 - v.mix_weight1, mxp_bg.volume.scattering)) + ), + absorption_coefficient: mix * mxp_fg.volume.absorption_coefficient + + (1.0 - mix) * mxp_bg.volume.absorption_coefficient, + scattering_coefficient: v.scattering_coefficient + ) +); + +// helper to compute ior for generalized_schlick +color mx_f0_to_ior(color F0) +{ + float3 sqrtF0 = math::sqrt(math::clamp(float3(F0), 0.01, 0.99)); + return color((float3(1.0) + sqrtF0) / (float3(1.0) - sqrtF0)); +} + +export material mx_generalized_schlick_bsdf( + float mxp_weight = 1.0, + color mxp_color0 = color(1.0), + color mxp_color82 = color(1.0), // MDL 1.10 + color mxp_color90 = color(1.0), + float mxp_exponent = 5.0, + float2 mxp_roughness = float2(0.05), + float3 mxp_normal = state::normal(), + float3 mxp_tangent = state::texture_tangent_u(0), + uniform core::mx_distribution_type mxp_distribution = core::mx_distribution_type_ggx [[ anno::unused() ]], + uniform mx_scatter_mode mxp_scatter_mode = mx_scatter_mode_R, + material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]], // layering + float mxp_top_weight = 1.0, // layering for cases where top is scaled using a mix + float mxp_thinfilm_thickness = 0.0, + float mxp_thinfilm_ior = 1.0 +) [[ + anno::usage( "materialx:bsdf") +]] += let { + float coatIor = mxp_thinfilm_ior <= 0.0 ? 1.0 : mxp_thinfilm_ior; + bsdf ggx_model_R = df::microfacet_ggx_smith_bsdf( + roughness_u: mxp_roughness.x, + roughness_v: mxp_roughness.y, + tint: color(1.0) * mxp_top_weight, + multiscatter_tint: color(1.0) * mxp_top_weight, + tangent_u: mxp_tangent, + mode: df::scatter_reflect); + + bsdf ggx_model_T = df::microfacet_ggx_smith_bsdf( + roughness_u: mxp_roughness.x, + roughness_v: mxp_roughness.y, + tint: color(1.0) * mxp_top_weight, + multiscatter_tint: color(1.0) * mxp_top_weight, + tangent_u: mxp_tangent, + mode: df::scatter_transmit); + +} in material( + surface: material_surface( + scattering: df::unbounded_mix( + df::bsdf_component[]( + df::bsdf_component( + mxp_weight, + mxp_scatter_mode == mx_scatter_mode_T + ? df::color_custom_curve_layer( + normal_reflectivity: mxp_color0, + grazing_reflectivity: mxp_color82 * mxp_color90, + exponent: mxp_exponent, + layer: bsdf(), + base: ggx_model_T, + normal: mxp_normal) + : df::thin_film( + thickness: mxp_thinfilm_thickness, + ior: color(coatIor), + base: df::color_custom_curve_layer( + normal_reflectivity: mxp_color0, + grazing_reflectivity: mxp_color82 * mxp_color90, + exponent: mxp_exponent, + layer: ggx_model_R, + base: mxp_scatter_mode == mx_scatter_mode_R + ? mxp_base.surface.scattering + : ggx_model_T, + normal: mxp_normal)) + ), + df::bsdf_component( + 1.0 - mxp_weight, + mxp_base.surface.scattering) + ) + ) + ), + ior: mx_f0_to_ior(mxp_color0), + // we need to carry volume properties along for SSS + volume: mxp_base.volume +); + + +// TODO MDL 1.8 +// * will add support for thin film above a color_custom_curve_layer node until then, thin_film will have no effect +// * thin_film(thickness: 0.0, ior: < 1.0) will be handled properly +export material mx_dielectric_bsdf( + float mxp_weight = 1.0, + color mxp_tint = color(1.0), + float mxp_ior = 1.5, + float2 mxp_roughness = float2(0.0), + float3 mxp_normal = state::normal(), + float3 mxp_tangent = state::texture_tangent_u(0), + uniform core::mx_distribution_type mxp_distribution = core::mx_distribution_type_ggx [[ anno::unused() ]], + uniform mx_scatter_mode mxp_scatter_mode = mx_scatter_mode_R, + material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]], // layering + float mxp_top_weight = 1.0, // layering for cases where top is scaled using a mix + float mxp_thinfilm_thickness = 0.0, + float mxp_thinfilm_ior = 1.0 +) [[ + anno::usage( "materialx:bsdf") +]] += let { + float coatIor = mxp_thinfilm_ior <= 0.0 ? 1.0 : mxp_thinfilm_ior; + float grazing_refl = math::max((1.0 - math::average(mxp_roughness)), 0.0); + float root_r = (mxp_ior-1)/(mxp_ior+1); + bsdf bsdf_R = df::thin_film( + thickness: mxp_thinfilm_thickness, + ior: color(coatIor), + // fresnel layer has issues if base is a diffuse transmission, use custom curve for now + // this will break thin_film but improves standard_surface with diffuse transmission + base: df::custom_curve_layer( + normal_reflectivity: root_r*root_r, + grazing_reflectivity: grazing_refl, + weight: mxp_weight, + layer: df::microfacet_ggx_smith_bsdf( + roughness_u: mxp_roughness.x, + roughness_v: mxp_roughness.y, + tint: mxp_tint * mxp_top_weight, + multiscatter_tint: mxp_tint * mxp_top_weight, + tangent_u: mxp_tangent, + mode: df::scatter_reflect), + base: mxp_base.surface.scattering, + normal: mxp_normal)); + + bsdf bsdf_T = df::weighted_layer( + weight: mxp_weight, + layer: df::microfacet_ggx_smith_bsdf( + roughness_u: mxp_roughness.x, + roughness_v: mxp_roughness.y, + tint: mxp_tint * mxp_top_weight, + multiscatter_tint: mxp_tint * mxp_top_weight, + tangent_u: mxp_tangent, + mode: df::scatter_transmit), + normal: mxp_normal); + + bsdf bsdf_RT = df::weighted_layer( + weight: mxp_weight, + layer: df::thin_film( + thickness: mxp_thinfilm_thickness, + ior: color(coatIor), + base: df::microfacet_ggx_smith_bsdf( + roughness_u: mxp_roughness.x, + roughness_v: mxp_roughness.y, + tint: mxp_tint * mxp_top_weight, + multiscatter_tint: mxp_tint * mxp_top_weight, + tangent_u: mxp_tangent, + mode: df::scatter_reflect_transmit)), + normal: mxp_normal); + + bsdf bsdf_selected = (mxp_scatter_mode == mx_scatter_mode_R) ? bsdf_R : + ((mxp_scatter_mode == mx_scatter_mode_T) ? bsdf_T : bsdf_RT); +} in material( + surface: material_surface( + scattering: bsdf_selected + ), + // we need to carry volume properties along for SSS + ior: color(mxp_ior), + volume: mxp_base.volume +); + +export material mx_conductor_bsdf( + float mxp_weight = 1.0, + color mxp_ior = color(0.18, 0.42, 1.37), + color mxp_extinction = color(3.42, 2.35, 1.77), + float2 mxp_roughness = float2(0.0), + float3 mxp_normal = state::normal(), + float3 mxp_tangent = state::texture_tangent_u(0), + uniform core::mx_distribution_type mxp_distribution = core::mx_distribution_type_ggx [[ anno::unused() ]], + float mxp_thinfilm_thickness = 0.0, + float mxp_thinfilm_ior = 1.0 +) [[ + anno::usage( "materialx:bsdf") +]] += let { + float coatIor = mxp_thinfilm_ior <= 0.0 ? 1.0 : mxp_thinfilm_ior; + bsdf ggx_model = df::microfacet_ggx_smith_bsdf( + roughness_u: mxp_roughness.x, + roughness_v: mxp_roughness.y, + tint: color(1.0), + multiscatter_tint: color(1.0), + tangent_u: mxp_tangent); + bsdf conductor = df::fresnel_factor( + ior: mxp_ior, + extinction_coefficient: mxp_extinction, + base: ggx_model); + bsdf thin_film_conductor = df::thin_film( + thickness: mxp_thinfilm_thickness, + ior: color(coatIor), + base: conductor); +} in material( + surface: material_surface( + scattering: df::weighted_layer( + weight: mxp_weight, + layer: thin_film_conductor, + normal: mxp_normal + ) + ), + ior: mxp_ior, +); + +// Shader Nodes + +// NOTE: The MDL material with thin_walled == false uses the same material_surface +// properties for the front- and backface, the material will not be black +// from the backside as mandated by the MaterialX spec. +export material mx_surface( + material mxp_bsdf = material() [[ anno::usage( "materialx:bsdf") ]], + material mxp_edf = material() [[ anno::usage( "materialx:edf") ]], + float mxp_opacity = 1.0, + uniform bool mxp_thin_walled = false, + float mxp_transmission_ior = 0.0 // extra parameter for setting transmission IOR +) [[ + anno::usage( "materialx:surfaceshader") +]] += let { + bsdf bsdf_node = mxp_bsdf.surface.scattering; + material_emission edf_node = mxp_edf.surface.emission; + // we need to carry volume properties along for SSS + material_volume bsdf_volume = mxp_bsdf.volume; +} in material( + thin_walled: mxp_thin_walled, + surface: material_surface( + scattering: bsdf_node, + emission: edf_node + ), + ior: mxp_transmission_ior > 0.0 ? color(mxp_transmission_ior) : mxp_bsdf.ior, + volume: bsdf_volume, + geometry: material_geometry( + cutout_opacity: mxp_opacity + ) +); diff --git a/source/MaterialXGenMdl/mdl/materialx/sampling.mdl b/source/MaterialXGenMdl/mdl/materialx/sampling.mdl index 1809503653..15228efeca 100644 --- a/source/MaterialXGenMdl/mdl/materialx/sampling.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/sampling.mdl @@ -5,7 +5,9 @@ mdl 1.6; +import ::anno::*; import ::math::*; +import ::state::*; import .::core::*; @@ -15,14 +17,14 @@ export const int MX_MAX_SAMPLE_COUNT = 49; export const int MX_WEIGHT_ARRAY_SIZE = 84; // This is not available in MDL so just use a "small" number -float2 dFdx(float2 uv) +float2 dFdx(float2 uv [[anno::unused()]]) { - return uv+0.0001; + return float2(0.001, 0); } -float2 dFdy(float2 uv) +float2 dFdy(float2 uv [[anno::unused()]]) { - return uv+0.0001; + return float2(0, 0.001); } // @@ -49,11 +51,10 @@ export float2 mx_compute_sample_size_uv(float2 uv, float filterSize, float filte // export float3 mx_normal_from_samples_sobel(float[9] S, float scale) { - float nx = S[0] - S[2] + (2.0*S[3]) - (2.0*S[5]) + S[6] - S[8]; - float ny = S[0] + (2.0*S[1]) + S[2] - S[6] - (2.0*S[7]) - S[8]; - float nz = scale * ::math::sqrt(1.0 - nx*nx - ny*ny); - float3 norm = ::math::normalize(float3(nx, ny, nz)); - return (norm + 1.0) * 0.5; + float nx = S[0] - S[2] + (2.0*S[3]) - (2.0*S[5]) + S[6] - S[8]; + float ny = S[0] + (2.0*S[1]) + S[2] - S[6] - (2.0*S[7]) - S[8]; + float3 norm = math::normalize(float3(nx * scale, ny * scale, 0.125)); + return (norm + 1.0) * 0.5; } // Kernel weights for box filter diff --git a/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl b/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl index 79ed3dff4f..a23c0150ed 100644 --- a/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl @@ -4,15 +4,15 @@ // // MDL implementation of all Standard Source Nodes of // MaterialX: An Open Standard for Network-Based CG Object Looks -// Document v1.37 REV2, January 19, 2020 +// Document version 1.39, September 15, 2024 // www.materialx.org // in -// NVIDIA Material Definition Language 1.7 +// NVIDIA Material Definition Language 1.9 // Language Specification -// Document version 1.7.2, January 17, 2022 +// Document version 1.9.2, September 16, 2024 // www.nvidia.com/mdl -mdl 1.8; +mdl 1.9; // forward the latest version -export using .::stdlib_1_8 import *; +export using .::stdlib_1_9 import *; diff --git a/source/MaterialXGenMdl/mdl/materialx/stdlib_1_9.mdl b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_9.mdl new file mode 100644 index 0000000000..549287c5b7 --- /dev/null +++ b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_9.mdl @@ -0,0 +1,387 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// +// MDL implementation of all Standard Source Nodes of +// MaterialX: An Open Standard for Network-Based CG Object Looks +// Document version 1.39, September 15, 2024 +// www.materialx.org +// in +// NVIDIA Material Definition Language 1.9 +// Language Specification +// Document version 1.9.2, September 16, 2024 +// www.nvidia.com/mdl + +mdl 1.9; + +import ::anno::*; +import ::df::*; +import ::math::*; +import ::scene::*; +import ::state::*; + +import .::core::*; +import .::noise::*; +import .::hsv::*; + +// Changes since MDL 1.8 +// - lift the restriction of uniform IORs + +// forward unchanged definitions from the previous version +export using .::stdlib_1_7 import mx_surfacematerial; +export using .::stdlib_1_7 import mx_surface_unlit; +export using .::stdlib_1_7 import mx_image_float; +export using .::stdlib_1_7 import mx_image_color3; +export using .::stdlib_1_7 import mx_image_color4; +export using .::stdlib_1_7 import mx_image_vector2; +export using .::stdlib_1_7 import mx_image_vector3; +export using .::stdlib_1_7 import mx_image_vector4; +export using .::stdlib_1_7 import mx_constant_float; +export using .::stdlib_1_7 import mx_constant_color3; +export using .::stdlib_1_7 import mx_constant_color4; +export using .::stdlib_1_7 import mx_constant_vector2; +export using .::stdlib_1_7 import mx_constant_vector3; +export using .::stdlib_1_7 import mx_constant_vector4; +export using .::stdlib_1_7 import mx_constant_boolean; +export using .::stdlib_1_7 import mx_constant_integer; +export using .::stdlib_1_7 import mx_constant_matrix33; +export using .::stdlib_1_7 import mx_constant_matrix44; +export using .::stdlib_1_7 import mx_constant_string; +export using .::stdlib_1_7 import mx_constant_filename; +export using .::stdlib_1_7 import mx_ramplr_float; +export using .::stdlib_1_7 import mx_ramplr_color3; +export using .::stdlib_1_7 import mx_ramplr_color4; +export using .::stdlib_1_7 import mx_ramplr_vector2; +export using .::stdlib_1_7 import mx_ramplr_vector3; +export using .::stdlib_1_7 import mx_ramplr_vector4; +export using .::stdlib_1_7 import mx_ramptb_float; +export using .::stdlib_1_7 import mx_ramptb_color3; +export using .::stdlib_1_7 import mx_ramptb_color4; +export using .::stdlib_1_7 import mx_ramptb_vector2; +export using .::stdlib_1_7 import mx_ramptb_vector3; +export using .::stdlib_1_7 import mx_ramptb_vector4; +export using .::stdlib_1_7 import mx_splitlr_float; +export using .::stdlib_1_7 import mx_splitlr_color3; +export using .::stdlib_1_7 import mx_splitlr_color4; +export using .::stdlib_1_7 import mx_splitlr_vector2; +export using .::stdlib_1_7 import mx_splitlr_vector3; +export using .::stdlib_1_7 import mx_splitlr_vector4; +export using .::stdlib_1_7 import mx_splittb_float; +export using .::stdlib_1_7 import mx_splittb_color3; +export using .::stdlib_1_7 import mx_splittb_color4; +export using .::stdlib_1_7 import mx_splittb_vector2; +export using .::stdlib_1_7 import mx_splittb_vector3; +export using .::stdlib_1_7 import mx_splittb_vector4; +export using .::stdlib_1_7 import mx_position_vector3; +export using .::stdlib_1_7 import mx_normal_vector3; +export using .::stdlib_1_7 import mx_tangent_vector3; +export using .::stdlib_1_7 import mx_bitangent_vector3; +export using .::stdlib_1_7 import mx_texcoord_vector2; +export using .::stdlib_1_7 import mx_texcoord_vector3; +export using .::stdlib_1_7 import mx_geomcolor_float; +export using .::stdlib_1_7 import mx_geomcolor_color3; +export using .::stdlib_1_7 import mx_geomcolor_color4; +export using .::stdlib_1_7 import mx_ambientocclusion_float; +export using .::stdlib_1_7 import mx_frame_float; +export using .::stdlib_1_7 import mx_time_float; +export using .::stdlib_1_7 import mx_modulo_color3; +export using .::stdlib_1_7 import mx_modulo_color4; +export using .::stdlib_1_7 import mx_modulo_color3FA; +export using .::stdlib_1_7 import mx_modulo_color4FA; +export using .::stdlib_1_7 import mx_invert_color4; +export using .::stdlib_1_7 import mx_invert_color4FA; +export using .::stdlib_1_7 import mx_absval_color4; +export using .::stdlib_1_7 import mx_floor_color3; +export using .::stdlib_1_7 import mx_floor_color4; +export using .::stdlib_1_7 import mx_ceil_color3; +export using .::stdlib_1_7 import mx_ceil_color4; +export using .::stdlib_1_7 import mx_round_color3; +export using .::stdlib_1_7 import mx_round_color4; +export using .::stdlib_1_7 import mx_power_color4; +export using .::stdlib_1_7 import mx_power_color4FA; +export using .::stdlib_1_7 import mx_sin_float; +export using .::stdlib_1_7 import mx_cos_float; +export using .::stdlib_1_7 import mx_tan_float; +export using .::stdlib_1_7 import mx_asin_float; +export using .::stdlib_1_7 import mx_acos_float; +export using .::stdlib_1_7 import mx_atan2_float; +export using .::stdlib_1_7 import mx_sin_vector2; +export using .::stdlib_1_7 import mx_cos_vector2; +export using .::stdlib_1_7 import mx_tan_vector2; +export using .::stdlib_1_7 import mx_asin_vector2; +export using .::stdlib_1_7 import mx_acos_vector2; +export using .::stdlib_1_7 import mx_atan2_vector2; +export using .::stdlib_1_7 import mx_sin_vector3; +export using .::stdlib_1_7 import mx_cos_vector3; +export using .::stdlib_1_7 import mx_tan_vector3; +export using .::stdlib_1_7 import mx_asin_vector3; +export using .::stdlib_1_7 import mx_acos_vector3; +export using .::stdlib_1_7 import mx_atan2_vector3; +export using .::stdlib_1_7 import mx_sin_vector4; +export using .::stdlib_1_7 import mx_cos_vector4; +export using .::stdlib_1_7 import mx_tan_vector4; +export using .::stdlib_1_7 import mx_asin_vector4; +export using .::stdlib_1_7 import mx_acos_vector4; +export using .::stdlib_1_7 import mx_atan2_vector4; +export using .::stdlib_1_7 import mx_sqrt_float; +export using .::stdlib_1_7 import mx_ln_float; +export using .::stdlib_1_7 import mx_exp_float; +export using .::stdlib_1_7 import mx_sqrt_vector2; +export using .::stdlib_1_7 import mx_ln_vector2; +export using .::stdlib_1_7 import mx_exp_vector2; +export using .::stdlib_1_7 import mx_sqrt_vector3; +export using .::stdlib_1_7 import mx_ln_vector3; +export using .::stdlib_1_7 import mx_exp_vector3; +export using .::stdlib_1_7 import mx_sqrt_vector4; +export using .::stdlib_1_7 import mx_ln_vector4; +export using .::stdlib_1_7 import mx_exp_vector4; +export using .::stdlib_1_7 import mx_sign_color3; +export using .::stdlib_1_7 import mx_sign_color4; +export using .::stdlib_1_7 import mx_clamp_color4; +export using .::stdlib_1_7 import mx_clamp_color4FA; +export using .::stdlib_1_7 import mx_min_color4; +export using .::stdlib_1_7 import mx_min_color4; +export using .::stdlib_1_7 import mx_max_color4; +export using .::stdlib_1_7 import mx_max_color4; +export using .::stdlib_1_7 import mx_transformpoint_vector3; +export using .::stdlib_1_7 import mx_transformvector_vector3; +export using .::stdlib_1_7 import mx_transformnormal_vector3; +export using .::stdlib_1_7 import mx_transformmatrix_vector2M3; +export using .::stdlib_1_7 import mx_transformmatrix_vector3; +export using .::stdlib_1_7 import mx_transformmatrix_vector3M4; +export using .::stdlib_1_7 import mx_transformmatrix_vector4; +export using .::stdlib_1_7 import mx_normalmap_float; +export using .::stdlib_1_7 import mx_normalmap_vector2; +export using .::stdlib_1_7 import mx_transpose_matrix33; +export using .::stdlib_1_7 import mx_transpose_matrix44; +export using .::stdlib_1_7 import mx_determinant_matrix33; +export using .::stdlib_1_7 import mx_determinant_matrix44; +export using .::stdlib_1_7 import mx_invertmatrix_matrix33; +export using .::stdlib_1_7 import mx_invertmatrix_matrix44; +export using .::stdlib_1_7 import mx_rotate2d_vector2; +export using .::stdlib_1_7 import mx_rotate3d_vector3; +export using .::stdlib_1_7 import mx_remap_float; +export using .::stdlib_1_7 import mx_remap_color3; +export using .::stdlib_1_7 import mx_remap_color4; +export using .::stdlib_1_7 import mx_remap_vector2; +export using .::stdlib_1_7 import mx_remap_vector3; +export using .::stdlib_1_7 import mx_remap_vector4; +export using .::stdlib_1_7 import mx_remap_color3FA; +export using .::stdlib_1_7 import mx_remap_color4FA; +export using .::stdlib_1_7 import mx_remap_vector2FA; +export using .::stdlib_1_7 import mx_remap_vector3FA; +export using .::stdlib_1_7 import mx_remap_vector4FA; +export using .::stdlib_1_7 import mx_smoothstep_float; +export using .::stdlib_1_7 import mx_smoothstep_color3; +export using .::stdlib_1_7 import mx_smoothstep_color4; +export using .::stdlib_1_7 import mx_smoothstep_vector2; +export using .::stdlib_1_7 import mx_smoothstep_vector3; +export using .::stdlib_1_7 import mx_smoothstep_vector4; +export using .::stdlib_1_7 import mx_smoothstep_color3FA; +export using .::stdlib_1_7 import mx_smoothstep_color4FA; +export using .::stdlib_1_7 import mx_smoothstep_vector2FA; +export using .::stdlib_1_7 import mx_smoothstep_vector3FA; +export using .::stdlib_1_7 import mx_smoothstep_vector4FA; +export using .::stdlib_1_7 import mx_curveadjust_float; +export using .::stdlib_1_7 import mx_curveadjust_color3; +export using .::stdlib_1_7 import mx_curveadjust_color4; +export using .::stdlib_1_7 import mx_curveadjust_vector2; +export using .::stdlib_1_7 import mx_curveadjust_vector3; +export using .::stdlib_1_7 import mx_curveadjust_vector4; +export using .::stdlib_1_7 import mx_luminance_color3; +export using .::stdlib_1_7 import mx_luminance_color4; +export using .::stdlib_1_7 import mx_rgbtohsv_color3; +export using .::stdlib_1_7 import mx_rgbtohsv_color4; +export using .::stdlib_1_7 import mx_hsvtorgb_color3; +export using .::stdlib_1_7 import mx_hsvtorgb_color4; +export using .::stdlib_1_7 import mx_premult_color4; +export using .::stdlib_1_7 import mx_unpremult_color4; +export using .::stdlib_1_7 import mx_plus_color4; +export using .::stdlib_1_7 import mx_minus_color4; +export using .::stdlib_1_7 import mx_difference_color4; +export using .::stdlib_1_7 import mx_burn_float; +export using .::stdlib_1_7 import mx_burn_color3; +export using .::stdlib_1_7 import mx_burn_color4; +export using .::stdlib_1_7 import mx_dodge_float; +export using .::stdlib_1_7 import mx_dodge_color3; +export using .::stdlib_1_7 import mx_dodge_color4; +export using .::stdlib_1_7 import mx_screen_color4; +export using .::stdlib_1_7 import mx_disjointover_color4; +export using .::stdlib_1_7 import mx_in_color4; +export using .::stdlib_1_7 import mx_mask_color4; +export using .::stdlib_1_7 import mx_matte_color4; +export using .::stdlib_1_7 import mx_out_color4; +export using .::stdlib_1_7 import mx_over_color4; +export using .::stdlib_1_7 import mx_mix_color4; +export using .::stdlib_1_7 import mx_mix_color4_color4; +export using .::stdlib_1_7 import mx_mix_volumeshader; +export using .::stdlib_1_7 import mx_mix_displacementshader; +export using .::stdlib_1_7 import mx_ifgreater_float; +export using .::stdlib_1_7 import mx_ifgreater_integer; +export using .::stdlib_1_7 import mx_ifgreater_color3; +export using .::stdlib_1_7 import mx_ifgreater_color4; +export using .::stdlib_1_7 import mx_ifgreater_vector2; +export using .::stdlib_1_7 import mx_ifgreater_vector3; +export using .::stdlib_1_7 import mx_ifgreater_vector4; +export using .::stdlib_1_7 import mx_ifgreater_matrix33; +export using .::stdlib_1_7 import mx_ifgreater_matrix44; +export using .::stdlib_1_7 import mx_ifgreater_boolean; +export using .::stdlib_1_7 import mx_ifgreater_floatI; +export using .::stdlib_1_7 import mx_ifgreater_integerI; +export using .::stdlib_1_7 import mx_ifgreater_color3I; +export using .::stdlib_1_7 import mx_ifgreater_color4I; +export using .::stdlib_1_7 import mx_ifgreater_vector2I; +export using .::stdlib_1_7 import mx_ifgreater_vector3I; +export using .::stdlib_1_7 import mx_ifgreater_vector4I; +export using .::stdlib_1_7 import mx_ifgreater_matrix33I; +export using .::stdlib_1_7 import mx_ifgreater_matrix44I; +export using .::stdlib_1_7 import mx_ifgreater_booleanI; +export using .::stdlib_1_7 import mx_ifgreatereq_float; +export using .::stdlib_1_7 import mx_ifgreatereq_integer; +export using .::stdlib_1_7 import mx_ifgreatereq_color3; +export using .::stdlib_1_7 import mx_ifgreatereq_color4; +export using .::stdlib_1_7 import mx_ifgreatereq_vector2; +export using .::stdlib_1_7 import mx_ifgreatereq_vector3; +export using .::stdlib_1_7 import mx_ifgreatereq_vector4; +export using .::stdlib_1_7 import mx_ifgreatereq_matrix33; +export using .::stdlib_1_7 import mx_ifgreatereq_matrix44; +export using .::stdlib_1_7 import mx_ifgreatereq_boolean; +export using .::stdlib_1_7 import mx_ifgreatereq_floatI; +export using .::stdlib_1_7 import mx_ifgreatereq_integerI; +export using .::stdlib_1_7 import mx_ifgreatereq_color3I; +export using .::stdlib_1_7 import mx_ifgreatereq_color4I; +export using .::stdlib_1_7 import mx_ifgreatereq_vector2I; +export using .::stdlib_1_7 import mx_ifgreatereq_vector3I; +export using .::stdlib_1_7 import mx_ifgreatereq_vector4I; +export using .::stdlib_1_7 import mx_ifgreatereq_matrix33I; +export using .::stdlib_1_7 import mx_ifgreatereq_matrix44I; +export using .::stdlib_1_7 import mx_ifgreatereq_booleanI; +export using .::stdlib_1_7 import mx_ifequal_float; +export using .::stdlib_1_7 import mx_ifequal_integer; +export using .::stdlib_1_7 import mx_ifequal_color3; +export using .::stdlib_1_7 import mx_ifequal_color4; +export using .::stdlib_1_7 import mx_ifequal_vector2; +export using .::stdlib_1_7 import mx_ifequal_vector3; +export using .::stdlib_1_7 import mx_ifequal_vector4; +export using .::stdlib_1_7 import mx_ifequal_matrix33; +export using .::stdlib_1_7 import mx_ifequal_matrix44; +export using .::stdlib_1_7 import mx_ifequal_boolean; +export using .::stdlib_1_7 import mx_ifequal_floatI; +export using .::stdlib_1_7 import mx_ifequal_integerI; +export using .::stdlib_1_7 import mx_ifequal_color3I; +export using .::stdlib_1_7 import mx_ifequal_color4I; +export using .::stdlib_1_7 import mx_ifequal_vector2I; +export using .::stdlib_1_7 import mx_ifequal_vector3I; +export using .::stdlib_1_7 import mx_ifequal_vector4I; +export using .::stdlib_1_7 import mx_ifequal_matrix33I; +export using .::stdlib_1_7 import mx_ifequal_matrix44I; +export using .::stdlib_1_7 import mx_ifequal_booleanI; +export using .::stdlib_1_7 import mx_ifequal_floatB; +export using .::stdlib_1_7 import mx_ifequal_integerB; +export using .::stdlib_1_7 import mx_ifequal_color3B; +export using .::stdlib_1_7 import mx_ifequal_color4B; +export using .::stdlib_1_7 import mx_ifequal_vector2B; +export using .::stdlib_1_7 import mx_ifequal_vector3B; +export using .::stdlib_1_7 import mx_ifequal_vector4B; +export using .::stdlib_1_7 import mx_ifequal_matrix33B; +export using .::stdlib_1_7 import mx_ifequal_matrix44B; +export using .::stdlib_1_7 import mx_ifequal_booleanB; +export using .::stdlib_1_7 import mx_creatematrix_vector3_matrix33; +export using .::stdlib_1_7 import mx_creatematrix_vector3_matrix44; +export using .::stdlib_1_7 import mx_creatematrix_vector4_matrix44; +export using .::stdlib_1_7 import mx_extract_color3; +export using .::stdlib_1_7 import mx_extract_color4; +export using .::stdlib_1_7 import mx_extract_vector2; +export using .::stdlib_1_7 import mx_extract_vector3; +export using .::stdlib_1_7 import mx_extract_vector4; +export using .::stdlib_1_7 import mx_blur_float; +export using .::stdlib_1_7 import mx_blur_color3; +export using .::stdlib_1_7 import mx_blur_color4; +export using .::stdlib_1_7 import mx_blur_vector2; +export using .::stdlib_1_7 import mx_blur_vector3; +export using .::stdlib_1_7 import mx_blur_vector4; +export using .::stdlib_1_7 import mx_heighttonormal_vector3; +export using .::stdlib_1_7 import mx_noise2d_float; +export using .::stdlib_1_7 import mx_noise2d_float2; +export using .::stdlib_1_7 import mx_noise2d_float3; +export using .::stdlib_1_7 import mx_noise2d_float4; +export using .::stdlib_1_7 import mx_noise3d_float; +export using .::stdlib_1_7 import mx_noise3d_float2; +export using .::stdlib_1_7 import mx_noise3d_float3; +export using .::stdlib_1_7 import mx_noise3d_float4; +export using .::stdlib_1_7 import mx_fractal3d_float; +export using .::stdlib_1_7 import mx_fractal3d_float2; +export using .::stdlib_1_7 import mx_fractal3d_float3; +export using .::stdlib_1_7 import mx_fractal3d_float4; +export using .::stdlib_1_7 import mx_cellnoise2d_float; +export using .::stdlib_1_7 import mx_cellnoise3d_float; +export using .::stdlib_1_7 import mx_worleynoise2d_float; +export using .::stdlib_1_7 import mx_worleynoise2d_float2; +export using .::stdlib_1_7 import mx_worleynoise2d_float3; +export using .::stdlib_1_7 import mx_worleynoise3d_float; +export using .::stdlib_1_7 import mx_worleynoise3d_float2; +export using .::stdlib_1_7 import mx_worleynoise3d_float3; +export using .::stdlib_1_7 import mx_combine2_color4CF; + +export using .::stdlib_1_7 import mx_geompropvalue_string; +export using .::stdlib_1_8 import mx_geompropvalue_boolean; +export using .::stdlib_1_8 import mx_geompropvalue_integer; +export using .::stdlib_1_8 import mx_geompropvalue_float; +export using .::stdlib_1_8 import mx_geompropvalue_color3; +export using .::stdlib_1_8 import mx_geompropvalue_color4; +export using .::stdlib_1_8 import mx_geompropvalue_vector2; +export using .::stdlib_1_8 import mx_geompropvalue_vector3; +export using .::stdlib_1_8 import mx_geompropvalue_vector4; +export using .::stdlib_1_8 import mx_viewdirection_vector3; + + + +// mix all parts of the material, bsdf, edf, and vdf, geometry +export material mx_mix_surfaceshader( + material mxp_fg = material() [[ anno::usage( "materialx:surfaceshader") ]], + material mxp_bg = material() [[ anno::usage( "materialx:surfaceshader") ]], + float mxp_mix = 0.0 +) [[ + anno::description("Node Group: compositing"), + anno::usage( "materialx:surfaceshader") +]] += material( + surface: material_surface( + scattering: df::weighted_layer( + weight: mxp_mix, + layer: mxp_fg.surface.scattering, + base: mxp_bg.surface.scattering + ), + emission: material_emission( + emission: df::clamped_mix( + df::edf_component[]( + df::edf_component( mxp_mix, mxp_fg.surface.emission.emission), + df::edf_component( 1.0 - mxp_mix, mxp_bg.surface.emission.emission)) + ), + intensity: mxp_mix * mxp_fg.surface.emission.intensity + + (1.0 - mxp_mix) * mxp_bg.surface.emission.intensity + ) + ), + + // we need to carry volume properties along for SSS + ior: mxp_mix * mxp_fg.ior + (1.0 - mxp_mix) * mxp_bg.ior, + volume: material_volume( + scattering: df::clamped_mix( + df::vdf_component[]( + df::vdf_component( mxp_mix, mxp_fg.volume.scattering), + df::vdf_component( 1.0 - mxp_mix, mxp_bg.volume.scattering)) + ), + absorption_coefficient: mxp_mix * mxp_fg.volume.absorption_coefficient + + (1.0 - mxp_mix) * mxp_bg.volume.absorption_coefficient, + scattering_coefficient: mxp_mix * mxp_fg.volume.scattering_coefficient + + (1.0 - mxp_mix) * mxp_bg.volume.scattering_coefficient + ), + geometry: material_geometry( + displacement: mxp_mix * mxp_fg.geometry.displacement + + (1.0 - mxp_mix) * mxp_bg.geometry.displacement, + cutout_opacity: mxp_mix * mxp_fg.geometry.cutout_opacity + + (1.0 - mxp_mix) * mxp_bg.geometry.cutout_opacity, + normal: mxp_mix * mxp_fg.geometry.normal + + (1.0 - mxp_mix) * mxp_bg.geometry.normal + ) +); diff --git a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp index e1a23cf7d4..638a4fd10c 100644 --- a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp +++ b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp @@ -225,15 +225,9 @@ void MdlShaderGeneratorTester::compileSource(const std::vector& so moduleToTest = moduleToTest.substr(0, moduleToTest.size() - sourceCodePaths[0].getExtension().length() - 1); std::string renderExec(MATERIALX_MDL_RENDER_EXECUTABLE); - bool testMDLC = renderExec.empty(); - if (testMDLC) + std::string mdlcExec(MATERIALX_MDLC_EXECUTABLE); + if (!mdlcExec.empty()) // always run compiler { - std::string mdlcExec(MATERIALX_MDLC_EXECUTABLE); - if (mdlcExec.empty()) - { - return; - } - std::string mdlcCommand = mdlcExec; // use the same paths as the resolver @@ -264,12 +258,19 @@ void MdlShaderGeneratorTester::compileSource(const std::vector& so _logFile << "\tReturn code: " << std::to_string(returnValue) << std::endl; writeErrorCode = true; } - _logFile << "\tError: " << line << std::endl; + if (line.find(": Warning ") != std::string::npos) + { + _logFile << "\tWarning: " << line << std::endl; + } + else + { + _logFile << "\tError: " << line << std::endl; + } } CHECK(returnValue == 0); } - else + if (!renderExec.empty()) // render if renderer is availabe { std::string renderCommand = renderExec; @@ -358,6 +359,7 @@ TEST_CASE("GenShader: MDL Shader Generation", "[genmdl]") mx::FilePathVec testRootPaths; testRootPaths.push_back(searchPath.find("resources/Materials/TestSuite")); testRootPaths.push_back(searchPath.find("resources/Materials/Examples/StandardSurface")); + testRootPaths.push_back(searchPath.find("resources/Materials/Examples/UsdPreviewSurface")); const mx::FilePath logPath("genmdl_mdl_generate_test.txt"); From 6fd2dc2f3ebea66afa705c24cc795aa9e8f64420 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Mon, 25 Nov 2024 14:03:35 -0800 Subject: [PATCH 4/9] Remove unimplemented nodes from libraries (#2120) This changelist removes the unimplemented 'ambientocclusion', 'arrayappend', and 'curveadjust' nodes from the MaterialX data libraries, aligning the data libraries with the current 1.39 specification. Additionally, this change removes hardcoded skip count checks from MaterialXTest, as these tests have not proven themselves to be a beneficial safeguard against regressions, and frequently trip up contributors to the MaterialX project. --- libraries/README.md | 3 -- .../stdlib/genglsl/stdlib_genglsl_impl.mtlx | 6 --- .../stdlib/genmdl/stdlib_genmdl_impl.mtlx | 7 --- .../stdlib/genmsl/stdlib_genmsl_impl.mtlx | 4 -- .../genosl/mx_ambientocclusion_float.osl | 5 -- .../stdlib/genosl/stdlib_genosl_impl.mtlx | 7 --- libraries/stdlib/stdlib_defs.mtlx | 53 ------------------- python/Scripts/genmdl.py | 8 +-- .../mdl/materialx/stdlib_1_6.mdl | 17 ------ .../mdl/materialx/stdlib_1_8.mdl | 1 - .../mdl/materialx/stdlib_1_9.mdl | 1 - .../MaterialXGenGlsl/GenGlsl.cpp | 2 +- .../MaterialXTest/MaterialXGenGlsl/GenGlsl.h | 2 +- .../MaterialXTest/MaterialXGenMdl/GenMdl.cpp | 2 +- source/MaterialXTest/MaterialXGenMdl/GenMdl.h | 2 +- .../MaterialXTest/MaterialXGenMsl/GenMsl.cpp | 2 +- source/MaterialXTest/MaterialXGenMsl/GenMsl.h | 2 +- .../MaterialXTest/MaterialXGenOsl/GenOsl.cpp | 2 +- source/MaterialXTest/MaterialXGenOsl/GenOsl.h | 2 +- .../MaterialXGenShader/GenShaderUtil.cpp | 6 +-- .../MaterialXGenShader/GenShaderUtil.h | 3 +- .../MaterialXRenderOsl/GenReference.cpp | 3 +- 22 files changed, 12 insertions(+), 128 deletions(-) delete mode 100644 libraries/stdlib/genosl/mx_ambientocclusion_float.osl diff --git a/libraries/README.md b/libraries/README.md index 15916f76e2..0ace221bcc 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -74,7 +74,4 @@ This folder contains the standard data libraries for MaterialX, providing declar - Basic GLSL and MSL `lightshader` node definitions and implementations are provided for the following light types: - point, directional, spot - Shader generation does not currently support: - - `ambientocclusion` node. - - `arrayappend` node. - - `curveadjust` node. - `displacementshader` and `volumeshader` nodes for hardware shading targets (GLSL, MSL). diff --git a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx index 69f8f9a7f8..ad3a21e9cf 100644 --- a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx +++ b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx @@ -129,12 +129,6 @@ - - - - - - diff --git a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx index b190937c41..6ac2b862dd 100644 --- a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx +++ b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx @@ -131,13 +131,6 @@ - - - - - - - diff --git a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx index afdfb2cfbb..3cb99052cf 100644 --- a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx +++ b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx @@ -45,10 +45,6 @@ - - - - diff --git a/libraries/stdlib/genosl/mx_ambientocclusion_float.osl b/libraries/stdlib/genosl/mx_ambientocclusion_float.osl deleted file mode 100644 index 10baf0b736..0000000000 --- a/libraries/stdlib/genosl/mx_ambientocclusion_float.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_ambientocclusion_float(float coneangle, float maxdistance, output float result) -{ - // This node is a stub and does not currently operate to specification - result = 0; -} diff --git a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx index 716e1072d7..db318976c5 100644 --- a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx +++ b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx @@ -131,13 +131,6 @@ - - - - - - - diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index 943e36ec88..e6f8d431e7 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -1354,21 +1354,6 @@ - - - - - - - - - - - @@ -2899,44 +2884,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp b/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp index b77eebbd86..a72207c581 100644 --- a/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp +++ b/source/MaterialXGenOsl/Nodes/ClosureLayerNodeOsl.cpp @@ -37,51 +37,6 @@ void ClosureLayerNodeOsl::emitFunctionCall(const ShaderNode& _node, GenContext& ShaderNode* top = topInput->getConnection()->getNode(); ShaderNode* base = baseInput->getConnection()->getNode(); -#ifdef MATERIALX_OSL_LEGACY_CLOSURES - - ClosureContext* cct = context.getClosureContext(); - - // Evaluate top and base nodes and combine their result - // according to throughput. - // - // TODO: In the BSDF over BSDF case should we emit code - // to check the top throughput amount before calling - // the base BSDF? - - // Make sure the connections are sibling nodes and not the graph interface. - if (top->getParent() == node.getParent()) - { - // If this layer node has closure parameters set, - // we pass this on to the top component only. - ScopedSetClosureParams setParams(&node, top, cct); - shadergen.emitFunctionCall(*top, context, stage); - } - if (base->getParent() == node.getParent()) - { - shadergen.emitFunctionCall(*base, context, stage); - } - - // Get the result variables. - const string& topResult = topInput->getConnection()->getVariable(); - const string& baseResult = baseInput->getConnection()->getVariable(); - - // Calculate the layering result. - emitOutputVariables(node, context, stage); - if (base->getOutput()->getType() == Type::VDF) - { - // Combining a surface closure with a volumetric closure is simply done with the add operator in OSL. - shadergen.emitLine(output->getVariable() + ".response = " + topResult + ".response + " + baseResult, stage); - // Just pass the throughput along. - shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput", stage); - } - else - { - shadergen.emitLine(output->getVariable() + ".response = " + topResult + ".response + " + baseResult + ".response * " + topResult + ".throughput", stage); - shadergen.emitLine(output->getVariable() + ".throughput = " + topResult + ".throughput * " + baseResult + ".throughput", stage); - } - -#else - // Emit the function call for top and base layer. // Make sure the connections are sibling nodes and not the graph interface. if (top->getParent() == node.getParent()) @@ -102,8 +57,6 @@ void ClosureLayerNodeOsl::emitFunctionCall(const ShaderNode& _node, GenContext& shadergen.emitOutput(output, true, false, context, stage); shadergen.emitString(" = layer(" + topResult + ", " + baseResult + ")", stage); shadergen.emitLineEnd(stage); - -#endif // MATERIALX_OSL_LEGACY_CLOSURES } MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp index d0d9d96cba..ff8cad36f5 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.cpp +++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp @@ -45,22 +45,6 @@ OslShaderGenerator::OslShaderGenerator() : registerImplementation("IM_layer_bsdf_" + OslShaderGenerator::TARGET, ClosureLayerNodeOsl::create); registerImplementation("IM_layer_vdf_" + OslShaderGenerator::TARGET, ClosureLayerNodeOsl::create); -#ifdef MATERIALX_OSL_LEGACY_CLOSURES - - // - registerImplementation("IM_mix_bsdf_" + OslShaderGenerator::TARGET, ClosureMixNode::create); - registerImplementation("IM_mix_edf_" + OslShaderGenerator::TARGET, ClosureMixNode::create); - // - registerImplementation("IM_add_bsdf_" + OslShaderGenerator::TARGET, ClosureAddNode::create); - registerImplementation("IM_add_edf_" + OslShaderGenerator::TARGET, ClosureAddNode::create); - // - registerImplementation("IM_multiply_bsdfC_" + OslShaderGenerator::TARGET, ClosureMultiplyNode::create); - registerImplementation("IM_multiply_bsdfF_" + OslShaderGenerator::TARGET, ClosureMultiplyNode::create); - registerImplementation("IM_multiply_edfC_" + OslShaderGenerator::TARGET, ClosureMultiplyNode::create); - registerImplementation("IM_multiply_edfF_" + OslShaderGenerator::TARGET, ClosureMultiplyNode::create); - -#endif // MATERIALX_OSL_LEGACY_CLOSURES - // registerImplementation("IM_surface_" + OslShaderGenerator::TARGET, SurfaceNodeOsl::create); @@ -158,10 +142,6 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G const bool isSurfaceShaderOutput = singleOutput && singleOutput->getType() == Type::SURFACESHADER; -#ifdef MATERIALX_OSL_LEGACY_CLOSURES - const bool isBsdfOutput = singleOutput && singleOutput->getType() == Type::BSDF; -#endif - if (isSurfaceShaderOutput) { // Special case for having 'surfaceshader' as final output type. @@ -170,16 +150,6 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G // to understand this output. emitLine("output closure color " + singleOutput->getVariable() + " = 0", stage, false); } -#ifdef MATERIALX_OSL_LEGACY_CLOSURES - else if (isBsdfOutput) - { - // Special case for having 'BSDF' as final output type. - // For legacy closures this type is a struct internally (response, throughput, thickness, ior) - // so we must declare this as a single closure color type in order for renderers - // to understand this output. - emitLine("output closure color " + singleOutput->getVariable() + " = 0", stage, false); - } -#endif else { // Just emit all outputs the way they are declared. @@ -253,18 +223,6 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G emitLine(singleOutput->getVariable() + " = (" + result + ".bsdf + " + result + ".edf) * opacity_weight + transparent() * (1.0 - opacity_weight)", stage); emitScopeEnd(stage); } -#ifdef MATERIALX_OSL_LEGACY_CLOSURES - else if (isBsdfOutput) - { - // Special case for having 'BSDF' as final output type. - // For legacy closures this type is a struct internally (response, throughput, thickness, ior) - // so we must declare this as a single closure color type in order for renderers - // to understand this output. - const ShaderGraphOutputSocket* socket = graph.getOutputSocket(0); - const string result = getUpstreamResult(socket, context); - emitLine(singleOutput->getVariable() + " = " + result + ".response", stage); - } -#endif else { // Assign results to final outputs. diff --git a/source/MaterialXGenOsl/OslSyntax.cpp b/source/MaterialXGenOsl/OslSyntax.cpp index 797a891ce6..a85821c4fd 100644 --- a/source/MaterialXGenOsl/OslSyntax.cpp +++ b/source/MaterialXGenOsl/OslSyntax.cpp @@ -371,19 +371,6 @@ OslSyntax::OslSyntax() EMPTY_STRING, "struct textureresource { string filename; string colorspace; };")); -#ifdef MATERIALX_OSL_LEGACY_CLOSURES - - registerTypeSyntax( - Type::BSDF, - std::make_shared( - "BSDF", - "BSDF(null_closure, color(1.0))", - "{ 0, color(1.0) }", - "closure color", - "struct BSDF { closure color response; color throughput; };")); - -#else - registerTypeSyntax( Type::BSDF, std::make_shared( @@ -393,8 +380,6 @@ OslSyntax::OslSyntax() "closure color", "#define BSDF closure color")); -#endif // MATERIALX_OSL_LEGACY_CLOSURES - registerTypeSyntax( Type::EDF, std::make_shared( diff --git a/source/MaterialXTest/CMakeLists.txt b/source/MaterialXTest/CMakeLists.txt index 4835787ed8..c3fae603dc 100644 --- a/source/MaterialXTest/CMakeLists.txt +++ b/source/MaterialXTest/CMakeLists.txt @@ -96,11 +96,6 @@ endif() add_custom_command(TARGET MaterialXTest POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/../../libraries ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libraries) -if(MATERIALX_OSL_LEGACY_CLOSURES) - add_custom_command(TARGET MaterialXTest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E rename - ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libraries/pbrlib/genosl/pbrlib_genosl_impl.legacy ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libraries/pbrlib/genosl/pbrlib_genosl_impl.mtlx) -endif() if(MATERIALX_BUILD_GEN_MDL) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../source/MaterialXGenMdl/mdl/" From 344705f0214332a8b7199832ff90aefb9b054200 Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Tue, 26 Nov 2024 12:49:28 -0500 Subject: [PATCH 6/9] Fix mxvalidate to check for stdlib usage (#2122) Patch `mxvalidate.py` script to avoid trying to access an undefined object `stdlib` if not specified from the command line (default). --- python/Scripts/mxvalidate.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/Scripts/mxvalidate.py b/python/Scripts/mxvalidate.py index 8cc1ee78fd..e0ccf34a4e 100755 --- a/python/Scripts/mxvalidate.py +++ b/python/Scripts/mxvalidate.py @@ -17,6 +17,7 @@ def main(): opts = parser.parse_args() # Load standard libraries if requested. + stdlib = None if opts.stdlib: stdlib = mx.createDocument() try: @@ -29,7 +30,8 @@ def main(): doc = mx.createDocument() try: mx.readFromXmlFile(doc, opts.inputFilename) - doc.setDataLibrary(stdlib) + if stdlib: + doc.setDataLibrary(stdlib) except mx.ExceptionFileMissing as err: print(err) sys.exit(0) From cbb63ec82de7be3cea6bc0c85f12223be1e87d5e Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 26 Nov 2024 16:26:27 -0800 Subject: [PATCH 7/9] Update MacOS version in GitHub CI (#2123) This changelist updates Python wheel generation to the `macos-14-large` environment in GitHub CI, as Python versions before 3.11 have been removed from the `macos-13` environment. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b2d5f182bf..3f67667550 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -389,7 +389,7 @@ jobs: fail-fast: false matrix: python-minor: ['7', '8', '9', '10', '11', '12'] - os: ['ubuntu-22.04', 'windows-2022', 'macos-13'] + os: ['ubuntu-22.04', 'windows-2022', 'macos-14-large'] steps: - name: Sync Repository From b6d473d01edcf2b61291e22f09ac182c32555a68 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 3 Dec 2024 17:28:54 -0800 Subject: [PATCH 8/9] Update changelog for recent work (#2129) --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fedc1ceaa..6fb0c98143 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ ## [1.39.2] - Development +### Added +- Added support for the [Chiang Hair BSDF](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1968), with initial implementations in hardware shading languages and MDL. +- Added support for the [Disney Principled](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2004) shading model, implemented as a language-independent graph. +- Added support for [data library referencing](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2054), enabling improved performance in shader generation. +- Added support for [custom structure types](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1831) in MaterialX. +- Added support for [functional equivalence](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2003) tests between MaterialX elements. +- Added support for [transmission effects](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2027) in the translation graph from Standard Surface to glTF PBR. +- Added support for [coated emission](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2087) in the translation graph from Standard Surface to UsdPreviewSurface. +- Added support for [Apple framework builds](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2020). +- Added support for [MDL 1.9](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2102) in shader generation. +- Added support for [viewdirection space](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2036) in hardware shading languages. +- Added a [combined version define](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2031) to MaterialX C++. +- Added a [release signing workflow](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2009) to GitHub Actions. +- Added documentation for [keyboard shortcuts](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2026) in the MaterialX Viewer. + +### Changed +- Reduced duplication between the [MSL and GLSL implementations](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2068) of nodes. + +### Fixed +- Fixed [unintentional camera orbiting](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2032) in the render view of the MaterialX Graph Editor. +- Fixed [banding artifacts](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1977) in the MaterialX Viewer on MacOS. +- Fixed a call to the [anisotropic_vdf closure](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2016) in OSL shader generation. + +### Removed +- Removed support for the [legacy OSL closures](https://github.com/AcademySoftwareFoundation/MaterialX/pull/2121), focusing exclusively on the MaterialX-synchronized closures in OSL 1.12 and beyond. + ## [1.39.1] - 2024-09-03 ### Added From bfbf6729385a7820dc2ab00332b30b93eff6a3e8 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 4 Dec 2024 10:36:45 -0800 Subject: [PATCH 9/9] Static analysis fixes (#2130) This changelist addresses a handful of static analysis warnings flagged by PVS-Studio: - Add a missing reference to `rhs` in `ValueElement::isAttributeEquivalent`. - Remove unused variables and unneeded string copies in `StructTypeSyntax::getValue` and `GlslStructTypeSyntax::getValue`. - Simplify boolean logic in `ClosureLayerNodeMdl::emitFunctionCall`. - Declare an immutable array as a `std::array` in `Viewer::createDocumentationInterface`. --- source/MaterialXCore/Element.cpp | 2 +- source/MaterialXGenGlsl/GlslSyntax.cpp | 4 ++-- source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp | 2 +- source/MaterialXGenShader/Syntax.cpp | 7 ++----- source/MaterialXView/Viewer.cpp | 2 +- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/source/MaterialXCore/Element.cpp b/source/MaterialXCore/Element.cpp index 3bede2fe74..78c59e9efc 100644 --- a/source/MaterialXCore/Element.cpp +++ b/source/MaterialXCore/Element.cpp @@ -749,7 +749,7 @@ bool ValueElement::isAttributeEquivalent(ConstElementPtr rhs, const string& attr else if (uiAttributes.find(attributeName) != uiAttributes.end()) { const string& uiAttribute = getAttribute(attributeName); - const string& rhsUiAttribute = getAttribute(attributeName); + const string& rhsUiAttribute = rhs->getAttribute(attributeName); ValuePtr uiValue = !rhsUiAttribute.empty() ? Value::createValueFromStrings(uiAttribute, getType()) : nullptr; ValuePtr rhsUiValue = !rhsUiAttribute.empty() ? Value::createValueFromStrings(rhsUiAttribute, getType()) : nullptr; if (uiValue && rhsUiValue) diff --git a/source/MaterialXGenGlsl/GlslSyntax.cpp b/source/MaterialXGenGlsl/GlslSyntax.cpp index 651a4ab5ff..7054725b76 100644 --- a/source/MaterialXGenGlsl/GlslSyntax.cpp +++ b/source/MaterialXGenGlsl/GlslSyntax.cpp @@ -400,8 +400,8 @@ string GlslStructTypeSyntax::getValue(const Value& value, bool /* uniform */) co result += separator; separator = ","; - auto memberTypeName = memberValue->getTypeString(); - auto memberTypeDesc = TypeDesc::get(memberTypeName); + const string& memberTypeName = memberValue->getTypeString(); + TypeDesc memberTypeDesc = TypeDesc::get(memberTypeName); // Recursively use the syntax to generate the output, so we can supported nested structs. result += _parentSyntax->getValue(memberTypeDesc, *memberValue, true); diff --git a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp index 8949ae6cc0..5b187f80aa 100644 --- a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp @@ -128,7 +128,7 @@ void ClosureLayerNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext& ShaderNode* fg = fgOutput ? fgOutput->getNode() : nullptr; ShaderNode* bg = bgOutput ? bgOutput->getNode() : nullptr; ShaderNode* mix = mixOutput ? mixOutput->getNode() : nullptr; - if ((fg && !bg) || (!fg && bg)) + if ((bool) fg != (bool) bg) { baseReceiverNode = fg ? fg : bg; // take the node that is valid top = baseReceiverNode; diff --git a/source/MaterialXGenShader/Syntax.cpp b/source/MaterialXGenShader/Syntax.cpp index b8eed3e9b8..81daa9e0a7 100644 --- a/source/MaterialXGenShader/Syntax.cpp +++ b/source/MaterialXGenShader/Syntax.cpp @@ -286,9 +286,6 @@ string StructTypeSyntax::getValue(const Value& value, bool /*uniform*/) const { const AggregateValue& aggValue = static_cast(value); - auto typeDesc = TypeDesc::get(aggValue.getTypeString()); - auto structTypeDesc = StructTypeDesc::get(typeDesc.getStructIndex()); - string result = "{"; string separator = ""; @@ -297,8 +294,8 @@ string StructTypeSyntax::getValue(const Value& value, bool /*uniform*/) const result += separator; separator = ";"; - auto memberTypeName = memberValue->getTypeString(); - auto memberTypeDesc = TypeDesc::get(memberTypeName); + const string& memberTypeName = memberValue->getTypeString(); + TypeDesc memberTypeDesc = TypeDesc::get(memberTypeName); // Recursively use the syntax to generate the output, so we can support nested structs. const string valueStr = _parentSyntax->getValue(memberTypeDesc, *memberValue, true); diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp index 46d03a1665..aefdf2d401 100644 --- a/source/MaterialXView/Viewer.cpp +++ b/source/MaterialXView/Viewer.cpp @@ -702,7 +702,7 @@ void Viewer::createDocumentationInterface(ng::ref parent) ng::Alignment::Minimum, 2, 2); gridLayout2->set_col_alignment({ ng::Alignment::Minimum, ng::Alignment::Maximum }); - const std::vector> KEYBOARD_SHORTCUTS = + const std::array, 16> KEYBOARD_SHORTCUTS = { std::make_pair("R", "Reload the current material from file. " "Hold SHIFT to reload all standard libraries as well."),