From 46a5b507b82bb38a70c66877e5d87e588ca9785e Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sun, 10 Sep 2023 10:50:11 -0700 Subject: [PATCH 001/128] Update development build to 1.38.9 --- CHANGELOG.md | 2 ++ CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5704c54b84..47b1bfe8b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Change Log +## [1.38.9] - Development + ## [1.38.8] - 2023-09-08 ### Added diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e8763d6c7..c255924fa4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # MaterialX Version set(MATERIALX_MAJOR_VERSION 1) set(MATERIALX_MINOR_VERSION 38) -set(MATERIALX_BUILD_VERSION 8) +set(MATERIALX_BUILD_VERSION 9) set(MATERIALX_LIBRARY_VERSION ${MATERIALX_MAJOR_VERSION}.${MATERIALX_MINOR_VERSION}.${MATERIALX_BUILD_VERSION}) # Cmake setup From 1a39d99a41ccfd5c0a12759b185af3946e2ff45f Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 12 Sep 2023 17:03:47 -0700 Subject: [PATCH 002/128] Update documentation - Update links to pre-built binaries in README.md. - Update link to ASWF Open Source Days in README.md. - Update MaterialX Overview in MainPage.md. - Update code and data syntax in ShaderGeneration.md. - Update documentation for the ImageHandler::acquireImage method. --- README.md | 8 +- documents/DeveloperGuide/MainPage.md | 2 +- documents/DeveloperGuide/ShaderGeneration.md | 135 +++++++++---------- source/MaterialXRender/ImageHandler.h | 3 + 4 files changed, 71 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index e6c6e2d0e4..ddccb4a9db 100644 --- a/README.md +++ b/README.md @@ -60,13 +60,13 @@ The Open Chess Set is an open reference asset, consisting of a [MaterialX file]( The following packages contain pre-built binaries for the latest release, including the MaterialX viewer, Python libraries, and example assets: -- [Microsoft Windows (Visual Studio 2022, Python 3.9)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_Windows_VS2022_x64_Python39.zip) -- [MacOS (Xcode 13, Python 3.9)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_MacOS_Xcode_13_Python39.zip) -- [Linux (GCC 11, Python 3.9)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_Linux_GCC_11_Python39.zip) +- [Microsoft Windows (Visual Studio 2022, Python 3.11)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_Windows_VS2022_x64_Python311.zip) +- [MacOS (Xcode 14, Python 3.11)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_MacOS_Xcode_14_Python311.zip) +- [Linux (GCC 12, Python 3.11)](https://github.com/AcademySoftwareFoundation/MaterialX/releases/latest/download/MaterialX_Linux_GCC_12_Python311.zip) ### Additional Resources - The [Developer Guide](http://www.materialx.org/docs/api/index.html) contains a developer-oriented overview of MaterialX with API documentation. - The [Python Scripts](python/Scripts) folder contains standalone examples of MaterialX Python code. - The [JavaScript](javascript) folder contains details on building JavaScript bindings for MaterialX. -- Presentations at [ASWF Open Source Days](http://www.materialx.org/assets/ASWF_OSD2022_MaterialX_OSL_Final.pdf) and the [SIGGRAPH Physically Based Shading Course](https://blog.selfshadow.com/publications/s2020-shading-course/#materialx) provide details on the roadmap for MaterialX development. +- Presentations at [ASWF Open Source Days](https://materialx.org/assets/ASWF_OSD2023_MaterialX_Final.pdf) and the [SIGGRAPH Physically Based Shading Course](https://blog.selfshadow.com/publications/s2020-shading-course/#materialx) provide details on the roadmap for MaterialX development. diff --git a/documents/DeveloperGuide/MainPage.md b/documents/DeveloperGuide/MainPage.md index 79441a3e4d..d6c098a23d 100644 --- a/documents/DeveloperGuide/MainPage.md +++ b/documents/DeveloperGuide/MainPage.md @@ -1,6 +1,6 @@ # MaterialX Overview -MaterialX is an open standard for transfer of rich material and look-development content between applications and renderers. Originated at Lucasfilm in 2012, MaterialX has been used by Industrial Light & Magic (ILM) in feature films such as _Star Wars: The Force Awakens_ and real-time experiences such as _Trials on Tatooine_, and it remains the central material format for new ILM productions. +MaterialX is an open standard for representing rich material and look-development content in computer graphics, enabling its platform-independent description and exchange across applications and renderers. Launched at [Industrial Light & Magic](https://www.ilm.com/) in 2012, MaterialX has been a key technology in their feature films and real-time experiences since _Star Wars: The Force Awakens_ and _Millennium Falcon: Smugglers Run_. The project was released as open source in 2017, with companies including Sony Pictures Imageworks, Pixar, Autodesk, Adobe, and SideFX contributing to its ongoing development. In 2021, MaterialX became the seventh hosted project of the [Academy Software Foundation](https://www.aswf.io/). ### Quick Start for Developers diff --git a/documents/DeveloperGuide/ShaderGeneration.md b/documents/DeveloperGuide/ShaderGeneration.md index 059b34d580..01bd823ec4 100644 --- a/documents/DeveloperGuide/ShaderGeneration.md +++ b/documents/DeveloperGuide/ShaderGeneration.md @@ -33,37 +33,41 @@ Figure 2. The first option is to keep inline code in a file. The file extension ```xml // Nodedef elements for node - - - + + + + - - - + + + + <... more types ...> // Implementation elements for node - - + + <... more types ...> // Nodedef elements for node - - - - + + + + + - - - - + + + + + <... more types ...> // Implementation elements for node - - + + <... more types ...> ``` ```c++ @@ -79,30 +83,29 @@ For nodes that can’t be implemented by inline expressions a function definitio ```xml // Nodedef element - - - - - - - - - - - + + + + + + + + + + + + // Implementation element - + ``` ```c++ // File 'mx_image_color3.osl' contains: void mx_image_color3(string file, string layer, color defaultvalue, - vector2 texcoord, string filtertype, - string uaddressmode, string vaddressmode, - string framerange, int frameoffset, - string frameendaction, output color out) + vector2 texcoord, string uaddressmode, string vaddressmode, string filtertype, + string framerange, int frameoffset, string frameendaction, + output color out) { // Sample the texture out = texture(file, texcoord.x, texcoord.y, @@ -120,40 +123,28 @@ As an alternative to defining source code, there is also an option to reference This is useful for creating a compound for a set of nodes performing some common operation. It can then be referenced as a node inside other nodegraphs. It is also useful for creating compatibility graphs for unknown nodes. If a node is created by some third party, and its implementation is unknown or proprietary, a compatibility graph can be created using known nodes and be referenced as a stand-in implementation. Linking a nodegraph to a nodedef is done by simply setting a nodedef attribute on the nodegraph definition. See Figure 4 for an example. ```xml - - + + + + - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + + + + + + - + ``` **Figure 4**: Checker node implementation using a nodegraph. @@ -161,10 +152,9 @@ This is useful for creating a compound for a set of nodes performing some common ### 1.3.4 Dynamic Code Generation In some situations static source code is not enough to implement a node. The code might need to be customized depending on parameters set on the node. Or for a hardware render target vertex streams or uniform inputs might need to be created in order to supply the data needed for the node implementation. -In this case, a C++ class can be added to handle the implementation of the node. The class should be derived from the base class `ShaderNodeImpl`. It should specify what language and target it is for by overriding `getLanguage()` and `getTarget()`. It can also be specified to support all languages or all targets by setting the identifier to an empty string, as done for the target identifier in the example below. It then needs to be registered for a `ShaderGenerator` by calling `ShaderGenerator::registerImplementation()`. See Figure 5 for an example. +In this case, a C++ class can be added to handle the implementation of the node. The class should be derived from the base class `ShaderNodeImpl`. It should specify what target it is for by overriding `getTarget()`. It then needs to be registered for a `ShaderGenerator` by calling `ShaderGenerator::registerImplementation()`. See Figure 5 for an example. -When a `ShaderNodeImpl` class is used for a nodedef the corresponding `` -element doesn’t need a file attribute, since no static source code is used. The `` element will then act only as a declaration that there exists an implementation for the nodedef for a particular language and target. +When a `ShaderNodeImpl` class is used for a nodedef the corresponding `` element doesn’t need a file attribute, since no static source code is used. The `` element will then act only as a declaration that there exists an implementation for the nodedef for a particular target. Note that by using a `ShaderNodeImpl` class for your node's implementation it is no longer data driven, as in the other three methods above. So it's recommended to use this only when inline expressions or static source code functions are not enough to handle the implementation of a node. @@ -175,8 +165,7 @@ class FooOsl : public ShaderNodeImpl public: static ShaderNodeImplPtr create() { return std::make_shared(); } - const string& getLanguage() const override { return LANGUAGE_OSL; } - const string& getTarget() const override { return EMPTY_STRING; } + const string& getTarget() const override { return OslShaderGenerator::TARGET; } void emitFunctionDefinition(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override @@ -291,7 +280,8 @@ class TexCoordGlsl : public ShaderNodeImpl const string index = indexInput ? indexInput->getValue()->getValueString() : "0"; const string variable = "texcoord_" + index; - BEGIN_SHADER_STAGE(stage, Stage::VERTEX) + DEFINE_SHADER_STAGE(stage, Stage::VERTEX) + { VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); const string prefix = vertexData.getInstance() + "."; ShaderPort* texcoord = vertexData[variable]; @@ -300,9 +290,10 @@ class TexCoordGlsl : public ShaderNodeImpl shadergen.emitLine(prefix + texcoord->getVariable() + " = i_" + variable, stage); texcoord->setEmitted(); } - END_SHADER_STAGE(shader, Stage::VERTEX) + } - BEGIN_SHADER_STAGE(stage, Stage::PIXEL) + DEFINE_SHADER_STAGE(stage, Stage::PIXEL) + { VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); const string prefix = vertexData.getInstance() + "."; ShaderPort* texcoord = vertexData[variable]; @@ -310,7 +301,7 @@ class TexCoordGlsl : public ShaderNodeImpl shadergen.emitOutput(node.getOutput(), true, false, context, stage); shadergen.emitString(" = " + prefix + texcoord->getVariable(), stage); shadergen.emitLineEnd(stage); - END_SHADER_STAGE(shader, Stage::PIXEL) + } } }; ``` diff --git a/source/MaterialXRender/ImageHandler.h b/source/MaterialXRender/ImageHandler.h index c744eb2f6a..fafc021857 100644 --- a/source/MaterialXRender/ImageHandler.h +++ b/source/MaterialXRender/ImageHandler.h @@ -186,7 +186,10 @@ class MX_RENDER_API ImageHandler /// Acquire an image from the cache or file system. If the image is not /// found in the cache, then each image loader will be applied in turn. + /// If the image cannot be found by any loader, then a uniform image of the + /// given default color will be returned. /// @param filePath File path of the image. + /// @param defaultColor Default color to use as a fallback for missing images. /// @return On success, a shared pointer to the acquired image. ImagePtr acquireImage(const FilePath& filePath, const Color4& defaultColor = Color4(0.0f)); From a5a74feab2eec007ca8e87eeb9c57c667e32ff2c Mon Sep 17 00:00:00 2001 From: Niklas Harrysson Date: Sun, 17 Sep 2023 00:11:53 +0200 Subject: [PATCH 003/128] Fix attenuation of coated emission in Standard Surface (#1534) This change list fixes a math mistake in the handling of how emission is attenuated by the top coat in Standard Surface. Thanks to @portsmouth and @Reedbeta for reporting my mistake and suggesting a workaround. --- libraries/bxdf/standard_surface.mtlx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libraries/bxdf/standard_surface.mtlx b/libraries/bxdf/standard_surface.mtlx index 843885aa50..c7de68929a 100644 --- a/libraries/bxdf/standard_surface.mtlx +++ b/libraries/bxdf/standard_surface.mtlx @@ -386,6 +386,10 @@ + + + + @@ -398,8 +402,8 @@ - - + + From 6c486837e682abd61fdd566fc28ef9980cdcda93 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Fri, 22 Sep 2023 10:26:46 -0700 Subject: [PATCH 004/128] Align default precision across shading languages (#1538) This changelist removes explicit overrides of floating-point precision in shader generation, making the default precision 6 decimal places across shading languages, and allowing the client to adjust the precision of generated shaders via Value::setFloatPrecision. This addresses a slight visual regression in generated OSL (with a maximum visual error on the order of 1e-3), caused by a hard-coding of floating-point precision to 3 decimal places in OslSyntax. --- source/MaterialXCore/Value.cpp | 5 ++++- source/MaterialXCore/Value.h | 2 +- source/MaterialXGenGlsl/GlslShaderGenerator.cpp | 4 +--- source/MaterialXGenMdl/MdlShaderGenerator.cpp | 3 +++ source/MaterialXGenMsl/MslShaderGenerator.cpp | 4 +--- source/MaterialXGenOsl/OslShaderGenerator.cpp | 3 +++ source/MaterialXGenOsl/OslSyntax.cpp | 1 - 7 files changed, 13 insertions(+), 9 deletions(-) diff --git a/source/MaterialXCore/Value.cpp b/source/MaterialXCore/Value.cpp index 238473d5ad..3e8c1f4462 100644 --- a/source/MaterialXCore/Value.cpp +++ b/source/MaterialXCore/Value.cpp @@ -242,7 +242,10 @@ ScopedFloatFormatting::ScopedFloatFormatting(Value::FloatFormat format, int prec _precision(Value::getFloatPrecision()) { Value::setFloatFormat(format); - Value::setFloatPrecision(precision); + if (precision >= 0) + { + Value::setFloatPrecision(precision); + } } ScopedFloatFormatting::~ScopedFloatFormatting() diff --git a/source/MaterialXCore/Value.h b/source/MaterialXCore/Value.h index 8e55a97acf..1bd29b1d2b 100644 --- a/source/MaterialXCore/Value.h +++ b/source/MaterialXCore/Value.h @@ -198,7 +198,7 @@ template class MX_CORE_API TypedValue : public Value class MX_CORE_API ScopedFloatFormatting { public: - explicit ScopedFloatFormatting(Value::FloatFormat format, int precision = 6); + explicit ScopedFloatFormatting(Value::FloatFormat format, int precision = -1); ~ScopedFloatFormatting(); private: diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp index 766b61ec05..839f591aa5 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp @@ -279,9 +279,7 @@ ShaderPtr GlslShaderGenerator::generate(const string& name, ElementPtr element, { ShaderPtr shader = createShader(name, element, context); - // Turn on fixed float formatting to make sure float values are - // emitted with a decimal point and not as integers, and to avoid - // any scientific notation which isn't supported by all OpenGL targets. + // Request fixed floating-point notation for consistency across targets. ScopedFloatFormatting fmt(Value::FloatFormatFixed); // Make sure we initialize/reset the binding context before generation. diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.cpp b/source/MaterialXGenMdl/MdlShaderGenerator.cpp index dddf1f2f13..f64b555c20 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.cpp +++ b/source/MaterialXGenMdl/MdlShaderGenerator.cpp @@ -198,6 +198,9 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G ShaderPtr shader = createShader(name, element, context); + // Request fixed floating-point notation for consistency across targets. + ScopedFloatFormatting fmt(Value::FloatFormatFixed); + ShaderGraph& graph = shader->getGraph(); ShaderStage& stage = shader->getStage(Stage::PIXEL); diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index dcb0a3ed69..0d97e8408f 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -283,9 +283,7 @@ ShaderPtr MslShaderGenerator::generate(const string& name, ElementPtr element, G { ShaderPtr shader = createShader(name, element, context); - // Turn on fixed float formatting to make sure float values are - // emitted with a decimal point and not as integers, and to avoid - // any scientific notation which isn't supported by all OpenGL targets. + // Request fixed floating-point notation for consistency across targets. ScopedFloatFormatting fmt(Value::FloatFormatFixed); // Make sure we initialize/reset the binding context before generation. diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp index b4edbee44b..b37a84c579 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.cpp +++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp @@ -170,6 +170,9 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G { ShaderPtr shader = createShader(name, element, context); + // Request fixed floating-point notation for consistency across targets. + ScopedFloatFormatting fmt(Value::FloatFormatFixed); + ShaderGraph& graph = shader->getGraph(); ShaderStage& stage = shader->getStage(Stage::PIXEL); diff --git a/source/MaterialXGenOsl/OslSyntax.cpp b/source/MaterialXGenOsl/OslSyntax.cpp index d421c5e3d9..5a6b45dd61 100644 --- a/source/MaterialXGenOsl/OslSyntax.cpp +++ b/source/MaterialXGenOsl/OslSyntax.cpp @@ -220,7 +220,6 @@ class OSLMatrix3TypeSyntax : public AggregateTypeSyntax string getValue(const Value& value, bool uniform) const override { - ScopedFloatFormatting fmt(Value::FloatFormatFixed, 3); StringVec values = splitString(value.getValueString(), ","); return getValue(values, uniform); } From 7009c6daf7459716350593e318e4243d6e808f19 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Thu, 28 Sep 2023 17:57:00 -0700 Subject: [PATCH 005/128] Initial coverage test in GitHub CI This changelist adds an initial coverage test to GitHub Actions builds, uploading the generated HTML document as a new build artifact. --- .github/workflows/main.yml | 61 +++++++++++++++++++++++++++----------- CMakeLists.txt | 6 ++++ 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d5ac9d3f79..4fdcefb7fb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,6 +39,14 @@ jobs: python: 3.11 upload_shaders: ON + - name: Linux_GCC_CoverageAnalysis + os: ubuntu-22.04 + compiler: gcc + compiler_version: "None" + python: None + coverage_analysis: ON + cmake_config: -DMATERIALX_COVERAGE_ANALYSIS=ON -DMATERIALX_BUILD_RENDER=OFF -DMATERIALX_BUILD_PYTHON=OFF + - name: Linux_Clang_10_Python37 os: ubuntu-20.04 compiler: clang @@ -120,28 +128,32 @@ jobs: run: | sudo apt-get update sudo apt-get install xorg-dev mesa-utils - if [ "${{ matrix.compiler }}" = "gcc" ]; then - sudo apt-get install -y g++-${{ matrix.compiler_version }} g++-${{ matrix.compiler_version }}-multilib - echo "CC=gcc-${{ matrix.compiler_version }}" >> $GITHUB_ENV - echo "CXX=g++-${{ matrix.compiler_version }}" >> $GITHUB_ENV - else - sudo apt-get install -y clang-${{ matrix.compiler_version }} libc++-${{ matrix.compiler_version }}-dev libc++abi-${{ matrix.compiler_version }}-dev - echo "CC=clang-${{ matrix.compiler_version }}" >> $GITHUB_ENV - echo "CXX=clang++-${{ matrix.compiler_version }}" >> $GITHUB_ENV + if [ "${{ matrix.compiler_version }}" != 'None' ]; then + if [ "${{ matrix.compiler }}" = "gcc" ]; then + sudo apt-get install -y g++-${{ matrix.compiler_version }} g++-${{ matrix.compiler_version }}-multilib + echo "CC=gcc-${{ matrix.compiler_version }}" >> $GITHUB_ENV + echo "CXX=g++-${{ matrix.compiler_version }}" >> $GITHUB_ENV + else + sudo apt-get install -y clang-${{ matrix.compiler_version }} libc++-${{ matrix.compiler_version }}-dev libc++abi-${{ matrix.compiler_version }}-dev + echo "CC=clang-${{ matrix.compiler_version }}" >> $GITHUB_ENV + echo "CXX=clang++-${{ matrix.compiler_version }}" >> $GITHUB_ENV + fi fi - name: Install Dependencies (MacOS) if: runner.os == 'macOS' run: | - if [ "${{ matrix.compiler }}" = "gcc" ]; then - brew install gcc@${{ matrix.compiler_version }} - echo "CC=gcc-${{ matrix.compiler_version }}" >> $GITHUB_ENV - echo "CXX=g++-${{ matrix.compiler_version }}" >> $GITHUB_ENV - else - ls -ls /Applications/ - sudo xcode-select -switch /Applications/Xcode_${{ matrix.compiler_version }}.app - echo "CC=clang" >> $GITHUB_ENV - echo "CXX=clang++" >> $GITHUB_ENV + if [ "${{ matrix.compiler_version }}" != 'None' ]; then + if [ "${{ matrix.compiler }}" = "gcc" ]; then + brew install gcc@${{ matrix.compiler_version }} + echo "CC=gcc-${{ matrix.compiler_version }}" >> $GITHUB_ENV + echo "CXX=g++-${{ matrix.compiler_version }}" >> $GITHUB_ENV + else + ls -ls /Applications/ + sudo xcode-select -switch /Applications/Xcode_${{ matrix.compiler_version }}.app + echo "CC=clang" >> $GITHUB_ENV + echo "CXX=clang++" >> $GITHUB_ENV + fi fi - name: Install Dependencies (Windows) @@ -222,6 +234,14 @@ jobs: run: | python python/Scripts/generateshader.py resources/Materials/Examples/StandardSurface --target msl --validator "xcrun metal --language=metal" --validatorArgs="-w" + - name: Coverage Analysis Tests + if: matrix.coverage_analysis == 'ON' + run: | + sudo apt-get install gcovr + mkdir coverage + gcovr --html --html-details --output coverage/index.html --exclude .*\/External\/.* --root .. . + working-directory: build + - name: Static Analysis Tests if: matrix.static_analysis == 'ON' && runner.os == 'Linux' run: | @@ -279,6 +299,13 @@ jobs: name: Renders_${{ matrix.name }} path: build/render/*.png + - name: Upload Coverage Report + uses: actions/upload-artifact@v3 + if: matrix.coverage_analysis == 'ON' + with: + name: MaterialX_Coverage + path: build/coverage + - name: JavaScript CMake Generate if: matrix.build_javascript == 'ON' run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index c255924fa4..de6aa7442f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ option(MATERIALX_INSTALL_PYTHON "Install the MaterialX Python package as a third option(MATERIALX_INSTALL_RESOURCES "Install the resources folder when building render modules." ON) option(MATERIALX_TEST_RENDER "Run rendering tests for MaterialX Render module. GPU required for graphics validation." ON) option(MATERIALX_WARNINGS_AS_ERRORS "Interpret all compiler warnings as errors." OFF) +option(MATERIALX_COVERAGE_ANALYSIS "Build MaterialX libraries with coverage analysis on supporting platforms." OFF) option(MATERIALX_DYNAMIC_ANALYSIS "Build MaterialX libraries with dynamic analysis on supporting platforms." OFF) option(MATERIALX_OSL_LEGACY_CLOSURES "Build OSL shader generation supporting the legacy OSL closures." ON) @@ -138,6 +139,7 @@ mark_as_advanced(MATERIALX_INSTALL_PYTHON) mark_as_advanced(MATERIALX_INSTALL_RESOURCES) mark_as_advanced(MATERIALX_TEST_RENDER) mark_as_advanced(MATERIALX_WARNINGS_AS_ERRORS) +mark_as_advanced(MATERIALX_COVERAGE_ANALYSIS) mark_as_advanced(MATERIALX_DYNAMIC_ANALYSIS) mark_as_advanced(MATERIALX_PYTHON_VERSION) mark_as_advanced(MATERIALX_PYTHON_EXECUTABLE) @@ -228,6 +230,10 @@ else() if(MATERIALX_WARNINGS_AS_ERRORS) add_compile_options(-Werror) endif() + if(MATERIALX_COVERAGE_ANALYSIS) + add_compile_options(--coverage -O0) + add_link_options(--coverage) + endif() if(MATERIALX_DYNAMIC_ANALYSIS) set(DYNAMIC_ANALYSIS_OPTIONS -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-sanitize-recover=all) add_compile_options(${DYNAMIC_ANALYSIS_OPTIONS}) From 0bd09787e869619ea4ca0f78fe89711539d9f2cf Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 3 Oct 2023 09:08:10 -0700 Subject: [PATCH 006/128] Improvements to shader generation tests - Include all example documents by default in shader generation tests, rather than excluding a subset of the examples in all generators. - Remove an unused input from the render test suite options, eliminating a source of syntax errors in shader generation tests. --- resources/Materials/TestSuite/_options.mtlx | 3 --- .../MaterialXGenShader/GenShaderUtil.cpp | 21 ------------------- .../MaterialXGenShader/GenShaderUtil.h | 8 +++---- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/resources/Materials/TestSuite/_options.mtlx b/resources/Materials/TestSuite/_options.mtlx index 8716cba5f0..bb29fbd7c1 100644 --- a/resources/Materials/TestSuite/_options.mtlx +++ b/resources/Materials/TestSuite/_options.mtlx @@ -87,9 +87,6 @@ - - - diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp index 863cd1af05..261aacdefe 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp @@ -480,27 +480,6 @@ void ShaderGeneratorTester::setupDependentLibraries() loadLibraries({ "libraries" }, _searchPath, _dependLib, _skipLibraryFiles); } -void ShaderGeneratorTester::addSkipFiles() -{ - _skipFiles.insert("_options.mtlx"); - _skipFiles.insert("light_rig_test_1.mtlx"); - _skipFiles.insert("light_rig_test_2.mtlx"); - _skipFiles.insert("light_compound_test.mtlx"); - _skipFiles.insert("xinclude_search_path.mtlx"); - _skipFiles.insert("1_38_parameter_to_input.mtlx"); - _skipFiles.insert("1_36_to_1_37.mtlx"); - _skipFiles.insert("1_37_to_1_38.mtlx"); - _skipFiles.insert("material_element_to_surface_material.mtlx"); -} - -void ShaderGeneratorTester::addSkipNodeDefs() -{ -} - -void ShaderGeneratorTester::addSkipLibraryFiles() -{ -} - LightIdMap ShaderGeneratorTester::computeLightIdMap(const std::vector& nodes) { std::unordered_map idMap; diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h index 7be195e9de..ea34170d71 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h @@ -180,13 +180,13 @@ class ShaderGeneratorTester virtual void setTestStages() = 0; // Add files in to not examine - virtual void addSkipFiles(); + virtual void addSkipFiles() { }; // Add nodedefs to not examine - virtual void addSkipNodeDefs(); + virtual void addSkipNodeDefs() { }; // Add files to be skipped while loading libraries - virtual void addSkipLibraryFiles(); + virtual void addSkipLibraryFiles() { }; // Add color management virtual void addColorManagement(); @@ -268,8 +268,6 @@ class ShaderGeneratorTester mx::StringSet _usedImplementations; }; - - } // namespace GenShaderUtil #endif From a79ddfb25589955bdb6060f4ce379dce56029275 Mon Sep 17 00:00:00 2001 From: Niklas Harrysson Date: Wed, 4 Oct 2023 17:16:32 +0200 Subject: [PATCH 007/128] Use explicit colorspace parameters in OSL texture calls (#1546) This change list adds the parameter "colorspace" to the texture call in OSL, for sampling color3/color4 textures. Previously this was supported under the covers, by token replacement that a custom OSL generator had to setup, and only done for the Arnold OSL generator. --- libraries/stdlib/genosl/mx_image_color3.osl | 3 +-- libraries/stdlib/genosl/mx_image_color4.osl | 2 +- source/MaterialXGenOsl/OslShaderGenerator.cpp | 4 ---- source/MaterialXGenOsl/OslShaderGenerator.h | 3 --- 4 files changed, 2 insertions(+), 10 deletions(-) diff --git a/libraries/stdlib/genosl/mx_image_color3.osl b/libraries/stdlib/genosl/mx_image_color3.osl index 15b594e885..89ba94f376 100644 --- a/libraries/stdlib/genosl/mx_image_color3.osl +++ b/libraries/stdlib/genosl/mx_image_color3.osl @@ -12,6 +12,5 @@ void mx_image_color3(textureresource file, string layer, color default_value, ve color missingColor = default_value; vector2 st = mx_transform_uv(texcoord); - out = texture(file.filename, st.x, st.y, "subimage", layer, "missingcolor", missingColor, "swrap", uaddressmode, "twrap", vaddressmode $extraTextureLookupArguments); + out = texture(file.filename, st.x, st.y, "subimage", layer, "missingcolor", missingColor, "swrap", uaddressmode, "twrap", vaddressmode, "colorspace", file.colorspace); } - diff --git a/libraries/stdlib/genosl/mx_image_color4.osl b/libraries/stdlib/genosl/mx_image_color4.osl index 3bde1a5047..261108b5b4 100644 --- a/libraries/stdlib/genosl/mx_image_color4.osl +++ b/libraries/stdlib/genosl/mx_image_color4.osl @@ -15,7 +15,7 @@ void mx_image_color4(textureresource file, string layer, color4 default_value, v vector2 st = mx_transform_uv(texcoord); float alpha; color rgb = texture(file.filename, st.x, st.y, "alpha", alpha, "subimage", layer, - "missingcolor", missingColor, "missingalpha", missingAlpha, "swrap", uaddressmode, "twrap", vaddressmode $extraTextureLookupArguments ); + "missingcolor", missingColor, "missingalpha", missingAlpha, "swrap", uaddressmode, "twrap", vaddressmode, "colorspace", file.colorspace); out = color4(rgb, alpha); } diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp index b37a84c579..28ada48626 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.cpp +++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp @@ -26,7 +26,6 @@ MATERIALX_NAMESPACE_BEGIN const string OslShaderGenerator::TARGET = "genosl"; -const string OslShaderGenerator::T_FILE_EXTRA_ARGUMENTS = "$extraTextureLookupArguments"; // // OslShaderGenerator methods @@ -161,9 +160,6 @@ OslShaderGenerator::OslShaderGenerator() : // registerImplementation("IM_surfacematerial_" + OslShaderGenerator::TARGET, MaterialNodeOsl::create); - - // Extra arguments for texture lookups. - _tokenSubstitutions[T_FILE_EXTRA_ARGUMENTS] = EMPTY_STRING; } ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, GenContext& context) const diff --git a/source/MaterialXGenOsl/OslShaderGenerator.h b/source/MaterialXGenOsl/OslShaderGenerator.h index 91690adc1d..0c7ca426d7 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.h +++ b/source/MaterialXGenOsl/OslShaderGenerator.h @@ -48,9 +48,6 @@ class MX_GENOSL_API OslShaderGenerator : public ShaderGenerator void registerShaderMetadata(const DocumentPtr& doc, GenContext& context) const override; protected: - // Extra file arguments for texture lookup call - static const string T_FILE_EXTRA_ARGUMENTS; - /// Create and initialize a new OSL shader for shader generation. virtual ShaderPtr createShader(const string& name, ElementPtr element, GenContext& context) const; From ab4c211ac3bc033afa8c9a0dbcfafa48eff2147e Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Wed, 4 Oct 2023 11:26:15 -0400 Subject: [PATCH 008/128] Add XML tags to MaterialX blocks in specification (#1544) - Add xml formatting tag for spec markdown docs. - Existing docs like shader gen already use the appropriate formatting tags. - Tested this with converters such as pandoc, and VScode markdown converter and should make no difference as they will just end up as preformatted text `
`.
---
 documents/Specification/MaterialX.GeomExts.md |  42 +++---
 .../Specification/MaterialX.Specification.md  | 130 +++++++++---------
 .../Specification/MaterialX.Supplement.md     |   2 +-
 3 files changed, 87 insertions(+), 87 deletions(-)

diff --git a/documents/Specification/MaterialX.GeomExts.md b/documents/Specification/MaterialX.GeomExts.md
index fb0d581ed8..5ff300de01 100644
--- a/documents/Specification/MaterialX.GeomExts.md
+++ b/documents/Specification/MaterialX.GeomExts.md
@@ -113,7 +113,7 @@ Collections are recipes for building a list of geometries (which can be any path
 
 A **<collection>** element contains lists of geometry expressions and/or collections to be included, and an optional list of geometry expressions to be excluded:
 
-```
+```xml
   
@@ -132,7 +132,7 @@ As a shorthand convenience, MaterialX allows the specification of a `geomprefix`
 So the following MTLX file snippets are equivalent:
 
 
-```
+```xml
   
     
   
@@ -176,7 +176,7 @@ The most common use for geominfo elements is to define the filenames (or portion
 
 A **<geominfo>** element contains one or more geometry property and/or token definitions, and associates them and their values with all geometries listed in the `geom` or `collection` attribute of the <geominfo>:
 
-```
+```xml
   
     ...geometry property and token value definitions...
   
@@ -200,7 +200,7 @@ The core MaterialX Specification defines a Geometric Property, or "geomprop", as
 
 MaterialX Geometry Extensions expands upons this by allowing the use of <geomprop> elements to define specific uniform values of a geometric property with specific geometries, as opposed to relying on those values being defined externally.  This could include application-specific metadata, attributes passed from a lighting package to a renderer, or other geometry-specific data.  A geomprop may also specify a `unittype` and `unit` if appropriate to indicate that the geometric property's value is in that unit; see the [**Units** section of the main MaterialX Specification](./MaterialX.Specification.md#units), although typically the <geompropdef> would define the `unittype` and `unit`, and a geomprop would only provide an overriding `unit` if the unit for its value differed from the geompropdef's defined default unit.
 
-```
+```xml
     
 ```
 
@@ -216,7 +216,7 @@ Only float and vectorN geometric properties may specify a `unittype` an
 
 For example, one could specify a unique surface ID value associated with a geometry:
 
-```
+```xml
   
   
     
@@ -225,13 +225,13 @@ For example, one could specify a unique surface ID value associated with a geome
 
 GeomProp values can be accessed from a nodegraph using a `` node:
 
-```
+```xml
   
 ```
 
 A <geomprop> can also be used to define a default value for an intrinsic varying geometric property such as "geomcolor" for the geometry specified by the enclosing <geominfo>, which would be returned by the corresponding Geometric node (e.g. <geomcolor>) if the current geometry did not itself define values for that property.
 
-```
+```xml
   
     
   
@@ -243,7 +243,7 @@ A <geomprop> can also be used to define a default value for an intrinsic vary
 
 Token elements may be used within <geominfo> elements to define constant (typically string or integer) named values associated with specific geometries.  These geometry token values can be substituted into filenames within image nodes; see the [**Additional Filename Substitutions**](#additional-filename-substitutions) section above for details:
 
-```
+```xml
   
 ```
 
@@ -257,7 +257,7 @@ Token elements have the following attributes:
 
 For example, one could specify a texture identifier value associated with a geometry:
 
-```
+```xml
   
     
   
@@ -265,7 +265,7 @@ For example, one could specify a texture identifier value associated with a geom
 
 and then reference that token's value in a filename:
 
-```
+```xml
   
     
@@ -279,7 +279,7 @@ The <txtid> in the file name would be replaced by whatever value the txtid to
 
 TokenDefault elements define the default value for a specified geometry token name; this default value will be used in a filename string substitution if an explicit token value is not defined for the current geometry.  Since TokenDefault does not apply to any geometry in particular, it must be used outside of a <geominfo> element.
 
-```
+```xml
   
 ```
 
@@ -288,7 +288,7 @@ TokenDefault elements define the default value for a specified geometry token na
 
 Workflows involving textures with implicitly-computed filenames based on u,v coordinates (such as <UDIM> and <UVTILE>) can be made more efficient by explicitly listing the set of values that they resolve to for any given geometry.  The MaterialX specification reserves two geomprop names for this purpose, `udimset` and `uvtileset`, each of which is a stringarray containing a comma-separated list of UDIM or UVTILE values:
 
-```
+```xml
   
     
   
@@ -313,7 +313,7 @@ A MaterialX document can contain multiple property and/or look elements.
 
 A **<property>** element defines the name, type and value of a look-specific non-material property of geometry; <**propertyset**> elements are used to group a number of <property>s into a single named object.  The connection between properties or propertysets and specific geometries or collections is done in a <look> element, so that these properties can be reused across different geometries, and enabled in some looks but not others.  <Property> elements may only be used within <propertyset>s; they may not be used independently, although a dedicated <propertyassign> element may be used within a <look> to declare a property name, type, value and assignment all at once.
 
-```
+```xml
   
     
     
@@ -338,7 +338,7 @@ In the example above, the "trace_maxdiffusedepth" property is target-specific, h
 
 A **<look>** element contains one or more material, variant, visibility and/or propertyset assignment declarations:
 
-```
+```xml
   
     ...materialassign, variantassign, visibilityassign, property/propertysetassign declarations...
   
@@ -348,7 +348,7 @@ Looks can inherit the assignments from another look by including an `inherit` at
 
 A number of looks can be grouped together into a **LookGroup**, e.g. to indicate which looks are defined for a particular asset:
 
-```
+```xml
   
 ```
 
@@ -368,7 +368,7 @@ For elements which make assignments to geometries, the pathed names within `geom
 
 MaterialAssign elements are used within a <look> to connect a specified material to one or more geometries or collections (either a `geom` or a `collection` may be specified, but not both).
 
-```
+```xml
   
@@ -383,7 +383,7 @@ Material assignments are generally assumed to be mutually-exclusive, that is, an
 
 VariantAssign elements are used within a <materialassign> or a <look> to apply the values defined in one variant of a variantset to one assigned material, or to all applicable materials in a look.
 
-```
+```xml
   
     
     
@@ -407,7 +407,7 @@ In the above example, the input/token values defined within variant "var1" will
 
 Visibility elements are used within a <look> to define various types of generalized visibility between a "viewer" object and other geometries.  A "viewer object" is simply a geometry that has the ability to "see" other geometries in some rendering context and thus may need to have the list of geometries that it "sees" in different contexts be specified; the most common examples are light sources and a primary rendering camera.
 
-```
+```xml
   
@@ -442,7 +442,7 @@ If the <visibility> `geom` or `collection` refers to light geometry, then ass
 
 For the "secondary" vistype, `viewergeom` should be renderable geometry rather than a light, to declare that certain other geometry is or is not visible to indirect bounce illumination or raytraced reflections in that `viewergeom`.  In this example, "/b" would not be seen in reflections nor contribute indirect bounce illumination to "/a", while geometry "/c" would not be visible to _any_ secondary rays:
 
-```
+```xml
   
   
 ```
@@ -452,7 +452,7 @@ For the "secondary" vistype, `viewergeom` should be renderable geometry rather t
 
 PropertyAssign and PropertySetAssign elements are used within a <look> to connect a specified property value or propertyset to one or more geometries or collections.
 
-```
+```xml
   
@@ -467,7 +467,7 @@ Either a `geom` or a `collection` may be specified, but not both.  Multiple prop
 
 This example defines four collections, a light shader and material, and a propertyset, which are then used by two looks:
 
-```
+```xml
 
 
   
diff --git a/documents/Specification/MaterialX.Specification.md b/documents/Specification/MaterialX.Specification.md
index 7e876bdb57..4b99956fb4 100644
--- a/documents/Specification/MaterialX.Specification.md
+++ b/documents/Specification/MaterialX.Specification.md
@@ -267,7 +267,7 @@ Types not defined with a specific semantic are assumed to have semantic="default
 
 Custom types are defined using the <typedef> element:
 
-```
+```xml
   
   
 ```
@@ -292,7 +292,7 @@ The standard MaterialX distribution includes definitions for four "shader"-seman
 
 An MTLX file (with file extension ".mtlx") has the following general form:
 
-```
+```xml
   
   
     
@@ -303,7 +303,7 @@ That is, a standard XML declaration line followed by a root <materialx> eleme
 
 Standard XML XIncludes are supported ([http://en/wikipedia.org/wiki/XInclude](http://en/wikipedia.org/wiki/Xinclude)), as well as standard XML comments and the XML character entities `"`, `&`, `'`, `<` and `>`:
 
-```
+```xml
   
   
   
@@ -345,7 +345,7 @@ The working color space of a MaterialX document is defined by the `colorspace` a
 
 The color space of individual color image files and values may be defined via a `colorspace` attribute in an input which defines a filename or value.  Color images and values in spaces other than the working color space are expected to be transformed by the application into the working space before computations are performed.  In the example below, an image file has been defined in the “srgb_texture” color space, while its default value has been defined in “lin_rec709”; both should be transformed to the application’s working color space before being applied to any computations.
 
-```
+```xml
   
     
@@ -364,7 +364,7 @@ MaterialX allows floating-point and vector values to be defined in terms of a sp
 
 Unit types are defined using a <unittypedef> element, and a set of units of that type is defined using a <unitdef> element with one or more child <unit> elements:
 
-```
+```xml
   
   
     
@@ -397,7 +397,7 @@ References to elements in a different namespace are qualified using the syntax "
 
 Mtllib.mtlx contains the following (assuming that "..." contains any necessary material input connections and other element definitions):
 
-```
+```xml
   
   
     ...
@@ -412,7 +412,7 @@ Mtllib.mtlx contains the following (assuming that "..." contains any necessary m
 
 Then another MaterialX file could reference these materials like this:
 
-```
+```xml
     
     ...
     
@@ -423,7 +423,7 @@ Then another MaterialX file could reference these materials like this:
 
 Similarly, if a .mtlx file defining the "site_ops" namespace defined a custom color3-typed node "mynoise" with a single float input "f", it could be used in a node graph like this:
 
-```
+```xml
     
       
     
@@ -431,7 +431,7 @@ Similarly, if a .mtlx file defining the "site_ops" namespace defined a custom co
 
 A `namespace` attribute may also be added to individual <nodedef>s or <nodegraph>s, in which case the `name` and `node` of a <nodedef>, or just the `name` of a <nodegraph> will be assigned to the specified `namespace`.  In a <nodegraph>, the `nodedef` must include a namespace reference if the <nodedef> to which it refers is defined in a specific namespace, even if it's the same namespace as the <nodegraph>: this is because the `namespace` only applies to the content that is created by or contained within an element, not to anything external referenced by that element.
 
-```
+```xml
   
     
   
@@ -453,14 +453,14 @@ Geometric Properties, or "geomprops", are intrinsic or user-defined surface coor
 
 One may also define custom geometric properties using a <geompropdef> element:
 
-```
+```xml
   
 ```
 
 e.g.
 
-```
+```xml
   
   
 ```
@@ -469,13 +469,13 @@ The `type` of the geomprop may be any non-array MaterialX type, although `string
 
 Once defined, a custom geomprop name may be used any place that a standard geomprop can:
 
-```
+```xml
   
 ```
 
 A geompropdef may also specify a `unittype` and a `unit` to indicate that the geometric property is defined in terms of a specific unit.  If a geomprop with a defined unit is accessed in a nodegraph using <geompropvalue>, the geometric property value will be converted from the unit specified by the geompropdef to the application-specified scene unit.
 
-```
+```xml
   
 ```
 
@@ -487,7 +487,7 @@ As a shorthand convenience, MaterialX allows the specification of a `fileprefix`
 
 So the following snippets are equivalent:
 
-```
+```xml
   
     
       
@@ -538,7 +538,7 @@ Nodes are individual data generation or processing "blocks".  Node functionality
 
 Individual node elements have the form:
 
-```
+```xml
   
     
@@ -560,7 +560,7 @@ Node elements contain zero or more <input> elements defining the name, type,
 
 A float/vectorN input of a node, or a "filename"-type input referring to an image file containing float or vectorN values, may specify a unit for its value by providing a `unit` attribute, and that unit must be one associated with the `unittype` for that input in the nodedef, if specified; please see the [Units](#units) section above for details on declaring units and unittypes.  If the nodedef for a node (see the [Custom Nodes](#custom-nodes) section below) does not declare a `unittype` for an input, the node may do so; it is not permissible to provide a `unit` for a node input without a compatible `unittype` being defined on either the node or applicable nodedef.
 
-```
+```xml
   
     
   
@@ -570,7 +570,7 @@ Unless specified otherwise, all inputs default to a value of 0 in all channels f
 
 A node input must generally be connected to outputs of the same type, but float inputs may also be connected to any single channel within a multi-channel data types by adding an integer "channel" attribute, indicating the channel number (0-3) to extract from the input:
 
-```
+```xml
   
     
   
@@ -593,7 +593,7 @@ Standard MaterialX nodes have exactly one output, while custom nodes may have an
 
 A graph containing any number of nodes and output declarations forms a Node Graph, which may be enclosed within a <nodegraph> element to group them together into a single functional unit.  Please see the [Custom Node Definition Using Node Graphs](#custom-node-definition-using-node-graphs) section below for details on how nodegraphs can be used to describe the functionality of new nodes.
 
-```
+```xml
   
     ...node element(s)...
     ...output element(s)...
@@ -606,7 +606,7 @@ A graph containing any number of nodes and output declarations forms a Node Grap
 
 Output data streams are defined using **<output>** elements, and may be used to declare which output streams are connectable to other MaterialX elements.  Within a node graph, an <output> element declares an output stream that may be connected to a shader input or to the input of a referencing node in another graph when the nodegraph is the implementation of a custom node.  See the [Custom Node Definition Using Node Graphs](#custom-node-definition-using-node-graphs) section for details on the use of node graphs as node implementations.
 
-```
+```xml
   
   
@@ -640,7 +640,7 @@ This section defines the Source Nodes that all MaterialX implementations are exp
 
 Texture nodes are used to read filtered image data from image or texture map files for processing within a node graph.
 
-```
+```xml
   
     
     
@@ -721,7 +721,7 @@ Arbitrary frame number expressions and speed changes are not supported.
 
 Procedural nodes are used to generate value data programmatically.
 
-```
+```xml
   
     
   
@@ -900,7 +900,7 @@ To scale or offset the noise pattern generated by `noise3d`, `fractal3d` or `cel
 
 Geometric nodes are used to reference local geometric properties from within a node graph:
 
-```
+```xml
   
   
     
@@ -982,7 +982,7 @@ Applications may also reference other renderer-specific named spaces, at the exp
 
 Global nodes generate color data using non-local geometric context, requiring access to geometric features beyond the surface point being processed.  This non-local context can be provided by tracing rays into the scene, rasterizing scene geometry, or any other appropriate method.
 
-```
+```xml
   
     
   
@@ -1002,7 +1002,7 @@ Standard Global nodes:
 
 Application nodes are used to reference application-defined properties within a node graph, and have no inputs:
 
-```
+```xml
   
   
 ```
@@ -1028,7 +1028,7 @@ Standard Application nodes:
 
 Operator nodes process one or more required input streams to form an output.  Like other nodes, each operator must define its output type, which in most cases also determines the type(s) of the required input streams.
 
-```
+```xml
   
     
     
@@ -1786,7 +1786,7 @@ A simple merge of two single-layer images with a separate mask image, followed b
 
 ![Nodegraph Example 1](media/nodegraph1.png "Nodegraph Example 1")
 
-```
+```xml
 
 
   
@@ -1818,7 +1818,7 @@ A more complex nodegraph using geometry properties to define two diffuse albedo
 
 ![Nodegraph Example 2](media/nodegraph2.png "Nodegraph Example 2")
 
-```
+```xml
 
 
   
@@ -1885,7 +1885,7 @@ MaterialX supports the definition of nodes, attributes and inputs that are speci
 
 Targets are declared using a <targetdef> element:
 
-```
+```xml
   
   
   
@@ -1893,7 +1893,7 @@ Targets are declared using a <targetdef> element:
 
 A target may inherit from another target, so that any reference to a parent target will automatically include any definitions specific to the inherited child target that do not have a definition for the parent target itself:
 
-```
+```xml
   
   
   
@@ -1913,14 +1913,14 @@ While the MaterialX specification describes the attributes and elements that are
 If an application requires additional information related to any MaterialX element, it may define and utilize additional attributes with non-standard names.  Custom attributes are defined using <attributedef> elements:
 
 
-```
+```xml
   
 ```
 
 where _name_ is a unique name for the attributedef, _attrname_ is the name of the custom attribute to define, _type_ is the type of the attribute (typically string, stringarray, integer or boolean, although any MaterialX type is allowed), _defaultvalue_ is the default value for the attribute, _target_ is an optional list of targets to which this attribute applies, and _elements_ is an optional list of element names or elementname/inputname in which the attribute may be used.  It is also permissible to provide enum and enumvalues attributes for an attributedef, to define specific labels and values that the custom attribute is allowed to take, using the same syntax and limitations as enum/enumvalues on nodedef inputs and tokens (see below).  By default, a custom attribute is not emitted as metadata in generated shaders, but can be exported if the `exportable` attribute is set to "true".  Examples:
 
-```
+```xml
   
   
     
   
@@ -1948,7 +1948,7 @@ Once defined, custom attributes may be used in exactly the same manner as standa
 
 If an application requires additional custom inputs within a standard MaterialX node, it may define a target application-specific <nodedef> for that node inheriting the base input definitions from the standard node's <nodedef>, then add inputs specific to that target application.  
 
-```
+```xml
   
     
   
@@ -1958,7 +1958,7 @@ In the above example, a Maya-specific version of the color4-type <image> node
 
 When using a node, the definition appropriate for the current target will automatically be used, and other targets will ignore any inputs that are not part of the nodedef for that target.  However, one may specify a documentational  `target` attribute on an input to hint what target it is intended for if desired.  In this example, the "preFilter" input has indicated that it is specific to the "maya" target.
 
-```
+```xml
   
     
     
@@ -1998,7 +1998,7 @@ NodeDefs must define one or more child <output> elements within the <noded
 
 The parameter interface of a custom node is specified via a set of child <input> and <token> elements of the <nodedef>, while documentation of the folder structure of a node may be defined using a number of <uifolder> elements, each of which may provide a doc attribute to provide documentation for that folder layer.  A <uifolder> element may not contain any other elements; in particular, the <input>s and <token>s of the nodedef interface must be direct children of the <nodedef>.  Nested folders may be indicated using a full path for the folder, with a "/" separator between folder levels.
 
-```
+```xml
   
     
     
@@ -2012,7 +2012,7 @@ The parameter interface of a custom node is specified via a set of child <inp
 
 **Input** elements are used within a <nodedef> to declare the spatially-varying and uniform inputs for a node:
 
-```
+```xml
   
 ```
 
@@ -2047,7 +2047,7 @@ It is permissible to define a `value` or a `defaultgeomprop` for an input but no
 
 **Token** elements are used within a <nodedef> to declare uniform "interface token" string-substitution values to be referenced and substituted within filenames used in a node's nodegraph implementation:
 
-```
+```xml
   
 ```
 
@@ -2068,7 +2068,7 @@ Please see the [Example Pre-Shader Compositing Material](#example-pre-shader-com
 
 **Output** elements are used within a <nodedef> to declare an output for node definitions, including the output's name, type, and default value or "defaultinput" connection:
 
-```
+```xml
   
 ```
 
@@ -2103,7 +2103,7 @@ An <implementation> may define a `file` or `sourcecode` attribute, or neither
 
 Because the names used for node inputs (such as "normal" or "default") may conflict with the reserved words in various shading languages, or may simply be different for specific targets, <implementation> elements may contain a number of <input> elements to remap the `name`s of <input>s as specified in the <nodedef> to different `implname`s to indicate what the input name is actually called in the implementation's code.  Only the inputs that need to be remapped to new `implname`s need to be listed; for each, it is recommended that the `type` of that input be listed for clarity, but if specified, it must match the type specified in the <nodedef>: <implementation>s are not allowed to change the type or any other attribute defined in the <nodedef>.  In this example, the <implementation> declares that the "default" input defined in the "ND_image_color3" nodedef is actually called "default_value" in the "mx_image_color" function:
 
-```
+```xml
   
     
@@ -2112,7 +2112,7 @@ Because the names used for node inputs (such as "normal" or "default") may confl
 
 For uniform inputs and tokens whose nodedef description includes an enum list of allowable values, individual implementations may associate different target-specific resolved values for them potentially of a different type; these may be described by providing an `enumvalues` attribute on the uniform input or token within an <implementation> and if appropriate, an `impltype` to declare the target-specific type of these enumvalues.  Note that if the type of an enum input in the nodedef is an array type, then the `impltype` (if specified) must also be an array type, while `enumvalues` is a list of values of the base (non-array) type.  The following <implementation> states that for the "mystudio" target, the uaddressmode and vaddressmode inputs of the "image" node are actually called "extrapolate_u" and "extrapolate_v", are integers rather than strings, and take different values (e.g. "clamp" is 2):
 
-```
+```xml
   
   
      element with a file attribute defining an external compiled implementation of a surface shader may contain one or more <aov> elements to declare the names and types of arbitrary output variables ("AOVs") which the shader can output to the renderer.  AOVs must be of type float, color3, vector3, BSDF or EDF.  Note that in MaterialX, AOVs for pre-shading "pattern" colors are normally of type color3, while post-shaded color-like values are normally of type BSDF and emissive color-like values are normally of type EDF.  An <implementation> with a `nodegraph` attribute may not contain <aov> elements; instead, <aovoutput> elements within the nodegraph should be used.
 
-```
+```xml
   
@@ -2139,7 +2139,7 @@ An <implementation> element with a file attribute defining an external compil
 
 #### Example Custom Nodes Defined by External File Implementations
 
-```
+```xml
   
     
     
@@ -2179,7 +2179,7 @@ This example defines two templates for a custom operator node called "mariBlend"
 
 Here is an example of a two-output node definition and external implementation declaration.
 
-```
+```xml
   
     
     
@@ -2203,7 +2203,7 @@ A **<nodegraph>** element consists of at least one node element and at least
 
 A **functional nodegraph** is a nodegraph-based implementation for a specified <nodedef>, with the <nodedef> declaring the set of inputs that the nodegraph accepts: a functional nodegraph may not itself specify any direct child input elements.
 
-```
+```xml
   
     ...node element(s)...
     ...output element(s)...
@@ -2212,7 +2212,7 @@ A **functional nodegraph** is a nodegraph-based implementation for a specified &
 
 or
 
-```
+```xml
   
     ...node element(s)...
     ...output element(s)...
@@ -2223,7 +2223,7 @@ or
 
 The type(s) of the <output>(s) of the <nodedef> and the type(s) of the nodegraph <output>(s) must agree, and if there are multiple outputs, then the `name`s of the <output>s in the <nodegraph> and <nodedef> must also agree.  The inputs and tokens of the <nodedef> can be referenced within <input> and <token> elements of nodes within the nodegraph implementation using `interfacename` attributes in place of `value` or `nodename` attributes, e.g. a nodedef input "i2" and interface token "diffmap" could be referenced as follows:
 
-```
+```xml
     
     
 ```
@@ -2235,7 +2235,7 @@ Note that a uniform <input> of a node within the nodegraph may use `interface
 
 A **compound <nodegraph>** element may specify one or more child <input> and/or <token> elements.  In this case, the <nodegraph> functions as a collapsible "wrapper" for the contained nodes.
 
-```
+```xml
   
     [...input and/or token element(s)...]
     ...node and/or (compound) nodegraph element(s)...
@@ -2250,7 +2250,7 @@ It is permissible to define multiple nodegraph- and/or file-based implementation
 
 #### Example Custom Node Defined by a Nodegraph
 
-```
+```xml
   
     
     
@@ -2277,7 +2277,7 @@ The inputs of the nodegraph are declared by the <nodedef>, and the nodes with
 
 Once defined with a <nodedef>, using a custom node within a node graph follows the same syntax as any other standard node: the name of the element is the name of the custom node, and the MaterialX type of the node's output is required; the custom node's child elements define connections of inputs to other node outputs as well as any input values for the custom node.
 
-```
+```xml
   
     
     
@@ -2292,7 +2292,7 @@ Once defined with a <nodedef>, using a custom node within a node graph follow
 
 When invoking nodes with multiple outputs, the `type` of the node should be declared as "multioutput", and other node inputs connecting to an output of the node must include an `output` attribute to specify which output of the node to connect to:
 
-```
+```xml
   
     
     
@@ -2313,7 +2313,7 @@ When invoking nodes with multiple outputs, the `type` of the node should be decl
 
 Custom nodes that output data types with a "shader" semantic are referred to in MaterialX as "Shader Nodes".  Shaders, along with their inputs, are declared using the same <nodedef>, <implementation> and <nodegraph> elements described above:
 
-```
+```xml
   
     ...input declarations...
     
@@ -2331,7 +2331,7 @@ NodeDef elements defining shader nodes do not typically include `default` or `de
 
 As mentioned in the [Custom Data Types](#custom-data-types) section earlier, the standard MaterialX distribution includes the following standard data types for shaders:
 
-```
+```xml
   
   
   
@@ -2342,7 +2342,7 @@ These types all declare that they have "shader" semantic, but define different c
 
 Instantiation of shader nodes to give them specific values is done the same way as instantiating any other node type:
 
-```
+```xml
   
     
     
@@ -2352,7 +2352,7 @@ Instantiation of shader nodes to give them specific values is done the same way
 
 Instantiated shader nodes can also inherit from other shader nodes of the same class:
 
-```
+```xml
   
     
   
@@ -2398,7 +2398,7 @@ The Standard MaterialX Library defines the following nodes and node variants ope
 
 A functional nodegraph with either a "shader" or "material"-semantic output type may contain a number of <aovoutput> elements to declare arbitrary output variables ("AOVs") which the renderer can see and output as additional streams of information.  AOVoutputs must be of type float, color3 or vector3 for pre-shading "pattern" values, or BSDF or EDF for shader-node output values; the renderer is expected to extract the appropriate color-like information from BSDF and EDF types.  AOVs defined within a shader-semantic node instantiated within this functional nodegraph may be "passed along" and potentially renamed (but may not be modified or operated on in any way) by providing a sourceaov attribute in the <aovoutput>.
 
-```
+```xml
   
 ```
@@ -2413,7 +2413,7 @@ The attributes for <aovoutput> elements are:
 
 Examples:
 
-```
+```xml
   
   
@@ -2424,7 +2424,7 @@ Examples:
 
 Example of using <aovoutput> with sourceaov to forward AOVs from within an instantiation of a shader-semantic node; this assumes that <standard_surface> has itself defined <aovoutput>s for "diffuse" and "specular" AOVs:
 
-```
+```xml
   
     
       s for geometric
 
 Custom nodes that output data types with a "material" semantic are referred to in MaterialX as "Material Nodes".  Material nodes typically have one or more "shader" semantic inputs which establish what shaders the material references; previous versions of MaterialX used <shaderref> elements to establish these shader-to-material connections.  Material Nodes are declared using the same <nodedef> elements as described above:
 
-```
+```xml
   
     
     ...additional shader or input declarations...
@@ -2476,7 +2476,7 @@ The attributes for <nodedef> elements as they pertain to the declaration of m
 
 The standard MaterialX distribution includes a single material type definition used as the output type for all material nodes:
 
-```
+```xml
   
 ```
 
@@ -2501,7 +2501,7 @@ as well as definitions for three standard material nodes, all outputting type "m
 
 Material nodes supporting multiple shaders of the same type for different rendering targets can be defined:
 
-```
+```xml
   
     
     
@@ -2514,7 +2514,7 @@ Material nodes supporting multiple shaders of the same type for different render
 
 Creating materials with specific values bound to shader inputs involves instantiating a Shader Node for each desired shader type and setting values on those shader nodes, and connecting the shader node(s) to the inputs of a Material Node:
 
-```
+```xml
   
     
     
@@ -2535,7 +2535,7 @@ Alternatively, and perhaps more usefully, a complete network of multiple shader
 
 Materials can inherit from other materials, to add or change shaders connected to different inputs; in this example, a displacement shader is added to the above "Mgold" material to create a new "Mgolddsp" material:
 
-```
+```xml
   
     
     
@@ -2555,7 +2555,7 @@ Inheritance of material-type custom nodes is also allowed, so that new or change
 
 A material to blend between three different surface layers using mask textures.  This example also demonstrates the use of the "target" attribute of a shader implementation element to define multiple renderer-specific shaders of the same type referenced within a single material, and the use of interface tokens to define texture filenames.
 
-```
+```xml
 
 
   
+
+  
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+    
+      
+    
+  
+  
+    
+    
+    
+    
+    
+    
+    
+    
+  
+  
+    
+  
+
diff --git a/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_25.mtlx b/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_25.mtlx
new file mode 100644
index 0000000000..df723e7054
--- /dev/null
+++ b/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_25.mtlx
@@ -0,0 +1,28 @@
+
+
+  
+
+  
+    
+    
+    
+    
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  
+
diff --git a/resources/Materials/TestSuite/stdlib/upgrade/1_36_to_1_37.mtlx b/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_36.mtlx
similarity index 99%
rename from resources/Materials/TestSuite/stdlib/upgrade/1_36_to_1_37.mtlx
rename to resources/Materials/TestSuite/stdlib/upgrade/syntax_1_36.mtlx
index 84db1c6101..08a049435f 100644
--- a/resources/Materials/TestSuite/stdlib/upgrade/1_36_to_1_37.mtlx
+++ b/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_36.mtlx
@@ -1,9 +1,7 @@
 
 
   
 
   
diff --git a/resources/Materials/TestSuite/stdlib/upgrade/1_37_to_1_38.mtlx b/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx
similarity index 62%
rename from resources/Materials/TestSuite/stdlib/upgrade/1_37_to_1_38.mtlx
rename to resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx
index 28b9ae8ad2..3cb8eb6237 100644
--- a/resources/Materials/TestSuite/stdlib/upgrade/1_37_to_1_38.mtlx
+++ b/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx
@@ -1,5 +1,9 @@
 
-
+
+  
+
   
     
       
@@ -37,4 +41,24 @@
       
     
+ + + + + + + + + + + + + + + + + + + + diff --git a/source/MaterialXCore/Document.cpp b/source/MaterialXCore/Document.cpp index 4ba48cc84b..0449189873 100644 --- a/source/MaterialXCore/Document.cpp +++ b/source/MaterialXCore/Document.cpp @@ -492,12 +492,10 @@ void Document::upgradeVersion() if (nodeDef->hasAttribute("shadertype")) { nodeDef->setType(SURFACE_SHADER_TYPE_STRING); - nodeDef->removeAttribute("shadertype"); } if (nodeDef->hasAttribute("shaderprogram")) { nodeDef->setNodeString(nodeDef->getAttribute("shaderprogram")); - nodeDef->removeAttribute("shaderprogram"); } } else if (child->getCategory() == "shaderref") @@ -751,8 +749,18 @@ void Document::upgradeVersion() // Remove legacy shader nodedefs. for (NodeDefPtr nodeDef : getNodeDefs()) { - if (nodeDef->getType() == "surface") + if (nodeDef->hasAttribute("shadertype")) { + for (ElementPtr mat : getChildrenOfType("material")) + { + for (ElementPtr shaderRef : mat->getChildrenOfType("shaderref")) + { + if (shaderRef->getAttribute(InterfaceElement::NODE_DEF_ATTRIBUTE) == nodeDef->getName()) + { + shaderRef->removeAttribute(InterfaceElement::NODE_DEF_ATTRIBUTE); + } + } + } removeNodeDef(nodeDef->getName()); } } diff --git a/source/MaterialXGraphEditor/RenderView.cpp b/source/MaterialXGraphEditor/RenderView.cpp index 176014ba65..d2967e6b85 100644 --- a/source/MaterialXGraphEditor/RenderView.cpp +++ b/source/MaterialXGraphEditor/RenderView.cpp @@ -82,26 +82,6 @@ void applyModifiers(mx::DocumentPtr doc, const DocumentModifiers& modifiers) } } - // Remap references to unimplemented shader nodedefs. - for (mx::NodePtr materialNode : doc->getMaterialNodes()) - { - for (mx::NodePtr shader : getShaderNodes(materialNode)) - { - mx::NodeDefPtr nodeDef = shader->getNodeDef(); - if (nodeDef && !nodeDef->getImplementation()) - { - std::vector altNodeDefs = doc->getMatchingNodeDefs(nodeDef->getNodeString()); - for (mx::NodeDefPtr altNodeDef : altNodeDefs) - { - if (altNodeDef->getImplementation()) - { - shader->setNodeDefString(altNodeDef->getName()); - } - } - } - } - } - // Remap unsupported texture coordinate indices. for (mx::ElementPtr elem : doc->traverseTree()) { diff --git a/source/MaterialXTest/MaterialXCore/Document.cpp b/source/MaterialXTest/MaterialXCore/Document.cpp index 29092071cf..af39035dbe 100644 --- a/source/MaterialXTest/MaterialXCore/Document.cpp +++ b/source/MaterialXTest/MaterialXCore/Document.cpp @@ -108,108 +108,3 @@ TEST_CASE("Document", "[document]") // Validate the combined document. REQUIRE(doc->validate()); } - -TEST_CASE("Version", "[document]") -{ - mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); - mx::DocumentPtr stdlib = mx::createDocument(); - mx::loadLibraries({ "libraries" }, searchPath, stdlib); - searchPath.append(searchPath.find("resources/Materials/TestSuite/stdlib/upgrade")); - - // 1.36 to 1.37 - { - mx::DocumentPtr doc = mx::createDocument(); - mx::readFromXmlFile(doc, "1_36_to_1_37.mtlx", searchPath); - doc->importLibrary(stdlib); - REQUIRE(doc->validate()); - - mx::XmlWriteOptions writeOptions; - writeOptions.writeXIncludeEnable = true; - std::string xmlString = mx::writeToXmlString(doc, &writeOptions); - - mx::DocumentPtr doc2 = mx::createDocument(); - mx::readFromXmlString(doc2, xmlString); - REQUIRE(doc2->validate()); - - // Check conversion to desired types occurred - std::unordered_map convertSet = - { - { "invertmatrix", 2}, - { "rotate2d", 1}, - { "rotate3d", 1}, - { "transformmatrix", 7}, - { "ifgreatereq", 7}, - { "separate2", 1}, - { "separate3", 1}, - { "separate4", 1}, - { "combine2", 1}, - { "combine3", 1}, - { "combine4", 1} - }; - for (mx::NodePtr node : doc2->getNodes()) - { - auto convertItem = convertSet.find(node->getCategory()); - if (convertItem != convertSet.end()) - { - convertItem->second--; - } - } - for (auto convertItem : convertSet) - { - REQUIRE((convertItem.second == 0)); - } - } - - // 1.37 to 1.38 - { - mx::DocumentPtr doc = mx::createDocument(); - mx::readFromXmlFile(doc, "1_37_to_1_38.mtlx", searchPath); - doc->importLibrary(stdlib); - REQUIRE(doc->validate()); - - mx::XmlWriteOptions writeOptions; - writeOptions.writeXIncludeEnable = false; - std::string xmlString = mx::writeToXmlString(doc, &writeOptions); - - mx::DocumentPtr doc2 = mx::createDocument(); - mx::readFromXmlString(doc2, xmlString); - REQUIRE(doc2->validate()); - - // atan2 test - const std::string ATAN2 = "atan2"; - mx::StringMap ATAN2_MAP; - ATAN2_MAP["in1"] = "in2"; - ATAN2_MAP["in2"] = "in1"; - - for (mx::ElementPtr elem : doc->traverseTree()) - { - mx::NodePtr node = elem->asA(); - if (!node) - { - continue; - } - const std::string& nodeCategory = node->getCategory(); - if (nodeCategory == ATAN2) - { - const std::string &nodePath = node->getNamePath(); - for (auto in : ATAN2_MAP) - { - mx::ElementPtr input = node->getChild(in.first); - if (input) - { - mx::ElementPtr newNode = doc2->getDescendant(nodePath); - REQUIRE((newNode && newNode->getChild(in.second))); - } - } - } - } - - mx::NodeGraphPtr testNodeGraph = doc2->getNodeGraph("NG_Test"); - REQUIRE(!testNodeGraph->getNode("add")); - REQUIRE(testNodeGraph->getNode("add1")); - REQUIRE(testNodeGraph->getNode("add2")); - REQUIRE(testNodeGraph->getNode("add2")->getInput("in1")->getInterfaceName() == "add"); - REQUIRE(testNodeGraph->getNode("add1")->getInput("in1")->getNodeName() == "add2"); - } -} - diff --git a/source/MaterialXTest/MaterialXRender/RenderUtil.cpp b/source/MaterialXTest/MaterialXRender/RenderUtil.cpp index af392a9a05..0460f9282a 100644 --- a/source/MaterialXTest/MaterialXRender/RenderUtil.cpp +++ b/source/MaterialXTest/MaterialXRender/RenderUtil.cpp @@ -76,19 +76,6 @@ void ShaderRenderTester::loadDependentLibraries(GenShaderUtil::TestSuiteOptions loadAdditionalLibraries(dependLib, options); } -void ShaderRenderTester::addSkipFiles() -{ - _skipFiles.insert("_options.mtlx"); - _skipFiles.insert("light_rig_test_1.mtlx"); - _skipFiles.insert("light_rig_test_2.mtlx"); - _skipFiles.insert("light_compound_test.mtlx"); - _skipFiles.insert("xinclude_search_path.mtlx"); - _skipFiles.insert("1_38_parameter_to_input.mtlx"); - _skipFiles.insert("1_36_to_1_37.mtlx"); - _skipFiles.insert("1_37_to_1_38.mtlx"); - _skipFiles.insert("material_element_to_surface_material.mtlx"); -} - bool ShaderRenderTester::validate(const mx::FilePath optionsFilePath) { #ifdef LOG_TO_FILE @@ -144,9 +131,6 @@ bool ShaderRenderTester::validate(const mx::FilePath optionsFilePath) } ioTimer.endTimer(); - // Add files to skip - addSkipFiles(); - // Load in the library dependencies once // This will be imported in each test document below ioTimer.startTimer(); @@ -215,11 +199,6 @@ bool ShaderRenderTester::validate(const mx::FilePath optionsFilePath) for (const mx::FilePath& file : files) { - if (_skipFiles.count(file)) - { - continue; - } - ioTimer.startTimer(); // Check if a file override set is used and ignore all files // not part of the override set diff --git a/source/MaterialXTest/MaterialXRender/RenderUtil.h b/source/MaterialXTest/MaterialXRender/RenderUtil.h index 9f892569de..b29145dcb1 100644 --- a/source/MaterialXTest/MaterialXRender/RenderUtil.h +++ b/source/MaterialXTest/MaterialXRender/RenderUtil.h @@ -114,9 +114,6 @@ class ShaderRenderTester } #endif - // Add files to skip - void addSkipFiles(); - // Load dependencies void loadDependentLibraries(GenShaderUtil::TestSuiteOptions options, mx::FileSearchPath searchPath, mx::DocumentPtr& dependLib); @@ -181,9 +178,6 @@ class ShaderRenderTester bool _resolveImageFilenames; mx::StringResolverPtr _customFilenameResolver; - // Files to skip - mx::StringSet _skipFiles; - // Color management information mx::ColorManagementSystemPtr _colorManagementSystem; mx::FilePath _colorManagementConfigFile; diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp index 6346658d07..560a19e778 100644 --- a/source/MaterialXView/Viewer.cpp +++ b/source/MaterialXView/Viewer.cpp @@ -121,26 +121,6 @@ void applyModifiers(mx::DocumentPtr doc, const DocumentModifiers& modifiers) } } - // Remap references to unimplemented shader nodedefs. - for (mx::NodePtr materialNode : doc->getMaterialNodes()) - { - for (mx::NodePtr shader : getShaderNodes(materialNode)) - { - mx::NodeDefPtr nodeDef = shader->getNodeDef(); - if (nodeDef && !nodeDef->getImplementation()) - { - std::vector altNodeDefs = doc->getMatchingNodeDefs(nodeDef->getNodeString()); - for (mx::NodeDefPtr altNodeDef : altNodeDefs) - { - if (altNodeDef->getImplementation()) - { - shader->setNodeDefString(altNodeDef->getName()); - } - } - } - } - } - // Remap unsupported texture coordinate indices. for (mx::ElementPtr elem : doc->traverseTree()) { From 85dc5e1ea3239de507af07143224fd1c7852ee75 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sat, 7 Oct 2023 09:59:34 -0700 Subject: [PATCH 011/128] Improvements to 1.37 upgrade (#1555) - Add an example shading model graph using MaterialX 1.37 syntax, allowing improved coverage of version upgrade logic in unit tests. - Simplify the logic for 1.37 upgrades in Document::upgradeVersion, removing legacy code that was dedicated to upgrading the MaterialX standard libraries. --- .../TestSuite/stdlib/upgrade/syntax_1_37.mtlx | 151 ++++++++++------ source/MaterialXCore/Document.cpp | 166 +++++------------- 2 files changed, 144 insertions(+), 173 deletions(-) diff --git a/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx b/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx index 3cb8eb6237..66dc69f668 100644 --- a/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx +++ b/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx @@ -4,61 +4,110 @@ Examples of MaterialX 1.37 syntax --> - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + diff --git a/source/MaterialXCore/Document.cpp b/source/MaterialXCore/Document.cpp index 0449189873..80143bb9c8 100644 --- a/source/MaterialXCore/Document.cpp +++ b/source/MaterialXCore/Document.cpp @@ -1040,39 +1040,7 @@ void Document::upgradeVersion() } } - // Update atan2 interface and rotate3d interface - const string ATAN2 = "atan2"; - const string IN1 = "in1"; - const string IN2 = "in2"; - const string ROTATE3D = "rotate3d"; - const string AXIS = "axis"; - const string INPUT_ONE = "1.0"; - - // Update nodedefs - bool upgradeAtan2Instances = false; - for (auto nodedef : getMatchingNodeDefs(ATAN2)) - { - InputPtr input = nodedef->getInput(IN1); - InputPtr input2 = nodedef->getInput(IN2); - string inputValue = input->getValueString(); - // Only flip value if nodedef value is the previous versions. - if (inputValue == INPUT_ONE) - { - input->setValueString(input2->getValueString()); - input2->setValueString(inputValue); - upgradeAtan2Instances = true; - } - } - for (auto nodedef : getMatchingNodeDefs(ROTATE3D)) - { - ElementPtr axis = nodedef->getChild(AXIS); - if (axis) - { - nodedef->changeChildCategory(axis, "input"); - } - } - - // Update BSDF interfaces + // Define BSDF node pairs. using StringPair = std::pair; const StringPair DIELECTRIC_BRDF = { "dielectric_brdf", "dielectric_bsdf" }; const StringPair DIELECTRIC_BTDF = { "dielectric_btdf", "dielectric_bsdf" }; @@ -1085,57 +1053,11 @@ void Document::upgradeVersion() const StringPair SUBSURFACE_BRDF = { "subsurface_brdf", "subsurface_bsdf" }; const StringPair THIN_FILM_BRDF = { "thin_film_brdf", "thin_film_bsdf" }; - const string SCATTER_MODE = "scatter_mode"; - const string BSDF = "BSDF"; - const string LAYER = "layer"; - const string TOP = "top"; - const string BASE = "base"; - const string INTERIOR = "interior"; - const string ARTISTIC_IOR = "artistic_ior"; - const string COMPLEX_IOR = "complex_ior"; - const string REFLECTIVITY = "reflectivity"; - const string EDGE_COLOR = "edge_color"; - const string IOR = "ior"; - const string EXTINCTION = "extinction"; - const string COLOR3 = "color3"; - const string VECTOR3 = "vector3"; - const string CONVERT = "convert"; - const string IN = "in"; - - // Function for upgrading BSDF nodedef. - auto upgradeBsdfNodeDef = [SCATTER_MODE](NodeDefPtr nodedef, const string& newCategory, bool addScatterMode = false) - { - if (nodedef) - { - nodedef->setName(newCategory); - if (addScatterMode) - { - InputPtr mode = nodedef->addInput(SCATTER_MODE, STRING_TYPE_STRING); - mode->setIsUniform(true); - mode->setValueString("R"); - mode->setAttribute("enum", "R,T,RT"); - } - } - }; - - // Update nodedefs. - upgradeBsdfNodeDef(getNodeDef(DIELECTRIC_BRDF.first), DIELECTRIC_BRDF.second, true); - upgradeBsdfNodeDef(getNodeDef(GENERALIZED_SCHLICK_BRDF.first), GENERALIZED_SCHLICK_BRDF.second, true); - upgradeBsdfNodeDef(getNodeDef(CONDUCTOR_BRDF.first), CONDUCTOR_BRDF.second); - upgradeBsdfNodeDef(getNodeDef(SHEEN_BRDF.first), SHEEN_BRDF.second); - upgradeBsdfNodeDef(getNodeDef(DIFFUSE_BRDF.first), DIFFUSE_BRDF.second); - upgradeBsdfNodeDef(getNodeDef(BURLEY_DIFFUSE_BRDF.first), BURLEY_DIFFUSE_BRDF.second); - upgradeBsdfNodeDef(getNodeDef(DIFFUSE_BTDF.first), DIFFUSE_BTDF.second); - upgradeBsdfNodeDef(getNodeDef(SUBSURFACE_BRDF.first), SUBSURFACE_BRDF.second); - upgradeBsdfNodeDef(getNodeDef(THIN_FILM_BRDF.first), THIN_FILM_BRDF.second); - removeNodeDef(DIELECTRIC_BTDF.first); - removeNodeDef(COMPLEX_IOR); - // Function for upgrading old nested layering setup // to new setup with layer operators. - auto upgradeBsdfLayering = [TOP, BASE, LAYER, BSDF](NodePtr node) + auto upgradeBsdfLayering = [](NodePtr node) { - InputPtr base = node->getInput(BASE); + InputPtr base = node->getInput("base"); if (base) { NodePtr baseNode = base->getConnectedNode(); @@ -1146,13 +1068,13 @@ void Document::upgradeVersion() // so we don't need to update any connection references. const string oldName = node->getName(); node->setName(oldName + "__layer_top"); - NodePtr layer = parent->addNode(LAYER, oldName, BSDF); - InputPtr layerTop = layer->addInput(TOP, BSDF); - InputPtr layerBase = layer->addInput(BASE, BSDF); + NodePtr layer = parent->addNode("layer", oldName, "BSDF"); + InputPtr layerTop = layer->addInput("top", "BSDF"); + InputPtr layerBase = layer->addInput("base", "BSDF"); layerTop->setConnectedNode(node); layerBase->setConnectedNode(baseNode); } - node->removeInput(BASE); + node->removeInput("base"); } }; @@ -1177,31 +1099,31 @@ void Document::upgradeVersion() continue; } const string& nodeCategory = node->getCategory(); - if (upgradeAtan2Instances && nodeCategory == ATAN2) + if (nodeCategory == "atan2") { - InputPtr input = node->getInput(IN1); - InputPtr input2 = node->getInput(IN2); + InputPtr input = node->getInput("in1"); + InputPtr input2 = node->getInput("in2"); if (input && input2) { input->setName(EMPTY_STRING); - input2->setName(IN1); - input->setName(IN2); + input2->setName("in1"); + input->setName("in2"); } else { if (input) { - input->setName(IN2); + input->setName("in2"); } if (input2) { - input2->setName(IN1); + input2->setName("in1"); } } } - else if (nodeCategory == ROTATE3D) + else if (nodeCategory == "rotate3d") { - ElementPtr axis = node->getChild(AXIS); + ElementPtr axis = node->getChild("axis"); if (axis) { node->changeChildCategory(axis, "input"); @@ -1215,8 +1137,8 @@ void Document::upgradeVersion() else if (nodeCategory == DIELECTRIC_BTDF.first) { node->setCategory(DIELECTRIC_BTDF.second); - node->removeInput(INTERIOR); - InputPtr mode = node->addInput(SCATTER_MODE, STRING_TYPE_STRING); + node->removeInput("interior"); + InputPtr mode = node->addInput("scatter_mode", STRING_TYPE_STRING); mode->setValueString("T"); } else if (nodeCategory == GENERALIZED_SCHLICK_BRDF.first) @@ -1240,32 +1162,32 @@ void Document::upgradeVersion() // Create an artistic_ior node to convert from artistic to physical parameterization. GraphElementPtr parent = node->getParent()->asA(); - NodePtr artisticIor = parent->addNode(ARTISTIC_IOR, node->getName() + "__artistic_ior", "multioutput"); - OutputPtr artisticIor_ior = artisticIor->addOutput(IOR, COLOR3); - OutputPtr artisticIor_extinction = artisticIor->addOutput(EXTINCTION, COLOR3); + NodePtr artisticIor = parent->addNode("artistic_ior", node->getName() + "__artistic_ior", "multioutput"); + OutputPtr artisticIor_ior = artisticIor->addOutput("ior", "color3"); + OutputPtr artisticIor_extinction = artisticIor->addOutput("extinction", "color3"); // Copy values and connections from conductor node to artistic_ior node. - InputPtr reflectivity = node->getInput(REFLECTIVITY); + InputPtr reflectivity = node->getInput("reflectivity"); if (reflectivity) { - InputPtr artisticIor_reflectivity = artisticIor->addInput(REFLECTIVITY, COLOR3); + InputPtr artisticIor_reflectivity = artisticIor->addInput("reflectivity", "color3"); copyAttributes(reflectivity, artisticIor_reflectivity); } - InputPtr edge_color = node->getInput(EDGE_COLOR); + InputPtr edge_color = node->getInput("edge_color"); if (edge_color) { - InputPtr artisticIor_edge_color = artisticIor->addInput(EDGE_COLOR, COLOR3); + InputPtr artisticIor_edge_color = artisticIor->addInput("edge_color", "color3"); copyAttributes(edge_color, artisticIor_edge_color); } // Update the parameterization on the conductor node // and connect it to the artistic_ior node. - node->removeInput(REFLECTIVITY); - node->removeInput(EDGE_COLOR); - InputPtr ior = node->addInput(IOR, COLOR3); + node->removeInput("reflectivity"); + node->removeInput("edge_color"); + InputPtr ior = node->addInput("ior", "color3"); ior->setNodeName(artisticIor->getName()); ior->setOutputString(artisticIor_ior->getName()); - InputPtr extinction = node->addInput(EXTINCTION, COLOR3); + InputPtr extinction = node->addInput("extinction", "color3"); extinction->setNodeName(artisticIor->getName()); extinction->setOutputString(artisticIor_extinction->getName()); } @@ -1285,17 +1207,17 @@ void Document::upgradeVersion() { node->setCategory(SUBSURFACE_BRDF.second); } - else if (nodeCategory == ARTISTIC_IOR) + else if (nodeCategory == "artistic_ior") { - OutputPtr ior = node->getOutput(IOR); + OutputPtr ior = node->getOutput("ior"); if (ior) { - ior->setType(COLOR3); + ior->setType("color3"); } - OutputPtr extinction = node->getOutput(EXTINCTION); + OutputPtr extinction = node->getOutput("extinction"); if (extinction) { - extinction->setType(COLOR3); + extinction->setType("color3"); } } @@ -1306,18 +1228,18 @@ void Document::upgradeVersion() // since we can't modify the graph while traversing it. for (InputPtr input : node->getInputs()) { - if (input->getOutputString() == IOR && input->getType() == VECTOR3) + if (input->getOutputString() == "ior" && input->getType() == "vector3") { NodePtr connectedNode = input->getConnectedNode(); - if (connectedNode && connectedNode->getCategory() == ARTISTIC_IOR) + if (connectedNode && connectedNode->getCategory() == "artistic_ior") { artisticIorConnections.push_back(input); } } - else if (input->getOutputString() == EXTINCTION && input->getType() == VECTOR3) + else if (input->getOutputString() == "extinction" && input->getType() == "vector3") { NodePtr connectedNode = input->getConnectedNode(); - if (connectedNode && connectedNode->getCategory() == ARTISTIC_IOR) + if (connectedNode && connectedNode->getCategory() == "artistic_ior") { artisticExtConnections.push_back(input); } @@ -1331,10 +1253,10 @@ void Document::upgradeVersion() NodePtr artisticIorNode = input->getConnectedNode(); ElementPtr node = input->getParent(); GraphElementPtr parent = node->getParent()->asA(); - NodePtr convert = parent->addNode(CONVERT, node->getName() + "__convert_ior", VECTOR3); - InputPtr convertInput = convert->addInput(IN, COLOR3); + NodePtr convert = parent->addNode("convert", node->getName() + "__convert_ior", "vector3"); + InputPtr convertInput = convert->addInput("in", "color3"); convertInput->setNodeName(artisticIorNode->getName()); - convertInput->setOutputString(IOR); + convertInput->setOutputString("ior"); input->setNodeName(convert->getName()); input->removeAttribute(PortElement::OUTPUT_ATTRIBUTE); } @@ -1343,10 +1265,10 @@ void Document::upgradeVersion() NodePtr artisticIorNode = input->getConnectedNode(); ElementPtr node = input->getParent(); GraphElementPtr parent = node->getParent()->asA(); - NodePtr convert = parent->addNode(CONVERT, node->getName() + "__convert_extinction", VECTOR3); - InputPtr convertInput = convert->addInput(IN, COLOR3); + NodePtr convert = parent->addNode("convert", node->getName() + "__convert_extinction", "vector3"); + InputPtr convertInput = convert->addInput("in", "color3"); convertInput->setNodeName(artisticIorNode->getName()); - convertInput->setOutputString(EXTINCTION); + convertInput->setOutputString("extinction"); input->setNodeName(convert->getName()); input->removeAttribute(PortElement::OUTPUT_ATTRIBUTE); } From f583ea1aaa4d1e97488fd7528695d7590a566db5 Mon Sep 17 00:00:00 2001 From: Igor Elovikov Date: Sat, 7 Oct 2023 20:13:03 +0300 Subject: [PATCH 012/128] Fix Ninja builds of both Viewer and Editor (#1533) Related to: #1208 --- source/MaterialXGraphEditor/External/Glfw/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/MaterialXGraphEditor/External/Glfw/CMakeLists.txt b/source/MaterialXGraphEditor/External/Glfw/CMakeLists.txt index eaae85a825..2ec553856f 100644 --- a/source/MaterialXGraphEditor/External/Glfw/CMakeLists.txt +++ b/source/MaterialXGraphEditor/External/Glfw/CMakeLists.txt @@ -41,7 +41,7 @@ if (BUILD_SHARED_LIBS AND UNIX) # On Unix-like systems, shared libraries can use the soname system. set(GLFW_LIB_NAME glfw) else() - set(GLFW_LIB_NAME glfw3) + set(GLFW_LIB_NAME glfw3_minimal) endif() if (GLFW_VULKAN_STATIC) From 695901492ef791d09a0ecf23c0ef7680aa27a563 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sat, 7 Oct 2023 15:39:32 -0700 Subject: [PATCH 013/128] Improvements to look inheritance - Add support for look inheritance in the MaterialX viewer. - Improve coverage of look inheritance in MaterialX unit tests. - Raises statement coverage for MaterialX unit tests to 88.6%. --- source/MaterialXTest/MaterialXCore/Look.cpp | 2 ++ source/MaterialXView/Viewer.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/MaterialXTest/MaterialXCore/Look.cpp b/source/MaterialXTest/MaterialXCore/Look.cpp index 4106bf2eb3..006538891c 100644 --- a/source/MaterialXTest/MaterialXCore/Look.cpp +++ b/source/MaterialXTest/MaterialXCore/Look.cpp @@ -75,6 +75,7 @@ TEST_CASE("Look", "[look]") // Create an inherited look. mx::LookPtr look2 = doc->addLook(); look2->setInheritsFrom(look); + REQUIRE(look2->getActiveMaterialAssigns().size() == 2); REQUIRE(look2->getActivePropertySetAssigns().size() == 1); REQUIRE(look2->getActiveVisibilities().size() == 1); @@ -86,6 +87,7 @@ TEST_CASE("Look", "[look]") // Disconnect the inherited look. look2->setInheritsFrom(nullptr); + REQUIRE(look2->getActiveMaterialAssigns().empty()); REQUIRE(look2->getActivePropertySetAssigns().empty()); REQUIRE(look2->getActiveVisibilities().empty()); } diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp index 560a19e778..c06846f2ce 100644 --- a/source/MaterialXView/Viewer.cpp +++ b/source/MaterialXView/Viewer.cpp @@ -1375,7 +1375,7 @@ void Viewer::loadDocument(const mx::FilePath& filename, mx::DocumentPtr librarie // with later assignments superseding earlier ones. for (mx::LookPtr look : doc->getLooks()) { - for (mx::MaterialAssignPtr matAssign : look->getMaterialAssigns()) + for (mx::MaterialAssignPtr matAssign : look->getActiveMaterialAssigns()) { const std::string& activeGeom = matAssign->getActiveGeom(); for (mx::MeshPartitionPtr part : _geometryList) From c7f01d89e402ff58364cbdcf52cbd2d6f2213e0e Mon Sep 17 00:00:00 2001 From: Niklas Harrysson Date: Mon, 9 Oct 2023 19:54:24 +0200 Subject: [PATCH 014/128] Improve OSL generation of filename inputs (#1547) This change list modifies the generation of public filename parameters from being a textureresource struct, to being two separate string parameters for filename and colorspace. --- source/MaterialXGenOsl/OslShaderGenerator.cpp | 212 +++++++++++------- source/MaterialXGenOsl/OslShaderGenerator.h | 3 + 2 files changed, 130 insertions(+), 85 deletions(-) diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp index 28ada48626..fbb2bb29be 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.cpp +++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp @@ -294,6 +294,25 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G emitLineBreak(stage); } + // Inputs of type 'filename' has been generated into two shader inputs. + // So here we construct a single 'textureresource' from these inputs, + // to be used further downstream. See emitShaderInputs() for details. + VariableBlock& inputs = stage.getUniformBlock(OSL::UNIFORMS); + for (size_t i = 0; i < inputs.size(); ++i) + { + ShaderPort* input = inputs[i]; + if (input->getType() == Type::FILENAME) + { + // Construct the textureresource variable. + const string newVariableName = input->getVariable() + "_"; + const string& type = _syntax->getTypeName(input->getType()); + emitLine(type + newVariableName + " = {" + input->getVariable() + ", " + input->getVariable() + "_colorspace}", stage); + + // Update the variable name to be used downstream. + input->setVariable(newVariableName); + } + } + // 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); @@ -489,111 +508,75 @@ void OslShaderGenerator::emitLibraryIncludes(ShaderStage& stage, GenContext& con emitLineBreak(stage); } -namespace -{ - -std::unordered_map GEOMPROP_DEFINITIONS = -{ - { "Pobject", "transform(\"object\", P)" }, - { "Pworld", "P" }, - { "Nobject", "transform(\"object\", N)" }, - { "Nworld", "N" }, - { "Tobject", "transform(\"object\", dPdu)" }, - { "Tworld", "dPdu" }, - { "Bobject", "transform(\"object\", dPdv)" }, - { "Bworld", "dPdv" }, - { "UV0", "{u,v}" }, - { "Vworld", "I" } -}; - -} // anonymous namespace - void OslShaderGenerator::emitShaderInputs(const VariableBlock& inputs, ShaderStage& stage) const { - const std::unordered_map UI_WIDGET_METADATA = - { - { Type::FLOAT, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("number", Type::STRING->getName())) }, - { Type::INTEGER, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("number", Type::STRING->getName())) }, - { Type::FILENAME, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("filename", Type::STRING->getName())) }, - { Type::BOOLEAN, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("checkBox", Type::STRING->getName())) } - }; - - const std::set METADATA_TYPE_BLACKLIST = + static const std::unordered_map GEOMPROP_DEFINITIONS = { - Type::VECTOR2, // Custom struct types doesn't support metadata declarations. - Type::VECTOR4, // - Type::COLOR4, // - Type::FILENAME, // - Type::BSDF // + { "Pobject", "transform(\"object\", P)" }, + { "Pworld", "P" }, + { "Nobject", "transform(\"object\", N)" }, + { "Nworld", "N" }, + { "Tobject", "transform(\"object\", dPdu)" }, + { "Tworld", "dPdu" }, + { "Bobject", "transform(\"object\", dPdv)" }, + { "Bworld", "dPdv" }, + { "UV0", "{u,v}" }, + { "Vworld", "I" } }; for (size_t i = 0; i < inputs.size(); ++i) { const ShaderPort* input = inputs[i]; - const string& type = _syntax->getTypeName(input->getType()); - string value = _syntax->getValue(input, true); - - emitLineBegin(stage); - emitString(type + " " + input->getVariable(), stage); - const string& geomprop = input->getGeomProp(); - if (!geomprop.empty()) + if (input->getType() == Type::FILENAME) { - auto it = GEOMPROP_DEFINITIONS.find(geomprop); - if (it != GEOMPROP_DEFINITIONS.end()) - { - value = it->second; - } + // Shader inputs of type 'filename' (textures) need special handling. + // In OSL codegen a 'filename' is translated to the custom type 'textureresource', + // which is a struct containing a file string and a colorspace string. + // For the published shader interface we here split this into two separate inputs, + // which gives a nicer shader interface with widget metadata on each input. + + ValuePtr value = input->getValue(); + const string valueStr = value ? value->getValueString() : EMPTY_STRING; + + // Add the file string input + emitLineBegin(stage); + emitString("string " + input->getVariable() + " = \"" + valueStr + "\"", stage); + emitMetadata(input, stage); + emitString(",", stage); + emitLineEnd(stage, false); + + // Add the colorspace string input + emitLineBegin(stage); + emitString("string " + input->getVariable() + "_colorspace = \"" + input->getColorSpace() + "\"", stage); + emitLineEnd(stage, false); + emitScopeBegin(stage, Syntax::DOUBLE_SQUARE_BRACKETS); + emitLine("string widget = \"colorspace\"", stage, false); + emitScopeEnd(stage, false, false); } - - if (value.empty()) + else { - value = _syntax->getDefaultValue(input->getType()); - } - emitString(" = " + value, stage); - - // - // Add shader input metadata. - // - - auto widgetMetadataIt = UI_WIDGET_METADATA.find(input->getType()); - const ShaderMetadata* widgetMetadata = widgetMetadataIt != UI_WIDGET_METADATA.end() ? &widgetMetadataIt->second : nullptr; - const ShaderMetadataVecPtr& metadata = input->getMetadata(); + emitLineBegin(stage); + emitString(type + " " + input->getVariable(), stage); - if (widgetMetadata || (metadata && metadata->size())) - { - StringVec metadataLines; - if (metadata) + string value = _syntax->getValue(input, true); + const string& geomprop = input->getGeomProp(); + if (!geomprop.empty()) { - for (size_t j = 0; j < metadata->size(); ++j) + auto it = GEOMPROP_DEFINITIONS.find(geomprop); + if (it != GEOMPROP_DEFINITIONS.end()) { - const ShaderMetadata& data = metadata->at(j); - if (METADATA_TYPE_BLACKLIST.count(data.type) == 0) - { - const string& delim = (widgetMetadata || j < metadata->size() - 1) ? Syntax::COMMA : EMPTY_STRING; - const string& dataType = _syntax->getTypeName(data.type); - const string dataValue = _syntax->getValue(data.type, *data.value, true); - metadataLines.push_back(dataType + " " + data.name + " = " + dataValue + delim); - } + value = it->second; } } - if (widgetMetadata) + if (value.empty()) { - const string& dataType = _syntax->getTypeName(widgetMetadata->type); - const string dataValue = _syntax->getValue(widgetMetadata->type, *widgetMetadata->value, true); - metadataLines.push_back(dataType + " " + widgetMetadata->name + " = " + dataValue); - } - if (metadataLines.size()) - { - emitLineEnd(stage, false); - emitScopeBegin(stage, Syntax::DOUBLE_SQUARE_BRACKETS); - for (auto line : metadataLines) - { - emitLine(line, stage, false); - } - emitScopeEnd(stage, false, false); + value = _syntax->getDefaultValue(input->getType()); } + + emitString(" = " + value, stage); + emitMetadata(input, stage); } if (i < inputs.size()) @@ -618,6 +601,65 @@ void OslShaderGenerator::emitShaderOutputs(const VariableBlock& outputs, ShaderS } } +void OslShaderGenerator::emitMetadata(const ShaderPort* port, ShaderStage& stage) const +{ + static const std::unordered_map UI_WIDGET_METADATA = + { + { Type::FLOAT, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("number", Type::STRING->getName())) }, + { Type::INTEGER, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("number", Type::STRING->getName())) }, + { Type::FILENAME, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("filename", Type::STRING->getName())) }, + { Type::BOOLEAN, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("checkBox", Type::STRING->getName())) } + }; + + static const std::set METADATA_TYPE_BLACKLIST = + { + Type::VECTOR2, // Custom struct types doesn't support metadata declarations. + Type::VECTOR4, // + Type::COLOR4, // + Type::FILENAME, // + Type::BSDF // + }; + + auto widgetMetadataIt = UI_WIDGET_METADATA.find(port->getType()); + const ShaderMetadata* widgetMetadata = widgetMetadataIt != UI_WIDGET_METADATA.end() ? &widgetMetadataIt->second : nullptr; + const ShaderMetadataVecPtr& metadata = port->getMetadata(); + + if (widgetMetadata || (metadata && metadata->size())) + { + StringVec metadataLines; + if (metadata) + { + for (size_t j = 0; j < metadata->size(); ++j) + { + const ShaderMetadata& data = metadata->at(j); + if (METADATA_TYPE_BLACKLIST.count(data.type) == 0) + { + const string& delim = (widgetMetadata || j < metadata->size() - 1) ? Syntax::COMMA : EMPTY_STRING; + const string& dataType = _syntax->getTypeName(data.type); + const string dataValue = _syntax->getValue(data.type, *data.value, true); + metadataLines.push_back(dataType + " " + data.name + " = " + dataValue + delim); + } + } + } + if (widgetMetadata) + { + const string& dataType = _syntax->getTypeName(widgetMetadata->type); + const string dataValue = _syntax->getValue(widgetMetadata->type, *widgetMetadata->value, true); + metadataLines.push_back(dataType + " " + widgetMetadata->name + " = " + dataValue); + } + if (metadataLines.size()) + { + emitLineEnd(stage, false); + emitScopeBegin(stage, Syntax::DOUBLE_SQUARE_BRACKETS); + for (auto line : metadataLines) + { + emitLine(line, stage, false); + } + emitScopeEnd(stage, false, false); + } + } +} + namespace OSL { diff --git a/source/MaterialXGenOsl/OslShaderGenerator.h b/source/MaterialXGenOsl/OslShaderGenerator.h index 0c7ca426d7..e5cf13977e 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.h +++ b/source/MaterialXGenOsl/OslShaderGenerator.h @@ -59,6 +59,9 @@ class MX_GENOSL_API OslShaderGenerator : public ShaderGenerator /// Emit a block of shader outputs. virtual void emitShaderOutputs(const VariableBlock& inputs, ShaderStage& stage) const; + + /// Emit metadata for a shader parameter. + virtual void emitMetadata(const ShaderPort* port, ShaderStage& stage) const; }; namespace OSL From 54adaeefcb2864632e2e7a38e842e8cd6658ea54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ars=C3=A8ne=20P=C3=A9rard-Gayot?= Date: Fri, 13 Oct 2023 21:47:47 +0200 Subject: [PATCH 015/128] Fix edge case in HW shader generation for texcoords (#1559) This merges both TexCoordNodeMsl and TexCoordNodeGlsl into a single HwTexCoordNode. The parts of the node that are configurable (e.g. the input index) can be changed via re-implementation of the virtual member function getIndexInput(). The new mechanism works regardless of syntax, and uses the smallest texcoord width, depending on what is used in the shader graph. --- .../TestSuite/stdlib/texture/texcoord.mtlx | 25 ++++++ .../MaterialXGenGlsl/GlslShaderGenerator.cpp | 6 +- source/MaterialXGenGlsl/GlslShaderGenerator.h | 2 +- .../Nodes/TexCoordNodeGlsl.cpp | 62 -------------- source/MaterialXGenMsl/MslShaderGenerator.cpp | 6 +- source/MaterialXGenMsl/MslShaderGenerator.h | 2 +- .../MaterialXGenMsl/Nodes/TexCoordNodeMsl.cpp | 62 -------------- .../MaterialXGenMsl/Nodes/TexCoordNodeMsl.h | 26 ------ source/MaterialXGenShader/HwShaderGenerator.h | 3 + .../Nodes/HwTexCoordNode.cpp | 83 +++++++++++++++++++ .../Nodes/HwTexCoordNode.h} | 15 ++-- source/MaterialXGenShader/ShaderStage.cpp | 17 +++- source/MaterialXGenShader/ShaderStage.h | 26 ++++-- 13 files changed, 163 insertions(+), 172 deletions(-) create mode 100644 resources/Materials/TestSuite/stdlib/texture/texcoord.mtlx delete mode 100644 source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.cpp delete mode 100644 source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.cpp delete mode 100644 source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.h create mode 100644 source/MaterialXGenShader/Nodes/HwTexCoordNode.cpp rename source/{MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.h => MaterialXGenShader/Nodes/HwTexCoordNode.h} (55%) diff --git a/resources/Materials/TestSuite/stdlib/texture/texcoord.mtlx b/resources/Materials/TestSuite/stdlib/texture/texcoord.mtlx new file mode 100644 index 0000000000..4fbf6d12d9 --- /dev/null +++ b/resources/Materials/TestSuite/stdlib/texture/texcoord.mtlx @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp index 839f591aa5..87582c8f50 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -174,8 +174,8 @@ GlslShaderGenerator::GlslShaderGenerator() : // registerImplementation("IM_bitangent_vector3_" + GlslShaderGenerator::TARGET, BitangentNodeGlsl::create); // - registerImplementation("IM_texcoord_vector2_" + GlslShaderGenerator::TARGET, TexCoordNodeGlsl::create); - registerImplementation("IM_texcoord_vector3_" + GlslShaderGenerator::TARGET, TexCoordNodeGlsl::create); + registerImplementation("IM_texcoord_vector2_" + GlslShaderGenerator::TARGET, HwTexCoordNode::create); + registerImplementation("IM_texcoord_vector3_" + GlslShaderGenerator::TARGET, HwTexCoordNode::create); // registerImplementation("IM_geomcolor_float_" + GlslShaderGenerator::TARGET, GeomColorNodeGlsl::create); registerImplementation("IM_geomcolor_color3_" + GlslShaderGenerator::TARGET, GeomColorNodeGlsl::create); diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.h b/source/MaterialXGenGlsl/GlslShaderGenerator.h index 1df2ace543..4464f5d47c 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.h +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.h @@ -45,7 +45,7 @@ class MX_GENGLSL_API GlslShaderGenerator : public HwShaderGenerator ShaderNodeImplPtr getImplementation(const NodeDef& nodedef, GenContext& context) const override; /// Determine the prefix of vertex data variables. - virtual string getVertexDataPrefix(const VariableBlock& vertexData) const; + string getVertexDataPrefix(const VariableBlock& vertexData) const override; public: /// Unique identifier for this generator target diff --git a/source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.cpp deleted file mode 100644 index 846c77f5b7..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TexCoordNodeGlsl::create() -{ - return std::make_shared(); -} - -void TexCoordNodeGlsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const -{ - const ShaderOutput* output = node.getOutput(); - const ShaderInput* indexInput = node.getInput(INDEX); - const string index = indexInput ? indexInput->getValue()->getValueString() : "0"; - - ShaderStage& vs = shader.getStage(Stage::VERTEX); - ShaderStage& ps = shader.getStage(Stage::PIXEL); - - addStageInput(HW::VERTEX_INPUTS, output->getType(), HW::T_IN_TEXCOORD + "_" + index, vs); - addStageConnector(HW::VERTEX_DATA, output->getType(), HW::T_TEXCOORD + "_" + index, vs, ps); -} - -void TexCoordNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - const GlslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); - - const ShaderInput* indexInput = node.getInput(INDEX); - const string index = indexInput ? indexInput->getValue()->getValueString() : "0"; - const string variable = HW::T_TEXCOORD + "_" + index; - - DEFINE_SHADER_STAGE(stage, Stage::VERTEX) - { - VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - ShaderPort* texcoord = vertexData[variable]; - if (!texcoord->isEmitted()) - { - shadergen.emitLine(prefix + texcoord->getVariable() + " = " + HW::T_IN_TEXCOORD + "_" + index, stage); - texcoord->setEmitted(); - } - } - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - ShaderPort* texcoord = vertexData[variable]; - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = " + prefix + texcoord->getVariable(), stage); - shadergen.emitLineEnd(stage); - } -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index 0d97e8408f..1d93104ce8 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -178,8 +178,8 @@ MslShaderGenerator::MslShaderGenerator() : // registerImplementation("IM_bitangent_vector3_" + MslShaderGenerator::TARGET, BitangentNodeMsl::create); // - registerImplementation("IM_texcoord_vector2_" + MslShaderGenerator::TARGET, TexCoordNodeMsl::create); - registerImplementation("IM_texcoord_vector3_" + MslShaderGenerator::TARGET, TexCoordNodeMsl::create); + registerImplementation("IM_texcoord_vector2_" + MslShaderGenerator::TARGET, HwTexCoordNode::create); + registerImplementation("IM_texcoord_vector3_" + MslShaderGenerator::TARGET, HwTexCoordNode::create); // registerImplementation("IM_geomcolor_float_" + MslShaderGenerator::TARGET, GeomColorNodeMsl::create); registerImplementation("IM_geomcolor_color3_" + MslShaderGenerator::TARGET, GeomColorNodeMsl::create); diff --git a/source/MaterialXGenMsl/MslShaderGenerator.h b/source/MaterialXGenMsl/MslShaderGenerator.h index ecbf37d7a6..631c38f33d 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.h +++ b/source/MaterialXGenMsl/MslShaderGenerator.h @@ -48,7 +48,7 @@ class MX_GENMSL_API MslShaderGenerator : public HwShaderGenerator ShaderNodeImplPtr getImplementation(const NodeDef& nodedef, GenContext& context) const override; /// Determine the prefix of vertex data variables. - virtual string getVertexDataPrefix(const VariableBlock& vertexData) const; + string getVertexDataPrefix(const VariableBlock& vertexData) const override; public: /// Unique identifier for this generator target diff --git a/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.cpp deleted file mode 100644 index a88152eb82..0000000000 --- a/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TexCoordNodeMsl::create() -{ - return std::make_shared(); -} - -void TexCoordNodeMsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const -{ - const ShaderOutput* output = node.getOutput(); - const ShaderInput* indexInput = node.getInput(INDEX); - const string index = indexInput ? indexInput->getValue()->getValueString() : "0"; - - ShaderStage& vs = shader.getStage(Stage::VERTEX); - ShaderStage& ps = shader.getStage(Stage::PIXEL); - - addStageInput(HW::VERTEX_INPUTS, output->getType(), HW::T_IN_TEXCOORD + "_" + index, vs); - addStageConnector(HW::VERTEX_DATA, output->getType(), HW::T_TEXCOORD + "_" + index, vs, ps); -} - -void TexCoordNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - const MslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); - - const ShaderInput* indexInput = node.getInput(INDEX); - const string index = indexInput ? indexInput->getValue()->getValueString() : "0"; - const string variable = HW::T_TEXCOORD + "_" + index; - - DEFINE_SHADER_STAGE(stage, Stage::VERTEX) - { - VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - ShaderPort* texcoord = vertexData[variable]; - if (!texcoord->isEmitted()) - { - shadergen.emitLine(prefix + texcoord->getVariable() + " = " + HW::T_IN_TEXCOORD + "_" + index, stage); - texcoord->setEmitted(); - } - } - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - ShaderPort* texcoord = vertexData[variable]; - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = " + prefix + texcoord->getVariable(), stage); - shadergen.emitLineEnd(stage); - } -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.h b/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.h deleted file mode 100644 index 6c227cc63b..0000000000 --- a/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TEXCOORDNODEMSL_H -#define MATERIALX_TEXCOORDNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TexCoord node implementation for MSL -class MX_GENMSL_API TexCoordNodeMsl : public MslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenShader/HwShaderGenerator.h b/source/MaterialXGenShader/HwShaderGenerator.h index 66d60dc68a..bba572c631 100644 --- a/source/MaterialXGenShader/HwShaderGenerator.h +++ b/source/MaterialXGenShader/HwShaderGenerator.h @@ -306,6 +306,9 @@ class MX_GENSHADER_API HwShaderGenerator : public ShaderGenerator /// Unbind all light shaders previously bound. static void unbindLightShaders(GenContext& context); + /// Determine the prefix of vertex data variables. + virtual string getVertexDataPrefix(const VariableBlock& vertexData) const = 0; + /// Types of closure contexts for HW. enum ClosureContextType { diff --git a/source/MaterialXGenShader/Nodes/HwTexCoordNode.cpp b/source/MaterialXGenShader/Nodes/HwTexCoordNode.cpp new file mode 100644 index 0000000000..3aa84400df --- /dev/null +++ b/source/MaterialXGenShader/Nodes/HwTexCoordNode.cpp @@ -0,0 +1,83 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include + +MATERIALX_NAMESPACE_BEGIN + +string HwTexCoordNode::INDEX = "index"; + +ShaderNodeImplPtr HwTexCoordNode::create() +{ + return std::make_shared(); +} + +void HwTexCoordNode::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const +{ + const ShaderOutput* output = node.getOutput(); + const string index = getIndex(node); + + ShaderStage& vs = shader.getStage(Stage::VERTEX); + ShaderStage& ps = shader.getStage(Stage::PIXEL); + + addStageInput(HW::VERTEX_INPUTS, output->getType(), HW::T_IN_TEXCOORD + "_" + index, vs, true); + addStageConnector(HW::VERTEX_DATA, output->getType(), HW::T_TEXCOORD + "_" + index, vs, ps, true); +} + +void HwTexCoordNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +{ + const HwShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); + + const string index = getIndex(node); + const string variable = HW::T_TEXCOORD + "_" + index; + const ShaderOutput* output = node.getOutput(); + + DEFINE_SHADER_STAGE(stage, Stage::VERTEX) + { + VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); + const string prefix = shadergen.getVertexDataPrefix(vertexData); + ShaderPort* texcoord = vertexData[variable]; + if (!texcoord->isEmitted()) + { + shadergen.emitLine(prefix + texcoord->getVariable() + " = " + HW::T_IN_TEXCOORD + "_" + index, stage); + texcoord->setEmitted(); + } + } + + DEFINE_SHADER_STAGE(stage, Stage::PIXEL) + { + VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); + const string prefix = shadergen.getVertexDataPrefix(vertexData); + ShaderPort* texcoord = vertexData[variable]; + shadergen.emitLineBegin(stage); + shadergen.emitOutput(output, true, false, context, stage); + + // Extract the requested number of components from the texture coordinates (which may be a + // larger datatype than the requested number of texture coordinates, if several texture + // coordinate nodes with different width coexist). + string suffix = EMPTY_STRING; + if (output->getType() == Type::VECTOR2) + { + suffix = ".xy"; + } + else if (output->getType() == Type::VECTOR3) + { + suffix = ".xyz"; + } + + shadergen.emitString(" = " + prefix + texcoord->getVariable() + suffix, stage); + shadergen.emitLineEnd(stage); + } +} + +string HwTexCoordNode::getIndex(const ShaderNode& node) const +{ + const ShaderInput* input = node.getInput(INDEX); + return input ? input->getValue()->getValueString() : "0"; +} + +MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.h b/source/MaterialXGenShader/Nodes/HwTexCoordNode.h similarity index 55% rename from source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.h rename to source/MaterialXGenShader/Nodes/HwTexCoordNode.h index c15a86fd9c..9aae3d18ce 100644 --- a/source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.h +++ b/source/MaterialXGenShader/Nodes/HwTexCoordNode.h @@ -3,15 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#ifndef MATERIALX_TEXCOORDNODEGLSL_H -#define MATERIALX_TEXCOORDNODEGLSL_H +#ifndef MATERIALX_HWTEXCOORDNODE_H +#define MATERIALX_HWTEXCOORDNODE_H -#include +#include MATERIALX_NAMESPACE_BEGIN -/// TexCoord node implementation for GLSL -class MX_GENGLSL_API TexCoordNodeGlsl : public GlslImplementation +/// Generic texture coordinate node for hardware languages +class MX_GENSHADER_API HwTexCoordNode : public ShaderNodeImpl { public: static ShaderNodeImplPtr create(); @@ -19,6 +19,11 @@ class MX_GENGLSL_API TexCoordNodeGlsl : public GlslImplementation void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; + + protected: + virtual string getIndex(const ShaderNode& node) const; + + static string INDEX; }; MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenShader/ShaderStage.cpp b/source/MaterialXGenShader/ShaderStage.cpp index 822f3c9664..b5387bcb94 100644 --- a/source/MaterialXGenShader/ShaderStage.cpp +++ b/source/MaterialXGenShader/ShaderStage.cpp @@ -65,11 +65,26 @@ ShaderPort* VariableBlock::find(const ShaderPortPredicate& predicate) return nullptr; } -ShaderPort* VariableBlock::add(const TypeDesc* type, const string& name, ValuePtr value) +ShaderPort* VariableBlock::add(const TypeDesc* type, const string& name, ValuePtr value, bool shouldWiden) { auto it = _variableMap.find(name); if (it != _variableMap.end()) { + if (shouldWiden) + { + // Automatically try to widen the type of the shader port if the requested type differs from + // the existing port's type. + if (it->second->getType()->getSize() < type->getSize()) + { + it->second->setType(type); + } + } + else if (type != it->second->getType()) + { + throw ExceptionShaderGenError("Trying to add shader port '" + name + "' with type '" + + type->getName() + "', but existing shader port with type '" + + it->second->getType()->getName() + "' was found"); + } return it->second.get(); } diff --git a/source/MaterialXGenShader/ShaderStage.h b/source/MaterialXGenShader/ShaderStage.h index 71004f8e52..a6a5cec0b8 100644 --- a/source/MaterialXGenShader/ShaderStage.h +++ b/source/MaterialXGenShader/ShaderStage.h @@ -113,7 +113,14 @@ class MX_GENSHADER_API VariableBlock ShaderPort* find(const ShaderPortPredicate& predicate); /// Add a new shader port to this block. - ShaderPort* add(const TypeDesc* type, const string& name, ValuePtr value = nullptr); + /// @param type The desired shader port type + /// @param name The shader port name + /// @param value The value to attach to the shader port + /// @param shouldWiden When false, an exception is thrown if the type of the existing port with + /// the same name does not match the requested type. When true, the types can mismatch, and the + /// type of any existing port is widened to match the requested type when necessary. + /// @return A new shader port, or a pre-existing shader port with the same name. + ShaderPort* add(const TypeDesc* type, const string& name, ValuePtr value = nullptr, bool shouldWiden = false); /// Add an existing shader port to this block. void add(ShaderPortPtr port); @@ -339,20 +346,22 @@ inline ShaderPort* addStageUniform(const string& block, inline ShaderPort* addStageInput(const string& block, const TypeDesc* type, const string& name, - ShaderStage& stage) + ShaderStage& stage, + bool shouldWiden = false) { VariableBlock& inputs = stage.getInputBlock(block); - return inputs.add(type, name); + return inputs.add(type, name, {}, shouldWiden); } /// Utility function for adding a new shader port to an output block. inline ShaderPort* addStageOutput(const string& block, const TypeDesc* type, const string& name, - ShaderStage& stage) + ShaderStage& stage, + bool shouldWiden = false) { VariableBlock& outputs = stage.getOutputBlock(block); - return outputs.add(type, name); + return outputs.add(type, name, {}, shouldWiden); } /// Utility function for adding a connector block between stages. @@ -370,10 +379,11 @@ inline void addStageConnector(const string& block, const TypeDesc* type, const string& name, ShaderStage& from, - ShaderStage& to) + ShaderStage& to, + bool shouldWiden = false) { - addStageOutput(block, type, name, from); - addStageInput(block, type, name, to); + addStageOutput(block, type, name, from, shouldWiden); + addStageInput(block, type, name, to, shouldWiden); } MATERIALX_NAMESPACE_END From eb52ec28e09fc86e00b6e7120f5676d37db6e8b8 Mon Sep 17 00:00:00 2001 From: Erika Harrison Date: Fri, 13 Oct 2023 17:26:19 -0600 Subject: [PATCH 016/128] Update link connections by dragging between ports (#1569) Currently, one must explicitly delete an existing link before adding a new link for a given node. This change enables dragging to update a link connection, and automatically deletes the existing link on the input pin if one exists. Note: An output pin on a node may have many outgoing links, but an input pin may only have one incoming link. This behaviour is unchanged. Also: - Renames a few variables for consistency on start/end and input/output pins - Ensures you can't add a link from an input to an input, or from an output to an output - Can also drag from an output to an input and have it correctly delete existing link --- source/MaterialXGraphEditor/Graph.cpp | 307 ++++++++++++++------------ source/MaterialXGraphEditor/Graph.h | 4 +- 2 files changed, 171 insertions(+), 140 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 2b28317ee2..522280cb08 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -846,7 +846,7 @@ void Graph::setRenderMaterial(UiNodePtr node) } } -void Graph::updateMaterials(mx::InputPtr input, mx::ValuePtr value) +void Graph::updateMaterials(mx::InputPtr input /* = nullptr */, mx::ValuePtr value /* = nullptr */) { std::string renderablePath; if (_currRenderNode) @@ -2483,12 +2483,22 @@ void Graph::setDefaults(mx::InputPtr input) } } -void Graph::addLink(ed::PinId inputPinId, ed::PinId outputPinId) +void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) { - int end_attr = int(outputPinId.Get()); - int start_attr = int(inputPinId.Get()); - UiPinPtr inputPin = getPin(outputPinId); - UiPinPtr outputPin = getPin(inputPinId); + // prefer to assume left to right - start is an output, end is an input; swap if inaccurate + if (UiPinPtr inputPin = getPin(endPinId); inputPin && inputPin->_kind != ed::PinKind::Input) + { + auto tmp = startPinId; + startPinId = endPinId; + endPinId = tmp; + } + + int end_attr = int(endPinId.Get()); + int start_attr = int(startPinId.Get()); + ed::PinId outputPinId = startPinId; + ed::PinId inputPinId = endPinId; + UiPinPtr outputPin = getPin(outputPinId); + UiPinPtr inputPin = getPin(inputPinId); if (!inputPin || !outputPin) { @@ -2505,187 +2515,206 @@ void Graph::addLink(ed::PinId inputPinId, ed::PinId outputPinId) return; } - if (inputPin->_connected == false) + // Perform kind check + bool kindsMatch = (outputPin->_kind == inputPin->_kind); + if (kindsMatch) { - int upNode = getNodeId(inputPinId); - int downNode = getNodeId(outputPinId); - UiNodePtr uiDownNode = _graphNodes[downNode]; - UiNodePtr uiUpNode = _graphNodes[upNode]; - if (!uiDownNode || !uiUpNode) - { - ed::RejectNewItem(); - return; - } + ed::RejectNewItem(); + showLabel("Invalid connection due to same input/output kind", ImColor(50, 50, 50, 255)); + return; + } - // make sure there is an implementation for node - const mx::ShaderGenerator& shadergen = _renderer->getGenContext().getShaderGenerator(); + int upNode = getNodeId(outputPinId); + int downNode = getNodeId(inputPinId); + UiNodePtr uiDownNode = _graphNodes[downNode]; + UiNodePtr uiUpNode = _graphNodes[upNode]; + if (!uiDownNode || !uiUpNode) + { + ed::RejectNewItem(); + return; + } - // Prevent direct connecting from input to output - if (uiDownNode->getInput() && uiUpNode->getOutput()) - { - ed::RejectNewItem(); - showLabel("Direct connections between inputs and outputs is invalid", ImColor(50, 50, 50, 255)); - return; - } + // make sure there is an implementation for node + const mx::ShaderGenerator& shadergen = _renderer->getGenContext().getShaderGenerator(); - // Find the implementation for this nodedef if not an input or output uinode - if (uiDownNode->getInput() && _isNodeGraph) + // Prevent direct connecting from input to output + if (uiDownNode->getInput() && uiUpNode->getOutput()) + { + ed::RejectNewItem(); + showLabel("Direct connections between inputs and outputs is invalid", ImColor(50, 50, 50, 255)); + return; + } + + // Find the implementation for this nodedef if not an input or output uinode + if (uiDownNode->getInput() && _isNodeGraph) + { + ed::RejectNewItem(); + showLabel("Cannot connect to inputs inside of graph", ImColor(50, 50, 50, 255)); + return; + } + else if (uiUpNode->getNode()) + { + mx::ShaderNodeImplPtr impl = shadergen.getImplementation(*_graphNodes[upNode]->getNode()->getNodeDef(), _renderer->getGenContext()); + if (!impl) { ed::RejectNewItem(); - showLabel("Cannot connect to inputs inside of graph", ImColor(50, 50, 50, 255)); + showLabel("Invalid Connection: Node does not have an implementation", ImColor(50, 50, 50, 255)); return; } - else if (uiUpNode->getNode()) + } + + if (ed::AcceptNewItem()) + { + // If the accepting node already has a link, remove it + if (inputPin->_connected) { - mx::ShaderNodeImplPtr impl = shadergen.getImplementation(*_graphNodes[upNode]->getNode()->getNodeDef(), _renderer->getGenContext()); - if (!impl) + for (auto linksItr = _currLinks.begin(); linksItr != _currLinks.end(); linksItr++) { - ed::RejectNewItem(); - showLabel("Invalid Connection: Node does not have an implementation", ImColor(50, 50, 50, 255)); - return; + if (linksItr->_endAttr == end_attr) + { + // found existing link - remove it; adapted from deleteLink + // note: ed::BreakLinks doesn't work as the order ends up inaccurate + deleteLinkInfo(linksItr->_startAttr, linksItr->_endAttr); + _currLinks.erase(linksItr); + break; + } } + } - if (ed::AcceptNewItem()) - { - // Since we accepted new link, lets add one to our list of links. - Link link; - link._startAttr = start_attr; - link._endAttr = end_attr; - _currLinks.push_back(link); - _frameCount = ImGui::GetFrameCount(); - _renderer->setMaterialCompilation(true); + // Since we accepted new link, lets add one to our list of links. + Link link; + link._startAttr = start_attr; + link._endAttr = end_attr; + _currLinks.push_back(link); + _frameCount = ImGui::GetFrameCount(); + _renderer->setMaterialCompilation(true); - if (uiDownNode->getNode() || uiDownNode->getNodeGraph()) + if (uiDownNode->getNode() || uiDownNode->getNodeGraph()) + { + mx::InputPtr connectingInput = nullptr; + for (UiPinPtr pin : uiDownNode->inputPins) { - mx::InputPtr connectingInput = nullptr; - for (UiPinPtr pin : uiDownNode->inputPins) + if (pin->_pinId == inputPinId) { - if (pin->_pinId == outputPinId) + addNodeInput(uiDownNode, pin->_input); + // update value to be empty + if (uiDownNode->getNode() && uiDownNode->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) { - addNodeInput(uiDownNode, pin->_input); - // update value to be empty - if (uiDownNode->getNode() && uiDownNode->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) + if (uiUpNode->getOutput() != nullptr) { - if (uiUpNode->getOutput() != nullptr) - { - pin->_input->setConnectedOutput(uiUpNode->getOutput()); - } - else if (uiUpNode->getInput() != nullptr) - { - pin->_input->setInterfaceName(uiUpNode->getName()); - } - else + pin->_input->setConnectedOutput(uiUpNode->getOutput()); + } + else if (uiUpNode->getInput() != nullptr) + { + pin->_input->setInterfaceName(uiUpNode->getName()); + } + else + { + // node graph + if (uiUpNode->getNodeGraph() != nullptr) { - // node graph - if (uiUpNode->getNodeGraph() != nullptr) + for (UiPinPtr outPin : uiUpNode->outputPins) { - for (UiPinPtr outPin : uiUpNode->outputPins) + // set pin connection to correct output + if (outPin->_pinId == outputPinId) { - // set pin connection to correct output - if (outPin->_pinId == inputPinId) - { - mx::OutputPtr outputs = uiUpNode->getNodeGraph()->getOutput(outPin->_name); - pin->_input->setConnectedOutput(outputs); - } + mx::OutputPtr outputs = uiUpNode->getNodeGraph()->getOutput(outPin->_name); + pin->_input->setConnectedOutput(outputs); } } - else - { - pin->_input->setConnectedNode(uiUpNode->getNode()); - } } + else + { + pin->_input->setConnectedNode(uiUpNode->getNode()); + } + } + } + else + { + if (uiUpNode->getInput()) + { + pin->_input->setInterfaceName(uiUpNode->getName()); } else { - if (uiUpNode->getInput()) - { - pin->_input->setInterfaceName(uiUpNode->getName()); - } - else + if (uiUpNode->getNode()) { - if (uiUpNode->getNode()) + mx::NodePtr upstreamNode = _graphNodes[upNode]->getNode(); + mx::NodeDefPtr upstreamNodeDef = upstreamNode->getNodeDef(); + bool isMultiOutput = upstreamNodeDef ? upstreamNodeDef->getOutputs().size() > 1 : false; + + // This is purely to avoid adding a reference to an update node only 1 output, + // as currently validation consides adding this an error. Otherwise + // it will add an "output" attribute all the time. + if (!isMultiOutput) { - mx::NodePtr upstreamNode = _graphNodes[upNode]->getNode(); - mx::NodeDefPtr upstreamNodeDef = upstreamNode->getNodeDef(); - bool isMultiOutput = upstreamNodeDef ? upstreamNodeDef->getOutputs().size() > 1 : false; - - // This is purely to avoid adding a reference to an update node only 1 output, - // as currently validation consides adding this an error. Otherwise - // it will add an "output" attribute all the time. - if (!isMultiOutput) - { - pin->_input->setConnectedNode(uiUpNode->getNode()); - } - else + pin->_input->setConnectedNode(uiUpNode->getNode()); + } + else + { + for (UiPinPtr outPin : _graphNodes[upNode]->outputPins) { - for (UiPinPtr outPin : _graphNodes[upNode]->outputPins) + // set pin connection to correct output + if (outPin->_pinId == outputPinId) { - // set pin connection to correct output - if (outPin->_pinId == inputPinId) + mx::OutputPtr outputs = uiUpNode->getNode()->getOutput(outPin->_name); + if (!outputs) { - mx::OutputPtr outputs = uiUpNode->getNode()->getOutput(outPin->_name); - if (!outputs) - { - outputs = uiUpNode->getNode()->addOutput(outPin->_name, pin->_input->getType()); - } - pin->_input->setConnectedOutput(outputs); + outputs = uiUpNode->getNode()->addOutput(outPin->_name, pin->_input->getType()); } + pin->_input->setConnectedOutput(outputs); } } } - else if (uiUpNode->getNodeGraph()) + } + else if (uiUpNode->getNodeGraph()) + { + for (UiPinPtr outPin : uiUpNode->outputPins) { - for (UiPinPtr outPin : uiUpNode->outputPins) + // set pin connection to correct output + if (outPin->_pinId == outputPinId) { - // set pin connection to correct output - if (outPin->_pinId == inputPinId) - { - mx::OutputPtr outputs = uiUpNode->getNodeGraph()->getOutput(outPin->_name); - pin->_input->setConnectedOutput(outputs); - } + mx::OutputPtr outputs = uiUpNode->getNodeGraph()->getOutput(outPin->_name); + pin->_input->setConnectedOutput(outputs); } } } } - - pin->setConnected(true); - pin->_input->removeAttribute(mx::ValueElement::VALUE_ATTRIBUTE); - connectingInput = pin->_input; - break; } + + pin->setConnected(true); + pin->_input->removeAttribute(mx::ValueElement::VALUE_ATTRIBUTE); + connectingInput = pin->_input; + break; } - // create new edge and set edge information - createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput); } - else if (_graphNodes[downNode]->getOutput() != nullptr) - { - mx::InputPtr connectingInput = nullptr; - _graphNodes[downNode]->getOutput()->setConnectedNode(_graphNodes[upNode]->getNode()); + // create new edge and set edge information + createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput); + } + else if (_graphNodes[downNode]->getOutput() != nullptr) + { + mx::InputPtr connectingInput = nullptr; + _graphNodes[downNode]->getOutput()->setConnectedNode(_graphNodes[upNode]->getNode()); - // create new edge and set edge information - createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput); - } - else + // create new edge and set edge information + createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput); + } + else + { + // create new edge and set edge info + UiEdge newEdge = UiEdge(_graphNodes[upNode], _graphNodes[downNode], nullptr); + if (!edgeExists(newEdge)) { - // create new edge and set edge info - UiEdge newEdge = UiEdge(_graphNodes[upNode], _graphNodes[downNode], nullptr); - if (!edgeExists(newEdge)) - { - _graphNodes[downNode]->edges.push_back(newEdge); - _currEdge.push_back(newEdge); + _graphNodes[downNode]->edges.push_back(newEdge); + _currEdge.push_back(newEdge); - // update input node num and output connections - _graphNodes[downNode]->setInputNodeNum(1); - _graphNodes[upNode]->setOutputConnection(_graphNodes[downNode]); - } + // update input node num and output connections + _graphNodes[downNode]->setInputNodeNum(1); + _graphNodes[upNode]->setOutputConnection(_graphNodes[downNode]); } } } - else - { - ed::RejectNewItem(); - } } void Graph::removeEdge(int downNode, int upNode, UiPinPtr pin) @@ -4045,12 +4074,12 @@ void Graph::drawGraph(ImVec2 mousePos) // Add new link if (ed::BeginCreate()) { - ed::PinId inputPinId, outputPinId, filterPinId; - if (ed::QueryNewLink(&inputPinId, &outputPinId)) + ed::PinId startPinId, endPinId, filterPinId; + if (ed::QueryNewLink(&startPinId, &endPinId)) { if (!readOnly()) { - addLink(inputPinId, outputPinId); + addLink(startPinId, endPinId); } else { diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index 8c76f0f68d..9b9857c69a 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -90,7 +90,9 @@ class Graph // Add link to nodegraph and set up connections between UiNodes and // MaterialX Nodes to update shader - void addLink(ed::PinId inputPinId, ed::PinId outputPinId); + // startPinId - where the link was initiated + // endPinId - where the link was ended + void addLink(ed::PinId startPinId, ed::PinId endPinId); // Delete link from current link vector and remove any connections in // UiNode or MaterialX Nodes to update shader From 044645345bd491250ff6041489b83b28640e54bb Mon Sep 17 00:00:00 2001 From: Andy <94316446+beersandrew@users.noreply.github.com> Date: Sat, 14 Oct 2023 22:56:53 +0300 Subject: [PATCH 017/128] Restructure Add Node List (#1562) Added a list of nodes to the best of my ability to be the order they should be displayed --- source/MaterialXGraphEditor/Graph.cpp | 166 ++++++++++++++------------ source/MaterialXGraphEditor/Graph.h | 27 ++++- 2 files changed, 112 insertions(+), 81 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 522280cb08..849b8607b4 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -236,9 +236,6 @@ void Graph::addExtraNodes() return; } - // Clear any old nodes, if we previously used tab with another graph doc - _extraNodes.clear(); - // Get all types from the doc std::vector types; std::vector typeDefs = _graphDoc->getTypeDefs(); @@ -252,18 +249,16 @@ void Graph::addExtraNodes() for (const std::string& type : types) { std::string nodeName = "ND_input_" + type; - _extraNodes["Input Nodes"].push_back({ nodeName, type, "input" }); + _nodesToAdd.emplace_back(nodeName, type, "input", "Input Nodes"); nodeName = "ND_output_" + type; - _extraNodes["Output Nodes"].push_back({ nodeName, type, "output" }); + _nodesToAdd.emplace_back(nodeName, type, "output", "Output Nodes"); } // Add group node - std::vector groupNode{ "ND_group", "", "group" }; - _extraNodes["Group Nodes"].push_back(groupNode); + _nodesToAdd.emplace_back("ND_group", "", "group", "Group Nodes"); // Add nodegraph node - std::vector nodeGraph{ "ND_nodegraph", "", "nodegraph" }; - _extraNodes["Node Graph"].push_back(nodeGraph); + _nodesToAdd.emplace_back("ND_nodegraph", "", "nodegraph", "Node Graph"); } ed::PinId Graph::getOutputPin(UiNodePtr node, UiNodePtr upNode, UiPinPtr input) @@ -1224,20 +1219,63 @@ void Graph::setUiNodeInfo(UiNodePtr node, const std::string& type, const std::st void Graph::createNodeUIList(mx::DocumentPtr doc) { _nodesToAdd.clear(); - const std::string EXTRA_GROUP_NAME = "extra"; - for (mx::NodeDefPtr nodeDef : doc->getNodeDefs()) + + std::vector ordered_groups = { + "texture2d", + "texture3d", + "procedural", + "procedural2d", + "procedural3d", + "geometric", + "translation", + "convolution2d", + "math", + "adjustment", + "compositing", + "conditional", + "channel", + "organization", + "global", + "application", + "material", + "shader", + "pbr", + "light", + "colortransform", + "no_group" + }; + + auto nodeDefs = doc->getNodeDefs(); + std::unordered_map> groupToNodeDef; + + for (const auto& nodeDef : nodeDefs) { - // NodeDef is the key for the map std::string group = nodeDef->getNodeGroup(); + if (group.empty()) { - group = EXTRA_GROUP_NAME; + group = "no_group"; } - if (_nodesToAdd.find(group) == _nodesToAdd.end()) + + if (groupToNodeDef.find(group) == groupToNodeDef.end()) { - _nodesToAdd[group] = std::vector(); + groupToNodeDef[group] = std::vector(); + } + groupToNodeDef[group].push_back(nodeDef); + } + + for (const auto& group : ordered_groups) + { + auto it = groupToNodeDef.find(group); + if (it != groupToNodeDef.end()) + { + const auto& groupNodeDefs = it->second; + + for (const auto& nodeDef : groupNodeDefs) + { + _nodesToAdd.emplace_back(nodeDef->getName(), nodeDef->getType(), nodeDef->getNodeString(), group); + } } - _nodesToAdd[group].push_back(nodeDef); } addExtraNodes(); @@ -3595,96 +3633,66 @@ void Graph::addNodePopup(bool cursor) // Input string length // Filter extra nodes - includes inputs, outputs, groups, and node graphs const std::string NODEGRAPH_ENTRY = "Node Graph"; - for (std::unordered_map>>::iterator it = _extraNodes.begin(); it != _extraNodes.end(); ++it) + + // Filter nodedefs and add to menu if matches filter + for (auto node : _nodesToAdd) { // Filter out list of nodes if (subs.size() > 0) { ImGui::SetNextWindowSizeConstraints(ImVec2(250.0f, 300.0f), ImVec2(-1.0f, 500.0f)); - for (size_t i = 0; i < it->second.size(); i++) - { - std::string str(it->second[i][0]); - std::string nodeName = it->second[i][0]; + std::string str(node.getName()); + std::string nodeName = node.getName(); - // Disallow creating nested nodegraphs - if (_isNodeGraph && it->first == NODEGRAPH_ENTRY) - { - continue; - } + // Disallow creating nested nodegraphs + if (_isNodeGraph && node.getGroup() == NODEGRAPH_ENTRY) + { + continue; + } - // Allow spaces to be used to search for node names - std::replace(subs.begin(), subs.end(), ' ', '_'); + // Allow spaces to be used to search for node names + std::replace(subs.begin(), subs.end(), ' ', '_'); - if (str.find(subs) != std::string::npos) + if (str.find(subs) != std::string::npos) + { + if (ImGui::MenuItem(getUserNodeDefName(nodeName).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) { - if (ImGui::MenuItem(getUserNodeDefName(nodeName).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) - { - addNode(it->second[i][2], getUserNodeDefName(nodeName), it->second[i][1]); - _addNewNode = true; - memset(input, '\0', sizeof(input)); - } + addNode(node.getCategory(), getUserNodeDefName(nodeName), node.getType()); + _addNewNode = true; + memset(input, '\0', sizeof(input)); } } } else { ImGui::SetNextWindowSizeConstraints(ImVec2(100, 10), ImVec2(-1, 300)); - if (ImGui::BeginMenu(it->first.c_str())) + if (ImGui::BeginMenu(node.getGroup().c_str())) { ImGui::SetWindowFontScale(_fontScale); - for (size_t j = 0; j < it->second.size(); j++) + std::string name = node.getName(); + std::string prefix = "ND_"; + if (name.compare(0, prefix.size(), prefix) == 0 && name.compare(prefix.size(), std::string::npos, node.getCategory()) == 0) { - std::string name = it->second[j][0]; if (ImGui::MenuItem(getUserNodeDefName(name).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) { - addNode(it->second[j][2], getUserNodeDefName(name), it->second[j][1]); - _addNewNode = true; - } - } - ImGui::EndMenu(); - } - } - } - - // Filter nodedefs and add to menu if matches filter - for (std::unordered_map>::iterator it = _nodesToAdd.begin(); it != _nodesToAdd.end(); ++it) - { - // Filter out list of nodes - if (subs.size() > 0) - { - ImGui::SetNextWindowSizeConstraints(ImVec2(250.0f, 300.0f), ImVec2(-1.0f, 500.0f)); - for (size_t i = 0; i < it->second.size(); i++) - { - std::string str(it->second[i]->getName()); - std::string nodeName = it->second[i]->getName(); - if (str.find(subs) != std::string::npos) - { - std::string val = getUserNodeDefName(nodeName); - if (ImGui::MenuItem(val.c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) - { - addNode(it->second[i]->getNodeString(), val, it->second[i]->getType()); + addNode(node.getCategory(), getUserNodeDefName(name), node.getType()); _addNewNode = true; - memset(input, '\0', sizeof(input)); } } - } - } - else - { - ImGui::SetNextWindowSizeConstraints(ImVec2(100, 10), ImVec2(-1, 300)); - if (ImGui::BeginMenu(it->first.c_str())) - { - ImGui::SetWindowFontScale(_fontScale); - for (size_t i = 0; i < it->second.size(); i++) + else { - std::string name = it->second[i]->getName(); - std::string val = getUserNodeDefName(name); - if (ImGui::MenuItem(val.c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) + if (ImGui::BeginMenu(node.getCategory().c_str())) { - addNode(it->second[i]->getNodeString(), val, it->second[i]->getType()); - _addNewNode = true; + if (ImGui::MenuItem(getUserNodeDefName(name).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) + { + addNode(node.getCategory(), getUserNodeDefName(name), node.getType()); + _addNewNode = true; + } + ImGui::EndMenu(); } } + + ImGui::EndMenu(); } } diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index 9b9857c69a..87d4119c2a 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -14,6 +14,30 @@ #include +class MenuItem +{ + public: + MenuItem(const std::string& name, const std::string& type, const std::string& category, const std::string& group) : + name(name), type(type), category(category), group(group) { } + + // getters + std::string getName() const { return name; } + std::string getType() const { return type; } + std::string getCategory() const { return category; } + std::string getGroup() const { return group; } + + // setters + void setName(const std::string& newName) { this->name = newName; } + void setType(const std::string& newType) { this->type = newType; } + void setCategory(const std::string& newCategory) { this->category = newCategory; } + void setGroup(const std::string& newGroup) { this->group = newGroup; } + + private: + std::string name; + std::string type; + std::string category; + std::string group; +}; namespace ed = ax::NodeEditor; namespace mx = MaterialX; @@ -248,8 +272,7 @@ class Graph std::vector _currGraphName; // for adding new nodes - std::unordered_map> _nodesToAdd; - std::unordered_map>> _extraNodes; + std::vector _nodesToAdd; // stacks to dive into and out of node graphs std::stack> _graphStack; From 74462510a32948341131b93d1695514cfc283927 Mon Sep 17 00:00:00 2001 From: iukpo-lucasfilm <145880411+iukpo-lucasfilm@users.noreply.github.com> Date: Sat, 14 Oct 2023 15:26:23 -0700 Subject: [PATCH 018/128] Stop Graph Editor from creating imgui.ini file (#1570) Added code to stop creation of imgui.ini after saving material after saving then closing Graph Editor --- source/MaterialXGraphEditor/Main.cpp | 51 ++++------------------------ 1 file changed, 7 insertions(+), 44 deletions(-) diff --git a/source/MaterialXGraphEditor/Main.cpp b/source/MaterialXGraphEditor/Main.cpp index 754d766798..5bbcbdad66 100644 --- a/source/MaterialXGraphEditor/Main.cpp +++ b/source/MaterialXGraphEditor/Main.cpp @@ -23,44 +23,6 @@ static void errorCallback(int error, const char* description) fprintf(stderr, "Glfw Error %d: %s\n", error, description); } -mx::FilePath getConfigPath() -{ - mx::FilePath configPath; - auto xdgConfigHome = mx::getEnviron("XDG_CONFIG_HOME"); - auto homeDirectory = mx::getEnviron("HOME"); - if (!xdgConfigHome.empty()) - { - configPath = mx::FilePath(xdgConfigHome); - } - else if (!homeDirectory.empty()) - { -#if defined(__APPLE__) - configPath = mx::FilePath(homeDirectory) / "Library" / "Preferences"; -#else - configPath = mx::FilePath(homeDirectory) / ".config"; - if (!configPath.exists()) - { - configPath.createDirectory(); - } -#endif - } - else - { - return {}; - } - - configPath = configPath / "MaterialX"; - configPath.createDirectory(); - - if (!configPath.exists()) - { - std::cerr << "Failed to create MaterialX config directory at " << configPath.asString() << std::endl; - return {}; - } - - return configPath / "GraphEditor.imgui.ini"; -} - const std::string options = " Options: \n" " --material [FILENAME] Specify the filename of the MTLX document to be displayed in the graph editor\n" @@ -197,13 +159,14 @@ int main(int argc, char* const argv[]) IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); - io.Fonts->AddFontDefault(); - mx::FilePath configPath = getConfigPath(); - if (!configPath.isEmpty()) - { - io.IniFilename = configPath.asString().c_str(); - } + // Set ini and log filename to NULL. This will prevent the automatic creation of imgui.ini + // in the same folder as the saved material. + // TODO: Consider setting the ini and log file paths to an application directory. + io.IniFilename = NULL; + io.LogFilename = NULL; + + io.Fonts->AddFontDefault(); // Setup Dear ImGui style ImGui::StyleColorsDark(); From a62a468ed80f4a6830950cc7a9ff7e544567d669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ars=C3=A8ne=20P=C3=A9rard-Gayot?= Date: Sun, 15 Oct 2023 20:18:43 +0200 Subject: [PATCH 019/128] Fix edge case in HW shader generation for transform nodes (#1560) This merges the TransformXXXNodeGlsl and TransformXXXNodeMsl classes into a HwTransformNode which has 3 subclasses, HwTransformVectorNode, HwTransformPointNode, and HwTransformNormalNode, all of which can be configured by overriding the virtual methods of HwTransformNode. --- .../MaterialXGenGlsl/GlslShaderGenerator.cpp | 15 +-- source/MaterialXGenGlsl/GlslShaderGenerator.h | 5 - .../Nodes/TransformNormalNodeGlsl.cpp | 43 ------- .../Nodes/TransformNormalNodeGlsl.h | 27 ----- .../Nodes/TransformPointNodeGlsl.cpp | 23 ---- .../Nodes/TransformPointNodeGlsl.h | 25 ---- .../Nodes/TransformVectorNodeGlsl.cpp | 84 ------------- .../Nodes/TransformVectorNodeGlsl.h | 30 ----- source/MaterialXGenMsl/MslShaderGenerator.cpp | 15 +-- source/MaterialXGenMsl/MslShaderGenerator.h | 5 - .../Nodes/TransformNormalNodeMsl.cpp | 43 ------- .../Nodes/TransformNormalNodeMsl.h | 27 ----- .../Nodes/TransformPointNodeMsl.cpp | 23 ---- .../Nodes/TransformPointNodeMsl.h | 25 ---- .../Nodes/TransformVectorNodeMsl.cpp | 84 ------------- .../Nodes/TransformVectorNodeMsl.h | 30 ----- .../Nodes/HwTransformNode.cpp | 110 ++++++++++++++++++ .../Nodes/HwTransformNode.h | 71 +++++++++++ source/MaterialXGenShader/ShaderNode.cpp | 5 + source/MaterialXGenShader/ShaderNode.h | 3 + .../PyMaterialXGenShader/PyShaderPort.cpp | 1 + 21 files changed, 198 insertions(+), 496 deletions(-) delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h delete mode 100644 source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp delete mode 100644 source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h delete mode 100644 source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp delete mode 100644 source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h delete mode 100644 source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp delete mode 100644 source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h create mode 100644 source/MaterialXGenShader/Nodes/HwTransformNode.cpp create mode 100644 source/MaterialXGenShader/Nodes/HwTransformNode.h diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp index 87582c8f50..ec5e48d4ec 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp @@ -22,9 +22,6 @@ #include #include #include -#include -#include -#include #include #include @@ -34,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -228,13 +226,13 @@ GlslShaderGenerator::GlslShaderGenerator() : registerImplementation(elementNames, BlurNodeGlsl::create); // elementNames = { @@ -902,11 +900,6 @@ ShaderNodeImplPtr GlslShaderGenerator::getImplementation(const NodeDef& nodedef, } const string GlslImplementation::SPACE = "space"; -const string GlslImplementation::TO_SPACE = "tospace"; -const string GlslImplementation::FROM_SPACE = "fromspace"; -const string GlslImplementation::WORLD = "world"; -const string GlslImplementation::OBJECT = "object"; -const string GlslImplementation::MODEL = "model"; const string GlslImplementation::INDEX = "index"; const string GlslImplementation::GEOMPROP = "geomprop"; diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.h b/source/MaterialXGenGlsl/GlslShaderGenerator.h index 4464f5d47c..acc8b0d6ee 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.h +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.h @@ -110,11 +110,6 @@ class MX_GENGLSL_API GlslImplementation : public ShaderNodeImpl /// Internal string constants static const string SPACE; - static const string TO_SPACE; - static const string FROM_SPACE; - static const string WORLD; - static const string OBJECT; - static const string MODEL; static const string INDEX; static const string GEOMPROP; }; diff --git a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp deleted file mode 100644 index 0800fb4bf3..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformNormalNodeGlsl::create() -{ - return std::make_shared(); -} - -void TransformNormalNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - TransformVectorNodeGlsl::emitFunctionCall(node, context, stage); - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - const ShaderOutput* output = node.getOutput(); - shadergen.emitLineBegin(stage); - shadergen.emitOutput(output, false, false, context, stage); - shadergen.emitString(" = normalize(" + output->getVariable() + ")", stage); - shadergen.emitLineEnd(stage); - } -} - -const string& TransformNormalNodeGlsl::getMatrix(const string& fromSpace, const string& toSpace) const -{ - if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD) - { - return HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX; - } - else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT)) - { - return HW::T_WORLD_TRANSPOSE_MATRIX; - } - return EMPTY_STRING; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h deleted file mode 100644 index f08ec564d9..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMNORMALNODEGLSL_H -#define MATERIALX_TRANSFORMNORMALNODEGLSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformNormal node implementation for GLSL -class MX_GENGLSL_API TransformNormalNodeGlsl : public TransformVectorNodeGlsl -{ - public: - static ShaderNodeImplPtr create(); - - protected: - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; - - const string& getMatrix(const string& fromSpace, const string& toSpace) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp deleted file mode 100644 index 1570939bfe..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformPointNodeGlsl::create() -{ - return std::make_shared(); -} - -string TransformPointNodeGlsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const -{ - const ShaderGenerator& shadergen = context.getShaderGenerator(); - return "vec4(" + shadergen.getUpstreamResult(in, context) + ", 1.0)"; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h deleted file mode 100644 index eb366d8190..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMPOINTNODEGLSL_H -#define MATERIALX_TRANSFORMPOINTNODEGLSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformPoint node implementation for GLSL -class MX_GENGLSL_API TransformPointNodeGlsl : public TransformVectorNodeGlsl -{ - public: - static ShaderNodeImplPtr create(); - - protected: - virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp deleted file mode 100644 index df1e921497..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformVectorNodeGlsl::create() -{ - return std::make_shared(); -} - -void TransformVectorNodeGlsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const -{ - const ShaderInput* toSpaceInput = node.getInput(TO_SPACE); - string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE); - string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const string& matrix = getMatrix(fromSpace, toSpace); - if (!matrix.empty()) - { - ShaderStage& ps = shader.getStage(Stage::PIXEL); - addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, matrix, ps); - } -} - -void TransformVectorNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - - const ShaderInput* inInput = node.getInput("in"); - if (inInput->getType() != Type::VECTOR3 && inInput->getType() != Type::VECTOR4) - { - throw ExceptionShaderGenError("Transform node must have 'in' type of vector3 or vector4."); - } - - const ShaderInput* toSpaceInput = node.getInput(TO_SPACE); - string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE); - string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = (", stage); - const string& matrix = getMatrix(fromSpace, toSpace); - if (!matrix.empty()) - { - shadergen.emitString(matrix + " * ", stage); - } - shadergen.emitString(getHomogeneousCoordinate(inInput, context), stage); - shadergen.emitString(").xyz", stage); - shadergen.emitLineEnd(stage); - } -} - -const string& TransformVectorNodeGlsl::getMatrix(const string& fromSpace, const string& toSpace) const -{ - if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD) - { - return HW::T_WORLD_MATRIX; - } - else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT)) - { - return HW::T_WORLD_INVERSE_MATRIX; - } - return EMPTY_STRING; -} - -string TransformVectorNodeGlsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const -{ - const ShaderGenerator& shadergen = context.getShaderGenerator(); - return "vec4(" + shadergen.getUpstreamResult(in, context) + ", 0.0)"; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h deleted file mode 100644 index e9861650b3..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMVECTORNODEGLSL_H -#define MATERIALX_TRANSFORMVECTORNODEGLSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformVector node implementation for GLSL -class MX_GENGLSL_API TransformVectorNodeGlsl : public GlslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; - - protected: - virtual const string& getMatrix(const string& fromSpace, const string& toSpace) const; - virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index 1d93104ce8..ea3fb7112d 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -22,9 +22,6 @@ #include #include #include -#include -#include -#include #include #include @@ -34,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -232,13 +230,13 @@ MslShaderGenerator::MslShaderGenerator() : registerImplementation(elementNames, BlurNodeMsl::create); // elementNames = { @@ -1404,11 +1402,6 @@ ShaderNodeImplPtr MslShaderGenerator::getImplementation(const NodeDef& nodedef, } const string MslImplementation::SPACE = "space"; -const string MslImplementation::TO_SPACE = "tospace"; -const string MslImplementation::FROM_SPACE = "fromspace"; -const string MslImplementation::WORLD = "world"; -const string MslImplementation::OBJECT = "object"; -const string MslImplementation::MODEL = "model"; const string MslImplementation::INDEX = "index"; const string MslImplementation::GEOMPROP = "geomprop"; diff --git a/source/MaterialXGenMsl/MslShaderGenerator.h b/source/MaterialXGenMsl/MslShaderGenerator.h index 631c38f33d..21817db735 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.h +++ b/source/MaterialXGenMsl/MslShaderGenerator.h @@ -137,11 +137,6 @@ class MX_GENMSL_API MslImplementation : public ShaderNodeImpl /// Internal string constants static const string SPACE; - static const string TO_SPACE; - static const string FROM_SPACE; - static const string WORLD; - static const string OBJECT; - static const string MODEL; static const string INDEX; static const string GEOMPROP; }; diff --git a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp deleted file mode 100644 index 98810c025b..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformNormalNodeMsl::create() -{ - return std::make_shared(); -} - -void TransformNormalNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - TransformVectorNodeMsl::emitFunctionCall(node, context, stage); - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - const ShaderOutput* output = node.getOutput(); - shadergen.emitLineBegin(stage); - shadergen.emitOutput(output, false, false, context, stage); - shadergen.emitString(" = normalize(" + output->getVariable() + ")", stage); - shadergen.emitLineEnd(stage); - } -} - -const string& TransformNormalNodeMsl::getMatrix(const string& fromSpace, const string& toSpace) const -{ - if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD) - { - return HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX; - } - else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT)) - { - return HW::T_WORLD_TRANSPOSE_MATRIX; - } - return EMPTY_STRING; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h b/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h deleted file mode 100644 index 603ba3771c..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMNORMALNODEMSL_H -#define MATERIALX_TRANSFORMNORMALNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformNormal node implementation for MSL -class MX_GENMSL_API TransformNormalNodeMsl : public TransformVectorNodeMsl -{ - public: - static ShaderNodeImplPtr create(); - - protected: - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; - - const string& getMatrix(const string& fromSpace, const string& toSpace) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp deleted file mode 100644 index 38db776855..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformPointNodeMsl::create() -{ - return std::make_shared(); -} - -string TransformPointNodeMsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const -{ - const ShaderGenerator& shadergen = context.getShaderGenerator(); - return "float4(" + shadergen.getUpstreamResult(in, context) + ", 1.0)"; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h b/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h deleted file mode 100644 index 9fc2361d7d..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMPOINTNODEMSL_H -#define MATERIALX_TRANSFORMPOINTNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformPoint node implementation for MSL -class MX_GENMSL_API TransformPointNodeMsl : public TransformVectorNodeMsl -{ - public: - static ShaderNodeImplPtr create(); - - protected: - virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp deleted file mode 100644 index c5d6ce242a..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformVectorNodeMsl::create() -{ - return std::make_shared(); -} - -void TransformVectorNodeMsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const -{ - const ShaderInput* toSpaceInput = node.getInput(TO_SPACE); - string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE); - string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const string& matrix = getMatrix(fromSpace, toSpace); - if (!matrix.empty()) - { - ShaderStage& ps = shader.getStage(Stage::PIXEL); - addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, matrix, ps); - } -} - -void TransformVectorNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - - const ShaderInput* inInput = node.getInput("in"); - if (inInput->getType() != Type::VECTOR3 && inInput->getType() != Type::VECTOR4) - { - throw ExceptionShaderGenError("Transform node must have 'in' type of vector3 or vector4."); - } - - const ShaderInput* toSpaceInput = node.getInput(TO_SPACE); - string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE); - string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = (", stage); - const string& matrix = getMatrix(fromSpace, toSpace); - if (!matrix.empty()) - { - shadergen.emitString(matrix + " * ", stage); - } - shadergen.emitString(getHomogeneousCoordinate(inInput, context), stage); - shadergen.emitString(").xyz", stage); - shadergen.emitLineEnd(stage); - } -} - -const string& TransformVectorNodeMsl::getMatrix(const string& fromSpace, const string& toSpace) const -{ - if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD) - { - return HW::T_WORLD_MATRIX; - } - else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT)) - { - return HW::T_WORLD_INVERSE_MATRIX; - } - return EMPTY_STRING; -} - -string TransformVectorNodeMsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const -{ - const ShaderGenerator& shadergen = context.getShaderGenerator(); - return "float4(" + shadergen.getUpstreamResult(in, context) + ", 0.0)"; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h b/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h deleted file mode 100644 index 013a3db29a..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMVECTORNODEMSL_H -#define MATERIALX_TRANSFORMVECTORNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformVector node implementation for MSL -class MX_GENMSL_API TransformVectorNodeMsl : public MslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; - - protected: - virtual const string& getMatrix(const string& fromSpace, const string& toSpace) const; - virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenShader/Nodes/HwTransformNode.cpp b/source/MaterialXGenShader/Nodes/HwTransformNode.cpp new file mode 100644 index 0000000000..018924855d --- /dev/null +++ b/source/MaterialXGenShader/Nodes/HwTransformNode.cpp @@ -0,0 +1,110 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include + +MATERIALX_NAMESPACE_BEGIN + +const string HwTransformNode::FROM_SPACE = "fromspace"; +const string HwTransformNode::TO_SPACE = "tospace"; +const string HwTransformNode::MODEL = "model"; +const string HwTransformNode::OBJECT = "object"; +const string HwTransformNode::WORLD = "world"; + +void HwTransformNode::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const +{ + const string toSpace = getToSpace(node); + const string fromSpace = getFromSpace(node); + const string& matrix = getMatrix(fromSpace, toSpace); + if (!matrix.empty()) + { + ShaderStage& ps = shader.getStage(Stage::PIXEL); + addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, matrix, ps); + } +} + +void HwTransformNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +{ + DEFINE_SHADER_STAGE(stage, Stage::PIXEL) + { + const ShaderGenerator& shadergen = context.getShaderGenerator(); + + const ShaderOutput* output = node.getOutput(); + const ShaderInput* inInput = node.getInput("in"); + if (inInput->getType() != Type::VECTOR3 && inInput->getType() != Type::VECTOR4) + { + throw ExceptionShaderGenError("Transform node must have 'in' type of vector3 or vector4."); + } + + shadergen.emitLineBegin(stage); + shadergen.emitOutput(output, true, false, context, stage); + shadergen.emitString(" = (", stage); + + const string toSpace = getToSpace(node); + const string fromSpace = getFromSpace(node); + const string& matrix = getMatrix(fromSpace, toSpace); + if (!matrix.empty()) + { + shadergen.emitString(matrix + " * ", stage); + } + + const string type = shadergen.getSyntax().getTypeName(Type::VECTOR4); + const string input = shadergen.getUpstreamResult(inInput, context); + shadergen.emitString(type + "(" + input + ", " + getHomogeneousCoordinate() + ")).xyz", stage); + shadergen.emitLineEnd(stage); + + if (shouldNormalize()) + { + shadergen.emitLineBegin(stage); + shadergen.emitOutput(output, false, false, context, stage); + shadergen.emitString(" = normalize(" + output->getVariable() + ")", stage); + shadergen.emitLineEnd(stage); + } + } +} + +string HwTransformNode::getFromSpace(const ShaderNode& node) const +{ + const ShaderInput* input = node.getInput(FROM_SPACE); + return input ? input->getValueString() : EMPTY_STRING; +} + +string HwTransformNode::getToSpace(const ShaderNode& node) const +{ + const ShaderInput* input = node.getInput(TO_SPACE); + return input ? input->getValueString() : EMPTY_STRING; +} + +const string& HwTransformNode::getMatrix(const string& fromSpace, const string& toSpace) const +{ + if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD) + { + return getModelToWorldMatrix(); + } + else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT)) + { + return getWorldToModelMatrix(); + } + return EMPTY_STRING; +} + +ShaderNodeImplPtr HwTransformVectorNode::create() +{ + return std::make_shared(); +} + +ShaderNodeImplPtr HwTransformPointNode::create() +{ + return std::make_shared(); +} + +ShaderNodeImplPtr HwTransformNormalNode::create() +{ + return std::make_shared(); +} + +MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenShader/Nodes/HwTransformNode.h b/source/MaterialXGenShader/Nodes/HwTransformNode.h new file mode 100644 index 0000000000..a97e57405c --- /dev/null +++ b/source/MaterialXGenShader/Nodes/HwTransformNode.h @@ -0,0 +1,71 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#ifndef MATERIALX_HWTRANSFORMNODE_H +#define MATERIALX_HWTRANSFORMNODE_H + +#include + +MATERIALX_NAMESPACE_BEGIN + +/// Generic transformation node for hardware languages +class MX_GENSHADER_API HwTransformNode : public ShaderNodeImpl +{ + public: + void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; + void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; + + protected: + virtual const string& getMatrix(const string& fromSpace, const string& toSpace) const; + virtual const string& getModelToWorldMatrix() const = 0; + virtual const string& getWorldToModelMatrix() const = 0; + virtual string getHomogeneousCoordinate() const = 0; + virtual bool shouldNormalize() const { return false; } + + virtual string getFromSpace(const ShaderNode&) const; + virtual string getToSpace(const ShaderNode&) const; + + static const string FROM_SPACE; + static const string TO_SPACE; + static const string MODEL; + static const string OBJECT; + static const string WORLD; +}; + +class MX_GENSHADER_API HwTransformVectorNode : public HwTransformNode +{ + public: + static ShaderNodeImplPtr create(); + + protected: + const string& getModelToWorldMatrix() const override { return HW::T_WORLD_MATRIX; } + const string& getWorldToModelMatrix() const override { return HW::T_WORLD_INVERSE_MATRIX; } + string getHomogeneousCoordinate() const override { return "0.0"; } +}; + +class MX_GENSHADER_API HwTransformPointNode : public HwTransformVectorNode +{ + public: + static ShaderNodeImplPtr create(); + + protected: + string getHomogeneousCoordinate() const override { return "1.0"; } +}; + +class MX_GENSHADER_API HwTransformNormalNode : public HwTransformNode +{ + public: + static ShaderNodeImplPtr create(); + + protected: + const string& getModelToWorldMatrix() const override { return HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX; } + const string& getWorldToModelMatrix() const override { return HW::T_WORLD_TRANSPOSE_MATRIX; } + string getHomogeneousCoordinate() const override { return "0.0"; } + bool shouldNormalize() const override { return true; } +}; + +MATERIALX_NAMESPACE_END + +#endif diff --git a/source/MaterialXGenShader/ShaderNode.cpp b/source/MaterialXGenShader/ShaderNode.cpp index 04551cb6d2..3e393178f1 100644 --- a/source/MaterialXGenShader/ShaderNode.cpp +++ b/source/MaterialXGenShader/ShaderNode.cpp @@ -32,6 +32,11 @@ string ShaderPort::getFullName() const return (_node->getName() + "_" + _name); } +string ShaderPort::getValueString() const +{ + return getValue() ? getValue()->getValueString() : EMPTY_STRING; +} + // // ShaderInput methods // diff --git a/source/MaterialXGenShader/ShaderNode.h b/source/MaterialXGenShader/ShaderNode.h index 536e0adc1e..dd74269764 100644 --- a/source/MaterialXGenShader/ShaderNode.h +++ b/source/MaterialXGenShader/ShaderNode.h @@ -170,6 +170,9 @@ class MX_GENSHADER_API ShaderPort : public std::enable_shared_from_this Date: Mon, 16 Oct 2023 13:54:34 -0700 Subject: [PATCH 020/128] Add floating popup to pins when hovered (#1565) Added a tooltip/popup showing the name, type, value and connection of a pin! --- source/MaterialXGraphEditor/Graph.cpp | 64 ++++++++++++++++++++++++++- source/MaterialXGraphEditor/Graph.h | 2 + source/MaterialXGraphEditor/UiNode.h | 23 ++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 849b8607b4..439f720e2e 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -2257,6 +2257,7 @@ std::vector Graph::createNodes(bool nodegraph) } upUiNode->outputPins[pinIndex]->addConnection(pin); + pin->addConnection(upUiNode->outputPins[pinIndex]); } pin->setConnected(true); } @@ -2322,6 +2323,7 @@ std::vector Graph::createNodes(bool nodegraph) } } upUiNode->outputPins[pinIndex]->addConnection(pin); + pin->addConnection(upUiNode->outputPins[pinIndex]); } pin->setConnected(true); } @@ -2392,6 +2394,7 @@ std::vector Graph::createNodes(bool nodegraph) } } upUiNode->outputPins[pinIndex]->addConnection(pin); + pin->addConnection(upUiNode->outputPins[pinIndex]); } } @@ -2628,6 +2631,11 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) _frameCount = ImGui::GetFrameCount(); _renderer->setMaterialCompilation(true); + inputPin->addConnection(outputPin); + outputPin->addConnection(inputPin); + outputPin->setConnected(true); + inputPin->setConnected(true); + if (uiDownNode->getNode() || uiDownNode->getNodeGraph()) { mx::InputPtr connectingInput = nullptr; @@ -2721,6 +2729,7 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) } } + pin->setConnected(true); pin->_input->removeAttribute(mx::ValueElement::VALUE_ATTRIBUTE); connectingInput = pin->_input; @@ -2806,9 +2815,13 @@ void Graph::deleteLinkInfo(int startAttr, int endAttr) setDefaults(_graphNodes[upNode]->getInput()); } + for (UiPinPtr connect : pin->_connections) + { + pin->deleteConnection(connect); + } + // Remove any output reference pin->_input->removeAttribute(mx::PortElement::OUTPUT_ATTRIBUTE); - pin->setConnected(false); // If a value exists update the input with it @@ -2833,6 +2846,10 @@ void Graph::deleteLinkInfo(int startAttr, int endAttr) _graphNodes[downNode]->getNodeGraph()->getInput(pin->_name)->removeAttribute(mx::ValueElement::INTERFACE_NAME_ATTRIBUTE); setDefaults(_graphNodes[upNode]->getInput()); } + for (UiPinPtr connect : pin->_connections) + { + pin->deleteConnection(connect); + } pin->_input->setConnectedNode(nullptr); pin->setConnected(false); setDefaults(pin->_input); @@ -2847,6 +2864,10 @@ void Graph::deleteLinkInfo(int startAttr, int endAttr) { removeEdge(downNode, upNode, pin); _graphNodes[downNode]->getOutput()->removeAttribute("nodename"); + for (UiPinPtr connect : pin->_connections) + { + pin->deleteConnection(connect); + } pin->setConnected(false); } } @@ -3744,6 +3765,46 @@ void Graph::searchNodePopup(bool cursor) } } +bool Graph::isPinHovered() +{ + ed::PinId currentPin = ed::GetHoveredPin(); + ed::PinId nullPin = 0; + return currentPin != nullPin; +} + +void Graph::addPinPopup() +{ + // Add a floating popup to pin when hovered + if (isPinHovered()) + { + ed::Suspend(); + UiPinPtr pin = getPin(ed::GetHoveredPin()); + std::string connected = ""; + std::string value = ""; + if (pin->_connected) + { + connected = "\nConnected to"; + int size = static_cast(pin->getConnections().size()); + for (int i = 0; i < size; i++) + { + UiPinPtr connectedPin = pin->getConnections()[i]; + connected = connected + " " + connectedPin->_name; + if (i != size - 1) + { + connected = connected + ","; + } + } + } + else if (pin->_input != nullptr) + { + value = "\nValue: " + pin->_input->getValueString(); + } + const std::string message("Name: " + pin->_name + "\nType: " + pin->_type + value + connected); + ImGui::SetTooltip("%s", message.c_str()); + ed::Resume(); + } +} + void Graph::readOnlyPopup() { if (_popup) @@ -3860,6 +3921,7 @@ void Graph::drawGraph(ImVec2 mousePos) ImGui::SetNextWindowSizeConstraints(ImVec2(250.0f, 300.0f), ImVec2(-1.0f, 500.0f)); addNodePopup(TextCursor); searchNodePopup(TextCursor); + addPinPopup(); readOnlyPopup(); ImGui::PopStyleVar(); diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index 87d4119c2a..fcdf93723e 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -213,6 +213,8 @@ class Graph void addNodePopup(bool cursor); void searchNodePopup(bool cursor); + bool isPinHovered(); + void addPinPopup(); bool readOnly(); void readOnlyPopup(); diff --git a/source/MaterialXGraphEditor/UiNode.h b/source/MaterialXGraphEditor/UiNode.h index c03ae43219..cf7aa41e28 100644 --- a/source/MaterialXGraphEditor/UiNode.h +++ b/source/MaterialXGraphEditor/UiNode.h @@ -95,6 +95,29 @@ class UiPin _connections.push_back(pin); } + void deleteConnection(UiPinPtr pin) + { + for (size_t i = 0; i < _connections.size(); i++) + { + if (_connections[i]->_pinId == pin->_pinId) + { + _connections.erase(_connections.begin()+i); + } + } + for (size_t i = 0; i < pin->_connections.size(); i++) + { + if (pin->_connections[i]->_pinId == _pinId) + { + pin->_connections.erase(pin->_connections.begin() + i); + } + } + if (pin->_connections.size() == 0) + { + pin->setConnected(false); + } + return; + } + const std::vector& getConnections() { return _connections; From d5634c83335766952026f6120dcea7b902894c44 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 17 Oct 2023 10:18:51 -0700 Subject: [PATCH 021/128] Refinements to Graph class - Move the ordered group vector in Graph::createNodeUIList to a constant at module scope. - Use the joinStrings helper function in Graph::addPinPopup to simplify its implementation. - Update comments to align with coding conventions. --- source/MaterialXGraphEditor/Graph.cpp | 105 ++++++++++++-------------- 1 file changed, 48 insertions(+), 57 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 439f720e2e..889789706b 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -23,6 +23,32 @@ const ImVec2 DEFAULT_NODE_SIZE = ImVec2(138, 116); const int DEFAULT_ALPHA = 255; const int FILTER_ALPHA = 50; +const std::array NODE_GROUP_ORDER = +{ + "texture2d", + "texture3d", + "procedural", + "procedural2d", + "procedural3d", + "geometric", + "translation", + "convolution2d", + "math", + "adjustment", + "compositing", + "conditional", + "channel", + "organization", + "global", + "application", + "material", + "shader", + "pbr", + "light", + "colortransform", + "none" +}; + // Based on ImRect_Expanded function in ImGui Node Editor blueprints-example.cpp ImRect expandImRect(const ImRect& rect, float x, float y) { @@ -1220,41 +1246,15 @@ void Graph::createNodeUIList(mx::DocumentPtr doc) { _nodesToAdd.clear(); - std::vector ordered_groups = { - "texture2d", - "texture3d", - "procedural", - "procedural2d", - "procedural3d", - "geometric", - "translation", - "convolution2d", - "math", - "adjustment", - "compositing", - "conditional", - "channel", - "organization", - "global", - "application", - "material", - "shader", - "pbr", - "light", - "colortransform", - "no_group" - }; - auto nodeDefs = doc->getNodeDefs(); std::unordered_map> groupToNodeDef; for (const auto& nodeDef : nodeDefs) { std::string group = nodeDef->getNodeGroup(); - if (group.empty()) { - group = "no_group"; + group = NODE_GROUP_ORDER.back(); } if (groupToNodeDef.find(group) == groupToNodeDef.end()) @@ -1264,7 +1264,7 @@ void Graph::createNodeUIList(mx::DocumentPtr doc) groupToNodeDef[group].push_back(nodeDef); } - for (const auto& group : ordered_groups) + for (const auto& group : NODE_GROUP_ORDER) { auto it = groupToNodeDef.find(group); if (it != groupToNodeDef.end()) @@ -2526,7 +2526,7 @@ void Graph::setDefaults(mx::InputPtr input) void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) { - // prefer to assume left to right - start is an output, end is an input; swap if inaccurate + // Prefer to assume left to right - start is an output, end is an input; swap if inaccurate if (UiPinPtr inputPin = getPin(endPinId); inputPin && inputPin->_kind != ed::PinKind::Input) { auto tmp = startPinId; @@ -2575,7 +2575,7 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) return; } - // make sure there is an implementation for node + // Make sure there is an implementation for node const mx::ShaderGenerator& shadergen = _renderer->getGenContext().getShaderGenerator(); // Prevent direct connecting from input to output @@ -2613,7 +2613,7 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) { if (linksItr->_endAttr == end_attr) { - // found existing link - remove it; adapted from deleteLink + // Found existing link - remove it; adapted from deleteLink // note: ed::BreakLinks doesn't work as the order ends up inaccurate deleteLinkInfo(linksItr->_startAttr, linksItr->_endAttr); _currLinks.erase(linksItr); @@ -2644,7 +2644,8 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) if (pin->_pinId == inputPinId) { addNodeInput(uiDownNode, pin->_input); - // update value to be empty + + // Update value to be empty if (uiDownNode->getNode() && uiDownNode->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) { if (uiUpNode->getOutput() != nullptr) @@ -2657,12 +2658,11 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) } else { - // node graph if (uiUpNode->getNodeGraph() != nullptr) { for (UiPinPtr outPin : uiUpNode->outputPins) { - // set pin connection to correct output + // Set pin connection to correct output if (outPin->_pinId == outputPinId) { mx::OutputPtr outputs = uiUpNode->getNodeGraph()->getOutput(outPin->_name); @@ -2689,10 +2689,6 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) mx::NodePtr upstreamNode = _graphNodes[upNode]->getNode(); mx::NodeDefPtr upstreamNodeDef = upstreamNode->getNodeDef(); bool isMultiOutput = upstreamNodeDef ? upstreamNodeDef->getOutputs().size() > 1 : false; - - // This is purely to avoid adding a reference to an update node only 1 output, - // as currently validation consides adding this an error. Otherwise - // it will add an "output" attribute all the time. if (!isMultiOutput) { pin->_input->setConnectedNode(uiUpNode->getNode()); @@ -2701,7 +2697,7 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) { for (UiPinPtr outPin : _graphNodes[upNode]->outputPins) { - // set pin connection to correct output + // Set pin connection to correct output if (outPin->_pinId == outputPinId) { mx::OutputPtr outputs = uiUpNode->getNode()->getOutput(outPin->_name); @@ -2718,7 +2714,7 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) { for (UiPinPtr outPin : uiUpNode->outputPins) { - // set pin connection to correct output + // Set pin connection to correct output if (outPin->_pinId == outputPinId) { mx::OutputPtr outputs = uiUpNode->getNodeGraph()->getOutput(outPin->_name); @@ -2729,14 +2725,14 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) } } - pin->setConnected(true); pin->_input->removeAttribute(mx::ValueElement::VALUE_ATTRIBUTE); connectingInput = pin->_input; break; } } - // create new edge and set edge information + + // Create new edge and set edge information createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput); } else if (_graphNodes[downNode]->getOutput() != nullptr) @@ -2744,19 +2740,19 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) mx::InputPtr connectingInput = nullptr; _graphNodes[downNode]->getOutput()->setConnectedNode(_graphNodes[upNode]->getNode()); - // create new edge and set edge information + // Create new edge and set edge information createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput); } else { - // create new edge and set edge info + // Create new edge and set edge info UiEdge newEdge = UiEdge(_graphNodes[upNode], _graphNodes[downNode], nullptr); if (!edgeExists(newEdge)) { _graphNodes[downNode]->edges.push_back(newEdge); _currEdge.push_back(newEdge); - // update input node num and output connections + // Update input node num and output connections _graphNodes[downNode]->setInputNodeNum(1); _graphNodes[upNode]->setOutputConnection(_graphNodes[downNode]); } @@ -3779,23 +3775,18 @@ void Graph::addPinPopup() { ed::Suspend(); UiPinPtr pin = getPin(ed::GetHoveredPin()); - std::string connected = ""; - std::string value = ""; + std::string connected; + std::string value; if (pin->_connected) { - connected = "\nConnected to"; - int size = static_cast(pin->getConnections().size()); - for (int i = 0; i < size; i++) + mx::StringVec connectedNames; + for (UiPinPtr connectedPin : pin->getConnections()) { - UiPinPtr connectedPin = pin->getConnections()[i]; - connected = connected + " " + connectedPin->_name; - if (i != size - 1) - { - connected = connected + ","; - } + connectedNames.push_back(connectedPin->_name); } + connected = "\nConnected to " + mx::joinStrings(connectedNames, ", "); } - else if (pin->_input != nullptr) + else if (pin->_input) { value = "\nValue: " + pin->_input->getValueString(); } From 1c78f460e582a83d0b79117428996b74b6b7b60c Mon Sep 17 00:00:00 2001 From: nicolassavva-autodesk <61437351+nicolassavva-autodesk@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:16:03 -0700 Subject: [PATCH 022/128] Remove unused uniforms in HW generation for heighttonormal (#1576) This PR addresses the undesirable shaderGen for Metal and GLSL targets when using the HeightToNormalNode. The parent ConvolutionNode class emits a couple of filter kernel arrays, for box and gaussian weights, that may cause shader compiler issues when they remain unused. --- source/MaterialXGenGlsl/Nodes/HeightToNormalNodeGlsl.cpp | 5 +++++ source/MaterialXGenGlsl/Nodes/HeightToNormalNodeGlsl.h | 2 ++ source/MaterialXGenMsl/Nodes/HeightToNormalNodeMsl.cpp | 5 +++++ source/MaterialXGenMsl/Nodes/HeightToNormalNodeMsl.h | 2 ++ 4 files changed, 14 insertions(+) diff --git a/source/MaterialXGenGlsl/Nodes/HeightToNormalNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/HeightToNormalNodeGlsl.cpp index 157cd5be04..e98a4ab75c 100644 --- a/source/MaterialXGenGlsl/Nodes/HeightToNormalNodeGlsl.cpp +++ b/source/MaterialXGenGlsl/Nodes/HeightToNormalNodeGlsl.cpp @@ -33,6 +33,11 @@ ShaderNodeImplPtr HeightToNormalNodeGlsl::create() return std::make_shared(); } +void HeightToNormalNodeGlsl::createVariables(const ShaderNode&, GenContext&, Shader&) const +{ + // Default filter kernels from ConvolutionNode are not used by this derived class. +} + void HeightToNormalNodeGlsl::computeSampleOffsetStrings(const string& sampleSizeName, const string& offsetTypeString, unsigned int, StringVec& offsetStrings) const { diff --git a/source/MaterialXGenGlsl/Nodes/HeightToNormalNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/HeightToNormalNodeGlsl.h index 638623ea43..fc6e6b421f 100644 --- a/source/MaterialXGenGlsl/Nodes/HeightToNormalNodeGlsl.h +++ b/source/MaterialXGenGlsl/Nodes/HeightToNormalNodeGlsl.h @@ -18,6 +18,8 @@ class MX_GENGLSL_API HeightToNormalNodeGlsl : public ConvolutionNode public: static ShaderNodeImplPtr create(); + void createVariables(const ShaderNode&, GenContext&, Shader& shader) const override; + void emitFunctionDefinition(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; diff --git a/source/MaterialXGenMsl/Nodes/HeightToNormalNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/HeightToNormalNodeMsl.cpp index 12b1a9675c..7282e5e9df 100644 --- a/source/MaterialXGenMsl/Nodes/HeightToNormalNodeMsl.cpp +++ b/source/MaterialXGenMsl/Nodes/HeightToNormalNodeMsl.cpp @@ -33,6 +33,11 @@ ShaderNodeImplPtr HeightToNormalNodeMsl::create() return std::make_shared(); } +void HeightToNormalNodeMsl::createVariables(const ShaderNode&, GenContext&, Shader&) const +{ + // Default filter kernels from ConvolutionNode are not used by this derived class. +} + void HeightToNormalNodeMsl::computeSampleOffsetStrings(const string& sampleSizeName, const string& offsetTypeString, unsigned int, StringVec& offsetStrings) const { diff --git a/source/MaterialXGenMsl/Nodes/HeightToNormalNodeMsl.h b/source/MaterialXGenMsl/Nodes/HeightToNormalNodeMsl.h index 752c411ed5..035ad300b4 100644 --- a/source/MaterialXGenMsl/Nodes/HeightToNormalNodeMsl.h +++ b/source/MaterialXGenMsl/Nodes/HeightToNormalNodeMsl.h @@ -18,6 +18,8 @@ class MX_GENMSL_API HeightToNormalNodeMsl : public ConvolutionNode public: static ShaderNodeImplPtr create(); + void createVariables(const ShaderNode&, GenContext&, Shader& shader) const override; + void emitFunctionDefinition(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; From 78d27622a0edc00f4936d7d7c613b29f5d181fe0 Mon Sep 17 00:00:00 2001 From: Rasmus Bonnedal Date: Thu, 19 Oct 2023 02:57:37 +0200 Subject: [PATCH 023/128] Update overlay node logic to match reference (#1539) This commit changes the overlay node to match the overlay operation in the Adobe PDF spec. It also changes the implementation to graph based instead of code snippets. --- .../Specification/MaterialX.Specification.md | 2 +- libraries/stdlib/genglsl/mx_overlay.glsl | 25 ---- .../stdlib/genglsl/mx_overlay_color3.glsl | 6 - .../stdlib/genglsl/mx_overlay_color4.glsl | 6 - .../stdlib/genglsl/stdlib_genglsl_impl.mtlx | 5 - .../stdlib/genmdl/stdlib_genmdl_impl.mtlx | 5 - .../stdlib/genmsl/stdlib_genmsl_impl.mtlx | 5 - libraries/stdlib/genosl/mx_overlay_color3.osl | 16 --- libraries/stdlib/genosl/mx_overlay_color4.osl | 22 ---- .../stdlib/genosl/stdlib_genosl_impl.mtlx | 5 - libraries/stdlib/stdlib_defs.mtlx | 4 +- libraries/stdlib/stdlib_ng.mtlx | 112 ++++++++++++++++++ .../stdlib/compositing/compositing.mtlx | 12 +- .../MaterialXGenMdl/mdl/materialx/stdlib.mdl | 60 ---------- 14 files changed, 121 insertions(+), 164 deletions(-) delete mode 100644 libraries/stdlib/genglsl/mx_overlay.glsl delete mode 100644 libraries/stdlib/genglsl/mx_overlay_color3.glsl delete mode 100644 libraries/stdlib/genglsl/mx_overlay_color4.glsl delete mode 100644 libraries/stdlib/genosl/mx_overlay_color3.osl delete mode 100644 libraries/stdlib/genosl/mx_overlay_color4.osl diff --git a/documents/Specification/MaterialX.Specification.md b/documents/Specification/MaterialX.Specification.md index 4b99956fb4..895b4756c5 100644 --- a/documents/Specification/MaterialX.Specification.md +++ b/documents/Specification/MaterialX.Specification.md @@ -1496,7 +1496,7 @@ Blend nodes take two 1-4 channel inputs and apply the same operator to all chann | **`burn`** | 1-(1-B)/F | float, colorN | | **`dodge`** | B/(1-F) | float, colorN | | **`screen`** | 1-(1-F)(1-B) | float, colorN | -| **`overlay`** | 2FB if F<0.5;
1-(1-F)(1-B) if F>=0.5 | float, colorN | +| **`overlay`** | 2FB if B<0.5;
1-2(1-F)(1-B) if B>=0.5 | float, colorN | #### Merge Nodes diff --git a/libraries/stdlib/genglsl/mx_overlay.glsl b/libraries/stdlib/genglsl/mx_overlay.glsl deleted file mode 100644 index e1bec8ac44..0000000000 --- a/libraries/stdlib/genglsl/mx_overlay.glsl +++ /dev/null @@ -1,25 +0,0 @@ -float mx_overlay(float fg, float bg) -{ - return (fg < 0.5) ? (2.0 * fg * bg) : (1.0 - (1.0 - fg) * (1.0 - bg)); -} - -vec2 mx_overlay(vec2 fg, vec2 bg) -{ - return vec2(mx_overlay(fg.r, bg.r), - mx_overlay(fg.g, bg.g)); -} - -vec3 mx_overlay(vec3 fg, vec3 bg) -{ - return vec3(mx_overlay(fg.r, bg.r), - mx_overlay(fg.g, bg.g), - mx_overlay(fg.b, bg.b)); -} - -vec4 mx_overlay(vec4 fg, vec4 bg) -{ - return vec4(mx_overlay(fg.r, bg.r), - mx_overlay(fg.g, bg.g), - mx_overlay(fg.b, bg.b), - mx_overlay(fg.a, bg.a)); -} diff --git a/libraries/stdlib/genglsl/mx_overlay_color3.glsl b/libraries/stdlib/genglsl/mx_overlay_color3.glsl deleted file mode 100644 index 3b6ae67804..0000000000 --- a/libraries/stdlib/genglsl/mx_overlay_color3.glsl +++ /dev/null @@ -1,6 +0,0 @@ -#include "mx_overlay.glsl" - -void mx_overlay_color3(vec3 fg, vec3 bg, float mix, out vec3 result) -{ - result = mix * mx_overlay(fg, bg) + (1.0-mix) * bg; -} diff --git a/libraries/stdlib/genglsl/mx_overlay_color4.glsl b/libraries/stdlib/genglsl/mx_overlay_color4.glsl deleted file mode 100644 index 411e0da372..0000000000 --- a/libraries/stdlib/genglsl/mx_overlay_color4.glsl +++ /dev/null @@ -1,6 +0,0 @@ -#include "mx_overlay.glsl" - -void mx_overlay_color4(vec4 fg, vec4 bg, float mix, out vec4 result) -{ - result = mix * mx_overlay(fg, bg) + (1.0-mix) * bg; -} diff --git a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx index 90d3120bd7..07aae6ce66 100644 --- a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx +++ b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx @@ -560,11 +560,6 @@ - - - - - diff --git a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx index ab0d776936..0081dec924 100644 --- a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx +++ b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx @@ -568,11 +568,6 @@ - - - - - diff --git a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx index fcab8fd69d..dea1c49636 100644 --- a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx +++ b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx @@ -560,11 +560,6 @@ - - - - - diff --git a/libraries/stdlib/genosl/mx_overlay_color3.osl b/libraries/stdlib/genosl/mx_overlay_color3.osl deleted file mode 100644 index 387653fe05..0000000000 --- a/libraries/stdlib/genosl/mx_overlay_color3.osl +++ /dev/null @@ -1,16 +0,0 @@ -float overlay(float fg, float bg) -{ - return (fg < 0.5) ? (2 * fg * bg) : (1 - (1 - fg) * (1 - bg)); -} - -color overlay(color fg, color bg) -{ - return color(overlay(fg[0], bg[0]), - overlay(fg[1], bg[1]), - overlay(fg[2], bg[2])); -} - -void mx_overlay_color3(color fg, color bg, float mix, output color out) -{ - out = mix * overlay(fg, bg) + (1-mix) * bg; -} diff --git a/libraries/stdlib/genosl/mx_overlay_color4.osl b/libraries/stdlib/genosl/mx_overlay_color4.osl deleted file mode 100644 index 1ae6a72c15..0000000000 --- a/libraries/stdlib/genosl/mx_overlay_color4.osl +++ /dev/null @@ -1,22 +0,0 @@ -float overlay(float fg, float bg) -{ - return (fg < 0.5) ? (2 * fg * bg) : (1 - (1 - fg) * (1 - bg)); -} - -color overlay(color fg, color bg) -{ - return color(overlay(fg[0], bg[0]), - overlay(fg[1], bg[1]), - overlay(fg[2], bg[2])); -} - -color4 overlay(color4 fg, color4 bg) -{ - return color4(overlay(fg.rgb, bg.rgb), - overlay(fg.a, bg.a)); -} - -void mx_overlay_color4(color4 fg, color4 bg, float mix, output color4 out) -{ - out = mix * overlay(fg, bg) + (1-mix) * bg; -} diff --git a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx index 1ba22ef6a3..42828ce641 100644 --- a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx +++ b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx @@ -561,11 +561,6 @@ - - - - - diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index bb5e8edd1f..3f187e2be1 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -3343,8 +3343,8 @@ diff --git a/libraries/stdlib/stdlib_ng.mtlx b/libraries/stdlib/stdlib_ng.mtlx index e031e72412..4983aaa477 100644 --- a/libraries/stdlib/stdlib_ng.mtlx +++ b/libraries/stdlib/stdlib_ng.mtlx @@ -3391,6 +3391,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Materials/TestSuite/stdlib/compositing/compositing.mtlx b/resources/Materials/TestSuite/stdlib/compositing/compositing.mtlx index e7a742c581..b125e70dca 100644 --- a/resources/Materials/TestSuite/stdlib/compositing/compositing.mtlx +++ b/resources/Materials/TestSuite/stdlib/compositing/compositing.mtlx @@ -183,24 +183,24 @@
- - + + - - + + - - + + diff --git a/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl b/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl index bce4a44ea5..8089feb7f0 100644 --- a/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl @@ -2777,66 +2777,6 @@ export color4 mx_screen_color4( return color4(rgb,a); } -float mx_overlay(float mxp_fg, float mxp_bg) -{ - return (mxp_fg < 0.5) ? (2 * mxp_fg * mxp_bg) : (1 - (1 - mxp_fg) * (1 - mxp_bg)); -} -float2 mx_overlay(float2 mxp_fg, float2 mxp_bg) [[ anno::unused() ]] -{ - return float2( - mx_overlay(mxp_fg.x, mxp_bg.x), - mx_overlay(mxp_fg.y, mxp_bg.y) - ); -} -color mx_overlay(color mxp_fg, color mxp_bg) -{ - float3 fg(mxp_fg); - float3 bg(mxp_bg); - return color( - mx_overlay(fg.x, bg.x), - mx_overlay(fg.y, bg.y), - mx_overlay(fg.z, bg.z) - ); -} - -export float mx_overlay_float( - float mxp_fg = 0.0, - float mxp_bg = 0.0, - float mxp_mix = 1.0 -) - [[ - anno::description("Node Group: compositing") - ]] -{ - return mxp_mix * mx_overlay(mxp_fg, mxp_bg) + (1-mxp_mix) * mxp_bg; -} - -export color mx_overlay_color3( - color mxp_fg = color(0.0), - color mxp_bg = color(0.0), - float mxp_mix = 1.0 -) - [[ - anno::description("Node Group: compositing") - ]] -{ - return mxp_mix * mx_overlay(mxp_fg, mxp_bg) + (1-mxp_mix) * mxp_bg; -} - -export color4 mx_overlay_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color rgb = mxp_mix * mx_overlay(mxp_fg.rgb, mxp_bg.rgb) + (1-mxp_mix) * mxp_bg.rgb; - float a = mxp_mix * mx_overlay(mxp_fg.a , mxp_bg.a ) + (1-mxp_mix) * mxp_bg.a; - return color4(rgb,a); -} - export color4 mx_disjointover_color4( color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), From a5b832dc8addc24cb2d661d6c1a04faacd684fe9 Mon Sep 17 00:00:00 2001 From: Stefan Habel <19556655+StefanHabel@users.noreply.github.com> Date: Tue, 24 Oct 2023 08:15:32 -0700 Subject: [PATCH 024/128] Fixed off-by-one index check in setChildIndex (#1582) Fixed an off-by-one index check in Element::setChildIndex(). --- source/MaterialXCore/Element.cpp | 2 +- source/MaterialXTest/MaterialXCore/Element.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/MaterialXCore/Element.cpp b/source/MaterialXCore/Element.cpp index 18d028efd3..5131dc8070 100644 --- a/source/MaterialXCore/Element.cpp +++ b/source/MaterialXCore/Element.cpp @@ -168,7 +168,7 @@ void Element::setChildIndex(const string& name, int index) return; } - if (index < 0 || index > (int) _childOrder.size()) + if (index < 0 || index >= (int) _childOrder.size()) { throw Exception("Invalid child index"); } diff --git a/source/MaterialXTest/MaterialXCore/Element.cpp b/source/MaterialXTest/MaterialXCore/Element.cpp index fc4939a74f..3865934ccb 100644 --- a/source/MaterialXTest/MaterialXCore/Element.cpp +++ b/source/MaterialXTest/MaterialXCore/Element.cpp @@ -54,6 +54,9 @@ TEST_CASE("Element", "[element]") REQUIRE(*doc2 != *doc); doc2->setChildIndex("elem1", doc2->getChildIndex("elem2")); REQUIRE(*doc2 == *doc); + REQUIRE_THROWS_AS(doc2->setChildIndex("elem1", -100), mx::Exception); + REQUIRE_THROWS_AS(doc2->setChildIndex("elem1", -1), mx::Exception); + REQUIRE_THROWS_AS(doc2->setChildIndex("elem1", 2), mx::Exception); REQUIRE_THROWS_AS(doc2->setChildIndex("elem1", 100), mx::Exception); REQUIRE(*doc2 == *doc); From 926ac2756c36f5541d44f6c3f8814bfebf228f3b Mon Sep 17 00:00:00 2001 From: Ashwin Bhat <1727158+ashwinbhat@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:45:51 -0700 Subject: [PATCH 025/128] Update Catch2 to version 2.13.10 (#1566) - Update Catch2 version to v2.13.10 - Catch2 v2.13.0 supports BENCHMARK tests. - A new BENCHMARK test "GenShader: ShaderGen Performance" to benchmark document load, validation and shadergen times --- CMakeLists.txt | 5 ++ source/MaterialXTest/CMakeLists.txt | 4 + source/MaterialXTest/External/Catch/catch.hpp | 28 ++++--- .../MaterialXGenGlsl/GenGlsl.cpp | 11 +++ .../MaterialXGenShader/GenShaderUtil.cpp | 79 +++++++++++++++++++ .../MaterialXGenShader/GenShaderUtil.h | 3 + 6 files changed, 119 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index de6aa7442f..0d6a64d6b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,7 @@ option(MATERIALX_BUILD_GEN_MSL "Build the MSL shader generator back-end." ON) option(MATERIALX_BUILD_RENDER "Build the MaterialX Render modules." ON) option(MATERIALX_BUILD_OIIO "Build OpenImageIO support for MaterialXRender." OFF) option(MATERIALX_BUILD_TESTS "Build unit tests." ON) +option(MATERIALX_BUILD_BENCHMARK_TESTS "Build benchmark tests." OFF) option(MATERIALX_BUILD_SHARED_LIBS "Build MaterialX libraries as shared rather than static." OFF) option(MATERIALX_PYTHON_LTO "Enable link-time optimizations for MaterialX Python." ON) @@ -131,6 +132,7 @@ mark_as_advanced(MATERIALX_BUILD_GEN_MSL) mark_as_advanced(MATERIALX_BUILD_RENDER) mark_as_advanced(MATERIALX_BUILD_OIIO) mark_as_advanced(MATERIALX_BUILD_TESTS) +mark_as_advanced(MATERIALX_BUILD_BENCHMARK_TESTS) mark_as_advanced(MATERIALX_BUILD_SHARED_LIBS) mark_as_advanced(MATERIALX_NAMESPACE_SUFFIX) mark_as_advanced(MATERIALX_LIBNAME_SUFFIX) @@ -177,6 +179,9 @@ endif() if(MATERIALX_TEST_RENDER) add_definitions(-DMATERIALX_TEST_RENDER) endif() +if (MATERIALX_BUILD_BENCHMARK_TESTS) + add_definitions(-DMATERIALX_BUILD_BENCHMARK_TESTS) +endif() if (MATERIALX_BUILD_GEN_MDL) add_definitions(-DMATERIALX_MDLC_EXECUTABLE=\"${MATERIALX_MDLC_EXECUTABLE}\") diff --git a/source/MaterialXTest/CMakeLists.txt b/source/MaterialXTest/CMakeLists.txt index e66db4bd2e..862a176b50 100644 --- a/source/MaterialXTest/CMakeLists.txt +++ b/source/MaterialXTest/CMakeLists.txt @@ -121,6 +121,10 @@ set_target_properties( VERSION "${MATERIALX_LIBRARY_VERSION}" SOVERSION "${MATERIALX_MAJOR_VERSION}") +if(MATERIALX_BUILD_BENCHMARK_TESTS) + target_compile_definitions(MaterialXTest PRIVATE -DCATCH_CONFIG_ENABLE_BENCHMARKING) +endif() + target_link_libraries( MaterialXTest ${CMAKE_DL_LIBS}) diff --git a/source/MaterialXTest/External/Catch/catch.hpp b/source/MaterialXTest/External/Catch/catch.hpp index d2a12427b2..9b309bddc6 100644 --- a/source/MaterialXTest/External/Catch/catch.hpp +++ b/source/MaterialXTest/External/Catch/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v2.13.9 - * Generated: 2022-04-12 22:37:23.260201 + * Catch v2.13.10 + * Generated: 2022-10-16 11:01:23.452308 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 9 +#define CATCH_VERSION_PATCH 10 #ifdef __clang__ # pragma clang system_header @@ -7395,8 +7395,6 @@ namespace Catch { template struct ObjectStorage { - using TStorage = typename std::aligned_storage::value>::type; - ObjectStorage() : data() {} ObjectStorage(const ObjectStorage& other) @@ -7439,7 +7437,7 @@ namespace Catch { return *static_cast(static_cast(&data)); } - TStorage data; + struct { alignas(T) unsigned char data[sizeof(T)]; } data; }; } @@ -7949,7 +7947,7 @@ namespace Catch { #if defined(__i386__) || defined(__x86_64__) #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ #elif defined(__aarch64__) - #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #define CATCH_TRAP() __asm__(".inst 0xd43e0000") #endif #elif defined(CATCH_PLATFORM_IPHONE) @@ -13558,7 +13556,7 @@ namespace Catch { // Handle list request if( Option listed = list( m_config ) ) - return static_cast( *listed ); + return (std::min) (MaxExitCode, static_cast(*listed)); TestGroup tests { m_config }; auto const totals = tests.execute(); @@ -15391,7 +15389,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 9, "", 0 ); + static Version version( 2, 13, 10, "", 0 ); return version; } @@ -17526,12 +17524,20 @@ namespace Catch { #ifndef __OBJC__ +#ifndef CATCH_INTERNAL_CDECL +#ifdef _MSC_VER +#define CATCH_INTERNAL_CDECL __cdecl +#else +#define CATCH_INTERNAL_CDECL +#endif +#endif + #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) // Standard C/C++ Win32 Unicode wmain entry point -extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { +extern "C" int CATCH_INTERNAL_CDECL wmain (int argc, wchar_t * argv[], wchar_t * []) { #else // Standard C/C++ main entry point -int main (int argc, char * argv[]) { +int CATCH_INTERNAL_CDECL main (int argc, char * argv[]) { #endif return Catch::Session().run( argc, argv ); diff --git a/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp b/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp index 339d3853cb..2cc4d7ccf4 100644 --- a/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp +++ b/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp @@ -119,6 +119,17 @@ TEST_CASE("GenShader: Bind Light Shaders", "[genglsl]") REQUIRE_NOTHROW(mx::HwShaderGenerator::bindLightShader(*spotLightShader, 66, context)); } +#ifdef MATERIALX_BUILD_BENCHMARK_TESTS +TEST_CASE("GenShader: Performance Test", "[genglsl]") +{ + mx::GenContext context(mx::GlslShaderGenerator::create()); + BENCHMARK("Load documents, validate and generate shader") + { + return GenShaderUtil::shaderGenPerformanceTest(context); + }; +} +#endif + enum class GlslType { Glsl400, diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp index 261aacdefe..2ca8afa86c 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp @@ -314,6 +314,85 @@ void testUniqueNames(mx::GenContext& context, const std::string& stage) REQUIRE(sgNode1->getOutput()->getVariable() == "unique_names_out"); } +// Test ShaderGen performance +void shaderGenPerformanceTest(mx::GenContext& context) +{ + mx::DocumentPtr nodeLibrary = mx::createDocument(); + mx::FilePath currentPath = mx::FilePath::getCurrentPath(); + const mx::FileSearchPath libSearchPath(currentPath); + + // Load the standard libraries. + loadLibraries({ "libraries" }, libSearchPath, nodeLibrary); + context.registerSourceCodeSearchPath(libSearchPath); + + // Enable Color Management + mx::ColorManagementSystemPtr colorManagementSystem = + mx::DefaultColorManagementSystem::create(context.getShaderGenerator().getTarget()); + + REQUIRE(colorManagementSystem); + if (colorManagementSystem) + { + context.getShaderGenerator().setColorManagementSystem(colorManagementSystem); + colorManagementSystem->loadLibrary(nodeLibrary); + } + + // Enable Unit System + mx::UnitSystemPtr unitSystem = mx::UnitSystem::create(context.getShaderGenerator().getTarget()); + REQUIRE(unitSystem); + if (unitSystem) + { + context.getShaderGenerator().setUnitSystem(unitSystem); + unitSystem->loadLibrary(nodeLibrary); + // Setup Unit converters + unitSystem->setUnitConverterRegistry(mx::UnitConverterRegistry::create()); + mx::UnitTypeDefPtr distanceTypeDef = nodeLibrary->getUnitTypeDef("distance"); + unitSystem->getUnitConverterRegistry()->addUnitConverter(distanceTypeDef, mx::LinearUnitConverter::create(distanceTypeDef)); + mx::UnitTypeDefPtr angleTypeDef = nodeLibrary->getUnitTypeDef("angle"); + unitSystem->getUnitConverterRegistry()->addUnitConverter(angleTypeDef, mx::LinearUnitConverter::create(angleTypeDef)); + context.getOptions().targetDistanceUnit = "meter"; + } + + // Read mtlx documents + mx::FilePathVec testRootPaths; + testRootPaths.push_back("resources/Materials/Examples/StandardSurface"); + + std::vector loadedDocuments; + mx::StringVec documentsPaths; + mx::StringVec errorLog; + + for (const auto& testRoot : testRootPaths) + { + mx::loadDocuments(testRoot, libSearchPath, {}, {}, loadedDocuments, documentsPaths, + nullptr, &errorLog); + } + + REQUIRE(loadedDocuments.size() > 0); + REQUIRE(loadedDocuments.size() == documentsPaths.size()); + + // Shuffle the order of documents and perform document library import validatation and shadergen + std::random_device random_dev; + std::mt19937 generator(random_dev()); + std::shuffle(loadedDocuments.begin(), loadedDocuments.end(), generator); + for (const auto& doc : loadedDocuments) + { + doc->importLibrary(nodeLibrary); + std::vector elements = mx::findRenderableElements(doc); + + REQUIRE(elements.size() > 0); + + std::string message; + bool docValid = doc->validate(&message); + + REQUIRE(docValid == true); + + mx::StringVec sourceCode; + mx::ShaderPtr shader = nullptr; + shader = context.getShaderGenerator().generate(elements[0]->getName(), elements[0], context); + + REQUIRE(shader != nullptr); + REQUIRE(shader->getSourceCode(mx::Stage::PIXEL).length() > 0); + } +} void ShaderGeneratorTester::checkImplementationUsage(const mx::StringSet& usedImpls, const mx::GenContext& context, diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h index ea34170d71..9c471466aa 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h @@ -52,6 +52,9 @@ void checkImplementations(mx::GenContext& context, // Utility test to check unique name generation on a shader generator void testUniqueNames(mx::GenContext& context, const std::string& stage); +// Utility to perfrom simple performance test to load, validate and generate shaders +void shaderGenPerformanceTest(mx::GenContext& context); + // // Render validation options. Reflects the _options.mtlx // file in the test suite area. From 578118d645657f800b4fd96f24c140325f9cb6bb Mon Sep 17 00:00:00 2001 From: Pablo Delgado Date: Sat, 28 Oct 2023 02:29:31 +0200 Subject: [PATCH 026/128] Fix MDL implementation of mx_hsvtorgb (#1584) --- source/MaterialXGenMdl/mdl/materialx/hsv.mdl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/MaterialXGenMdl/mdl/materialx/hsv.mdl b/source/MaterialXGenMdl/mdl/materialx/hsv.mdl index 888d4ada86..9adb1505cb 100644 --- a/source/MaterialXGenMdl/mdl/materialx/hsv.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/hsv.mdl @@ -25,16 +25,16 @@ import ::limits::*; export float3 mx_hsvtorgb(float3 hsv) { // from "Color Imaging, Fundamentals and Applications", Reinhard et al., p. 442 - // A hue of 1.0 is questionably valid, and needs to be interpreted as 0.0f - float h_prime = (hsv.x < 1.0f) ? hsv.x * 6.0f : 0.0f; // H * 360.0/60.0 - float h_floor = math::floor(h_prime); - float f = h_prime - h_floor; + float h = 6.0 * (hsv.x - math::floor(hsv.x)); + int hi = int(h); // truncate + float f = h - float(hi); + float zy = hsv.z*hsv.y; float a = hsv.z - zy; float b = hsv.z - zy*f; float c = a + zy*f; - switch(int(h_floor)) { + switch(hi) { default: // hue out of [0,1] range... // fall through... From 6a5a1adf7f5fdc408f141eb1dcc1e916ec783f5f Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Fri, 27 Oct 2023 17:42:44 -0700 Subject: [PATCH 027/128] Add initial Python 3.12 test This changelist adds an initial Python 3.12 test to GitHub CI, leveraging the support for this Python version in the Windows VS2022 environment. --- .github/workflows/main.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4fdcefb7fb..c842d3b530 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,7 +37,6 @@ jobs: compiler: gcc compiler_version: "12" python: 3.11 - upload_shaders: ON - name: Linux_GCC_CoverageAnalysis os: ubuntu-22.04 @@ -104,18 +103,19 @@ jobs: python: 3.7 cmake_config: -G "Visual Studio 16 2019" -A "Win32" -DMATERIALX_BUILD_SHARED_LIBS=ON - - name: Windows_VS2022_x64_Python39 + - name: Windows_VS2022_x64_Python311 os: windows-2022 architecture: x64 - python: 3.9 + python: 3.11 cmake_config: -G "Visual Studio 17 2022" -A "x64" + test_shaders: ON - - name: Windows_VS2022_x64_Python311 + - name: Windows_VS2022_x64_Python312 os: windows-2022 architecture: x64 - python: 3.11 + python: 3.12 cmake_config: -G "Visual Studio 17 2022" -A "x64" - test_shaders: ON + upload_shaders: ON steps: - name: Sync Repository @@ -172,6 +172,10 @@ jobs: python-version: ${{ matrix.python }} architecture: ${{ matrix.architecture }} + - name: Install Python Dependencies + if: matrix.python != 'None' + run: pip install setuptools + - name: Install Emscripten if: matrix.build_javascript == 'ON' run: | From 50062e5da4d6f279bcc134a61651096ea6a2c26c Mon Sep 17 00:00:00 2001 From: krohmerNV <42233792+krohmerNV@users.noreply.github.com> Date: Wed, 1 Nov 2023 00:17:38 +0100 Subject: [PATCH 028/128] Add fileTextureVerticalFlip option for MDL generation (#1418) When investigating the differences in the MaterialXTest I implemented the fileTextureVerticalFlip in the MDL shader gen. In theory this option is not needed because the MaterialX and MDL define the image coordinate both in the lower left. But it might be useful to align with existing but non standard conform renderers. It could for instance be used in the MaterialXTest to align with the flipped GLSL and OSL results. --- .../stdlib/genmdl/stdlib_genmdl_impl.mtlx | 12 ++--- source/MaterialXGenMdl/MdlShaderGenerator.cpp | 9 ++++ source/MaterialXGenMdl/Nodes/ImageNodeMdl.cpp | 50 +++++++++++++++++ source/MaterialXGenMdl/Nodes/ImageNodeMdl.h | 34 ++++++++++++ .../MaterialXGenMdl/mdl/materialx/stdlib.mdl | 54 ++++++++++++++++--- .../MaterialXTest/MaterialXGenMdl/GenMdl.cpp | 18 ++++++- 6 files changed, 164 insertions(+), 13 deletions(-) create mode 100644 source/MaterialXGenMdl/Nodes/ImageNodeMdl.cpp create mode 100644 source/MaterialXGenMdl/Nodes/ImageNodeMdl.h diff --git a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx index 0081dec924..022f0896f1 100644 --- a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx +++ b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx @@ -22,22 +22,22 @@ - + - + - + - + - + - + diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.cpp b/source/MaterialXGenMdl/MdlShaderGenerator.cpp index f64b555c20..e10d586d69 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.cpp +++ b/source/MaterialXGenMdl/MdlShaderGenerator.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -187,6 +188,14 @@ MdlShaderGenerator::MdlShaderGenerator() : // registerImplementation("IM_sheen_bsdf_" + MdlShaderGenerator::TARGET, LayerableNodeMdl::create); + + // + registerImplementation("IM_image_float_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create); + registerImplementation("IM_image_color3_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create); + registerImplementation("IM_image_color4_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create); + registerImplementation("IM_image_vector2_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create); + registerImplementation("IM_image_vector3_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create); + registerImplementation("IM_image_vector4_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create); } ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, GenContext& context) const diff --git a/source/MaterialXGenMdl/Nodes/ImageNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/ImageNodeMdl.cpp new file mode 100644 index 0000000000..502711fe01 --- /dev/null +++ b/source/MaterialXGenMdl/Nodes/ImageNodeMdl.cpp @@ -0,0 +1,50 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include +#include + +MATERIALX_NAMESPACE_BEGIN + +const string ImageNodeMdl::FLIP_V = "flip_v"; + +ShaderNodeImplPtr ImageNodeMdl::create() +{ + return std::make_shared(); +} + +void ImageNodeMdl::addInputs(ShaderNode& node, GenContext& context) const +{ + BASE::addInputs(node, context); + node.addInput(ImageNodeMdl::FLIP_V, Type::BOOLEAN)->setUniform(); +} + +bool ImageNodeMdl::isEditable(const ShaderInput& input) const +{ + if (input.getName() == ImageNodeMdl::FLIP_V) + { + return false; + } + return BASE::isEditable(input); +} + +void ImageNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext& context, ShaderStage& stage) const +{ + DEFINE_SHADER_STAGE(stage, Stage::PIXEL) + { + ShaderNode& node = const_cast(_node); + ShaderInput* flipUInput = node.getInput(ImageNodeMdl::FLIP_V); + ValuePtr value = TypedValue::createValue(context.getOptions().fileTextureVerticalFlip); + if (flipUInput) + { + flipUInput->setValue(value); + } + BASE::emitFunctionCall(_node, context, stage); + } +} + +MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMdl/Nodes/ImageNodeMdl.h b/source/MaterialXGenMdl/Nodes/ImageNodeMdl.h new file mode 100644 index 0000000000..fe88b2ce09 --- /dev/null +++ b/source/MaterialXGenMdl/Nodes/ImageNodeMdl.h @@ -0,0 +1,34 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#ifndef MATERIALX_IMAGENODEMDL_H +#define MATERIALX_IMAGENODEMDL_H + +#include + +#include "SourceCodeNodeMdl.h" + +MATERIALX_NAMESPACE_BEGIN + +/// Image node implementation for MDL +class MX_GENMDL_API ImageNodeMdl : public SourceCodeNodeMdl +{ + using BASE = SourceCodeNodeMdl; + + public: + static const string FLIP_V; ///< the empty string "" + + static ShaderNodeImplPtr create(); + + void addInputs(ShaderNode& node, GenContext& context) const override; + + bool isEditable(const ShaderInput& input) const override; + + void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; +}; + +MATERIALX_NAMESPACE_END + +#endif diff --git a/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl b/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl index 8089feb7f0..4ba4f0875a 100644 --- a/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl @@ -139,6 +139,11 @@ export float mx_image_float( anno::description("Enumeration {constant,clamp,periodic,mirror}."), anno::display_name("Frame End Action"), anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() ]] ) [[ @@ -153,7 +158,9 @@ export float mx_image_float( return mxp_default; float returnValue = ::tex::lookup_float(tex: mxp_file, - coord: mxp_texcoord, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode)); return returnValue; @@ -207,6 +214,11 @@ export color mx_image_color3( anno::description("Enumeration {constant,clamp,periodic,mirror}."), anno::display_name("Frame End Action"), anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() ]] ) [[ @@ -221,7 +233,9 @@ export color mx_image_color3( return mxp_default; color returnValue = ::tex::lookup_color(tex: mxp_file, - coord: mxp_texcoord, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode)); return returnValue; @@ -275,6 +289,11 @@ export color4 mx_image_color4( anno::description("Enumeration {constant,clamp,periodic,mirror}."), anno::display_name("Frame End Action"), anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() ]] ) [[ @@ -289,7 +308,9 @@ export color4 mx_image_color4( return mxp_default; color4 returnValue = mk_color4( ::tex::lookup_float4(tex: mxp_file, - coord: mxp_texcoord, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode))); return returnValue; @@ -343,6 +364,11 @@ export float2 mx_image_vector2( anno::description("Enumeration {constant,clamp,periodic,mirror}."), anno::display_name("Frame End Action"), anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() ]] ) [[ @@ -357,7 +383,9 @@ export float2 mx_image_vector2( return mxp_default; float2 returnValue = ::tex::lookup_float2(tex: mxp_file, - coord: mxp_texcoord, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode)); return returnValue; @@ -411,6 +439,11 @@ export float3 mx_image_vector3( anno::description("Enumeration {constant,clamp,periodic,mirror}."), anno::display_name("Frame End Action"), anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() ]] ) [[ @@ -425,7 +458,9 @@ export float3 mx_image_vector3( return mxp_default; float3 returnValue = ::tex::lookup_float3(tex: mxp_file, - coord: mxp_texcoord, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode)); return returnValue; @@ -479,6 +514,11 @@ export float4 mx_image_vector4( anno::description("Enumeration {constant,clamp,periodic,mirror}."), anno::display_name("Frame End Action"), anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() ]] ) [[ @@ -493,7 +533,9 @@ export float4 mx_image_vector4( return mxp_default; float4 returnValue = ::tex::lookup_float4(tex: mxp_file, - coord: mxp_texcoord, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode)); return returnValue; diff --git a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp index 1a3e127cde..22ad0d456e 100644 --- a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp +++ b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp @@ -288,7 +288,10 @@ void MdlShaderGeneratorTester::compileSource(const std::vector& so std::string iblFile = (rootPath / "resources/lights/san_giuseppe_bridge.hdr").asString(); renderCommand += " --hdr \"" + iblFile + "\" --hdr_rotate 90"; // set scene - renderCommand += " --uv_scale 0.5 1.0 --uv_offset 0.0 0.0 --uv_repeat --uv_flip"; + renderCommand += " --uv_scale 0.5 1.0 --uv_offset 0.0 0.0 --uv_repeat"; + renderCommand += " --uv_flip"; // this will flip the v coordinate of the vertices, which flips all the + // UV operations. In contrast, the fileTextureVerticalFlip option will + // only flip the image access nodes. renderCommand += " --camera 0 0 3 0 0 0 --fov 45"; // set the material @@ -365,6 +368,19 @@ TEST_CASE("GenShader: MDL Shader Generation", "[genmdl]") mx::GenOptions genOptions; genOptions.targetColorSpaceOverride = "lin_rec709"; + + // Flipping the texture lookups for the test renderer only. + // This is because OSL testrender does not allow to change the UV layout of their sphere (yet) and the MaterialX test suite + // adopts the OSL behavior in order to produce comparable results. This means that raw texture coordinates, or procedurals + // that use the texture coordinates, do not match what might be expected when reading the MaterialX spec: + // "[...] the image is mapped onto the geometry based on geometry UV coordinates, with the lower-left corner of an image + // mapping to the (0,0) UV coordinate [...]" + // This means for MDL: here, and only here in the test suite, we flip the UV coordinates of mesh using the `--uv_flip` option + // of the renderer, and to correct the image orientation, we apply `fileTextureVerticalFlip`. + // In regular MDL integrations this is not needed because MDL and MaterialX define the texture space equally with the origin + // at the bottom left. + genOptions.fileTextureVerticalFlip = true; + mx::FilePath optionsFilePath = searchPath.find("resources/Materials/TestSuite/_options.mtlx"); tester.validate(genOptions, optionsFilePath); } From f086b861d306eec39d864693f7ca56d7a9975f03 Mon Sep 17 00:00:00 2001 From: HudsonHN Date: Fri, 3 Nov 2023 11:04:23 -0700 Subject: [PATCH 029/128] Fix scroll wheel interaction across graph editor windows (#1578) Fixed scroll wheel causing both the renderview to zoom as well as the property editor to scroll. This is done by moving the renderview cursor bounds check up on the call stack and adding flags to disable scrolling for the property editor if the cursor is within the renderview. --- source/MaterialXGraphEditor/Graph.cpp | 113 +++++++++++++++----------- source/MaterialXGraphEditor/Graph.h | 2 +- 2 files changed, 65 insertions(+), 50 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 889789706b..88ee10a4c1 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -3241,13 +3241,27 @@ void Graph::graphButtons() // Create two windows using splitter float paneWidth = (leftPaneWidth - 2.0f); - ImGui::BeginChild("Selection", ImVec2(paneWidth, 0)); + + float aspectRatio = _renderer->getPixelRatio(); + ImVec2 screenSize = ImVec2(paneWidth, paneWidth / aspectRatio); + + ImVec2 mousePos = ImGui::GetMousePos(); + ImVec2 tempWindowPos = ImGui::GetCursorPos(); + bool cursorInRenderView = mousePos.x > tempWindowPos.x && mousePos.x < (tempWindowPos.x + screenSize.x) && + mousePos.y > tempWindowPos.y && mousePos.y < (tempWindowPos.y + screenSize.y); + + ImGuiWindowFlags windowFlags = 0; + + if (cursorInRenderView) + { + windowFlags |= ImGuiWindowFlags_NoScrollWithMouse; + } + + ImGui::BeginChild("Selection", ImVec2(paneWidth, 0), false, windowFlags); ImVec2 windowPos = ImGui::GetWindowPos(); // RenderView window ImVec2 wsize = ImVec2((float) _renderer->getViewWidth(), (float) _renderer->getViewHeight()); - float aspectRatio = _renderer->getPixelRatio(); - ImVec2 screenSize = ImVec2(paneWidth, paneWidth / aspectRatio); _renderer->setViewWidth((int) screenSize[0]); _renderer->setViewHeight((int) screenSize[1]); @@ -3267,7 +3281,10 @@ void Graph::graphButtons() ImGui::EndChild(); ImGui::SameLine(0.0f, 12.0f); - handleRenderViewInputs(windowPos, screenSize[0], screenSize[1]); + if (cursorInRenderView) + { + handleRenderViewInputs(); + } } void Graph::propertyEditor() @@ -3830,56 +3847,54 @@ void Graph::shaderPopup() } } -void Graph::handleRenderViewInputs(ImVec2 minValue, float width, float height) +void Graph::handleRenderViewInputs() { ImVec2 mousePos = ImGui::GetMousePos(); - if (mousePos.x > minValue.x && mousePos.x < (minValue.x + width) && mousePos.y > minValue.y && mousePos.y < (minValue.y + height)) + mx::Vector2 mxMousePos = mx::Vector2(mousePos.x, mousePos.y); + float scrollAmt = ImGui::GetIO().MouseWheel; + int button = -1; + bool down = false; + if (ImGui::IsMouseDragging(0) || ImGui::IsMouseDragging(1)) { - mx::Vector2 mxMousePos = mx::Vector2(mousePos.x, mousePos.y); - float scrollAmt = ImGui::GetIO().MouseWheel; - int button = -1; - bool down = false; - if (ImGui::IsMouseDragging(0) || ImGui::IsMouseDragging(1)) - { - _renderer->setMouseMotionEvent(mxMousePos); - } - if (ImGui::IsMouseClicked(0)) - { - button = 0; - down = true; - _renderer->setMouseButtonEvent(button, down, mxMousePos); - } - else if (ImGui::IsMouseClicked(1)) - { - button = 1; - down = true; - _renderer->setMouseButtonEvent(button, down, mxMousePos); - } - else if (ImGui::IsMouseReleased(0)) - { - button = 0; - _renderer->setMouseButtonEvent(button, down, mxMousePos); - } - else if (ImGui::IsMouseReleased(1)) - { - button = 1; - _renderer->setMouseButtonEvent(button, down, mxMousePos); - } - else if (ImGui::IsKeyPressed(ImGuiKey_KeypadAdd)) - { - _renderer->setKeyEvent(ImGuiKey_KeypadAdd); - } - else if (ImGui::IsKeyPressed(ImGuiKey_KeypadSubtract)) - { - _renderer->setKeyEvent(ImGuiKey_KeypadSubtract); - } + _renderer->setMouseMotionEvent(mxMousePos); + } + if (ImGui::IsMouseClicked(0)) + { + button = 0; + down = true; + _renderer->setMouseButtonEvent(button, down, mxMousePos); + } + else if (ImGui::IsMouseClicked(1)) + { + button = 1; + down = true; + _renderer->setMouseButtonEvent(button, down, mxMousePos); + } + else if (ImGui::IsMouseReleased(0)) + { + button = 0; + _renderer->setMouseButtonEvent(button, down, mxMousePos); + } + else if (ImGui::IsMouseReleased(1)) + { + button = 1; + _renderer->setMouseButtonEvent(button, down, mxMousePos); + } + else if (ImGui::IsKeyPressed(ImGuiKey_KeypadAdd)) + { + _renderer->setKeyEvent(ImGuiKey_KeypadAdd); + } + else if (ImGui::IsKeyPressed(ImGuiKey_KeypadSubtract)) + { + _renderer->setKeyEvent(ImGuiKey_KeypadSubtract); + } - // Scrolling not possible if open or save file dialog is open - if (scrollAmt != 0 && !_fileDialogSave.isOpened() && !_fileDialog.isOpened() && !_fileDialogGeom.isOpened()) - { - _renderer->setScrollEvent(scrollAmt); - } + // Scrolling not possible if open or save file dialog is open + if (scrollAmt != 0 && !_fileDialogSave.isOpened() && !_fileDialog.isOpened() && !_fileDialogGeom.isOpened()) + { + _renderer->setScrollEvent(scrollAmt); } + } void Graph::drawGraph(ImVec2 mousePos) diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index fcdf93723e..821ecf71fd 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -225,7 +225,7 @@ class Graph void selectMaterial(UiNodePtr node); // Allow for camera manipulation of render view window - void handleRenderViewInputs(ImVec2 minValue, float width, float height); + void handleRenderViewInputs(); // Set the node to display in render view based on selected node or nodegraph void setRenderMaterial(UiNodePtr node); From 83ae82eefa9e34e081f1341e34b194e84ad5b151 Mon Sep 17 00:00:00 2001 From: Stefan Habel <19556655+StefanHabel@users.noreply.github.com> Date: Thu, 9 Nov 2023 09:00:41 -0800 Subject: [PATCH 030/128] Resolved Python module import dependencies (#1595) This patch adds pybind11::module::import() calls to MaterialX Python C extension modules that depend on other MaterialX Python C extension modules. The intention is to allow any of the MaterialX Python C extension modules to be imported in any order. A couple of the Python scripts are updated to remove unused MaterialX imports, and to sort imports alphabetically (which is now possible as the modules import their own dependencies). --- python/Scripts/baketextures.py | 3 +-- python/Scripts/generateshader.py | 5 +++-- python/Scripts/translateshader.py | 6 ++---- source/PyMaterialX/PyMaterialX.h | 12 ++++++++++++ source/PyMaterialX/PyMaterialXFormat/PyModule.cpp | 3 +++ source/PyMaterialX/PyMaterialXGenGlsl/PyModule.cpp | 3 +++ source/PyMaterialX/PyMaterialXGenMdl/PyModule.cpp | 3 +++ source/PyMaterialX/PyMaterialXGenMsl/PyModule.cpp | 3 +++ source/PyMaterialX/PyMaterialXGenOsl/PyModule.cpp | 3 +++ source/PyMaterialX/PyMaterialXRender/PyModule.cpp | 3 +++ .../PyMaterialX/PyMaterialXRenderGlsl/PyModule.cpp | 3 +++ source/PyMaterialX/PyMaterialXRenderMsl/PyModule.mm | 3 +++ source/PyMaterialX/PyMaterialXRenderOsl/PyModule.cpp | 3 +++ 13 files changed, 45 insertions(+), 8 deletions(-) diff --git a/python/Scripts/baketextures.py b/python/Scripts/baketextures.py index caf2aaed3e..ce132036a6 100644 --- a/python/Scripts/baketextures.py +++ b/python/Scripts/baketextures.py @@ -5,9 +5,8 @@ import sys, os, argparse from sys import platform + import MaterialX as mx -from MaterialX import PyMaterialXGenShader -from MaterialX import PyMaterialXGenGlsl from MaterialX import PyMaterialXRender as mx_render from MaterialX import PyMaterialXRenderGlsl as mx_render_glsl if platform == "darwin": diff --git a/python/Scripts/generateshader.py b/python/Scripts/generateshader.py index 8329f7231e..038625eacf 100644 --- a/python/Scripts/generateshader.py +++ b/python/Scripts/generateshader.py @@ -5,12 +5,13 @@ ''' import sys, os, argparse, subprocess + import MaterialX as mx -import MaterialX.PyMaterialXGenShader as mx_gen_shader import MaterialX.PyMaterialXGenGlsl as mx_gen_glsl -import MaterialX.PyMaterialXGenOsl as mx_gen_osl import MaterialX.PyMaterialXGenMdl as mx_gen_mdl import MaterialX.PyMaterialXGenMsl as mx_gen_msl +import MaterialX.PyMaterialXGenOsl as mx_gen_osl +import MaterialX.PyMaterialXGenShader as mx_gen_shader def validateCode(sourceCodeFile, codevalidator, codevalidatorArgs): if codevalidator: diff --git a/python/Scripts/translateshader.py b/python/Scripts/translateshader.py index 71d7a480b5..f7c5686211 100644 --- a/python/Scripts/translateshader.py +++ b/python/Scripts/translateshader.py @@ -5,15 +5,13 @@ ''' import sys, os, argparse -import MaterialX as mx - from sys import platform + +import MaterialX as mx from MaterialX import PyMaterialXGenShader as mx_gen_shader -from MaterialX import PyMaterialXGenGlsl as ms_gen_glsl from MaterialX import PyMaterialXRender as mx_render from MaterialX import PyMaterialXRenderGlsl as mx_render_glsl if platform == "darwin": - from MaterialX import PyMaterialXGenMsl as ms_gen_msl from MaterialX import PyMaterialXRenderMsl as mx_render_msl def main(): diff --git a/source/PyMaterialX/PyMaterialX.h b/source/PyMaterialX/PyMaterialX.h index 7af67ac4bd..1e7bc7ff87 100644 --- a/source/PyMaterialX/PyMaterialX.h +++ b/source/PyMaterialX/PyMaterialX.h @@ -16,4 +16,16 @@ #include #include +// Define a macro to import a PyMaterialX module, e.g. `PyMaterialXCore`, +// either within the `MaterialX` Python package, e.g. in `installed/python/`, +// or as a standalone module, e.g. in `lib/` +#define PYMATERIALX_IMPORT_MODULE(MODULE_NAME) \ + try \ + { \ + pybind11::module::import("MaterialX." #MODULE_NAME); \ + } \ + catch (const py::error_already_set&) \ + { \ + pybind11::module::import(#MODULE_NAME); \ + } #endif diff --git a/source/PyMaterialX/PyMaterialXFormat/PyModule.cpp b/source/PyMaterialX/PyMaterialXFormat/PyModule.cpp index 842087d24f..3965f48753 100644 --- a/source/PyMaterialX/PyMaterialXFormat/PyModule.cpp +++ b/source/PyMaterialX/PyMaterialXFormat/PyModule.cpp @@ -15,6 +15,9 @@ PYBIND11_MODULE(PyMaterialXFormat, mod) { mod.doc() = "Module containing Python bindings for the MaterialXFormat library"; + // PyMaterialXFormat depends on types defined in PyMaterialXCore + PYMATERIALX_IMPORT_MODULE(PyMaterialXCore); + bindPyFile(mod); bindPyXmlIo(mod); bindPyUtil(mod); diff --git a/source/PyMaterialX/PyMaterialXGenGlsl/PyModule.cpp b/source/PyMaterialX/PyMaterialXGenGlsl/PyModule.cpp index a36b815d32..9ab46e514d 100644 --- a/source/PyMaterialX/PyMaterialXGenGlsl/PyModule.cpp +++ b/source/PyMaterialX/PyMaterialXGenGlsl/PyModule.cpp @@ -16,6 +16,9 @@ PYBIND11_MODULE(PyMaterialXGenGlsl, mod) { mod.doc() = "Module containing Python bindings for the MaterialXGenGlsl library"; + // PyMaterialXGenGlsl depends on types defined in PyMaterialXGenShader + PYMATERIALX_IMPORT_MODULE(PyMaterialXGenShader); + bindPyGlslShaderGenerator(mod); bindPyGlslResourceBindingContext(mod); diff --git a/source/PyMaterialX/PyMaterialXGenMdl/PyModule.cpp b/source/PyMaterialX/PyMaterialXGenMdl/PyModule.cpp index 020c944e63..a34b28a729 100644 --- a/source/PyMaterialX/PyMaterialXGenMdl/PyModule.cpp +++ b/source/PyMaterialX/PyMaterialXGenMdl/PyModule.cpp @@ -13,5 +13,8 @@ PYBIND11_MODULE(PyMaterialXGenMdl, mod) { mod.doc() = "Module containing Python bindings for the MaterialXGenMdl library"; + // PyMaterialXGenMdl depends on types defined in PyMaterialXGenShader + PYMATERIALX_IMPORT_MODULE(PyMaterialXGenShader); + bindPyMdlShaderGenerator(mod); }; diff --git a/source/PyMaterialX/PyMaterialXGenMsl/PyModule.cpp b/source/PyMaterialX/PyMaterialXGenMsl/PyModule.cpp index 6eda44871b..b3dcdb10a8 100644 --- a/source/PyMaterialX/PyMaterialXGenMsl/PyModule.cpp +++ b/source/PyMaterialX/PyMaterialXGenMsl/PyModule.cpp @@ -14,6 +14,9 @@ PYBIND11_MODULE(PyMaterialXGenMsl, mod) { mod.doc() = "Module containing Python bindings for the MaterialXGenMsl library"; + // PyMaterialXGenMsl depends on types defined in PyMaterialXGenShader + PYMATERIALX_IMPORT_MODULE(PyMaterialXGenShader); + bindPyMslShaderGenerator(mod); bindPyMslResourceBindingContext(mod); } diff --git a/source/PyMaterialX/PyMaterialXGenOsl/PyModule.cpp b/source/PyMaterialX/PyMaterialXGenOsl/PyModule.cpp index d772d18b6a..54d7d2439a 100644 --- a/source/PyMaterialX/PyMaterialXGenOsl/PyModule.cpp +++ b/source/PyMaterialX/PyMaterialXGenOsl/PyModule.cpp @@ -13,5 +13,8 @@ PYBIND11_MODULE(PyMaterialXGenOsl, mod) { mod.doc() = "Module containing Python bindings for the MaterialXGenOsl library"; + // PyMaterialXGenOsl depends on types defined in PyMaterialXGenShader + PYMATERIALX_IMPORT_MODULE(PyMaterialXGenShader); + bindPyOslShaderGenerator(mod); } diff --git a/source/PyMaterialX/PyMaterialXRender/PyModule.cpp b/source/PyMaterialX/PyMaterialXRender/PyModule.cpp index 1c60142346..bbf9688403 100644 --- a/source/PyMaterialX/PyMaterialXRender/PyModule.cpp +++ b/source/PyMaterialX/PyMaterialXRender/PyModule.cpp @@ -25,6 +25,9 @@ PYBIND11_MODULE(PyMaterialXRender, mod) { mod.doc() = "Module containing Python bindings for the MaterialXRender library"; + // PyMaterialXRender depends on types defined in PyMaterialXCore + PYMATERIALX_IMPORT_MODULE(PyMaterialXCore); + bindPyMesh(mod); bindPyGeometryHandler(mod); bindPyLightHandler(mod); diff --git a/source/PyMaterialX/PyMaterialXRenderGlsl/PyModule.cpp b/source/PyMaterialX/PyMaterialXRenderGlsl/PyModule.cpp index 32fb79239d..d0ef04158d 100644 --- a/source/PyMaterialX/PyMaterialXRenderGlsl/PyModule.cpp +++ b/source/PyMaterialX/PyMaterialXRenderGlsl/PyModule.cpp @@ -16,6 +16,9 @@ PYBIND11_MODULE(PyMaterialXRenderGlsl, mod) { mod.doc() = "Module containing Python bindings for the MaterialXRenderGlsl library"; + // PyMaterialXRenderGlsl depends on types defined in PyMaterialXRender + PYMATERIALX_IMPORT_MODULE(PyMaterialXRender); + bindPyGlslProgram(mod); bindPyGlslRenderer(mod); bindPyGLTextureHandler(mod); diff --git a/source/PyMaterialX/PyMaterialXRenderMsl/PyModule.mm b/source/PyMaterialX/PyMaterialXRenderMsl/PyModule.mm index 10b440d21c..f4d0dbeaeb 100644 --- a/source/PyMaterialX/PyMaterialXRenderMsl/PyModule.mm +++ b/source/PyMaterialX/PyMaterialXRenderMsl/PyModule.mm @@ -16,6 +16,9 @@ { mod.doc() = "Module containing Python bindings for the MaterialXRenderMsl library"; + // PyMaterialXRenderMsl depends on types defined in PyMaterialXRender + PYMATERIALX_IMPORT_MODULE(PyMaterialXRender); + bindPyMslProgram(mod); bindPyMslRenderer(mod); bindPyMetalTextureHandler(mod); diff --git a/source/PyMaterialX/PyMaterialXRenderOsl/PyModule.cpp b/source/PyMaterialX/PyMaterialXRenderOsl/PyModule.cpp index 15610066f3..4019d364ab 100644 --- a/source/PyMaterialX/PyMaterialXRenderOsl/PyModule.cpp +++ b/source/PyMaterialX/PyMaterialXRenderOsl/PyModule.cpp @@ -13,5 +13,8 @@ PYBIND11_MODULE(PyMaterialXRenderOsl, mod) { mod.doc() = "Module containing Python bindings for the MaterialXRenderOsl library"; + // PyMaterialXRenderOsl depends on types defined in PyMaterialXRender + PYMATERIALX_IMPORT_MODULE(PyMaterialXRender); + bindPyOslRenderer(mod); } From 30a446ea2548f4d7fc39a18dc1cde592191bab38 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sun, 19 Nov 2023 13:02:36 -0800 Subject: [PATCH 031/128] Add GCC 13 and Clang 15 builds This changelist adds GCC 13 and Clang 15 builds to GitHub CI, leveraging new support for these builds in the ubuntu-22.04 environment. --- .github/workflows/main.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c842d3b530..aeba7b2c45 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,18 +25,19 @@ jobs: python: 3.7 cmake_config: -DMATERIALX_BUILD_SHARED_LIBS=ON - - name: Linux_GCC_11_Python39 - os: ubuntu-20.04 - compiler: gcc - compiler_version: "11" - python: 3.9 - build_javascript: ON - - name: Linux_GCC_12_Python311 os: ubuntu-22.04 compiler: gcc compiler_version: "12" python: 3.11 + build_javascript: ON + + - name: Linux_GCC_13_Python312 + os: ubuntu-22.04 + compiler: gcc + compiler_version: "13" + python: 3.12 + static_analysis: ON - name: Linux_GCC_CoverageAnalysis os: ubuntu-22.04 @@ -52,20 +53,19 @@ jobs: compiler_version: "10" python: 3.7 cmake_config: -DMATERIALX_BUILD_SHARED_LIBS=ON - static_analysis: ON - - name: Linux_Clang_14_Python311 + - name: Linux_Clang_15_Python312 os: ubuntu-22.04 compiler: clang - compiler_version: "14" - python: 3.11 + compiler_version: "15" + python: 3.12 test_render: ON clang_format: ON - - name: Linux_Clang_14_DynamicAnalysis + - name: Linux_Clang_DynamicAnalysis os: ubuntu-22.04 compiler: clang - compiler_version: "14" + compiler_version: "15" python: None cmake_config: -DMATERIALX_DYNAMIC_ANALYSIS=ON dynamic_analysis: ON From 60c8a5967ab5561d571a78e0c246d3b304c794fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Arabeyre?= <34628622+eytienne@users.noreply.github.com> Date: Tue, 21 Nov 2023 01:51:32 +0100 Subject: [PATCH 032/128] Fixed null check in Graph::propertyEditor (#1601) --- source/MaterialXGraphEditor/Graph.cpp | 40 +++++++++++++-------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 88ee10a4c1..bab5df7b58 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -240,7 +240,7 @@ mx::DocumentPtr Graph::loadDocument(mx::FilePath filename) std::cerr << "*** Validation warnings for " << filename.asString() << " ***" << std::endl; std::cerr << message << std::endl; } - + // Cache the currently loaded file _materialFilename = filename; } @@ -2102,11 +2102,11 @@ mx::InputPtr Graph::findInput(mx::InputPtr nodeInput, const std::string& name) { if (_isNodeGraph) { - for (UiNodePtr node : _graphNodes) + for (UiNodePtr uiNode : _graphNodes) { - if (node->getNode()) + if (uiNode->getNode()) { - for (mx::InputPtr input : node->getNode()->getActiveInputs()) + for (mx::InputPtr input : uiNode->getNode()->getActiveInputs()) { if (input->getInterfaceInput()) { @@ -2547,7 +2547,7 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) return; } - // Perform type check + // Perform type check bool typesMatch = (outputPin->_type == inputPin->_type); if (!typesMatch) { @@ -3093,7 +3093,7 @@ void Graph::loadGraphFromFile(bool prompt) _fileDialog.open(); } else - { + { _graphDoc = loadDocument(_materialFilename); // Rebuild the UI @@ -3104,7 +3104,7 @@ void Graph::loadGraphFromFile(bool prompt) _renderer->setDocument(_graphDoc); _renderer->updateMaterials(nullptr); - } + } } void Graph::saveGraphToFile() @@ -3241,7 +3241,7 @@ void Graph::graphButtons() // Create two windows using splitter float paneWidth = (leftPaneWidth - 2.0f); - + float aspectRatio = _renderer->getPixelRatio(); ImVec2 screenSize = ImVec2(paneWidth, paneWidth / aspectRatio); @@ -3249,14 +3249,14 @@ void Graph::graphButtons() ImVec2 tempWindowPos = ImGui::GetCursorPos(); bool cursorInRenderView = mousePos.x > tempWindowPos.x && mousePos.x < (tempWindowPos.x + screenSize.x) && mousePos.y > tempWindowPos.y && mousePos.y < (tempWindowPos.y + screenSize.y); - + ImGuiWindowFlags windowFlags = 0; if (cursorInRenderView) { windowFlags |= ImGuiWindowFlags_NoScrollWithMouse; } - + ImGui::BeginChild("Selection", ImVec2(paneWidth, 0), false, windowFlags); ImVec2 windowPos = ImGui::GetWindowPos(); @@ -3306,16 +3306,16 @@ void Graph::propertyEditor() std::string name = _currUiNode->getNode()->getParent()->createValidChildName(temp); std::vector downstreamNodes = _currUiNode->getOutputConnections(); - for (UiNodePtr nodes : downstreamNodes) + for (UiNodePtr uiNode : downstreamNodes) { - if (nodes->getInput() == nullptr) + if (!uiNode->getInput() && uiNode->getNode()) { - for (mx::InputPtr input : nodes->getNode()->getActiveInputs()) + for (mx::InputPtr input : uiNode->getNode()->getActiveInputs()) { if (input->getConnectedNode() == _currUiNode->getNode()) { _currUiNode->getNode()->setName(name); - nodes->getNode()->setConnectedNode(input->getName(), _currUiNode->getNode()); + uiNode->getNode()->setConnectedNode(input->getName(), _currUiNode->getNode()); } } } @@ -3330,13 +3330,13 @@ void Graph::propertyEditor() { std::string name = _currUiNode->getInput()->getParent()->createValidChildName(temp); std::vector downstreamNodes = _currUiNode->getOutputConnections(); - for (UiNodePtr nodes : downstreamNodes) + for (UiNodePtr uiNode : downstreamNodes) { - if (nodes->getInput() == nullptr) + if (uiNode->getInput() == nullptr) { - if (nodes->getNode()) + if (uiNode->getNode()) { - for (mx::InputPtr input : nodes->getNode()->getActiveInputs()) + for (mx::InputPtr input : uiNode->getNode()->getActiveInputs()) { if (input->getInterfaceInput() == _currUiNode->getInput()) { @@ -3349,7 +3349,7 @@ void Graph::propertyEditor() } else { - nodes->getOutput()->setConnectedNode(_currUiNode->getNode()); + uiNode->getOutput()->setConnectedNode(_currUiNode->getNode()); } } } @@ -3726,7 +3726,6 @@ void Graph::addNodePopup(bool cursor) } } - ImGui::EndMenu(); } } @@ -3894,7 +3893,6 @@ void Graph::handleRenderViewInputs() { _renderer->setScrollEvent(scrollAmt); } - } void Graph::drawGraph(ImVec2 mousePos) From e45d67f2d2f5f9a972c6235960b74fceb9fc5487 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Mon, 20 Nov 2023 20:01:18 -0800 Subject: [PATCH 033/128] Initial C++ fuzz tests This changelist adds initial C++ fuzz tests to the XmlIo module of the MaterialX test suite. In these new tests, pseudo-random edits are applied to a set of source documents before import, in order to uncover edge cases that aren't yet handled in MaterialXCore and MaterialXFormat. Also: - Add missing type casts to invalidNameChar and hasWindowDriveSpecifier. - Make random numbers deterministic in shaderGenPerformanceTest. --- source/MaterialXCore/Util.cpp | 2 +- source/MaterialXFormat/File.cpp | 2 +- .../MaterialXTest/MaterialXFormat/XmlIo.cpp | 46 ++++++++++++++++++- .../MaterialXGenShader/GenShaderUtil.cpp | 5 +- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/source/MaterialXCore/Util.cpp b/source/MaterialXCore/Util.cpp index 9bb75a19b5..639b8f343c 100644 --- a/source/MaterialXCore/Util.cpp +++ b/source/MaterialXCore/Util.cpp @@ -24,7 +24,7 @@ const std::tuple LIBRARY_VERSION_TUPLE(MATERIALX_MAJOR_VERSION, bool invalidNameChar(char c) { - return !isalnum(c) && c != '_' && c != ':'; + return !isalnum((unsigned char) c) && c != '_' && c != ':'; } } // anonymous namespace diff --git a/source/MaterialXFormat/File.cpp b/source/MaterialXFormat/File.cpp index bb40ba54d1..62b7ec39a8 100644 --- a/source/MaterialXFormat/File.cpp +++ b/source/MaterialXFormat/File.cpp @@ -51,7 +51,7 @@ const string MATERIALX_SEARCH_PATH_ENV_VAR = "MATERIALX_SEARCH_PATH"; inline bool hasWindowsDriveSpecifier(const string& val) { - return (val.length() > 1 && std::isalpha(val[0]) && (val[1] == ':')); + return (val.length() > 1 && std::isalpha((unsigned char) val[0]) && (val[1] == ':')); } // diff --git a/source/MaterialXTest/MaterialXFormat/XmlIo.cpp b/source/MaterialXTest/MaterialXFormat/XmlIo.cpp index 1336a080c4..495712381e 100644 --- a/source/MaterialXTest/MaterialXFormat/XmlIo.cpp +++ b/source/MaterialXTest/MaterialXFormat/XmlIo.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include @@ -262,6 +261,51 @@ TEST_CASE("Comments and newlines", "[xmlio]") REQUIRE(origXml == newXml); } +TEST_CASE("Fuzz testing", "[xmlio]") +{ + mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); + mx::FilePath examplesPath = searchPath.find("resources/Materials/Examples/StandardSurface"); + + std::mt19937 rng(0); + std::uniform_int_distribution randChar(0, 255); + + for (const mx::FilePath& filename : examplesPath.getFilesInDirectory(mx::MTLX_EXTENSION)) + { + // Read the example file into an XML string buffer. + const std::string origString = mx::readFile(examplesPath / filename); + REQUIRE(origString.size() > 0); + std::uniform_int_distribution randPos(0, origString.size() - 1); + + // Iterate over test runs. + for (size_t testRun = 0; testRun < 256; testRun++) + { + std::string editString = origString; + + // Iterate over string edits. + for (size_t editIndex = 0; editIndex < 32; editIndex++) + { + // Randomly alter one character in the document. + size_t charIndex = randPos(rng); + size_t newChar = randChar(rng); + editString[charIndex] = (char) newChar; + + // Attempt to interpret the edited string as a document, allowing only MaterialX exceptions. + mx::DocumentPtr doc = mx::createDocument(); + try + { + mx::readFromXmlString(doc, editString, searchPath); + doc->validate(); + } + catch (const mx::Exception&) + { + // On a MaterialX exception, proceed to the next test run. + break; + } + } + } + } +} + TEST_CASE("Locale region testing", "[xmlio]") { // In the United States, the thousands separator is a comma, while in Germany it is a period. diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp index 2ca8afa86c..1280ff390d 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp @@ -370,9 +370,8 @@ void shaderGenPerformanceTest(mx::GenContext& context) REQUIRE(loadedDocuments.size() == documentsPaths.size()); // Shuffle the order of documents and perform document library import validatation and shadergen - std::random_device random_dev; - std::mt19937 generator(random_dev()); - std::shuffle(loadedDocuments.begin(), loadedDocuments.end(), generator); + std::mt19937 rng(0); + std::shuffle(loadedDocuments.begin(), loadedDocuments.end(), rng); for (const auto& doc : loadedDocuments) { doc->importLibrary(nodeLibrary); From 273b8a59c612d85313eaa9bbe719ad7c995f4b1d Mon Sep 17 00:00:00 2001 From: Stefan Habel <19556655+StefanHabel@users.noreply.github.com> Date: Mon, 27 Nov 2023 11:46:11 -0800 Subject: [PATCH 034/128] Fixed Python script errors flagged by pyflakes (#1604) --- python/Scripts/generateshader.py | 4 ++-- python/Scripts/genmdl.py | 10 ++++++---- python/Scripts/mxdoc.py | 4 +++- python/Scripts/mxformat.py | 4 +++- python/Scripts/mxvalidate.py | 6 ++++-- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/python/Scripts/generateshader.py b/python/Scripts/generateshader.py index 038625eacf..f6158d270a 100644 --- a/python/Scripts/generateshader.py +++ b/python/Scripts/generateshader.py @@ -25,7 +25,7 @@ def validateCode(sourceCodeFile, codevalidator, codevalidatorArgs): print(cmd_flatten) try: output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) - result = output.decode(encoding='utf-8') + return output.decode(encoding='utf-8') except subprocess.CalledProcessError as out: return (out.output.decode(encoding='utf-8')) return "" @@ -83,7 +83,7 @@ def main(): try: mx.loadLibraries(libraryFolders, searchPath, stdlib) doc.importLibrary(stdlib) - except err: + except Exception as err: print('Generation failed: "', err, '"') sys.exit(-1) diff --git a/python/Scripts/genmdl.py b/python/Scripts/genmdl.py index f42add0425..ded1021554 100644 --- a/python/Scripts/genmdl.py +++ b/python/Scripts/genmdl.py @@ -3,9 +3,11 @@ Generate MDL implementation directory based on MaterialX nodedefs ''' -import sys import os -import string; os.environ['PYTHONIOENCODING'] = 'utf-8' +import sys + +os.environ['PYTHONIOENCODING'] = 'utf-8' + import MaterialX as mx def usage(): @@ -345,7 +347,7 @@ def main(): doc = mx.createDocument() searchPath = os.path.join(_startPath, 'libraries') - libraryPath = os.path.join(searchPath, 'stdlib') + libraryPath = os.path.join(searchPath, LIBRARY) _loadLibraries(doc, searchPath, libraryPath) DEFINITION_PREFIX = 'ND_' @@ -522,7 +524,7 @@ def main(): if isinstance(elem, mx.Output): outputValue = elem.getAttribute('default') if outputValue == '[]': - outputvalue = '' + outputValue = '' if not outputValue: outputValue = elem.getAttribute('defaultinput') if outputValue: diff --git a/python/Scripts/mxdoc.py b/python/Scripts/mxdoc.py index 7ee21eb8e5..7c9ba09a07 100644 --- a/python/Scripts/mxdoc.py +++ b/python/Scripts/mxdoc.py @@ -3,7 +3,9 @@ Print markdown documentation for each nodedef in the given document. ''' -import sys, os, argparse +import argparse +import sys + import MaterialX as mx HEADERS = ('Name', 'Type', 'Default Value', diff --git a/python/Scripts/mxformat.py b/python/Scripts/mxformat.py index 8f6ad731e1..0b327883bd 100644 --- a/python/Scripts/mxformat.py +++ b/python/Scripts/mxformat.py @@ -4,7 +4,9 @@ the documents to the latest version of the standard. ''' -import sys, os, argparse +import argparse +import os + import MaterialX as mx def main(): diff --git a/python/Scripts/mxvalidate.py b/python/Scripts/mxvalidate.py index e251b4599b..8b5271e9ed 100755 --- a/python/Scripts/mxvalidate.py +++ b/python/Scripts/mxvalidate.py @@ -3,7 +3,9 @@ Verify that the given file is a valid MaterialX document. ''' -import sys, os, argparse +import argparse +import sys + import MaterialX as mx def main(): @@ -25,7 +27,7 @@ def main(): stdlib = mx.createDocument() try: mx.loadLibraries(mx.getDefaultDataLibraryFolders(), mx.getDefaultDataSearchPath(), stdlib) - except err: + except Exception as err: print(err) sys.exit(0) doc.importLibrary(stdlib) From 1cdecf734983676ddaf3c6f84bfe92792f887d0b Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Mon, 27 Nov 2023 12:46:48 -0800 Subject: [PATCH 035/128] Raise minimum CMake version to 3.16 This changelist raises the minimum CMake version to 3.16, allowing more modern CMake features to be leveraged in future pull requests. CMake 3.16 is the first version that natively supports Objective C++ files, which are an important component of the Metal Shading Language support in MaterialX. --- CMakeLists.txt | 16 +++++++--------- source/MaterialXGraphEditor/CMakeLists.txt | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d6a64d6b1..9d6519156e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(MATERIALX_BUILD_VERSION 9) set(MATERIALX_LIBRARY_VERSION ${MATERIALX_MAJOR_VERSION}.${MATERIALX_MINOR_VERSION}.${MATERIALX_BUILD_VERSION}) # Cmake setup -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.16) set(CMAKE_CXX_STANDARD 14) set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) set(CMAKE_MACOSX_RPATH ON) @@ -339,14 +339,12 @@ if(MATERIALX_BUILD_JS) add_subdirectory(source/JsMaterialX) endif() -if(${CMAKE_VERSION} VERSION_GREATER "3.6.2") - if(MATERIALX_BUILD_VIEWER) - set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT MaterialXView) - elseif(MATERIALX_BUILD_GRAPH_EDITOR) - set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT MaterialXGraphEditor) - elseif(MATERIALX_BUILD_TESTS) - set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT MaterialXTest) - endif() +if(MATERIALX_BUILD_VIEWER) + set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT MaterialXView) +elseif(MATERIALX_BUILD_GRAPH_EDITOR) + set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT MaterialXGraphEditor) +elseif(MATERIALX_BUILD_TESTS) + set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT MaterialXTest) endif() # Install root-level documents diff --git a/source/MaterialXGraphEditor/CMakeLists.txt b/source/MaterialXGraphEditor/CMakeLists.txt index 1785540bd8..f5f22be2c5 100644 --- a/source/MaterialXGraphEditor/CMakeLists.txt +++ b/source/MaterialXGraphEditor/CMakeLists.txt @@ -9,7 +9,7 @@ if (NOT IS_DIRECTORY "${DEAR_IMGUI_PREFIX}/backends") endif() if(MSVC) - add_compile_options(-wd4100) + add_compile_options(-wd4100 -wd4152 -wd4201 -wd4244 -wd4456) elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wno-unused -Wno-deprecated -Wno-comment -Wno-unused-variable) elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") From b50dea8ef6c6eda52f7ecabafeb45272a48cfe11 Mon Sep 17 00:00:00 2001 From: Paul Molodowitch Date: Tue, 28 Nov 2023 15:57:50 -0800 Subject: [PATCH 036/128] Link to the OpenGL::GL target instead of OPENGL_LIBRARIES (#1603) This prevents absolute paths from creeping into the output MaterialXConfig.cmake, which makes it not portable. Also, in general in modern CMake, targets are preferred over baked paths. Additionally, at least on Linux, ${OPENGL_LIBRARIES} includes libGLU, which is not actually a required dependency --- source/MaterialXRenderGlsl/CMakeLists.txt | 11 ++++------- source/MaterialXRenderMsl/CMakeLists.txt | 21 +++++++++------------ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/source/MaterialXRenderGlsl/CMakeLists.txt b/source/MaterialXRenderGlsl/CMakeLists.txt index cb2f3c27c2..fdeae933b9 100644 --- a/source/MaterialXRenderGlsl/CMakeLists.txt +++ b/source/MaterialXRenderGlsl/CMakeLists.txt @@ -50,7 +50,8 @@ if(MATERIALX_BUILD_SHARED_LIBS) target_compile_definitions(${MATERIALX_MODULE_NAME} PUBLIC GLAD_GLAPI_EXPORT PRIVATE GLAD_GLAPI_EXPORT_BUILD) endif() -set(COMMON_LIBRARIES +target_link_libraries( + ${MATERIALX_MODULE_NAME} MaterialXRenderHw MaterialXGenGlsl ${CMAKE_DL_LIBS}) @@ -59,28 +60,24 @@ if(WIN32) if(MSVC) target_link_libraries( ${MATERIALX_MODULE_NAME} - ${COMMON_LIBRARIES} Opengl32) elseif(MINGW) target_link_libraries( ${MATERIALX_MODULE_NAME} - ${COMMON_LIBRARIES} Opengl32 gdi32) endif() elseif(APPLE) target_link_libraries( ${MATERIALX_MODULE_NAME} - ${COMMON_LIBRARIES} - ${OPENGL_LIBRARIES} + OpenGL::GL "-framework Foundation" "-framework Cocoa" "-framework Metal") elseif(UNIX) target_link_libraries( ${MATERIALX_MODULE_NAME} - ${COMMON_LIBRARIES} - ${OPENGL_LIBRARIES} + OpenGL::GL ${X11_LIBRARIES} ${X11_Xt_LIB}) endif() diff --git a/source/MaterialXRenderMsl/CMakeLists.txt b/source/MaterialXRenderMsl/CMakeLists.txt index 4d5e286463..3410ac7931 100644 --- a/source/MaterialXRenderMsl/CMakeLists.txt +++ b/source/MaterialXRenderMsl/CMakeLists.txt @@ -42,34 +42,31 @@ add_library(${MATERIALX_MODULE_NAME} ${materialx_source} ${materialx_headers}) add_definitions(-DMATERIALX_RENDERMSL_EXPORTS) -set(COMMON_LIBRARIES +target_link_libraries( + ${MATERIALX_MODULE_NAME} MaterialXRenderHw MaterialXGenMsl ${CMAKE_DL_LIBS}) - -if(APPLE AND NOT MATERIALX_BUILD_IOS) -set(COMMON_LIBRARIES - ${COMMON_LIBRARIES} - "-framework Cocoa") -endif() if(MSVC) target_link_libraries( ${MATERIALX_MODULE_NAME} - ${COMMON_LIBRARIES} Opengl32) elseif(APPLE) + if(NOT MATERIALX_BUILD_IOS) + target_link_libraries( + ${MATERIALX_MODULE_NAME} + "-framework Cocoa" + OpenGL::GL) + endif() target_link_libraries( ${MATERIALX_MODULE_NAME} - ${COMMON_LIBRARIES} - ${OPENGL_LIBRARIES} "-framework Foundation" "-framework Metal") elseif(UNIX) target_link_libraries( ${MATERIALX_MODULE_NAME} - ${COMMON_LIBRARIES} - ${OPENGL_LIBRARIES} + OpenGL::GL ${X11_LIBRARIES} ${X11_Xt_LIB}) endif() From b8cc4de9122b5c08ffda70c31ccfef530fb68f6d Mon Sep 17 00:00:00 2001 From: Paul Molodowitch Date: Tue, 28 Nov 2023 16:32:55 -0800 Subject: [PATCH 037/128] Link to X11 targets instead of CMake variables (#1606) This prevents absolute paths from creeping into the output MaterialXConfig.cmake, which makes it not portable. Also, in general in modern CMake, targets are preferred over baked paths. --- source/MaterialXRenderGlsl/CMakeLists.txt | 4 ++-- source/MaterialXRenderHw/CMakeLists.txt | 4 ++-- source/MaterialXRenderMsl/CMakeLists.txt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/MaterialXRenderGlsl/CMakeLists.txt b/source/MaterialXRenderGlsl/CMakeLists.txt index fdeae933b9..067cc5d016 100644 --- a/source/MaterialXRenderGlsl/CMakeLists.txt +++ b/source/MaterialXRenderGlsl/CMakeLists.txt @@ -78,8 +78,8 @@ elseif(UNIX) target_link_libraries( ${MATERIALX_MODULE_NAME} OpenGL::GL - ${X11_LIBRARIES} - ${X11_Xt_LIB}) + X11::X11 + X11::Xt) endif() set_target_properties( diff --git a/source/MaterialXRenderHw/CMakeLists.txt b/source/MaterialXRenderHw/CMakeLists.txt index dfd262a3ae..9efc26017c 100644 --- a/source/MaterialXRenderHw/CMakeLists.txt +++ b/source/MaterialXRenderHw/CMakeLists.txt @@ -57,8 +57,8 @@ elseif(UNIX) ${MATERIALX_MODULE_NAME} MaterialXRender ${CMAKE_DL_LIBS} - ${X11_LIBRARIES} - ${X11_Xt_LIB}) + X11::X11 + X11::Xt) endif() set_target_properties( diff --git a/source/MaterialXRenderMsl/CMakeLists.txt b/source/MaterialXRenderMsl/CMakeLists.txt index 3410ac7931..41e00d4b9f 100644 --- a/source/MaterialXRenderMsl/CMakeLists.txt +++ b/source/MaterialXRenderMsl/CMakeLists.txt @@ -67,8 +67,8 @@ elseif(UNIX) target_link_libraries( ${MATERIALX_MODULE_NAME} OpenGL::GL - ${X11_LIBRARIES} - ${X11_Xt_LIB}) + X11::X11 + X11::Xt) endif() set_target_properties( From eb24c5ed9a524955604fe898a77c664225cb2a70 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 28 Nov 2023 17:25:48 -0800 Subject: [PATCH 038/128] Improvements to build scripts - Simplify CMake generation commands using the -S and -B options. - Simplify the usage of CMAKE_EXPORT_COMPILE_COMMANDS in GitHub CI. - Unify JavaScript build settings in the root-level CMakeLists.txt. --- .github/workflows/main.yml | 11 +++-------- CMakeLists.txt | 26 +++++++++++++++----------- javascript/build_javascript_win.bat | 8 +++----- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aeba7b2c45..0a71a31011 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,6 +38,7 @@ jobs: compiler_version: "13" python: 3.12 static_analysis: ON + cmake_config: -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - name: Linux_GCC_CoverageAnalysis os: ubuntu-22.04 @@ -197,10 +198,7 @@ jobs: run: find source \( -name *.h -o -name *.cpp -o -name *.mm \) ! -path "*/External/*" ! -path "*/NanoGUI/*" | xargs clang-format -i --verbose - name: CMake Generate - run: | - mkdir build - cd build - cmake -DMATERIALX_BUILD_PYTHON=ON -DMATERIALX_BUILD_VIEWER=ON -DMATERIALX_BUILD_GRAPH_EDITOR=ON -DMATERIALX_TEST_RENDER=OFF -DMATERIALX_WARNINGS_AS_ERRORS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ${{matrix.cmake_config}} .. + run: cmake -S . -B build -DMATERIALX_BUILD_PYTHON=ON -DMATERIALX_BUILD_VIEWER=ON -DMATERIALX_BUILD_GRAPH_EDITOR=ON -DMATERIALX_TEST_RENDER=OFF -DMATERIALX_WARNINGS_AS_ERRORS=ON ${{matrix.cmake_config}} - name: CMake Build run: cmake --build . --target install --config Release --parallel 2 @@ -312,10 +310,7 @@ jobs: - name: JavaScript CMake Generate if: matrix.build_javascript == 'ON' - run: | - mkdir javascript/build - cd javascript/build - cmake -DMATERIALX_BUILD_JS=ON -DMATERIALX_EMSDK_PATH=${{ env.EMSDK }} -DMATERIALX_BUILD_RENDER=OFF -DMATERIALX_BUILD_TESTS=OFF -DMATERIALX_BUILD_GEN_OSL=OFF -DMATERIALX_BUILD_GEN_MDL=OFF ../.. + run: cmake -S . -B javascript/build -DMATERIALX_BUILD_JS=ON -DMATERIALX_EMSDK_PATH=${{ env.EMSDK }} - name: JavaScript CMake Build if: matrix.build_javascript == 'ON' diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d6519156e..c29565a7ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,13 +61,21 @@ option(MATERIALX_BUILD_IOS "Build MaterialX for iOS." OFF) if (MATERIALX_BUILD_IOS) set(CMAKE_SYSTEM_NAME iOS) add_definitions(-DTARGET_OS_IOS=1) - set(MATERIALX_BUILD_PYTHON OFF) - set(MATERIALX_BUILD_VIEWER OFF) - set(MATERIALX_BUILD_GRAPH_EDITOR OFF) - set(MATERIALX_BUILD_GEN_GLSL OFF) - set(MATERIALX_BUILD_GEN_OSL OFF) - set(MATERIALX_BUILD_GEN_MDL OFF) - set(MATERIALX_BUILD_TESTS OFF) + set(MATERIALX_BUILD_PYTHON OFF) + set(MATERIALX_BUILD_VIEWER OFF) + set(MATERIALX_BUILD_GRAPH_EDITOR OFF) + set(MATERIALX_BUILD_GEN_GLSL OFF) + set(MATERIALX_BUILD_GEN_OSL OFF) + set(MATERIALX_BUILD_GEN_MDL OFF) + set(MATERIALX_BUILD_TESTS OFF) +endif() + +if (MATERIALX_BUILD_JS) + set(MATERIALX_BUILD_GEN_OSL OFF) + set(MATERIALX_BUILD_GEN_MSL OFF) + set(MATERIALX_BUILD_GEN_MDL OFF) + set(MATERIALX_BUILD_RENDER OFF) + set(MATERIALX_BUILD_TESTS OFF) endif() set(MATERIALX_PYTHON_VERSION "" CACHE STRING @@ -81,10 +89,6 @@ set(MATERIALX_PYTHON_PYBIND11_DIR "" CACHE PATH set(MATERIALX_OIIO_DIR "" CACHE PATH "Path to the root folder of the OpenImageIO installation.") -if (MATERIALX_BUILD_JS) - set(MATERIALX_BUILD_GEN_GLSL ON) -endif() - # Settings to define installation layout set(MATERIALX_INSTALL_INCLUDE_PATH "include" CACHE STRING "Install header include path (e.g. 'inc', 'include').") set(MATERIALX_INSTALL_LIB_PATH "lib" CACHE STRING "Install lib path (e.g. 'libs', 'lib').") diff --git a/javascript/build_javascript_win.bat b/javascript/build_javascript_win.bat index 43d8b8b562..8b08c26600 100644 --- a/javascript/build_javascript_win.bat +++ b/javascript/build_javascript_win.bat @@ -8,14 +8,12 @@ if NOT ["%errorlevel%"]==["0"] pause @echo --------------------- Build MaterialX With JavaScript --------------------- @echo on cd %MATERIALX_LOCATION% -mkdir javascript\build -cd javascript\build -cmake -DMATERIALX_BUILD_JS=ON -DMATERIALX_EMSDK_PATH=%EMSDK_LOCATION% -G Ninja -DMATERIALX_BUILD_RENDER=OFF -DMATERIALX_BUILD_TESTS=OFF -DMATERIALX_BUILD_GEN_OSL=OFF -DMATERIALX_BUILD_GEN_MDL=OFF ..\.. -cmake --build . --target install --config RelWithDebInfo --parallel 2 +cmake -S . -B javascript/build -DMATERIALX_BUILD_JS=ON -DMATERIALX_EMSDK_PATH=%EMSDK_LOCATION% -G Ninja +cmake --build javascript/build --target install --config RelWithDebInfo --parallel 2 if NOT ["%errorlevel%"]==["0"] pause @echo --------------------- Run JavaScript Tests --------------------- @echo on -cd ../MaterialXTest +cd javascript/MaterialXTest call npm install call npm run test call npm run test:browser From 61d4967f3307790aae7b5710eda5a44382c62680 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Fri, 1 Dec 2023 08:33:15 -0800 Subject: [PATCH 039/128] Apply Clang formatting This changelist applies Clang formatting to source files in the MaterialX codebase, and includes no functional changes. --- source/MaterialXCore/Definition.cpp | 2 +- source/MaterialXFormat/Util.cpp | 2 +- source/MaterialXFormat/Util.h | 2 +- .../MaterialXGenGlsl/GlslShaderGenerator.cpp | 20 ++--- source/MaterialXGenMdl/MdlShaderGenerator.cpp | 6 +- source/MaterialXGenMdl/MdlSyntax.cpp | 2 +- .../Nodes/ClosureCompoundNodeMdl.cpp | 2 +- .../Nodes/ClosureLayerNodeMdl.cpp | 24 +++--- .../Nodes/ClosureLayerNodeMdl.h | 16 ++-- source/MaterialXGenMsl/MslShaderGenerator.cpp | 2 +- source/MaterialXGenOsl/OslShaderGenerator.cpp | 2 +- .../MaterialXGenShader/HwShaderGenerator.cpp | 4 +- .../Nodes/HwTransformNode.cpp | 2 +- source/MaterialXGenShader/ShaderGenerator.cpp | 2 +- source/MaterialXGenShader/ShaderGenerator.h | 2 +- source/MaterialXGenShader/ShaderNode.cpp | 2 +- source/MaterialXGenShader/ShaderStage.cpp | 4 +- source/MaterialXGraphEditor/FileDialog.h | 6 +- source/MaterialXGraphEditor/Graph.cpp | 3 +- source/MaterialXGraphEditor/RenderView.cpp | 4 +- source/MaterialXGraphEditor/UiNode.h | 2 +- source/MaterialXRender/Camera.cpp | 8 +- source/MaterialXRender/Camera.h | 14 ++-- source/MaterialXRender/CgltfLoader.cpp | 13 ++- source/MaterialXRender/CgltfLoader.h | 4 +- source/MaterialXRender/GeometryHandler.cpp | 22 +++-- source/MaterialXRender/GeometryHandler.h | 2 +- source/MaterialXRender/Harmonics.cpp | 3 +- source/MaterialXRender/Harmonics.h | 3 +- source/MaterialXRender/ImageHandler.cpp | 11 ++- source/MaterialXRender/ImageHandler.h | 8 +- source/MaterialXRender/LightHandler.cpp | 4 +- source/MaterialXRender/LightHandler.h | 2 +- source/MaterialXRender/Mesh.cpp | 25 +++--- source/MaterialXRender/Mesh.h | 2 +- source/MaterialXRender/OiioImageLoader.cpp | 6 +- source/MaterialXRender/OiioImageLoader.h | 6 +- source/MaterialXRender/ShaderMaterial.cpp | 10 +-- source/MaterialXRender/ShaderMaterial.h | 4 +- source/MaterialXRender/ShaderRenderer.h | 6 +- source/MaterialXRender/StbImageLoader.cpp | 8 +- source/MaterialXRender/StbImageLoader.h | 2 +- source/MaterialXRender/TextureBaker.h | 10 +-- source/MaterialXRender/TextureBaker.inl | 83 +++++++++---------- source/MaterialXRender/TinyObjLoader.cpp | 8 +- source/MaterialXRender/TinyObjLoader.h | 2 +- source/MaterialXRender/Types.h | 6 +- source/MaterialXRender/Util.h | 22 ++--- source/MaterialXRenderGlsl/GLFramebuffer.cpp | 54 ++++++------ source/MaterialXRenderGlsl/GLTextureHandler.h | 2 +- source/MaterialXRenderGlsl/GlslMaterial.cpp | 2 +- source/MaterialXRenderGlsl/GlslMaterial.h | 5 +- source/MaterialXRenderGlsl/GlslProgram.cpp | 25 +++--- source/MaterialXRenderGlsl/GlslProgram.h | 2 +- source/MaterialXRenderGlsl/GlslRenderer.h | 2 +- source/MaterialXRenderGlsl/TextureBaker.h | 2 +- source/MaterialXRenderHw/SimpleWindow.h | 4 +- .../MaterialXRenderHw/SimpleWindowLinux.cpp | 6 +- .../MaterialXRenderHw/SimpleWindowWindows.cpp | 40 ++++----- source/MaterialXView/Editor.cpp | 58 ++++++------- source/MaterialXView/Editor.h | 4 +- source/MaterialXView/Main.cpp | 72 ++++++++-------- source/MaterialXView/RenderPipeline.h | 12 +-- 63 files changed, 347 insertions(+), 348 deletions(-) diff --git a/source/MaterialXCore/Definition.cpp b/source/MaterialXCore/Definition.cpp index cf9587ecda..c3150e2a87 100644 --- a/source/MaterialXCore/Definition.cpp +++ b/source/MaterialXCore/Definition.cpp @@ -84,7 +84,7 @@ InterfaceElementPtr NodeDef::getImplementation(const string& target) const } } } - + // Then search for a generic match. for (InterfaceElementPtr interface : interfaces) { diff --git a/source/MaterialXFormat/Util.cpp b/source/MaterialXFormat/Util.cpp index 32feda4d0d..48ded1d6b1 100644 --- a/source/MaterialXFormat/Util.cpp +++ b/source/MaterialXFormat/Util.cpp @@ -234,7 +234,7 @@ FileSearchPath getDefaultDataSearchPath() } currentPath = currentPath.getParentPath(); } - return FileSearchPath(); + return FileSearchPath(); } MATERIALX_NAMESPACE_END diff --git a/source/MaterialXFormat/Util.h b/source/MaterialXFormat/Util.h index 46f55c41ee..c7ef0c6d38 100644 --- a/source/MaterialXFormat/Util.h +++ b/source/MaterialXFormat/Util.h @@ -62,7 +62,7 @@ MX_FORMAT_API FileSearchPath getSourceSearchPath(ConstDocumentPtr doc); /// Return a file search path to the default data library folder. /// The module path and all parent paths are examined to until either there is -/// no parent or the library folder is found. +/// no parent or the library folder is found. MX_FORMAT_API FileSearchPath getDefaultDataSearchPath(); MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp index ec5e48d4ec..ea78e1bee3 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp @@ -56,17 +56,17 @@ GlslShaderGenerator::GlslShaderGenerator() : // StringVec elementNames; - + // elementNames = { // - "IM_switch_float_" + GlslShaderGenerator::TARGET, - "IM_switch_color3_" + GlslShaderGenerator::TARGET, - "IM_switch_color4_" + GlslShaderGenerator::TARGET, + "IM_switch_float_" + GlslShaderGenerator::TARGET, + "IM_switch_color3_" + GlslShaderGenerator::TARGET, + "IM_switch_color4_" + GlslShaderGenerator::TARGET, "IM_switch_vector2_" + GlslShaderGenerator::TARGET, "IM_switch_vector3_" + GlslShaderGenerator::TARGET, "IM_switch_vector4_" + GlslShaderGenerator::TARGET, - + // "IM_switch_floatI_" + GlslShaderGenerator::TARGET, "IM_switch_color3I_" + GlslShaderGenerator::TARGET, @@ -85,7 +85,7 @@ GlslShaderGenerator::GlslShaderGenerator() : "IM_swizzle_float_vector2_" + GlslShaderGenerator::TARGET, "IM_swizzle_float_vector3_" + GlslShaderGenerator::TARGET, "IM_swizzle_float_vector4_" + GlslShaderGenerator::TARGET, - + // "IM_swizzle_color3_float_" + GlslShaderGenerator::TARGET, "IM_swizzle_color3_color3_" + GlslShaderGenerator::TARGET, @@ -93,7 +93,7 @@ GlslShaderGenerator::GlslShaderGenerator() : "IM_swizzle_color3_vector2_" + GlslShaderGenerator::TARGET, "IM_swizzle_color3_vector3_" + GlslShaderGenerator::TARGET, "IM_swizzle_color3_vector4_" + GlslShaderGenerator::TARGET, - + // "IM_swizzle_color4_float_" + GlslShaderGenerator::TARGET, "IM_swizzle_color4_color3_" + GlslShaderGenerator::TARGET, @@ -101,7 +101,7 @@ GlslShaderGenerator::GlslShaderGenerator() : "IM_swizzle_color4_vector2_" + GlslShaderGenerator::TARGET, "IM_swizzle_color4_vector3_" + GlslShaderGenerator::TARGET, "IM_swizzle_color4_vector4_" + GlslShaderGenerator::TARGET, - + // "IM_swizzle_vector2_float_" + GlslShaderGenerator::TARGET, "IM_swizzle_vector2_color3_" + GlslShaderGenerator::TARGET, @@ -109,7 +109,7 @@ GlslShaderGenerator::GlslShaderGenerator() : "IM_swizzle_vector2_vector2_" + GlslShaderGenerator::TARGET, "IM_swizzle_vector2_vector3_" + GlslShaderGenerator::TARGET, "IM_swizzle_vector2_vector4_" + GlslShaderGenerator::TARGET, - + // "IM_swizzle_vector3_float_" + GlslShaderGenerator::TARGET, "IM_swizzle_vector3_color3_" + GlslShaderGenerator::TARGET, @@ -117,7 +117,7 @@ GlslShaderGenerator::GlslShaderGenerator() : "IM_swizzle_vector3_vector2_" + GlslShaderGenerator::TARGET, "IM_swizzle_vector3_vector3_" + GlslShaderGenerator::TARGET, "IM_swizzle_vector3_vector4_" + GlslShaderGenerator::TARGET, - + // "IM_swizzle_vector4_float_" + GlslShaderGenerator::TARGET, "IM_swizzle_vector4_color3_" + GlslShaderGenerator::TARGET, diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.cpp b/source/MaterialXGenMdl/MdlShaderGenerator.cpp index e10d586d69..af75a2cef4 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.cpp +++ b/source/MaterialXGenMdl/MdlShaderGenerator.cpp @@ -291,9 +291,9 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G { emitLine("float3 displacement__ = " + result + ".geometry.displacement", stage); emitLine("color finalOutput__ = mk_color3(" - "r: math::dot(displacement__, state::texture_tangent_u(0))," - "g: math::dot(displacement__, state::texture_tangent_v(0))," - "b: math::dot(displacement__, state::normal()))", stage); + "r: math::dot(displacement__, state::texture_tangent_u(0))," + "g: math::dot(displacement__, state::texture_tangent_v(0))," + "b: math::dot(displacement__, state::normal()))", stage); } else { diff --git a/source/MaterialXGenMdl/MdlSyntax.cpp b/source/MaterialXGenMdl/MdlSyntax.cpp index 9d5483bcca..7560297ce4 100644 --- a/source/MaterialXGenMdl/MdlSyntax.cpp +++ b/source/MaterialXGenMdl/MdlSyntax.cpp @@ -48,7 +48,7 @@ class MdlFilenameTypeSyntax : public ScalarTypeSyntax // assuming it ends with a slash ... if (outputValue.back() == '/') { - return getDefaultValue(true); + return getDefaultValue(true); } // ... or the last segment does not have an extension suffix size_t idx_s = outputValue.find_last_of('/'); diff --git a/source/MaterialXGenMdl/Nodes/ClosureCompoundNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/ClosureCompoundNodeMdl.cpp index e175696d55..0a2004cd71 100644 --- a/source/MaterialXGenMdl/Nodes/ClosureCompoundNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/ClosureCompoundNodeMdl.cpp @@ -41,7 +41,7 @@ void ClosureCompoundNodeMdl::emitFunctionDefinition(const ShaderNode& node, GenC { if (!outputSocket->getConnection()) continue; - + const ShaderNode* upstream = outputSocket->getConnection()->getNode(); const bool isMaterialExpr = (upstream->hasClassification(ShaderNode::Classification::CLOSURE) || upstream->hasClassification(ShaderNode::Classification::SHADER)); diff --git a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp index fd27d5e547..bff1351142 100644 --- a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp @@ -368,12 +368,12 @@ const string& MixBsdfNodeMdl::getOperatorName(size_t index) const { switch (index) { - case 0: - return StringConstantsMdl::FG; - case 1: - return StringConstantsMdl::BG; - default: - return StringConstantsMdl::EMPTY; + case 0: + return StringConstantsMdl::FG; + case 1: + return StringConstantsMdl::BG; + default: + return StringConstantsMdl::EMPTY; } } @@ -386,12 +386,12 @@ const string& AddOrMultiplyBsdfNodeMdl::getOperatorName(size_t index) const { switch (index) { - case 0: - return StringConstantsMdl::IN1; - case 1: - return StringConstantsMdl::IN2; - default: - return StringConstantsMdl::EMPTY; + case 0: + return StringConstantsMdl::IN1; + case 1: + return StringConstantsMdl::IN2; + default: + return StringConstantsMdl::EMPTY; } } diff --git a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h index 75ea46046c..95c51198f8 100644 --- a/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h +++ b/source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h @@ -21,18 +21,18 @@ class MX_GENMDL_API StringConstantsMdl public: /// String constants - static const string TOP; ///< layer parameter name of the top component + 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; ///< parameter of the mix node - static const string BG; ///< parameter of the mix node - static const string IN1; ///< parameter of the add and multiply nodes - static const string IN2; ///< parameter of the add and multiply nodes + static const string FG; ///< parameter of the mix node + static const string BG; ///< parameter of the mix node + static const string IN1; ///< parameter of the add and multiply nodes + static const string IN2; ///< parameter of the add and multiply nodes static const string THICKNESS; ///< thickness parameter name of the thin_film_bsdf - static const string IOR; ///< ior parameter name of the thin_film_bsdf + static const string IOR; ///< ior parameter name of the thin_film_bsdf static const string THIN_FILM_THICKNESS; ///< helper parameter name for transporting thickness - static const string THIN_FILM_IOR; ///< helper parameter name for transporting ior + static const string THIN_FILM_IOR; ///< helper parameter name for transporting ior static const string EMPTY; ///< the empty string "" }; @@ -41,7 +41,7 @@ class MX_GENMDL_API StringConstantsMdl /// thin_film_bsdf through layers and mixers, etc., to the elemental bsdfs that support thin film. /// Because thin-film can not be layered on any BSDF in MDL, we try to push down the parameters to /// the nodes that support thin-film. -template class CarryThinFilmParameters : public TBase +template class CarryThinFilmParameters : public TBase { public: /// Add the thin film inputs for transporting the parameter. diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index ea3fb7112d..7fe50fef4a 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -1018,7 +1018,7 @@ void MslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& co emitLightData(context, stage); } } - + bool needsLightBuffer = lighting && context.getOptions().hwMaxActiveLightSources > 0; emitMathMatrixScalarMathOperators(context, stage); diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp index fbb2bb29be..f16770174b 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.cpp +++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp @@ -536,7 +536,7 @@ void OslShaderGenerator::emitShaderInputs(const VariableBlock& inputs, ShaderSta // which is a struct containing a file string and a colorspace string. // For the published shader interface we here split this into two separate inputs, // which gives a nicer shader interface with widget metadata on each input. - + ValuePtr value = input->getValue(); const string valueStr = value ? value->getValueString() : EMPTY_STRING; diff --git a/source/MaterialXGenShader/HwShaderGenerator.cpp b/source/MaterialXGenShader/HwShaderGenerator.cpp index 568c666478..0db78eda27 100644 --- a/source/MaterialXGenShader/HwShaderGenerator.cpp +++ b/source/MaterialXGenShader/HwShaderGenerator.cpp @@ -260,9 +260,9 @@ ShaderPtr HwShaderGenerator::createShader(const string& name, ElementPtr element if (geomprop) { // A default geomprop was assigned to this graph input. - // For all internal connections to this input, break the connection + // For all internal connections to this input, break the connection // and assign a geomprop node that generates this data. - // Note: If a geomprop node exists already it is reused, + // Note: If a geomprop node exists already it is reused, // so only a single node per geometry type is created. ShaderInputVec connections = socket->getConnections(); for (auto connection : connections) diff --git a/source/MaterialXGenShader/Nodes/HwTransformNode.cpp b/source/MaterialXGenShader/Nodes/HwTransformNode.cpp index 018924855d..76394309af 100644 --- a/source/MaterialXGenShader/Nodes/HwTransformNode.cpp +++ b/source/MaterialXGenShader/Nodes/HwTransformNode.cpp @@ -17,7 +17,7 @@ const string HwTransformNode::WORLD = "world"; void HwTransformNode::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const { - const string toSpace = getToSpace(node); + const string toSpace = getToSpace(node); const string fromSpace = getFromSpace(node); const string& matrix = getMatrix(fromSpace, toSpace); if (!matrix.empty()) diff --git a/source/MaterialXGenShader/ShaderGenerator.cpp b/source/MaterialXGenShader/ShaderGenerator.cpp index 177201a9e3..d5f51aed1c 100644 --- a/source/MaterialXGenShader/ShaderGenerator.cpp +++ b/source/MaterialXGenShader/ShaderGenerator.cpp @@ -270,7 +270,7 @@ void ShaderGenerator::registerImplementation(const string& name, CreatorFunction void ShaderGenerator::registerImplementation(const StringVec& nameVec, CreatorFunction creator) { - for(const string& name : nameVec) + for (const string& name : nameVec) { _implFactory.registerClass(name, creator); } diff --git a/source/MaterialXGenShader/ShaderGenerator.h b/source/MaterialXGenShader/ShaderGenerator.h index 8e7f9855de..fa60a4d63e 100644 --- a/source/MaterialXGenShader/ShaderGenerator.h +++ b/source/MaterialXGenShader/ShaderGenerator.h @@ -151,7 +151,7 @@ class MX_GENSHADER_API ShaderGenerator /// Register a shader node implementation for a given implementation element name void registerImplementation(const string& name, CreatorFunction creator); - + /// Register a shader node implementation for a given set of implementation element names void registerImplementation(const StringVec& nameVec, CreatorFunction creator); diff --git a/source/MaterialXGenShader/ShaderNode.cpp b/source/MaterialXGenShader/ShaderNode.cpp index 3e393178f1..9ef5b0789a 100644 --- a/source/MaterialXGenShader/ShaderNode.cpp +++ b/source/MaterialXGenShader/ShaderNode.cpp @@ -290,7 +290,7 @@ ShaderNodePtr ShaderNode::create(const ShaderGraph* parent, const string& name, else if (nodeDef.getNodeString() == CONSTANT) { newNode->_classification = Classification::TEXTURE | Classification::CONSTANT; - } + } else if (nodeDef.getNodeString() == DOT) { newNode->_classification = Classification::TEXTURE | Classification::DOT; diff --git a/source/MaterialXGenShader/ShaderStage.cpp b/source/MaterialXGenShader/ShaderStage.cpp index b5387bcb94..d304c22dd2 100644 --- a/source/MaterialXGenShader/ShaderStage.cpp +++ b/source/MaterialXGenShader/ShaderStage.cpp @@ -82,8 +82,8 @@ ShaderPort* VariableBlock::add(const TypeDesc* type, const string& name, ValuePt else if (type != it->second->getType()) { throw ExceptionShaderGenError("Trying to add shader port '" + name + "' with type '" + - type->getName() + "', but existing shader port with type '" + - it->second->getType()->getName() + "' was found"); + type->getName() + "', but existing shader port with type '" + + it->second->getType()->getName() + "' was found"); } return it->second.get(); } diff --git a/source/MaterialXGraphEditor/FileDialog.h b/source/MaterialXGraphEditor/FileDialog.h index 49b905f28c..4b6c042ef8 100644 --- a/source/MaterialXGraphEditor/FileDialog.h +++ b/source/MaterialXGraphEditor/FileDialog.h @@ -16,9 +16,9 @@ class FileDialog public: enum Flags { - SelectDirectory = 1 << 0, // select directory instead of regular file - EnterNewFilename = 1 << 1, // allow user to enter new filename when selecting regular file - NoTitleBar = 1 << 2, // hide window title bar + SelectDirectory = 1 << 0, // select directory instead of regular file + EnterNewFilename = 1 << 1, // allow user to enter new filename when selecting regular file + NoTitleBar = 1 << 2, // hide window title bar }; public: diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index bab5df7b58..fc682e8f05 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -2620,7 +2620,6 @@ void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId) break; } } - } // Since we accepted new link, lets add one to our list of links. @@ -3668,7 +3667,7 @@ void Graph::addNodePopup(bool cursor) // Filter extra nodes - includes inputs, outputs, groups, and node graphs const std::string NODEGRAPH_ENTRY = "Node Graph"; - // Filter nodedefs and add to menu if matches filter + // Filter nodedefs and add to menu if matches filter for (auto node : _nodesToAdd) { // Filter out list of nodes diff --git a/source/MaterialXGraphEditor/RenderView.cpp b/source/MaterialXGraphEditor/RenderView.cpp index d2967e6b85..3c2e01dff9 100644 --- a/source/MaterialXGraphEditor/RenderView.cpp +++ b/source/MaterialXGraphEditor/RenderView.cpp @@ -299,7 +299,7 @@ void RenderView::loadMesh(const mx::FilePath& filename) _cameraTarget = mx::Vector3(); initCamera(); - + if (_shadowMap) { _imageHandler->releaseRenderResources(_shadowMap); @@ -848,7 +848,7 @@ void RenderView::initCamera() { _viewCamera->setViewportSize(mx::Vector2((float) _viewWidth, (float) _viewHeight)); - if ( _geometryHandler->getMeshes().empty()) + if (_geometryHandler->getMeshes().empty()) { return; } diff --git a/source/MaterialXGraphEditor/UiNode.h b/source/MaterialXGraphEditor/UiNode.h index cf7aa41e28..06d0281676 100644 --- a/source/MaterialXGraphEditor/UiNode.h +++ b/source/MaterialXGraphEditor/UiNode.h @@ -101,7 +101,7 @@ class UiPin { if (_connections[i]->_pinId == pin->_pinId) { - _connections.erase(_connections.begin()+i); + _connections.erase(_connections.begin() + i); } } for (size_t i = 0; i < pin->_connections.size(); i++) diff --git a/source/MaterialXRender/Camera.cpp b/source/MaterialXRender/Camera.cpp index 6464246e3a..7b9579376c 100644 --- a/source/MaterialXRender/Camera.cpp +++ b/source/MaterialXRender/Camera.cpp @@ -23,8 +23,8 @@ Matrix44 Camera::createViewMatrix(const Vector3& eye, } Matrix44 Camera::createPerspectiveMatrixZP(float left, float right, - float bottom, float top, - float nearP, float farP) + float bottom, float top, + float nearP, float farP) { return Matrix44( (2.0f * nearP) / (right - left), 0.0f, (right + left) / (right - left), 0.0f, @@ -34,8 +34,8 @@ Matrix44 Camera::createPerspectiveMatrixZP(float left, float right, } Matrix44 Camera::createOrthographicMatrixZP(float left, float right, - float bottom, float top, - float nearP, float farP) + float bottom, float top, + float nearP, float farP) { return Matrix44( 2.0f / (right - left), 0.0f, 0.0f, 0.0f, diff --git a/source/MaterialXRender/Camera.h b/source/MaterialXRender/Camera.h index a20c0f0e70..3135904b5a 100644 --- a/source/MaterialXRender/Camera.h +++ b/source/MaterialXRender/Camera.h @@ -163,17 +163,17 @@ class MX_RENDER_API Camera static Matrix44 createOrthographicMatrix(float left, float right, float bottom, float top, float nearP, float farP); - + /// Create a perpective projection matrix given a set of clip planes with [0,1] projected Z. static Matrix44 createPerspectiveMatrixZP(float left, float right, - float bottom, float top, - float nearP, float farP); + float bottom, float top, + float nearP, float farP); /// Create an orthographic projection matrix given a set of clip planes with [0,1] projected Z. static Matrix44 createOrthographicMatrixZP(float left, float right, - float bottom, float top, - float nearP, float farP); - + float bottom, float top, + float nearP, float farP); + /// Apply a perspective transform to the given 3D point, performing a /// homogeneous divide on the transformed result. static Vector3 transformPointPerspective(const Matrix44& m, const Vector3& v) @@ -185,7 +185,7 @@ class MX_RENDER_API Camera /// @} protected: - // Transform matrices + // Transform matrices Matrix44 _worldMatrix; Matrix44 _viewMatrix; Matrix44 _projectionMatrix; diff --git a/source/MaterialXRender/CgltfLoader.cpp b/source/MaterialXRender/CgltfLoader.cpp index 1c8ec598a6..fcc8831732 100644 --- a/source/MaterialXRender/CgltfLoader.cpp +++ b/source/MaterialXRender/CgltfLoader.cpp @@ -59,7 +59,7 @@ void computeMeshMatrices(GLTFMeshMatrixList& meshMatrices, cgltf_node* cnode) } // Iterate over all children. Note that the existence of a mesh - // does not imply that this is a leaf node so traversal should + // does not imply that this is a leaf node so traversal should // continue even when a mesh is encountered. for (cgltf_size i = 0; i < cnode->children_count; i++) { @@ -76,7 +76,7 @@ using GLTFMeshPathList = std::unordered_map; void computeMeshPaths(GLTFMeshPathList& meshPaths, cgltf_node* cnode, FilePath path, size_t nodeCount, size_t meshCount) { string cnodeName = cnode->name ? string(cnode->name) : DEFAULT_NODE_PREFIX + std::to_string(nodeCount++); - path = path / ( createValidName(cnodeName) + "/" ); + path = path / (createValidName(cnodeName) + "/"); cgltf_mesh* cmesh = cnode->mesh; if (cmesh) @@ -92,7 +92,7 @@ void computeMeshPaths(GLTFMeshPathList& meshPaths, cgltf_node* cnode, FilePath p } // Iterate over all children. Note that the existence of a mesh - // does not imply that this is a leaf node so traversal should + // does not imply that this is a leaf node so traversal should // continue even when a mesh is encountered. for (cgltf_size i = 0; i < cnode->children_count; i++) { @@ -220,11 +220,11 @@ bool CgltfLoader::load(const FilePath& filePath, MeshList& meshList, bool texcoo } // Iterate through all parent transform - for (size_t mtx=0; mtx < positionMatrices.size(); mtx++) + for (size_t mtx = 0; mtx < positionMatrices.size(); mtx++) { const Matrix44& positionMatrix = positionMatrices[mtx]; const Matrix44 normalMatrix = positionMatrix.getInverse().getTranspose(); - + for (cgltf_size primitiveIndex = 0; primitiveIndex < cmesh->primitives_count; ++primitiveIndex) { cgltf_primitive* primitive = &cmesh->primitives[primitiveIndex]; @@ -347,8 +347,7 @@ bool CgltfLoader::load(const FilePath& filePath, MeshList& meshList, bool texcoo else { if (_debugLevel > 0) - std::cout << "Unknown stream type: " << std::to_string(attribute->type) - << std::endl; + std::cout << "Unknown stream type: " << std::to_string(attribute->type) << std::endl; } // Fill in stream diff --git a/source/MaterialXRender/CgltfLoader.h b/source/MaterialXRender/CgltfLoader.h index 4f4a7145ba..fb63cb6102 100644 --- a/source/MaterialXRender/CgltfLoader.h +++ b/source/MaterialXRender/CgltfLoader.h @@ -6,7 +6,7 @@ #ifndef MATERIALX_CGLTFLOADER_H #define MATERIALX_CGLTFLOADER_H -/// @file +/// @file /// GLTF format loader using the Cgltf library #include @@ -32,7 +32,7 @@ class MX_RENDER_API CgltfLoader : public GeometryLoader static CgltfLoaderPtr create() { return std::make_shared(); } /// Load geometry from file path - bool load(const FilePath& filePath, MeshList& meshList, bool texcoordVerticalFlip=false) override; + bool load(const FilePath& filePath, MeshList& meshList, bool texcoordVerticalFlip = false) override; private: unsigned int _debugLevel; diff --git a/source/MaterialXRender/GeometryHandler.cpp b/source/MaterialXRender/GeometryHandler.cpp index e2c974a767..dfea0b2ceb 100644 --- a/source/MaterialXRender/GeometryHandler.cpp +++ b/source/MaterialXRender/GeometryHandler.cpp @@ -89,7 +89,7 @@ bool GeometryHandler::loadGeometry(const FilePath& filePath, bool texcoordVertic bool loaded = false; - std::pair range; + std::pair range; string extension = filePath.getExtension(); range = _geometryLoaders.equal_range(extension); GeometryLoaderMap::iterator first = --range.second; @@ -140,19 +140,17 @@ MeshPtr GeometryHandler::createQuadMesh(const Vector2& uvMin, const Vector2& uvM quadTexCoords->setStride(MeshStream::STRIDE_2D); if (!flipTexCoordsHorizontally) { - quadTexCoords->getData().assign({ - uvMax[0], uvMax[1], - uvMax[0], uvMin[1], - uvMin[0], uvMin[1], - uvMin[0], uvMax[1] }); + quadTexCoords->getData().assign({ uvMax[0], uvMax[1], + uvMax[0], uvMin[1], + uvMin[0], uvMin[1], + uvMin[0], uvMax[1] }); } else { - quadTexCoords->getData().assign({ - uvMax[0], uvMin[1], - uvMax[0], uvMax[1], - uvMin[0], uvMax[1], - uvMin[0], uvMin[1] }); + quadTexCoords->getData().assign({ uvMax[0], uvMin[1], + uvMax[0], uvMax[1], + uvMin[0], uvMax[1], + uvMin[0], uvMin[1] }); } MeshPartitionPtr quadIndices = MeshPartition::create(); quadIndices->getIndices().assign({ 0, 1, 3, 1, 2, 3 }); @@ -161,7 +159,7 @@ MeshPtr GeometryHandler::createQuadMesh(const Vector2& uvMin, const Vector2& uvM quadMesh->addStream(quadPositions); quadMesh->addStream(quadTexCoords); quadMesh->addPartition(quadIndices); - + return quadMesh; } diff --git a/source/MaterialXRender/GeometryHandler.h b/source/MaterialXRender/GeometryHandler.h index 0022487602..5dfc561e0e 100644 --- a/source/MaterialXRender/GeometryHandler.h +++ b/source/MaterialXRender/GeometryHandler.h @@ -121,7 +121,7 @@ class MX_RENDER_API GeometryHandler static MeshPtr createQuadMesh(const Vector2& uvMin = Vector2(0.0f, 0.0f), const Vector2& uvMax = Vector2(1.0f, 1.0f), bool flipTexCoordsHorizontally = false); - + protected: // Recompute bounds for all stored geometry void computeBounds(); diff --git a/source/MaterialXRender/Harmonics.cpp b/source/MaterialXRender/Harmonics.cpp index daf6a59d10..3d5c9d0a1d 100644 --- a/source/MaterialXRender/Harmonics.cpp +++ b/source/MaterialXRender/Harmonics.cpp @@ -9,7 +9,8 @@ MATERIALX_NAMESPACE_BEGIN -namespace { +namespace +{ const double PI = std::acos(-1.0); diff --git a/source/MaterialXRender/Harmonics.h b/source/MaterialXRender/Harmonics.h index 10d5f81e49..f51991361a 100644 --- a/source/MaterialXRender/Harmonics.h +++ b/source/MaterialXRender/Harmonics.h @@ -27,7 +27,8 @@ template class ShCoeffs public: ShCoeffs() = default; - explicit ShCoeffs(const std::array& arr) : _arr(arr) { } + explicit ShCoeffs(const std::array& arr) : + _arr(arr) { } /// @name Comparison Operators /// @{ diff --git a/source/MaterialXRender/ImageHandler.cpp b/source/MaterialXRender/ImageHandler.cpp index d54a18fedd..2d56207f32 100644 --- a/source/MaterialXRender/ImageHandler.cpp +++ b/source/MaterialXRender/ImageHandler.cpp @@ -306,12 +306,11 @@ void ImageSamplingProperties::setProperties(const string& fileNameUniform, bool ImageSamplingProperties::operator==(const ImageSamplingProperties& r) const { - return - (enableMipmaps == r.enableMipmaps && - uaddressMode == r.uaddressMode && - vaddressMode == r.vaddressMode && - filterType == r.filterType && - defaultColor == r.defaultColor) ; + return (enableMipmaps == r.enableMipmaps && + uaddressMode == r.uaddressMode && + vaddressMode == r.vaddressMode && + filterType == r.filterType && + defaultColor == r.defaultColor); } MATERIALX_NAMESPACE_END diff --git a/source/MaterialXRender/ImageHandler.h b/source/MaterialXRender/ImageHandler.h index fafc021857..e8eaf99b2f 100644 --- a/source/MaterialXRender/ImageHandler.h +++ b/source/MaterialXRender/ImageHandler.h @@ -35,7 +35,7 @@ using ImageHandlerPtr = std::shared_ptr; using ImageLoaderPtr = std::shared_ptr; /// Map from strings to vectors of image loaders -using ImageLoaderMap = std::unordered_map< string, std::vector >; +using ImageLoaderMap = std::unordered_map>; /// @class ImageSamplingProperties /// Interface to describe sampling properties for images. @@ -48,16 +48,16 @@ class MX_RENDER_API ImageSamplingProperties /// @param uniformBlock Block containing sampler uniforms void setProperties(const string& fileNameUniform, const VariableBlock& uniformBlock); - + bool operator==(const ImageSamplingProperties& r) const; /// Address mode options. Matches enumerations allowed for image address /// modes, except UNSPECIFIED which indicates no explicit mode was defined. enum class AddressMode : int - { + { UNSPECIFIED = -1, CONSTANT = 0, - CLAMP = 1, + CLAMP = 1, PERIODIC = 2, MIRROR = 3 }; diff --git a/source/MaterialXRender/LightHandler.cpp b/source/MaterialXRender/LightHandler.cpp index cc96d979c7..c7d9311005 100644 --- a/source/MaterialXRender/LightHandler.cpp +++ b/source/MaterialXRender/LightHandler.cpp @@ -51,7 +51,7 @@ void LightHandler::findLights(DocumentPtr doc, vector& lights) void LightHandler::registerLights(DocumentPtr doc, const vector& lights, GenContext& context) { - // Clear context light user data which is set when bindLightShader() + // Clear context light user data which is set when bindLightShader() // is called. This is necessary in case the light types have already been // registered. HwShaderGenerator::unbindLightShaders(context); @@ -71,7 +71,7 @@ void LightHandler::registerLights(DocumentPtr doc, const vector& lights } // Make sure max light count is large enough - const unsigned int lightCount = (unsigned int)lights.size(); + const unsigned int lightCount = (unsigned int) lights.size(); if (lightCount > context.getOptions().hwMaxActiveLightSources) { context.getOptions().hwMaxActiveLightSources = lightCount; diff --git a/source/MaterialXRender/LightHandler.h b/source/MaterialXRender/LightHandler.h index 666edd34a1..852ccfa41d 100644 --- a/source/MaterialXRender/LightHandler.h +++ b/source/MaterialXRender/LightHandler.h @@ -48,7 +48,7 @@ class MX_RENDER_API LightHandler /// @name Global State /// @{ - + /// Set the light transform. void setLightTransform(const Matrix44& mat) { diff --git a/source/MaterialXRender/Mesh.cpp b/source/MaterialXRender/Mesh.cpp index 110829cd21..bfa7dedd13 100644 --- a/source/MaterialXRender/Mesh.cpp +++ b/source/MaterialXRender/Mesh.cpp @@ -18,7 +18,8 @@ const string MeshStream::BITANGENT_ATTRIBUTE("bitangent"); const string MeshStream::COLOR_ATTRIBUTE("color"); const string MeshStream::GEOMETRY_PROPERTY_ATTRIBUTE("geomprop"); -namespace { +namespace +{ const float MAX_FLOAT = std::numeric_limits::max(); const size_t FACE_VERTEX_COUNT = 3; @@ -266,7 +267,7 @@ void Mesh::splitByUdims() // MeshStream methods // -void MeshStream::transform(const Matrix44 &matrix) +void MeshStream::transform(const Matrix44& matrix) { unsigned int stride = getStride(); size_t numElements = _data.size() / getStride(); @@ -274,17 +275,17 @@ void MeshStream::transform(const Matrix44 &matrix) getType() == MeshStream::TEXCOORD_ATTRIBUTE || getType() == MeshStream::GEOMETRY_PROPERTY_ATTRIBUTE) { - for (size_t i=0; i diff --git a/source/MaterialXRender/OiioImageLoader.h b/source/MaterialXRender/OiioImageLoader.h index 6619c85bb2..38781dad9e 100644 --- a/source/MaterialXRender/OiioImageLoader.h +++ b/source/MaterialXRender/OiioImageLoader.h @@ -7,7 +7,7 @@ #define MATERIALX_OIIOIMAGELOADER_H /// @file -/// Image loader wrapper using OpenImageIO +/// Image loader wrapper using OpenImageIO #include @@ -21,7 +21,7 @@ using OiioImageLoaderPtr = std::shared_ptr; class MX_RENDER_API OiioImageLoader : public ImageLoader { public: - OiioImageLoader() + OiioImageLoader() { // Set all extensions supported by OpenImageIO _extensions.insert(BMP_EXTENSION); @@ -40,7 +40,7 @@ class MX_RENDER_API OiioImageLoader : public ImageLoader _extensions.insert(TXT_EXTENSION); _extensions.insert(TXR_EXTENSION); } - virtual ~OiioImageLoader() { } + virtual ~OiioImageLoader() { } /// Create a new OpenImageIO image loader static OiioImageLoaderPtr create() { return std::make_shared(); } diff --git a/source/MaterialXRender/ShaderMaterial.cpp b/source/MaterialXRender/ShaderMaterial.cpp index d51efa54af..4e8ccc491f 100644 --- a/source/MaterialXRender/ShaderMaterial.cpp +++ b/source/MaterialXRender/ShaderMaterial.cpp @@ -8,8 +8,8 @@ MATERIALX_NAMESPACE_BEGIN -ShaderMaterial::ShaderMaterial() : _hasTransparency(false) {} -ShaderMaterial::~ShaderMaterial() {} +ShaderMaterial::ShaderMaterial() : _hasTransparency(false) { } +ShaderMaterial::~ShaderMaterial() { } void ShaderMaterial::setDocument(DocumentPtr doc) { @@ -62,9 +62,9 @@ bool ShaderMaterial::hasTransparency() const } bool ShaderMaterial::generateEnvironmentShader(GenContext& context, - const FilePath& filename, - DocumentPtr stdLib, - const FilePath& imagePath) + const FilePath& filename, + DocumentPtr stdLib, + const FilePath& imagePath) { // Read in the environment nodegraph. DocumentPtr doc = createDocument(); diff --git a/source/MaterialXRender/ShaderMaterial.h b/source/MaterialXRender/ShaderMaterial.h index cf500463e4..f29b6f763c 100644 --- a/source/MaterialXRender/ShaderMaterial.h +++ b/source/MaterialXRender/ShaderMaterial.h @@ -74,7 +74,7 @@ class MX_RENDER_API ShaderMaterial /// Generate a shader from our currently stored element and /// the given generator context. virtual bool generateShader(GenContext& context) = 0; - + /// Copies shader and API specific generated program from ShaderMaterial to this one. virtual void copyShader(MaterialPtr ShaderMaterial) = 0; @@ -86,7 +86,7 @@ class MX_RENDER_API ShaderMaterial const FilePath& filename, DocumentPtr stdLib, const FilePath& imagePath); - + /// Return the underlying hardware shader. ShaderPtr getShader() const; diff --git a/source/MaterialXRender/ShaderRenderer.h b/source/MaterialXRender/ShaderRenderer.h index c1cfbecfa0..829a0252c1 100644 --- a/source/MaterialXRender/ShaderRenderer.h +++ b/source/MaterialXRender/ShaderRenderer.h @@ -34,7 +34,7 @@ class MX_RENDER_API ShaderRenderer enum class MatrixConvention { OpenGL = 0, - Metal = 1 + Metal = 1 }; /// A map with name and source code for each shader stage. using StageMap = StringMap; @@ -133,7 +133,7 @@ class MX_RENDER_API ShaderRenderer protected: ShaderRenderer(unsigned int width, unsigned int height, Image::BaseType baseType, - MatrixConvention matrixConvention = MatrixConvention::OpenGL); + MatrixConvention matrixConvention = MatrixConvention::OpenGL); protected: unsigned int _width; @@ -167,7 +167,7 @@ class MX_RENDER_API ExceptionRenderError : public Exception { } - ExceptionRenderError& operator=(const ExceptionRenderError& e) + ExceptionRenderError& operator=(const ExceptionRenderError& e) { Exception::operator=(e); _errorLog = e._errorLog; diff --git a/source/MaterialXRender/StbImageLoader.cpp b/source/MaterialXRender/StbImageLoader.cpp index d8747b75ad..b367bf741c 100644 --- a/source/MaterialXRender/StbImageLoader.cpp +++ b/source/MaterialXRender/StbImageLoader.cpp @@ -7,9 +7,9 @@ #if defined(_MSC_VER) #pragma warning(push) - #pragma warning(disable: 4100) - #pragma warning(disable: 4505) - #pragma warning(disable: 4996) + #pragma warning(disable : 4100) + #pragma warning(disable : 4505) + #pragma warning(disable : 4996) #endif #define STB_IMAGE_IMPLEMENTATION @@ -96,7 +96,7 @@ ImagePtr StbImageLoader::loadImage(const FilePath& filePath) int height = 0; int channelCount = 0; Image::BaseType baseType = Image::BaseType::UINT8; - void *buffer = nullptr; + void* buffer = nullptr; // Select standard or float reader based on file extension. string extension = filePath.getExtension(); diff --git a/source/MaterialXRender/StbImageLoader.h b/source/MaterialXRender/StbImageLoader.h index dabbb8ca9e..f9d91fbcc7 100644 --- a/source/MaterialXRender/StbImageLoader.h +++ b/source/MaterialXRender/StbImageLoader.h @@ -34,7 +34,7 @@ class MX_RENDER_API StbImageLoader : public ImageLoader _extensions.insert(PSD_EXTENSION); _extensions.insert(TGA_EXTENSION); } - virtual ~StbImageLoader() { } + virtual ~StbImageLoader() { } /// Create a new stb image loader static StbImageLoaderPtr create() { return std::make_shared(); } diff --git a/source/MaterialXRender/TextureBaker.h b/source/MaterialXRender/TextureBaker.h index 54b1016451..656bb63c1d 100644 --- a/source/MaterialXRender/TextureBaker.h +++ b/source/MaterialXRender/TextureBaker.h @@ -27,7 +27,7 @@ using BakedDocumentVec = std::vector>; /// A helper class for baking procedural material content to textures. /// TODO: Add support for graphs containing geometric nodes such as position /// and normal. -template +template class TextureBaker : public Renderer { public: @@ -112,7 +112,7 @@ class TextureBaker : public Renderer /// Set the name of the baked graph element. void setBakedGraphName(const string& name) { - _bakedGraphName= name; + _bakedGraphName = name; } /// Return the name of the baked graph element. @@ -218,13 +218,13 @@ class TextureBaker : public Renderer void optimizeBakedTextures(NodePtr shader); /// Bake material to document in memory and write baked textures to disk. - DocumentPtr bakeMaterialToDoc(DocumentPtr doc, const FileSearchPath& searchPath, const string& materialPath, + DocumentPtr bakeMaterialToDoc(DocumentPtr doc, const FileSearchPath& searchPath, const string& materialPath, const StringVec& udimSet, std::string& documentName); /// Bake materials in the given document and write them to disk. If multiple documents are written, /// then the given output filename will be used as a template. void bakeAllMaterials(DocumentPtr doc, const FileSearchPath& searchPath, const FilePath& outputFileName); - + /// Set whether to write a separate document per material when calling bakeAllMaterials. /// By default separate documents are written. void writeDocumentPerMaterial(bool value) @@ -295,7 +295,7 @@ class TextureBaker : public Renderer StringMap _bakedInputMap; std::unordered_map _worldSpaceNodes; - + bool _flipSavedImage; bool _writeDocumentPerMaterial; diff --git a/source/MaterialXRender/TextureBaker.inl b/source/MaterialXRender/TextureBaker.inl index bcc9401210..65759ed998 100644 --- a/source/MaterialXRender/TextureBaker.inl +++ b/source/MaterialXRender/TextureBaker.inl @@ -13,7 +13,8 @@ MATERIALX_NAMESPACE_BEGIN -namespace { +namespace +{ const string SRGB_TEXTURE = "srgb_texture"; const string LIN_REC709 = "lin_rec709"; @@ -23,7 +24,7 @@ const string DEFAULT_UDIM_PREFIX = "_"; } // anonymous namespace -template +template string TextureBaker::getValueStringFromColor(const Color4& color, const string& type) { if (type == "color4" || type == "vector4") @@ -45,7 +46,7 @@ string TextureBaker::getValueStringFromColor(const Color4& return EMPTY_STRING; } -template +template TextureBaker::TextureBaker(unsigned int width, unsigned int height, Image::BaseType baseType, bool flipSavedImage) : Renderer(width, height, baseType), _distanceUnit("meter"), @@ -97,7 +98,7 @@ TextureBaker::TextureBaker(unsigned int width, unsigned int _frameCaptureImage->createResourceBuffer(); } -template +template size_t TextureBaker::findVarInTemplate(const string& filename, const string& var, size_t start) { size_t i = filename.find(var, start); @@ -112,17 +113,15 @@ size_t TextureBaker::findVarInTemplate(const string& filena return i; } -template +template FilePath TextureBaker::generateTextureFilename(const StringMap& filenameTemplateMap) { string bakedImageName = _textureFilenameTemplate; for (auto& pair : filenameTemplateMap) { - string replacement = (_texTemplateOverrides.count(pair.first)) ? - _texTemplateOverrides[pair.first] : pair.second; - replacement = (filenameTemplateMap.at("$UDIM").empty() && pair.first == "$UDIMPREFIX") ? - EMPTY_STRING : replacement; + string replacement = (_texTemplateOverrides.count(pair.first)) ? _texTemplateOverrides[pair.first] : pair.second; + replacement = (filenameTemplateMap.at("$UDIM").empty() && pair.first == "$UDIMPREFIX") ? EMPTY_STRING : replacement; for (size_t i = 0; (i = findVarInTemplate(bakedImageName, pair.first, i)) != string::npos; i++) { @@ -140,7 +139,7 @@ FilePath TextureBaker::generateTextureFilename(const String return _outputImagePath / bakedImageName; } -template +template StringMap TextureBaker::initializeFileTemplateMap(InputPtr input, NodePtr shader, const string& udim) { FilePath assetPath = FilePath(shader->getActiveSourceUri()); @@ -156,7 +155,7 @@ StringMap TextureBaker::initializeFileTemplateMap(InputPtr return filenameTemplateMap; } -template +template bool TextureBaker::writeBakedImage(const BakedImage& baked, ImagePtr image) { if (!Renderer::_imageHandler->saveImage(baked.filename, image, _flipSavedImage)) @@ -176,11 +175,11 @@ bool TextureBaker::writeBakedImage(const BakedImage& baked, return true; } -template +template void TextureBaker::bakeShaderInputs(NodePtr material, NodePtr shader, GenContext& context, const string& udim) { _material = material; - + if (!shader) { return; @@ -216,16 +215,16 @@ void TextureBaker::bakeShaderInputs(NodePtr material, NodeP Renderer::_imageHandler->clearImageCache(); } -template +template void TextureBaker::bakeGraphOutput(OutputPtr output, GenContext& context, const StringMap& filenameTemplateMap) { if (!output) { return; } - + bool encodeSrgb = _colorSpace == SRGB_TEXTURE && - (output->getType() == "color3" || output->getType() == "color4"); + (output->getType() == "color3" || output->getType() == "color4"); Renderer::getFramebuffer()->setEncodeSrgb(encodeSrgb); ShaderPtr shader = _generator->generate("BakingShader", output, context); @@ -258,7 +257,7 @@ void TextureBaker::bakeGraphOutput(OutputPtr output, GenCon } } -template +template void TextureBaker::optimizeBakedTextures(NodePtr shader) { if (!shader) @@ -320,7 +319,7 @@ void TextureBaker::optimizeBakedTextures(NodePtr shader) } } -template +template DocumentPtr TextureBaker::generateNewDocumentFromShader(NodePtr shader, const StringVec& udimSet) { if (!shader) @@ -359,7 +358,7 @@ DocumentPtr TextureBaker::generateNewDocumentFromShader(Nod // Optionally create a material node, connecting it to the new shader node. if (_material) { - string materialName = (_texTemplateOverrides.count("$MATERIAL"))? _texTemplateOverrides["$MATERIAL"] : _material->getName(); + string materialName = (_texTemplateOverrides.count("$MATERIAL")) ? _texTemplateOverrides["$MATERIAL"] : _material->getName(); NodePtr bakedMaterial = _bakedTextureDoc->addNode(_material->getCategory(), materialName + BAKED_POSTFIX, _material->getType()); for (auto sourceMaterialInput : _material->getInputs()) { @@ -483,9 +482,9 @@ DocumentPtr TextureBaker::generateNewDocumentFromShader(Nod return _bakedTextureDoc; } -template +template DocumentPtr TextureBaker::bakeMaterialToDoc(DocumentPtr doc, const FileSearchPath& searchPath, const string& materialPath, - const StringVec& udimSet, string& documentName) + const StringVec& udimSet, string& documentName) { if (_outputStream) { @@ -551,7 +550,7 @@ DocumentPtr TextureBaker::bakeMaterialToDoc(DocumentPtr doc return generateNewDocumentFromShader(shaderNode, udimSet); } -template +template void TextureBaker::bakeAllMaterials(DocumentPtr doc, const FileSearchPath& searchPath, const FilePath& outputFilename) { if (_outputImagePath.isEmpty()) @@ -593,31 +592,31 @@ void TextureBaker::bakeAllMaterials(DocumentPtr doc, const if (_writeDocumentPerMaterial) { - // Write documents in memory to disk. - size_t bakeCount = bakedDocuments.size(); - for (size_t i = 0; i < bakeCount; i++) - { - if (bakedDocuments[i].second) + // Write documents in memory to disk. + size_t bakeCount = bakedDocuments.size(); + for (size_t i = 0; i < bakeCount; i++) { - FilePath writeFilename = outputFilename; - - // Add additional filename decorations if there are multiple documents. - if (bakedDocuments.size() > 1) + if (bakedDocuments[i].second) { - const string extension = writeFilename.getExtension(); - writeFilename.removeExtension(); - string filenameSeparator = writeFilename.isDirectory()? EMPTY_STRING : "_"; - writeFilename = FilePath(writeFilename.asString() + filenameSeparator + bakedDocuments[i].first + "." + extension); - } + FilePath writeFilename = outputFilename; - writeToXmlFile(bakedDocuments[i].second, writeFilename); - if (_outputStream) - { - *_outputStream << "Wrote baked document: " << writeFilename.asString() << std::endl; + // Add additional filename decorations if there are multiple documents. + if (bakedDocuments.size() > 1) + { + const string extension = writeFilename.getExtension(); + writeFilename.removeExtension(); + string filenameSeparator = writeFilename.isDirectory() ? EMPTY_STRING : "_"; + writeFilename = FilePath(writeFilename.asString() + filenameSeparator + bakedDocuments[i].first + "." + extension); + } + + writeToXmlFile(bakedDocuments[i].second, writeFilename); + if (_outputStream) + { + *_outputStream << "Wrote baked document: " << writeFilename.asString() << std::endl; + } } } } -} else if (_bakedTextureDoc) { writeToXmlFile(_bakedTextureDoc, outputFilename); @@ -628,7 +627,7 @@ void TextureBaker::bakeAllMaterials(DocumentPtr doc, const } } -template +template void TextureBaker::setupUnitSystem(DocumentPtr unitDefinitions) { UnitTypeDefPtr distanceTypeDef = unitDefinitions ? unitDefinitions->getUnitTypeDef("distance") : nullptr; diff --git a/source/MaterialXRender/TinyObjLoader.cpp b/source/MaterialXRender/TinyObjLoader.cpp index 324a1df3e7..b01af1ebf9 100644 --- a/source/MaterialXRender/TinyObjLoader.cpp +++ b/source/MaterialXRender/TinyObjLoader.cpp @@ -23,7 +23,8 @@ MATERIALX_NAMESPACE_BEGIN -namespace { +namespace +{ const float MAX_FLOAT = std::numeric_limits::max(); const size_t FACE_VERTEX_COUNT = 3; @@ -32,9 +33,10 @@ class VertexVector : public VectorN { public: using VectorN::VectorN; - VertexVector(const Vector3& p, const Vector3& n, const Vector2& t) : VectorN(Uninit{}) + VertexVector(const Vector3& p, const Vector3& n, const Vector2& t) : + VectorN(Uninit{}) { - _arr = {p[0], p[1], p[2], n[0], n[1], n[2], t[0], t[1]}; + _arr = { p[0], p[1], p[2], n[0], n[1], n[2], t[0], t[1] }; } }; diff --git a/source/MaterialXRender/TinyObjLoader.h b/source/MaterialXRender/TinyObjLoader.h index 8cfb80762b..e3934f9e41 100644 --- a/source/MaterialXRender/TinyObjLoader.h +++ b/source/MaterialXRender/TinyObjLoader.h @@ -6,7 +6,7 @@ #ifndef MATERIALX_TINYOBJLOADER_H #define MATERIALX_TINYOBJLOADER_H -/// @file +/// @file /// OBJ geometry format loader using the TinyObj library #include diff --git a/source/MaterialXRender/Types.h b/source/MaterialXRender/Types.h index 6af59b9122..b3c15c9f8b 100644 --- a/source/MaterialXRender/Types.h +++ b/source/MaterialXRender/Types.h @@ -65,7 +65,7 @@ class MX_RENDER_API Vector3d : public VectorN Vector3d() = default; Vector3d(double x, double y, double z) : VectorN(Uninit{}) { - _arr = {x, y, z}; + _arr = { x, y, z }; } }; @@ -78,7 +78,7 @@ class MX_RENDER_API Vector4d : public VectorN Vector4d() = default; Vector4d(double x, double y, double z, double w) : VectorN(Uninit{}) { - _arr = {x, y, z, w}; + _arr = { x, y, z, w }; } }; @@ -91,7 +91,7 @@ class MX_RENDER_API Color3d : public VectorN Color3d() = default; Color3d(double r, double g, double b) : VectorN(Uninit{}) { - _arr = {r, g, b}; + _arr = { r, g, b }; } }; diff --git a/source/MaterialXRender/Util.h b/source/MaterialXRender/Util.h index 10799cfd33..922c06e529 100644 --- a/source/MaterialXRender/Util.h +++ b/source/MaterialXRender/Util.h @@ -31,28 +31,28 @@ MX_RENDER_API ShaderPtr createShader(const string& shaderName, GenContext& conte /// Create a shader with a constant color output, using the given standard libraries /// for code generation. MX_RENDER_API ShaderPtr createConstantShader(GenContext& context, - DocumentPtr stdLib, - const string& shaderName, - const Color3& color); + DocumentPtr stdLib, + const string& shaderName, + const Color3& color); /// Create a shader with depth value output, using the given standard libraries /// for code generation. MX_RENDER_API ShaderPtr createDepthShader(GenContext& context, - DocumentPtr stdLib, - const string& shaderName); + DocumentPtr stdLib, + const string& shaderName); /// Create a shader that generates a look-up table for directional albedo, using /// the given standard libraries for code generation. MX_RENDER_API ShaderPtr createAlbedoTableShader(GenContext& context, - DocumentPtr stdLib, - const string& shaderName); + DocumentPtr stdLib, + const string& shaderName); /// Create a blur shader, using the given standard libraries for code generation. MX_RENDER_API ShaderPtr createBlurShader(GenContext& context, - DocumentPtr stdLib, - const string& shaderName, - const string& filterType, - float filterSize); + DocumentPtr stdLib, + const string& shaderName, + const string& filterType, + float filterSize); /// @} /// @name User Interface Utilities diff --git a/source/MaterialXRenderGlsl/GLFramebuffer.cpp b/source/MaterialXRenderGlsl/GLFramebuffer.cpp index bb8e567c58..9516e9ad43 100644 --- a/source/MaterialXRenderGlsl/GLFramebuffer.cpp +++ b/source/MaterialXRenderGlsl/GLFramebuffer.cpp @@ -75,33 +75,33 @@ GLFramebuffer::GLFramebuffer(unsigned int width, unsigned int height, unsigned i string errorMessage; switch (status) { - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - errorMessage = "GL_FRAMEBUFFER_UNSUPPORTED"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; - break; - case GL_FRAMEBUFFER_UNDEFINED: - errorMessage = "GL_FRAMEBUFFER_UNDEFINED"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: - errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"; - break; - default: - errorMessage = std::to_string(status); - break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + errorMessage = "GL_FRAMEBUFFER_UNSUPPORTED"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; + break; + case GL_FRAMEBUFFER_UNDEFINED: + errorMessage = "GL_FRAMEBUFFER_UNDEFINED"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: + errorMessage = "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"; + break; + default: + errorMessage = std::to_string(status); + break; } throw ExceptionRenderError("Frame buffer object setup failed: " + errorMessage); diff --git a/source/MaterialXRenderGlsl/GLTextureHandler.h b/source/MaterialXRenderGlsl/GLTextureHandler.h index 4485ab98eb..942d6dc446 100644 --- a/source/MaterialXRenderGlsl/GLTextureHandler.h +++ b/source/MaterialXRenderGlsl/GLTextureHandler.h @@ -33,7 +33,7 @@ class MX_RENDERGLSL_API GLTextureHandler : public ImageHandler /// will fail if there are not enough available image units to bind to. bool bindImage(ImagePtr image, const ImageSamplingProperties& samplingProperties) override; - /// Unbind an image. + /// Unbind an image. bool unbindImage(ImagePtr image) override; /// Create rendering resources for the given image. diff --git a/source/MaterialXRenderGlsl/GlslMaterial.cpp b/source/MaterialXRenderGlsl/GlslMaterial.cpp index ce4582d44f..84668d2d0a 100644 --- a/source/MaterialXRenderGlsl/GlslMaterial.cpp +++ b/source/MaterialXRenderGlsl/GlslMaterial.cpp @@ -38,7 +38,7 @@ bool GlslMaterial::loadSource(const FilePath& vertexShaderFile, const FilePath& } // TODO: - // Here we set new source code on the _glProgram without rebuilding + // Here we set new source code on the _glProgram without rebuilding // the _hwShader instance. So the _hwShader is not in sync with the // _glProgram after this operation. _glProgram = GlslProgram::create(); diff --git a/source/MaterialXRenderGlsl/GlslMaterial.h b/source/MaterialXRenderGlsl/GlslMaterial.h index 1e3d0f7f3b..1ae945867a 100644 --- a/source/MaterialXRenderGlsl/GlslMaterial.h +++ b/source/MaterialXRenderGlsl/GlslMaterial.h @@ -24,7 +24,8 @@ using GlslMaterialPtr = std::shared_ptr; class MX_RENDERGLSL_API GlslMaterial : public ShaderMaterial { public: - GlslMaterial() : ShaderMaterial() + GlslMaterial() : + ShaderMaterial() { } ~GlslMaterial() { } @@ -45,7 +46,7 @@ class MX_RENDERGLSL_API GlslMaterial : public ShaderMaterial /// Generate a shader from the given hardware shader. bool generateShader(ShaderPtr hwShader) override; - + /// Copy shader from one material to this one void copyShader(MaterialPtr material) override { diff --git a/source/MaterialXRenderGlsl/GlslProgram.cpp b/source/MaterialXRenderGlsl/GlslProgram.cpp index 900cac0ef1..4497019e91 100644 --- a/source/MaterialXRenderGlsl/GlslProgram.cpp +++ b/source/MaterialXRenderGlsl/GlslProgram.cpp @@ -59,7 +59,7 @@ void GlslProgram::setStages(ShaderPtr shader) // Extract out the shader code per stage _shader = shader; - for (size_t i =0; inumStages(); ++i) + for (size_t i = 0; i < shader->numStages(); ++i) { const ShaderStage& stage = shader->getStage(i); addStage(stage.getName(), stage.getSourceCode()); @@ -101,7 +101,7 @@ void GlslProgram::build() // Compile vertex shader, if any GLuint vertexShaderId = UNDEFINED_OPENGL_RESOURCE_ID; - const string &vertexShaderSource = _stages[Stage::VERTEX]; + const string& vertexShaderSource = _stages[Stage::VERTEX]; if (!vertexShaderSource.empty()) { vertexShaderId = glCreateShader(GL_VERTEX_SHADER); @@ -138,7 +138,7 @@ void GlslProgram::build() fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); // Compile fragment shader - const char *fragmentChar = fragmentShaderSource.c_str(); + const char* fragmentChar = fragmentShaderSource.c_str(); glShaderSource(fragmentShaderId, 1, &fragmentChar, nullptr); glCompileShader(fragmentShaderId); @@ -324,7 +324,7 @@ void GlslProgram::bindPartition(MeshPartitionPtr part) void GlslProgram::bindMesh(MeshPtr mesh) { - _enabledStreamLocations.clear(); + _enabledStreamLocations.clear(); if (_programId == UNDEFINED_OPENGL_RESOURCE_ID) { @@ -547,7 +547,7 @@ void GlslProgram::bindTextures(ImageHandlerPtr imageHandler) // Always bind a texture unless it is a lighting texture. // Lighting textures are handled in the bindLighting() call. - // If no texture can be loaded then the default color defined in + // If no texture can be loaded then the default color defined in // "samplingProperties" will be used to create a fallback texture. if (fileName != HW::ENV_RADIANCE && fileName != HW::ENV_IRRADIANCE) @@ -903,7 +903,7 @@ const GlslProgram::InputMap& GlslProgram::updateUniformsList() // Process constants const VariableBlock& constants = ps.getConstantBlock(); - for (size_t i=0; i< constants.size(); ++i) + for (size_t i = 0; i < constants.size(); ++i) { const ShaderPort* v = constants[i]; // There is no way to match with an unnamed variable @@ -1197,9 +1197,9 @@ void GlslProgram::printUniforms(std::ostream& outputStream) string colorspace = input.second->colorspace; bool isConstant = input.second->isConstant; outputStream << "Program Uniform: \"" << input.first - << "\". Location:" << location - << ". GLtype: " << std::hex << gltype - << ". Size: " << std::dec << size; + << "\". Location:" << location + << ". GLtype: " << std::hex << gltype + << ". Size: " << std::dec << size; if (!type.empty()) outputStream << ". TypeString: \"" << type << "\""; if (!value.empty()) @@ -1217,7 +1217,6 @@ void GlslProgram::printUniforms(std::ostream& outputStream) } } - void GlslProgram::printAttributes(std::ostream& outputStream) { updateAttributesList(); @@ -1229,9 +1228,9 @@ void GlslProgram::printAttributes(std::ostream& outputStream) string type = input.second->typeString; string value = input.second->value ? input.second->value->getValueString() : EMPTY_STRING; outputStream << "Program Attribute: \"" << input.first - << "\". Location:" << location - << ". GLtype: " << std::hex << gltype - << ". Size: " << std::dec << size; + << "\". Location:" << location + << ". GLtype: " << std::hex << gltype + << ". Size: " << std::dec << size; if (!type.empty()) outputStream << ". TypeString: \"" << type << "\""; if (!value.empty()) diff --git a/source/MaterialXRenderGlsl/GlslProgram.h b/source/MaterialXRenderGlsl/GlslProgram.h index 2538c63fcb..e90853eedb 100644 --- a/source/MaterialXRenderGlsl/GlslProgram.h +++ b/source/MaterialXRenderGlsl/GlslProgram.h @@ -109,7 +109,7 @@ class MX_RENDERGLSL_API GlslProgram string path; /// Unit string unit; - /// Colorspace + /// Colorspace string colorspace; /// Program input constructor diff --git a/source/MaterialXRenderGlsl/GlslRenderer.h b/source/MaterialXRenderGlsl/GlslRenderer.h index 9ea121aec9..bdf16b44b3 100644 --- a/source/MaterialXRenderGlsl/GlslRenderer.h +++ b/source/MaterialXRenderGlsl/GlslRenderer.h @@ -50,7 +50,7 @@ class MX_RENDERGLSL_API GlslRenderer : public ShaderRenderer { return GLTextureHandler::create(imageLoader); } - + /// Destructor virtual ~GlslRenderer() { } diff --git a/source/MaterialXRenderGlsl/TextureBaker.h b/source/MaterialXRenderGlsl/TextureBaker.h index be1f713cd6..c084b00a1a 100644 --- a/source/MaterialXRenderGlsl/TextureBaker.h +++ b/source/MaterialXRenderGlsl/TextureBaker.h @@ -37,7 +37,7 @@ class MX_RENDERGLSL_API TextureBakerGlsl : public TextureBaker; /// @class SimpleWindow /// A platform-independent window class. -/// +/// /// Plaform-specific resources are encapsulated by a WindowWrapper instance. class MX_RENDERHW_API SimpleWindow { @@ -30,7 +30,7 @@ class MX_RENDERHW_API SimpleWindow virtual ~SimpleWindow(); /// Window initialization - bool initialize(const char* title, unsigned int width, unsigned int height, void *applicationShell); + bool initialize(const char* title, unsigned int width, unsigned int height, void* applicationShell); /// Return our platform-specific resource wrapper WindowWrapperPtr getWindowWrapper() diff --git a/source/MaterialXRenderHw/SimpleWindowLinux.cpp b/source/MaterialXRenderHw/SimpleWindowLinux.cpp index 23779bd92b..5a14a51aba 100644 --- a/source/MaterialXRenderHw/SimpleWindowLinux.cpp +++ b/source/MaterialXRenderHw/SimpleWindowLinux.cpp @@ -26,7 +26,7 @@ SimpleWindow::SimpleWindow() : bool SimpleWindow::initialize(const char* title, unsigned int width, unsigned int height, - void *applicationShell) + void* applicationShell) { int n = 0; @@ -49,13 +49,13 @@ bool SimpleWindow::initialize(const char* title, else { // Reuse existing application shell; - shell = (Widget)applicationShell; + shell = (Widget) applicationShell; } if (!shell) { _id = 0; - return false;; + return false; } Arg args[6]; diff --git a/source/MaterialXRenderHw/SimpleWindowWindows.cpp b/source/MaterialXRenderHw/SimpleWindowWindows.cpp index de5cf48fc1..070950e682 100644 --- a/source/MaterialXRenderHw/SimpleWindowWindows.cpp +++ b/source/MaterialXRenderHw/SimpleWindowWindows.cpp @@ -30,19 +30,19 @@ LRESULT CALLBACK NoOpProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { - case WM_CLOSE: - case WM_DESTROY: - break; - default: - return DefWindowProc(hWnd, msg, wParam, lParam); - break; + case WM_CLOSE: + case WM_DESTROY: + break; + default: + return DefWindowProc(hWnd, msg, wParam, lParam); + break; } return 0; } bool SimpleWindow::initialize(const char* title, unsigned int width, unsigned int height, - void * /*applicationShell*/) + void* /*applicationShell*/) { HINSTANCE hInstance = GetModuleHandle(NULL); @@ -50,14 +50,14 @@ bool SimpleWindow::initialize(const char* title, // WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = (WNDPROC)NoOpProc; + wc.lpfnWndProc = (WNDPROC) NoOpProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; // Set the instance to this application wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; // No background required - wc.lpszMenuName = NULL; // No menu required + wc.lpszMenuName = NULL; // No menu required wc.lpszClassName = _windowClassName; if (!RegisterClass(&wc)) @@ -73,10 +73,10 @@ bool SimpleWindow::initialize(const char* title, // Set the rectangle of the client area. RECT WindowRect; - WindowRect.left = (long)0; - WindowRect.top = (long)0; - WindowRect.right = (long)width; - WindowRect.bottom = (long)height; + WindowRect.left = (long) 0; + WindowRect.top = (long) 0; + WindowRect.right = (long) width; + WindowRect.bottom = (long) height; // Calculate the exact window size (including border) so that the // client area has the desired dimensions. @@ -86,13 +86,13 @@ bool SimpleWindow::initialize(const char* title, // Attempt to create the window. HWND hWnd = CreateWindowEx(dwExStyle, _windowClassName, title, dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, - 0, 0, // Window position - WindowRect.right - WindowRect.left, // Window width (including borders) - WindowRect.bottom - WindowRect.top, // Window height (including borders/title bar) - NULL, // No parent window - NULL, // No menu - hInstance, // Instance - NULL); // Don't pass anything To WM_CREATE + 0, 0, // Window position + WindowRect.right - WindowRect.left, // Window width (including borders) + WindowRect.bottom - WindowRect.top, // Window height (including borders/title bar) + NULL, // No parent window + NULL, // No menu + hInstance, // Instance + NULL); // Don't pass anything To WM_CREATE if (!hWnd) { diff --git a/source/MaterialXView/Editor.cpp b/source/MaterialXView/Editor.cpp index ff91f0f129..090937d6e5 100644 --- a/source/MaterialXView/Editor.cpp +++ b/source/MaterialXView/Editor.cpp @@ -18,14 +18,13 @@ namespace class EditorColorPicker : public ng::ColorPicker { public: - EditorColorPicker(ng::Widget *parent, const ng::Color& color) : + EditorColorPicker(ng::Widget* parent, const ng::Color& color) : ng::ColorPicker(parent, color) { - ng::Popup *popup = this->popup(); - ng::Widget *floatGroup = new ng::Widget(popup); - auto layout = - new ng::GridLayout(ng::Orientation::Horizontal, 2, - ng::Alignment::Middle, 2, 2); + ng::Popup* popup = this->popup(); + ng::Widget* floatGroup = new ng::Widget(popup); + auto layout = new ng::GridLayout(ng::Orientation::Horizontal, 2, + ng::Alignment::Middle, 2, 2); layout->set_col_alignment({ ng::Alignment::Fill, ng::Alignment::Fill }); layout->set_spacing(1, 1); floatGroup->set_layout(layout); @@ -51,7 +50,8 @@ class EditorColorPicker : public ng::ColorPicker // The color wheel does not handle alpha properly, so only // overwrite RGB in the callback. - m_callback = [this](const ng::Color &value) { + m_callback = [this](const ng::Color& value) + { _colorWidgets[0]->set_value(value[0]); _colorWidgets[1]->set_value(value[1]); _colorWidgets[2]->set_value(value[2]); @@ -110,7 +110,7 @@ void PropertyEditor::create(Viewer& parent) _window->set_position(previousPosition); _window->set_visible(_visible); - ng::VScrollPanel *scroll_panel = new ng::VScrollPanel(_window); + ng::VScrollPanel* scroll_panel = new ng::VScrollPanel(_window); scroll_panel->set_fixed_height(300); _container = new ng::Widget(scroll_panel); _container->set_layout(new ng::GroupLayout(1, 1, 1, 1)); @@ -122,7 +122,7 @@ void PropertyEditor::create(Viewer& parent) // 3 cell layout for label plus widget value pair. _gridLayout3 = new ng::GridLayout(ng::Orientation::Horizontal, 3, - ng::Alignment::Minimum, 2, 2); + ng::Alignment::Minimum, 2, 2); _gridLayout3->set_col_alignment({ ng::Alignment::Minimum, ng::Alignment::Maximum, ng::Alignment::Maximum }); } @@ -150,7 +150,7 @@ void PropertyEditor::addItemToForm(const mx::UIPropertyItem& item, const std::st { ng::Widget* twoColumns = new ng::Widget(container); twoColumns->set_layout(_gridLayout2); - ng::Label* groupLabel = new ng::Label(twoColumns, group); + ng::Label* groupLabel = new ng::Label(twoColumns, group); groupLabel->set_font_size(20); groupLabel->set_font("sans-bold"); new ng::Label(twoColumns, ""); @@ -163,7 +163,7 @@ void PropertyEditor::addItemToForm(const mx::UIPropertyItem& item, const std::st auto indexInEnumeration = [&value, &enumValues, &enumeration]() { size_t index = 0; - for (auto& enumValue: enumValues) + for (auto& enumValue : enumValues) { if (value->getValueString() == enumValue->getValueString()) { @@ -172,7 +172,7 @@ void PropertyEditor::addItemToForm(const mx::UIPropertyItem& item, const std::st index++; } index = 0; - for (auto& enumName: enumeration) + for (auto& enumName : enumeration) { if (value->getValueString() == enumName) { @@ -191,7 +191,7 @@ void PropertyEditor::addItemToForm(const mx::UIPropertyItem& item, const std::st twoColumns->set_layout(_gridLayout2); new ng::Label(twoColumns, label); - ng::ComboBox* comboBox = new ng::ComboBox(twoColumns, {""}); + ng::ComboBox* comboBox = new ng::ComboBox(twoColumns, { "" }); comboBox->set_enabled(editable); comboBox->set_items(enumeration); comboBox->set_selected_index(static_cast(valueIndex)); @@ -259,7 +259,7 @@ void PropertyEditor::addItemToForm(const mx::UIPropertyItem& item, const std::st mx::MaterialPtr material = viewer->getSelectedMaterial(); if (material) { - material->modifyUniform(path, mx::Value::createValue(value)); + material->modifyUniform(path, mx::Value::createValue(value)); } }); floatBox->set_fixed_size(ng::Vector2i(100, 20)); @@ -333,12 +333,12 @@ void PropertyEditor::addItemToForm(const mx::UIPropertyItem& item, const std::st { mx::Color3 v = value->asA(); ng::Color c(v[0], v[1], v[2], 1.0); - + new ng::Label(twoColumns, label); auto colorVar = new EditorColorPicker(twoColumns, c); colorVar->set_fixed_size({ 100, 20 }); colorVar->set_font_size(15); - colorVar->set_final_callback([path, viewer](const ng::Color &c) + colorVar->set_final_callback([path, viewer](const ng::Color& c) { mx::MaterialPtr material = viewer->getSelectedMaterial(); if (material) @@ -362,7 +362,7 @@ void PropertyEditor::addItemToForm(const mx::UIPropertyItem& item, const std::st auto colorVar = new EditorColorPicker(twoColumns, c); colorVar->set_fixed_size({ 100, 20 }); colorVar->set_font_size(15); - colorVar->set_final_callback([path, viewer](const ng::Color &c) + colorVar->set_final_callback([path, viewer](const ng::Color& c) { mx::MaterialPtr material = viewer->getSelectedMaterial(); if (material) @@ -583,10 +583,10 @@ void PropertyEditor::addItemToForm(const mx::UIPropertyItem& item, const std::st else { new ng::Label(twoColumns, label); - ng::TextBox* stringVar = new ng::TextBox(twoColumns, v); + ng::TextBox* stringVar = new ng::TextBox(twoColumns, v); stringVar->set_fixed_size({ 100, 20 }); stringVar->set_font_size(15); - stringVar->set_callback([path, viewer](const std::string &v) + stringVar->set_callback([path, viewer](const std::string& v) { mx::MaterialPtr material = viewer->getSelectedMaterial(); mx::ShaderPort* uniform = material ? material->findUniform(path) : nullptr; @@ -646,7 +646,7 @@ void PropertyEditor::updateContents(Viewer* viewer) mx::UIPropertyGroup groups; mx::UIPropertyGroup unnamedGroups; const std::string pathSeparator(":"); - mx::createUIPropertyGroups(elem->getDocument(), *publicUniforms, groups, unnamedGroups, pathSeparator); + mx::createUIPropertyGroups(elem->getDocument(), *publicUniforms, groups, unnamedGroups, pathSeparator); // First add items with named groups. std::string previousFolder; @@ -691,7 +691,7 @@ ng::FloatBox* createFloatWidget(ng::Widget* parent, const std::string& la { new ng::Label(parent, label); - ng::Slider *slider = new ng::Slider(parent); + ng::Slider* slider = new ng::Slider(parent); slider->set_value(value); ng::FloatBox* box = new ng::FloatBox(parent, value); @@ -732,7 +732,7 @@ ng::FloatBox* createFloatWidget(ng::Widget* parent, const std::string& la } } - slider->set_callback([box, callback](float value) + slider->set_callback([box, callback](float value) { box->set_value(value); callback(value); @@ -747,12 +747,12 @@ ng::FloatBox* createFloatWidget(ng::Widget* parent, const std::string& la } ng::IntBox* createIntWidget(ng::Widget* parent, const std::string& label, int value, - const mx::UIProperties* ui, std::function callback) + const mx::UIProperties* ui, std::function callback) { new ng::Label(parent, label); - ng::Slider *slider = new ng::Slider(parent); - slider->set_value((float)value); + ng::Slider* slider = new ng::Slider(parent); + slider->set_value((float) value); ng::IntBox* box = new ng::IntBox(parent, value); box->set_fixed_width(60); @@ -781,7 +781,7 @@ ng::IntBox* createIntWidget(ng::Widget* parent, const std::string& label, i } if (range.first != range.second) { - std::pair float_range((float)range.first, (float)range.second); + std::pair float_range((float) range.first, (float) range.second); slider->set_range(float_range); } if (ui->uiStep) @@ -794,12 +794,12 @@ ng::IntBox* createIntWidget(ng::Widget* parent, const std::string& label, i slider->set_callback([box, callback](float value) { - box->set_value((int)value); - callback((int)value); + box->set_value((int) value); + callback((int) value); }); box->set_callback([slider, callback](int value) { - slider->set_value((float)value); + slider->set_value((float) value); callback(value); }); diff --git a/source/MaterialXView/Editor.h b/source/MaterialXView/Editor.h index 8e74ca987d..b1fb4a3ade 100644 --- a/source/MaterialXView/Editor.h +++ b/source/MaterialXView/Editor.h @@ -19,7 +19,7 @@ namespace ng = nanogui; class Viewer; -class PropertyEditor +class PropertyEditor { public: PropertyEditor(); @@ -58,7 +58,7 @@ class PropertyEditor }; ng::FloatBox* createFloatWidget(ng::Widget* parent, const std::string& label, float value, - const mx::UIProperties*ui, std::function callback = nullptr); + const mx::UIProperties* ui, std::function callback = nullptr); ng::IntBox* createIntWidget(ng::Widget* parent, const std::string& label, int value, const mx::UIProperties* ui, std::function callback); diff --git a/source/MaterialXView/Main.cpp b/source/MaterialXView/Main.cpp index 99104f7fa2..c703e48883 100644 --- a/source/MaterialXView/Main.cpp +++ b/source/MaterialXView/Main.cpp @@ -13,40 +13,40 @@ NANOGUI_FORCE_DISCRETE_GPU(); -const std::string options = -" Options: \n" -" --material [FILENAME] Specify the filename of the MTLX document to be displayed in the viewer\n" -" --mesh [FILENAME] Specify the filename of the OBJ mesh to be displayed in the viewer\n" -" --meshRotation [VECTOR3] Specify the rotation of the displayed mesh as three comma-separated floats, representing rotations in degrees about the X, Y, and Z axes (defaults to 0,0,0)\n" -" --meshScale [FLOAT] Specify the uniform scale of the displayed mesh\n" -" --enableTurntable[BOOLEAN] Specify whether to enable turntable rendering of the scene\n" -" --turntableSteps [INTEGER] Specify the number of steps for a complete turntable rotation. Defaults to 360\n" -" --cameraPosition [VECTOR3] Specify the position of the camera as three comma-separated floats (defaults to 0,0,5)\n" -" --cameraTarget [VECTOR3] Specify the position of the camera target as three comma-separated floats (defaults to 0,0,0)\n" -" --cameraViewAngle [FLOAT] Specify the view angle of the camera, or zero for an orthographic projection (defaults to 45)\n" -" --cameraZoom [FLOAT] Specify the zoom factor for the camera, implemented as a mesh scale multiplier (defaults to 1)\n" -" --envRad [FILENAME] Specify the filename of the environment light to display, stored as HDR environment radiance in the latitude-longitude format\n" -" --envMethod [INTEGER] Specify the environment lighting method (0 = filtered importance sampling, 1 = prefiltered environment maps, defaults to 0)\n" -" --envSampleCount [INTEGER] Specify the environment sample count (defaults to 16)\n" -" --lightRotation [FLOAT] Specify the rotation in degrees of the lighting environment about the Y axis (defaults to 0)\n" -" --shadowMap [BOOLEAN] Specify whether shadow mapping is enabled (defaults to true)\n" -" --path [FILEPATH] Specify an additional data search path location (e.g. '/projects/MaterialX'). This absolute path will be queried when locating data libraries, XInclude references, and referenced images.\n" -" --library [FILEPATH] Specify an additional data library folder (e.g. 'vendorlib', 'studiolib'). This relative path will be appended to each location in the data search path when loading data libraries.\n" -" --screenWidth [INTEGER] Specify the width of the screen image in pixels (defaults to 1280)\n" -" --screenHeight [INTEGER] Specify the height of the screen image in pixels (defaults to 960)\n" -" --screenColor [VECTOR3] Specify the background color of the viewer as three comma-separated floats (defaults to 0.3,0.3,0.32)\n" -" --drawEnvironment [BOOLEAN] Specify whether to render the environment as the background (defaults to false)\n" -" --captureFilename [FILENAME] Specify the filename to which the first rendered frame should be written\n" -" --bakeWidth [INTEGER] Specify the target width for texture baking (defaults to maximum image width of the source document)\n" -" --bakeHeight [INTEGER] Specify the target height for texture baking (defaults to maximum image height of the source document)\n" -" --bakeFilename [STRING] Specify the output document filename for texture baking\n" -" --refresh [FLOAT] Specify the refresh period for the viewer in milliseconds (defaults to 50, set to -1 to disable)\n" -" --remap [TOKEN1:TOKEN2] Specify the remapping from one token to another when MaterialX document is loaded\n" -" --skip [NAME] Specify to skip elements matching the given name attribute\n" -" --terminator [STRING] Specify to enforce the given terminator string for file prefixes\n" -" --help Display the complete list of command-line options\n"; +const std::string options = + " Options: \n" + " --material [FILENAME] Specify the filename of the MTLX document to be displayed in the viewer\n" + " --mesh [FILENAME] Specify the filename of the OBJ mesh to be displayed in the viewer\n" + " --meshRotation [VECTOR3] Specify the rotation of the displayed mesh as three comma-separated floats, representing rotations in degrees about the X, Y, and Z axes (defaults to 0,0,0)\n" + " --meshScale [FLOAT] Specify the uniform scale of the displayed mesh\n" + " --enableTurntable[BOOLEAN] Specify whether to enable turntable rendering of the scene\n" + " --turntableSteps [INTEGER] Specify the number of steps for a complete turntable rotation. Defaults to 360\n" + " --cameraPosition [VECTOR3] Specify the position of the camera as three comma-separated floats (defaults to 0,0,5)\n" + " --cameraTarget [VECTOR3] Specify the position of the camera target as three comma-separated floats (defaults to 0,0,0)\n" + " --cameraViewAngle [FLOAT] Specify the view angle of the camera, or zero for an orthographic projection (defaults to 45)\n" + " --cameraZoom [FLOAT] Specify the zoom factor for the camera, implemented as a mesh scale multiplier (defaults to 1)\n" + " --envRad [FILENAME] Specify the filename of the environment light to display, stored as HDR environment radiance in the latitude-longitude format\n" + " --envMethod [INTEGER] Specify the environment lighting method (0 = filtered importance sampling, 1 = prefiltered environment maps, defaults to 0)\n" + " --envSampleCount [INTEGER] Specify the environment sample count (defaults to 16)\n" + " --lightRotation [FLOAT] Specify the rotation in degrees of the lighting environment about the Y axis (defaults to 0)\n" + " --shadowMap [BOOLEAN] Specify whether shadow mapping is enabled (defaults to true)\n" + " --path [FILEPATH] Specify an additional data search path location (e.g. '/projects/MaterialX'). This absolute path will be queried when locating data libraries, XInclude references, and referenced images.\n" + " --library [FILEPATH] Specify an additional data library folder (e.g. 'vendorlib', 'studiolib'). This relative path will be appended to each location in the data search path when loading data libraries.\n" + " --screenWidth [INTEGER] Specify the width of the screen image in pixels (defaults to 1280)\n" + " --screenHeight [INTEGER] Specify the height of the screen image in pixels (defaults to 960)\n" + " --screenColor [VECTOR3] Specify the background color of the viewer as three comma-separated floats (defaults to 0.3,0.3,0.32)\n" + " --drawEnvironment [BOOLEAN] Specify whether to render the environment as the background (defaults to false)\n" + " --captureFilename [FILENAME] Specify the filename to which the first rendered frame should be written\n" + " --bakeWidth [INTEGER] Specify the target width for texture baking (defaults to maximum image width of the source document)\n" + " --bakeHeight [INTEGER] Specify the target height for texture baking (defaults to maximum image height of the source document)\n" + " --bakeFilename [STRING] Specify the output document filename for texture baking\n" + " --refresh [FLOAT] Specify the refresh period for the viewer in milliseconds (defaults to 50, set to -1 to disable)\n" + " --remap [TOKEN1:TOKEN2] Specify the remapping from one token to another when MaterialX document is loaded\n" + " --skip [NAME] Specify to skip elements matching the given name attribute\n" + " --terminator [STRING] Specify to enforce the given terminator string for file prefixes\n" + " --help Display the complete list of command-line options\n"; -template void parseToken(std::string token, std::string type, T& res) +template void parseToken(std::string token, std::string type, T& res) { if (token.empty()) { @@ -64,7 +64,7 @@ template void parseToken(std::string token, std::string type, T& res) } int main(int argc, char* const argv[]) -{ +{ std::vector tokens; for (int i = 1; i < argc; i++) { @@ -131,7 +131,7 @@ int main(int argc, char* const argv[]) else if (token == "--turntableSteps") { parseToken(nextToken, "integer", turntableSteps); - turntableSteps = std::clamp(turntableSteps, 2, 360);; + turntableSteps = std::clamp(turntableSteps, 2, 360); } else if (token == "--cameraPosition") { @@ -159,7 +159,7 @@ int main(int argc, char* const argv[]) else if (token == "--envSampleCount") { parseToken(nextToken, "integer", envSampleCount); - } + } else if (token == "--lightRotation") { parseToken(nextToken, "float", lightRotation); diff --git a/source/MaterialXView/RenderPipeline.h b/source/MaterialXView/RenderPipeline.h index 82f5990513..87baac3fa4 100644 --- a/source/MaterialXView/RenderPipeline.h +++ b/source/MaterialXView/RenderPipeline.h @@ -44,16 +44,16 @@ class RenderPipeline virtual ~RenderPipeline() { } virtual void initialize(void* device, void* command_queue) = 0; - + virtual mx::ImageHandlerPtr createImageHandler() = 0; - virtual mx::MaterialPtr createMaterial() = 0; + virtual mx::MaterialPtr createMaterial() = 0; virtual void bakeTextures() = 0; - + virtual void updateAlbedoTable(int tableSize) = 0; virtual std::shared_ptr createTextureBaker(unsigned int width, unsigned int height, mx::Image::BaseType baseType) = 0; - + virtual void renderFrame(void* color_texture, int shadowMapSize, const char* dirLightNodeCat) = 0; virtual void initFramebuffer(int width, int height, @@ -62,9 +62,9 @@ class RenderPipeline void* color_texture) = 0; virtual mx::ImagePtr getShadowMap(int shadowMapSize) = 0; - + virtual mx::ImagePtr getFrameImage() = 0; - + public: Viewer* _viewer; }; From 343a587ec01ed8293ac8b4f6fd34dbdea04a5df3 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Mon, 4 Dec 2023 20:33:36 -0800 Subject: [PATCH 040/128] Improvements to GitHub CI - Add a MacOS build with Xcode 15 and Python 3.12. - Add INL files to the Clang Format step. - Simplify CMake build steps. --- .github/workflows/main.yml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0a71a31011..1af8012ef0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -78,17 +78,17 @@ jobs: cmake_config: -DMATERIALX_BUILD_SHARED_LIBS=ON python: 3.7 - - name: MacOS_Xcode_13_Python39 - os: macos-12 - compiler: xcode - compiler_version: "13.4" - python: 3.9 - - name: MacOS_Xcode_14_Python311 os: macos-13 compiler: xcode compiler_version: "14.3" python: 3.11 + + - name: MacOS_Xcode_15_Python312 + os: macos-13 + compiler: xcode + compiler_version: "15.0" + python: 3.12 test_shaders: ON - name: iOS_Xcode_15 @@ -195,14 +195,13 @@ jobs: - name: Run Clang Format if: matrix.clang_format == 'ON' - run: find source \( -name *.h -o -name *.cpp -o -name *.mm \) ! -path "*/External/*" ! -path "*/NanoGUI/*" | xargs clang-format -i --verbose + run: find source \( -name *.h -o -name *.cpp -o -name *.mm -o -name *.inl \) ! -path "*/External/*" ! -path "*/NanoGUI/*" | xargs clang-format -i --verbose - name: CMake Generate run: cmake -S . -B build -DMATERIALX_BUILD_PYTHON=ON -DMATERIALX_BUILD_VIEWER=ON -DMATERIALX_BUILD_GRAPH_EDITOR=ON -DMATERIALX_TEST_RENDER=OFF -DMATERIALX_WARNINGS_AS_ERRORS=ON ${{matrix.cmake_config}} - name: CMake Build - run: cmake --build . --target install --config Release --parallel 2 - working-directory: build + run: cmake --build build --target install --config Release --parallel 2 - name: CMake Unit Tests run: ctest -VV --output-on-failure --build-config Release @@ -314,8 +313,7 @@ jobs: - name: JavaScript CMake Build if: matrix.build_javascript == 'ON' - run: cmake --build . --target install --config Release --parallel 2 - working-directory: javascript/build + run: cmake --build javascript/build --target install --config Release --parallel 2 - name: JavaScript Unit Tests if: matrix.build_javascript == 'ON' From cd82ea55f2a280a94ce748d3f03d04e00c00ca40 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Fri, 8 Dec 2023 11:51:49 -0800 Subject: [PATCH 041/128] Update JavaScript packages This changelist updates all referenced JavaScript packages to their latest version via 'npm update'. --- javascript/MaterialXTest/package-lock.json | 1252 ++++++++++---------- javascript/MaterialXTest/package.json | 8 +- javascript/MaterialXView/package-lock.json | 466 +++++--- javascript/MaterialXView/package.json | 4 +- 4 files changed, 935 insertions(+), 795 deletions(-) diff --git a/javascript/MaterialXTest/package-lock.json b/javascript/MaterialXTest/package-lock.json index 7835f07ce5..5c3b779bc7 100644 --- a/javascript/MaterialXTest/package-lock.json +++ b/javascript/MaterialXTest/package-lock.json @@ -9,10 +9,10 @@ "version": "1.0.0", "license": "ISC", "devDependencies": { - "@babel/core": "^7.22.5", - "@babel/preset-env": "^7.22.5", - "@babel/register": "^7.22.5", - "chai": "^4.3.7", + "@babel/core": "^7.23.5", + "@babel/preset-env": "^7.23.5", + "@babel/register": "^7.22.15", + "chai": "^4.3.10", "copyfiles": "^2.4.1", "karma": "^6.4.2", "karma-chai": "^0.1.0", @@ -37,47 +37,48 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz", - "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz", - "integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", + "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helpers": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.5", + "@babel/parser": "^7.23.5", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -88,12 +89,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", - "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", + "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -115,51 +116,48 @@ } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", - "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", - "integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz", - "integrity": "sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz", + "integrity": "sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "semver": "^6.3.0" + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -169,14 +167,14 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.5.tgz", - "integrity": "sha512-1VpEFOIbMRaXyDeUwUfmTIxExLwQ+zkW+Bh5zXpApA3oQedBx9v/updixWxnx/bZpKw7u8VxWjb/qWpIcmPq8A==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "regexpu-core": "^5.3.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -186,39 +184,38 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.0.tgz", - "integrity": "sha512-RnanLx5ETe6aybRi1cO/edaRH+bNYWaryCEmjDDYyNr4wnSzyOp8T0dWipmqVHKEY3AbVKUom50AKSlj1zmKbg==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", + "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" + "resolve": "^1.14.2" }, "peerDependencies": { - "@babel/core": "^7.4.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -237,46 +234,46 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", - "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", - "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { @@ -301,15 +298,14 @@ } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz", - "integrity": "sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-wrap-function": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -319,20 +315,20 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz", - "integrity": "sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-simple-access": { @@ -360,9 +356,9 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", - "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { "@babel/types": "^7.22.5" @@ -372,69 +368,68 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz", - "integrity": "sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", "dev": true, "dependencies": { "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.5.tgz", - "integrity": "sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", + "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -442,9 +437,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", - "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -454,9 +449,9 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz", - "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -469,14 +464,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", - "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.5" + "@babel/plugin-transform-optional-chaining": "^7.23.3" }, "engines": { "node": ">=6.9.0" @@ -485,29 +480,29 @@ "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", + "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, "engines": { - "node": ">=4" + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -577,9 +572,9 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", - "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -592,9 +587,9 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", - "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -749,9 +744,9 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", - "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -764,14 +759,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.5.tgz", - "integrity": "sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", + "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { @@ -782,14 +777,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", - "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5" + "@babel/helper-remap-async-to-generator": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -799,9 +794,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", - "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -814,9 +809,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", - "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -829,12 +824,12 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", - "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -845,12 +840,12 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", - "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, @@ -862,19 +857,19 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.5.tgz", - "integrity": "sha512-2edQhLfibpWpsVBx2n/GKOz6JdGQvLruZQfGr9l1qes2KQaWswjBzhQF7UDUZMNaMMQeYnQzxwOMPsbYF7wqPQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz", + "integrity": "sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, "engines": { @@ -885,13 +880,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", - "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.5" + "@babel/template": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -901,9 +896,9 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", - "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -916,12 +911,12 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", - "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -932,9 +927,9 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", - "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -947,9 +942,9 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", - "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -963,12 +958,12 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", - "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -979,9 +974,9 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", - "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -995,9 +990,9 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", - "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", + "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1010,13 +1005,13 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", - "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -1027,9 +1022,9 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", - "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1043,9 +1038,9 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", - "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1058,9 +1053,9 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", - "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1074,9 +1069,9 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", - "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1089,12 +1084,12 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", - "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -1105,12 +1100,12 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", - "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, @@ -1122,15 +1117,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", - "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", + "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -1140,12 +1135,12 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", - "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -1172,9 +1167,9 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", - "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1187,9 +1182,9 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", - "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1203,9 +1198,9 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", - "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1219,16 +1214,16 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", - "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", + "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", + "@babel/compat-data": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.22.5" + "@babel/plugin-transform-parameters": "^7.23.3" }, "engines": { "node": ">=6.9.0" @@ -1238,13 +1233,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", - "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5" + "@babel/helper-replace-supers": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -1254,9 +1249,9 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", - "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1270,9 +1265,9 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.5.tgz", - "integrity": "sha512-AconbMKOMkyG+xCng2JogMCDcqW8wedQAqpVIL4cOSescZ7+iW8utC6YDZLMCSUIReEA733gzRSaOSXMAt/4WQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1287,9 +1282,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", - "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1302,12 +1297,12 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", - "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -1318,13 +1313,13 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", - "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, @@ -1336,9 +1331,9 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", - "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1351,13 +1346,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", - "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.1" + "regenerator-transform": "^0.15.2" }, "engines": { "node": ">=6.9.0" @@ -1367,9 +1362,9 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", - "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1382,9 +1377,9 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", - "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1397,9 +1392,9 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", - "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1413,9 +1408,9 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", - "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1428,9 +1423,9 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", - "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1443,9 +1438,9 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", - "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1458,9 +1453,9 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", - "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1473,12 +1468,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", - "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -1489,12 +1484,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", - "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -1505,12 +1500,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", - "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -1521,25 +1516,26 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.5.tgz", - "integrity": "sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.5.tgz", + "integrity": "sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.22.5", - "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", @@ -1551,61 +1547,60 @@ "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.22.5", - "@babel/plugin-transform-async-generator-functions": "^7.22.5", - "@babel/plugin-transform-async-to-generator": "^7.22.5", - "@babel/plugin-transform-block-scoped-functions": "^7.22.5", - "@babel/plugin-transform-block-scoping": "^7.22.5", - "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-class-static-block": "^7.22.5", - "@babel/plugin-transform-classes": "^7.22.5", - "@babel/plugin-transform-computed-properties": "^7.22.5", - "@babel/plugin-transform-destructuring": "^7.22.5", - "@babel/plugin-transform-dotall-regex": "^7.22.5", - "@babel/plugin-transform-duplicate-keys": "^7.22.5", - "@babel/plugin-transform-dynamic-import": "^7.22.5", - "@babel/plugin-transform-exponentiation-operator": "^7.22.5", - "@babel/plugin-transform-export-namespace-from": "^7.22.5", - "@babel/plugin-transform-for-of": "^7.22.5", - "@babel/plugin-transform-function-name": "^7.22.5", - "@babel/plugin-transform-json-strings": "^7.22.5", - "@babel/plugin-transform-literals": "^7.22.5", - "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", - "@babel/plugin-transform-member-expression-literals": "^7.22.5", - "@babel/plugin-transform-modules-amd": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.5", - "@babel/plugin-transform-modules-systemjs": "^7.22.5", - "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.4", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.5", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.3", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.3", + "@babel/plugin-transform-modules-umd": "^7.23.3", "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.22.5", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5", - "@babel/plugin-transform-numeric-separator": "^7.22.5", - "@babel/plugin-transform-object-rest-spread": "^7.22.5", - "@babel/plugin-transform-object-super": "^7.22.5", - "@babel/plugin-transform-optional-catch-binding": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.5", - "@babel/plugin-transform-parameters": "^7.22.5", - "@babel/plugin-transform-private-methods": "^7.22.5", - "@babel/plugin-transform-private-property-in-object": "^7.22.5", - "@babel/plugin-transform-property-literals": "^7.22.5", - "@babel/plugin-transform-regenerator": "^7.22.5", - "@babel/plugin-transform-reserved-words": "^7.22.5", - "@babel/plugin-transform-shorthand-properties": "^7.22.5", - "@babel/plugin-transform-spread": "^7.22.5", - "@babel/plugin-transform-sticky-regex": "^7.22.5", - "@babel/plugin-transform-template-literals": "^7.22.5", - "@babel/plugin-transform-typeof-symbol": "^7.22.5", - "@babel/plugin-transform-unicode-escapes": "^7.22.5", - "@babel/plugin-transform-unicode-property-regex": "^7.22.5", - "@babel/plugin-transform-unicode-regex": "^7.22.5", - "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.3", - "babel-plugin-polyfill-corejs3": "^0.8.1", - "babel-plugin-polyfill-regenerator": "^0.5.0", - "core-js-compat": "^3.30.2", - "semver": "^6.3.0" + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.23.4", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -1615,25 +1610,23 @@ } }, "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/register": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.22.5.tgz", - "integrity": "sha512-vV6pm/4CijSQ8Y47RH5SopXzursN35RQINfGJkmOlcpAtGuf94miFvIPhCKGQN7WGIcsgG1BHEX2KVdTYwTwUQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.22.15.tgz", + "integrity": "sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg==", "dev": true, "dependencies": { "clone-deep": "^4.0.1", @@ -1656,45 +1649,45 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", + "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", "dev": true, "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz", - "integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", + "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.5", + "@babel/types": "^7.23.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1703,13 +1696,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", + "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1740,9 +1733,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, "engines": { "node": ">=6.0.0" @@ -1764,21 +1757,15 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, "node_modules/@socket.io/component-emitter": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", @@ -1792,19 +1779,22 @@ "dev": true }, "node_modules/@types/cors": { - "version": "2.8.13", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", - "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/node": { - "version": "20.3.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.3.tgz", - "integrity": "sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==", - "dev": true + "version": "20.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", + "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/accepts": { "version": "1.3.8", @@ -1878,42 +1868,42 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.3.tgz", - "integrity": "sha512-bM3gHc337Dta490gg+/AseNB9L4YLHxq1nGKZZSHbhXv4aTYU2MD2cjza1Ru4S6975YLTaL1K8uJf6ukJhhmtw==", + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", + "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.4.0", - "semver": "^6.1.1" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.3", + "semver": "^6.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.1.tgz", - "integrity": "sha512-ikFrZITKg1xH6pLND8zT14UPgjKHiGLqex7rGEZCH2EvhsneJaJPemmpQaIZV5AL03II+lXylw3UmddDK8RU5Q==", + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", + "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.0", - "core-js-compat": "^3.30.1" + "@babel/helper-define-polyfill-provider": "^0.4.3", + "core-js-compat": "^3.33.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.0.tgz", - "integrity": "sha512-hDJtKjMLVa7Z+LwnTCxoDLQj6wdc+B8dun7ayF2fYieI6OzfuvcLMB32ihJZ4UhCBwNYGl5bg/x/P9cMdnkc2g==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", + "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.0" + "@babel/helper-define-polyfill-provider": "^0.4.3" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/balanced-match": { @@ -2008,9 +1998,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.21.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", - "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, "funding": [ { @@ -2027,10 +2017,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -2055,13 +2045,14 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2080,9 +2071,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001512", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz", - "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==", + "version": "1.0.30001566", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", + "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", "dev": true, "funding": [ { @@ -2100,18 +2091,18 @@ ] }, "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" }, "engines": { "node": ">=4" @@ -2132,10 +2123,13 @@ } }, "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { "node": "*" } @@ -2280,9 +2274,9 @@ } }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "node_modules/cookie": { @@ -2314,12 +2308,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.31.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.0.tgz", - "integrity": "sha512-hM7YCu1cU6Opx7MXNu0NuumM0ezNeAeRKadixyiQELWY3vT3De9S4J5ZBMraWV2vZnrE1Cirl0GtFtDtMUXzPw==", + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.34.0.tgz", + "integrity": "sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==", "dev": true, "dependencies": { - "browserslist": "^4.21.5" + "browserslist": "^4.22.2" }, "funding": { "type": "opencollective", @@ -2401,6 +2395,20 @@ "node": ">=6" } }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2454,9 +2462,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.449", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.449.tgz", - "integrity": "sha512-TxLRpRUj/107ATefeP8VIUWNOv90xJxZZbCW/eIbSZQiuiFANCx2b7u+GbVc9X4gU+xnbvypNMYVM/WArE1DNQ==", + "version": "1.4.609", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.609.tgz", + "integrity": "sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw==", "dev": true }, "node_modules/emoji-regex": { @@ -2475,9 +2483,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.1.tgz", - "integrity": "sha512-mGqhI+D7YxS9KJMppR6Iuo37Ed3abhU8NdfgSvJSDUafQutrN+sPTncJYTyM9+tkhSmWodKtVYGPPHyXJEwEQA==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", + "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -2488,17 +2496,17 @@ "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~5.1.0", + "engine.io-parser": "~5.2.1", "ws": "~8.11.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=10.2.0" } }, "node_modules/engine.io-parser": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.1.0.tgz", - "integrity": "sha512-enySgNiK5tyZFynt3z7iqBR+Bto9EVVVvDFuTT0ioHCGbzirZVGDGiQjZzEp8hWl6hd5FSVytJGuScX1C1C35w==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", "dev": true, "engines": { "node": ">=10.0.0" @@ -2652,15 +2660,15 @@ } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "dev": true, "funding": [ { @@ -2698,9 +2706,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -2712,10 +2720,13 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gensync": { "version": "1.0.0-beta.2", @@ -2736,24 +2747,24 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2800,24 +2811,24 @@ "node": ">=4" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -2827,6 +2838,18 @@ "node": ">=4" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", @@ -2851,6 +2874,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -2940,12 +2975,12 @@ } }, "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3264,12 +3299,12 @@ } }, "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "dependencies": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "node_modules/lru-cache": { @@ -3295,9 +3330,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -3618,9 +3653,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", - "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node_modules/noms": { @@ -3652,9 +3687,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3965,9 +4000,9 @@ "dev": true }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "dev": true, "dependencies": { "regenerate": "^1.4.2" @@ -3977,15 +4012,15 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", "dev": true }, "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, "dependencies": { "@babel/runtime": "^7.8.4" @@ -4045,12 +4080,12 @@ "dev": true }, "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -4109,9 +4144,9 @@ "dev": true }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -4126,6 +4161,21 @@ "randombytes": "^2.1.0" } }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -4159,21 +4209,21 @@ } }, "node_modules/socket.io": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.1.tgz", - "integrity": "sha512-W+utHys2w//dhFjy7iQQu9sGd3eokCjGbl2r59tyLqNiJJBdIebn3GAKEXBr3osqHTObJi2die/25bCx2zsaaw==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz", + "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.0", + "engine.io": "~6.5.2", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=10.2.0" } }, "node_modules/socket.io-adapter": { @@ -4440,9 +4490,9 @@ } }, "node_modules/ua-parser-js": { - "version": "0.7.35", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz", - "integrity": "sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==", + "version": "0.7.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.37.tgz", + "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==", "dev": true, "funding": [ { @@ -4452,12 +4502,22 @@ { "type": "paypal", "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" } ], "engines": { "node": "*" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -4526,9 +4586,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { diff --git a/javascript/MaterialXTest/package.json b/javascript/MaterialXTest/package.json index ac3fa3a182..cc67644462 100644 --- a/javascript/MaterialXTest/package.json +++ b/javascript/MaterialXTest/package.json @@ -16,10 +16,10 @@ "author": "", "license": "ISC", "devDependencies": { - "@babel/core": "^7.22.5", - "@babel/preset-env": "^7.22.5", - "@babel/register": "^7.22.5", - "chai": "^4.3.7", + "@babel/core": "^7.23.5", + "@babel/preset-env": "^7.23.5", + "@babel/register": "^7.22.15", + "chai": "^4.3.10", "copyfiles": "^2.4.1", "karma": "^6.4.2", "karma-chai": "^0.1.0", diff --git a/javascript/MaterialXView/package-lock.json b/javascript/MaterialXView/package-lock.json index 7bdf38ceba..7a8e6f71d7 100644 --- a/javascript/MaterialXView/package-lock.json +++ b/javascript/MaterialXView/package-lock.json @@ -11,11 +11,11 @@ "dependencies": { "dat.gui": "^0.7.9", "three": "^0.136.0", - "webpack": "^5.88.2" + "webpack": "^5.89.0" }, "devDependencies": { "copy-webpack-plugin": "^8.1.1", - "html-webpack-plugin": "^5.5.3", + "html-webpack-plugin": "^5.5.4", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.15.1" } @@ -43,9 +43,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "engines": { "node": ">=6.0.0" } @@ -73,19 +73,14 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" - }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -128,9 +123,9 @@ } }, "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, "dependencies": { "@types/connect": "*", @@ -138,27 +133,27 @@ } }, "node_modules/@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", - "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dev": true, "dependencies": { "@types/express-serve-static-core": "*", @@ -166,32 +161,32 @@ } }, "node_modules/@types/eslint": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.1.tgz", - "integrity": "sha512-XpNDc4Z5Tb4x+SW1MriMVeIsMoONHCkWFMkR/aPJbzEsxqHy+4Glu/BqTdPrApfDeMaXbtNh6bseNgl5KaWrSg==", + "version": "8.44.8", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.8.tgz", + "integrity": "sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, "dependencies": { "@types/body-parser": "*", @@ -201,9 +196,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.35", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", - "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", "dev": true, "dependencies": { "@types/node": "*", @@ -219,46 +214,58 @@ "dev": true }, "node_modules/@types/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "dev": true }, "node_modules/@types/http-proxy": { - "version": "1.17.11", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", - "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, "node_modules/@types/node": { - "version": "20.4.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz", - "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==" + "version": "20.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", + "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", + "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", "dev": true }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true }, "node_modules/@types/retry": { @@ -268,9 +275,9 @@ "dev": true }, "node_modules/@types/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", - "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, "dependencies": { "@types/mime": "^1", @@ -278,18 +285,18 @@ } }, "node_modules/@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "dev": true, "dependencies": { "@types/express": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", - "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", "dev": true, "dependencies": { "@types/http-errors": "*", @@ -298,18 +305,18 @@ } }, "node_modules/@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/ws": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", - "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, "dependencies": { "@types/node": "*" @@ -506,9 +513,9 @@ } }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "bin": { "acorn": "bin/acorn" }, @@ -730,9 +737,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", - "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "funding": [ { "type": "opencollective", @@ -748,10 +755,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -775,13 +782,14 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -798,9 +806,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001517", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz", - "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==", + "version": "1.0.30001566", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", + "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", "funding": [ { "type": "opencollective", @@ -852,9 +860,9 @@ } }, "node_modules/clean-css": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", - "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", "dev": true, "dependencies": { "source-map": "~0.6.0" @@ -1078,6 +1086,20 @@ "node": ">= 10" } }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -1131,9 +1153,9 @@ "dev": true }, "node_modules/dns-packet": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", - "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dev": true, "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" @@ -1223,9 +1245,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.470", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.470.tgz", - "integrity": "sha512-zZM48Lmy2FKWgqyvsX9XK+J6FfP7aCDUFLmgooLJzA7v1agCs/sxSoBpTIwDLhmbhpx9yJIxj2INig/ncjJRqg==" + "version": "1.4.609", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.609.tgz", + "integrity": "sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -1258,9 +1280,9 @@ } }, "node_modules/envinfo": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", - "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", + "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", "dev": true, "bin": { "envinfo": "dist/cli.js" @@ -1270,9 +1292,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", - "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" }, "node_modules/escalade": { "version": "3.1.1", @@ -1427,9 +1449,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -1520,10 +1542,19 @@ "node": ">=8" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "dev": true, "funding": [ { @@ -1559,9 +1590,9 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz", - "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", "dev": true }, "node_modules/fs.realpath": { @@ -1571,9 +1602,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -1585,21 +1616,24 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1674,6 +1708,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -1685,18 +1731,6 @@ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1705,6 +1739,18 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", @@ -1729,6 +1775,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -1818,9 +1876,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", - "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.4.tgz", + "integrity": "sha512-3wNSaVVxdxcu0jd4FpQFoICdqgxs4zIQQvj+2yQKFfBOnLETQ6X5CDWdeasuGlSsooFlMkEioWDTqBv1wvw5Iw==", "dev": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -1947,9 +2005,9 @@ } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, "engines": { "node": ">= 4" @@ -2021,12 +2079,12 @@ } }, "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2179,13 +2237,13 @@ } }, "node_modules/launch-editor": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz", - "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", "dev": true, "dependencies": { "picocolors": "^1.0.0", - "shell-quote": "^1.7.3" + "shell-quote": "^1.8.1" } }, "node_modules/loader-runner": { @@ -2397,9 +2455,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -2435,9 +2493,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2720,9 +2778,9 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "engines": { "node": ">=6" } @@ -2879,12 +2937,12 @@ "dev": true }, "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -3022,11 +3080,12 @@ "dev": true }, "node_modules/selfsigned": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", - "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dev": true, "dependencies": { + "@types/node-forge": "^1.3.0", "node-forge": "^1" }, "engines": { @@ -3150,6 +3209,21 @@ "node": ">= 0.8.0" } }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -3405,9 +3479,9 @@ } }, "node_modules/terser": { - "version": "5.19.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", - "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -3500,9 +3574,9 @@ } }, "node_modules/tslib": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", - "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, "node_modules/type-is": { @@ -3518,6 +3592,11 @@ "node": ">= 0.6" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -3528,9 +3607,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "funding": [ { "type": "opencollective", @@ -3625,9 +3704,9 @@ } }, "node_modules/webpack": { - "version": "5.88.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", - "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", + "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -3915,12 +3994,13 @@ } }, "node_modules/webpack-merge": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", - "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, "dependencies": { "clone-deep": "^4.0.1", + "flat": "^5.0.2", "wildcard": "^2.0.0" }, "engines": { @@ -3986,9 +4066,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", "dev": true, "engines": { "node": ">=10.0.0" diff --git a/javascript/MaterialXView/package.json b/javascript/MaterialXView/package.json index adce3d2e82..8912357208 100644 --- a/javascript/MaterialXView/package.json +++ b/javascript/MaterialXView/package.json @@ -12,11 +12,11 @@ "dependencies": { "dat.gui": "^0.7.9", "three": "^0.136.0", - "webpack": "^5.88.2" + "webpack": "^5.89.0" }, "devDependencies": { "copy-webpack-plugin": "^8.1.1", - "html-webpack-plugin": "^5.5.3", + "html-webpack-plugin": "^5.5.4", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.15.1" } From 20022bcd4a8981c1537f093fabcbbadad598d6fc Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 12 Dec 2023 18:42:20 -0800 Subject: [PATCH 042/128] Update three.js to r152 This changelist updates the version of three.js to r152 in the MaterialX Web Viewer, making a handful of adjustments to account for changes in texture storage conventions. --- javascript/MaterialXView/package-lock.json | 32 ++++++------ javascript/MaterialXView/package.json | 2 +- javascript/MaterialXView/source/helper.js | 60 +++------------------- javascript/MaterialXView/source/index.js | 4 +- 4 files changed, 27 insertions(+), 71 deletions(-) diff --git a/javascript/MaterialXView/package-lock.json b/javascript/MaterialXView/package-lock.json index 7a8e6f71d7..d5338a3517 100644 --- a/javascript/MaterialXView/package-lock.json +++ b/javascript/MaterialXView/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "dat.gui": "^0.7.9", - "three": "^0.136.0", + "three": "^0.152.2", "webpack": "^5.89.0" }, "devDependencies": { @@ -161,9 +161,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.44.8", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.8.tgz", - "integrity": "sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==", + "version": "8.44.9", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.9.tgz", + "integrity": "sha512-6yBxcvwnnYoYT1Uk2d+jvIfsuP4mb2EdIxFnrPABj5a/838qe5bGkNLFOiipX4ULQ7XVQvTxOh7jO+BTAiqsEw==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -806,9 +806,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001566", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", - "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", "funding": [ { "type": "opencollective", @@ -1245,9 +1245,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.609", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.609.tgz", - "integrity": "sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw==" + "version": "1.4.613", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.613.tgz", + "integrity": "sha512-r4x5+FowKG6q+/Wj0W9nidx7QO31BJwmR2uEo+Qh3YLGQ8SbBAFuDFpTxzly/I2gsbrFwBuIjrMp423L3O5U3w==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -3542,9 +3542,9 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/three": { - "version": "0.136.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.136.0.tgz", - "integrity": "sha512-+fEMX7nYLz2ZesVP/dyifli5Jf8gR3XPAnFJveQ80aMhibFduzrADnjMbARXh8+W9qLK7rshJCjAIL/6cDxC+A==" + "version": "0.152.2", + "resolved": "https://registry.npmjs.org/three/-/three-0.152.2.tgz", + "integrity": "sha512-Ff9zIpSfkkqcBcpdiFo2f35vA9ZucO+N8TNacJOqaEE6DrB0eufItVMib8bK8Pcju/ZNT6a7blE1GhTpkdsILw==" }, "node_modules/thunky": { "version": "1.1.0", @@ -4066,9 +4066,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", + "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", "dev": true, "engines": { "node": ">=10.0.0" diff --git a/javascript/MaterialXView/package.json b/javascript/MaterialXView/package.json index 8912357208..9518156883 100644 --- a/javascript/MaterialXView/package.json +++ b/javascript/MaterialXView/package.json @@ -11,7 +11,7 @@ "license": "ISC", "dependencies": { "dat.gui": "^0.7.9", - "three": "^0.136.0", + "three": "^0.152.2", "webpack": "^5.89.0" }, "devDependencies": { diff --git a/javascript/MaterialXView/source/helper.js b/javascript/MaterialXView/source/helper.js index 111dfd9b5d..98441a605f 100644 --- a/javascript/MaterialXView/source/helper.js +++ b/javascript/MaterialXView/source/helper.js @@ -19,59 +19,15 @@ const IMAGE_PATH_SEPARATOR = "/"; */ export function prepareEnvTexture(texture, capabilities) { - const rgbaTexture = RGBToRGBA_Float(texture); - rgbaTexture.wrapS = THREE.RepeatWrapping; - rgbaTexture.anisotropy = capabilities.getMaxAnisotropy(); - rgbaTexture.minFilter = THREE.LinearMipmapLinearFilter; - rgbaTexture.magFilter = THREE.LinearFilter; - rgbaTexture.generateMipmaps = true; - rgbaTexture.needsUpdate = true; + let newTexture = new THREE.DataTexture(texture.image.data, texture.image.width, texture.image.height, texture.format, texture.type); + newTexture.wrapS = THREE.RepeatWrapping; + newTexture.anisotropy = capabilities.getMaxAnisotropy(); + newTexture.minFilter = THREE.LinearMipmapLinearFilter; + newTexture.magFilter = THREE.LinearFilter; + newTexture.generateMipmaps = true; + newTexture.needsUpdate = true; - return rgbaTexture; -} - -/** - * Create a new (half)float texture containing an alpha channel with a value of 1 from a RGB (half)float texture. - * @param {THREE.Texture} texture - */ -function RGBToRGBA_Float(texture) -{ - const w = texture.image.width; - const h = texture.image.height; - const dataSize = texture.image.data.length; - const stride = dataSize / (w *h); - // No need to convert to RGBA if already 4 channel. - if (stride == 3) - { - const rgbData = texture.image.data; - const length = (rgbData.length / 3) * 4; - let rgbaData; - - switch (texture.type) - { - case THREE.FloatType: - rgbaData = new Float32Array(length); - break; - case THREE.HalfFloatType: - rgbaData = new Uint16Array(length); - break; - default: - break; - } - - if (rgbaData) - { - for (let i = 0; i < length / 4; i++) - { - rgbaData[(i * 4) + 0] = rgbData[(i * 3) + 0]; - rgbaData[(i * 4) + 1] = rgbData[(i * 3) + 1]; - rgbaData[(i * 4) + 2] = rgbData[(i * 3) + 2]; - rgbaData[(i * 4) + 3] = 1.0; - } - return new THREE.DataTexture(rgbaData, texture.image.width, texture.image.height, THREE.RGBAFormat, texture.type); - } - } - return texture; + return newTexture; } /** diff --git a/javascript/MaterialXView/source/index.js b/javascript/MaterialXView/source/index.js index 56e2e1f5a2..fa729ce4a6 100644 --- a/javascript/MaterialXView/source/index.js +++ b/javascript/MaterialXView/source/index.js @@ -83,10 +83,10 @@ function init() viewer.getEditor().initialize(); const hdrLoader = viewer.getHdrLoader(); - const fileLooder = viewer.getFileLoader(); + const fileLoader = viewer.getFileLoader(); Promise.all([ new Promise(resolve => hdrLoader.setDataType(THREE.FloatType).load('Lights/san_giuseppe_bridge_split.hdr', resolve)), - new Promise(resolve => fileLooder.load('Lights/san_giuseppe_bridge_split.mtlx', resolve)), + new Promise(resolve => fileLoader.load('Lights/san_giuseppe_bridge_split.mtlx', resolve)), new Promise(resolve => hdrLoader.setDataType(THREE.FloatType).load('Lights/irradiance/san_giuseppe_bridge_split.hdr', resolve)), new Promise(function (resolve) { MaterialX().then((module) => { From 1ef4619977c146549032122cabcd1baaa1a1ddd4 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sat, 16 Dec 2023 22:29:59 -0800 Subject: [PATCH 043/128] Web viewer HDRI improvements - Load HDR images in half-float format, improving render performance and browser compatibility. - Clarify HDR image names. --- javascript/MaterialXView/source/index.js | 8 ++++---- javascript/MaterialXView/source/viewer.js | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/javascript/MaterialXView/source/index.js b/javascript/MaterialXView/source/index.js index fa729ce4a6..6f0b6e44b3 100644 --- a/javascript/MaterialXView/source/index.js +++ b/javascript/MaterialXView/source/index.js @@ -85,18 +85,18 @@ function init() const hdrLoader = viewer.getHdrLoader(); const fileLoader = viewer.getFileLoader(); Promise.all([ - new Promise(resolve => hdrLoader.setDataType(THREE.FloatType).load('Lights/san_giuseppe_bridge_split.hdr', resolve)), + new Promise(resolve => hdrLoader.load('Lights/san_giuseppe_bridge_split.hdr', resolve)), + new Promise(resolve => hdrLoader.load('Lights/irradiance/san_giuseppe_bridge_split.hdr', resolve)), new Promise(resolve => fileLoader.load('Lights/san_giuseppe_bridge_split.mtlx', resolve)), - new Promise(resolve => hdrLoader.setDataType(THREE.FloatType).load('Lights/irradiance/san_giuseppe_bridge_split.hdr', resolve)), new Promise(function (resolve) { MaterialX().then((module) => { resolve(module); }); }) - ]).then(async ([loadedRadianceTexture, loadedLightSetup, loadedIrradianceTexture, mxIn]) => + ]).then(async ([radianceTexture, irradianceTexture, lightRigXml, mxIn]) => { // Initialize viewer + lighting - await viewer.initialize(mxIn, renderer, loadedRadianceTexture, loadedLightSetup, loadedIrradianceTexture); + await viewer.initialize(mxIn, renderer, radianceTexture, irradianceTexture, lightRigXml); // Load geometry let scene = viewer.getScene(); diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js index d1adfd9ef4..58e4613bae 100644 --- a/javascript/MaterialXView/source/viewer.js +++ b/javascript/MaterialXView/source/viewer.js @@ -1035,7 +1035,7 @@ export class Viewer // Create shader generator, generation context and "base" document which // contains the standard definition libraries and lighting elements. // - async initialize(mtlxIn, renderer, loadedRadianceTexture, loadedLightSetup, loadedIrradianceTexture) + async initialize(mtlxIn, renderer, radianceTexture, irradianceTexture, lightRigXml) { this.mx = mtlxIn; @@ -1047,30 +1047,30 @@ export class Viewer this.stdlib = this.mx.loadStandardLibraries(this.genContext); this.document.importLibrary(this.stdlib); - this.initializeLighting(renderer, loadedRadianceTexture, loadedLightSetup, loadedIrradianceTexture); + this.initializeLighting(renderer, radianceTexture, irradianceTexture, lightRigXml); - loadedRadianceTexture.mapping = THREE.EquirectangularReflectionMapping; - this.getScene().setBackgroundTexture(loadedRadianceTexture); + radianceTexture.mapping = THREE.EquirectangularReflectionMapping; + this.getScene().setBackgroundTexture(radianceTexture); } // // Load in lighting rig document and register lights with generation context // Initialize environment lighting (IBLs). // - async initializeLighting(renderer, loadedRadianceTexture, loadedLightSetup, loadedIrradianceTexture) + async initializeLighting(renderer, radianceTexture, irradianceTexture, lightRigXml) { // Load lighting setup into document const mx = this.getMx(); this.lightRigDoc = mx.createDocument(); - await mx.readFromXmlString(this.lightRigDoc, loadedLightSetup); + await mx.readFromXmlString(this.lightRigDoc, lightRigXml); this.document.importLibrary(this.lightRigDoc); // Register lights with generation context this.lights = findLights(this.document); this.lightData = registerLights(mx, this.lights, this.genContext); - this.radianceTexture = prepareEnvTexture(loadedRadianceTexture, renderer.capabilities); - this.irradianceTexture = prepareEnvTexture(loadedIrradianceTexture, renderer.capabilities); + this.radianceTexture = prepareEnvTexture(radianceTexture, renderer.capabilities); + this.irradianceTexture = prepareEnvTexture(irradianceTexture, renderer.capabilities); } getEditor() { From 95d9ee0a46c6df509f7c92f7fefc684cd9d4c092 Mon Sep 17 00:00:00 2001 From: ld-kerley <154285602+ld-kerley@users.noreply.github.com> Date: Mon, 18 Dec 2023 18:14:40 -0800 Subject: [PATCH 044/128] Fix for custom node groups in graph editor menu (#1617) Currently if you have node definitions added to groups that aren't in the fixed list that MaterialXGraphEditor understands, then they won't be added to the menu. --- source/MaterialXGraphEditor/Graph.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index fc682e8f05..f0d1791143 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -1248,6 +1248,7 @@ void Graph::createNodeUIList(mx::DocumentPtr doc) auto nodeDefs = doc->getNodeDefs(); std::unordered_map> groupToNodeDef; + std::vector groupList = std::vector(NODE_GROUP_ORDER.begin(), NODE_GROUP_ORDER.end()); for (const auto& nodeDef : nodeDefs) { @@ -1257,6 +1258,12 @@ void Graph::createNodeUIList(mx::DocumentPtr doc) group = NODE_GROUP_ORDER.back(); } + // If the group is not in the groupList already (seeded by NODE_GROUP_ORDER) then add it. + if (std::find(groupList.begin(), groupList.end(), group) == groupList.end()) + { + groupList.emplace_back(group); + } + if (groupToNodeDef.find(group) == groupToNodeDef.end()) { groupToNodeDef[group] = std::vector(); @@ -1264,7 +1271,7 @@ void Graph::createNodeUIList(mx::DocumentPtr doc) groupToNodeDef[group].push_back(nodeDef); } - for (const auto& group : NODE_GROUP_ORDER) + for (const auto& group : groupList) { auto it = groupToNodeDef.find(group); if (it != groupToNodeDef.end()) From cbff01a8d27a5017166dfdbb9a77e96b51827c69 Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Tue, 19 Dec 2023 17:08:46 -0500 Subject: [PATCH 045/128] Update UI library used for Web Viewer (#1618) - Switch to `lil-gui` which fixes a number of dat-gui issues including all input which did not show up anymore (regression). - Same GUI lib as used for ThreeJS examples for consistency. --- javascript/MaterialXView/package-lock.json | 6 ++++++ javascript/MaterialXView/package.json | 2 +- javascript/MaterialXView/source/viewer.js | 20 ++++---------------- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/javascript/MaterialXView/package-lock.json b/javascript/MaterialXView/package-lock.json index d5338a3517..2755bef7ea 100644 --- a/javascript/MaterialXView/package-lock.json +++ b/javascript/MaterialXView/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "dat.gui": "^0.7.9", + "lil-gui": "^0.19.1", "three": "^0.152.2", "webpack": "^5.89.0" }, @@ -2246,6 +2247,11 @@ "shell-quote": "^1.8.1" } }, + "node_modules/lil-gui": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.19.1.tgz", + "integrity": "sha512-9dbIg+UxS8RIROI6OH5gV2KrVE0Cn37bcLOQGF2GKN8ibTxDrUSLzzZfkQR82LnZsgs7DEZOOGfn3zhtd6hk0Q==" + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", diff --git a/javascript/MaterialXView/package.json b/javascript/MaterialXView/package.json index 9518156883..4c369406bd 100644 --- a/javascript/MaterialXView/package.json +++ b/javascript/MaterialXView/package.json @@ -10,7 +10,7 @@ "author": "", "license": "ISC", "dependencies": { - "dat.gui": "^0.7.9", + "lil-gui": "^0.19.1", "three": "^0.152.2", "webpack": "^5.89.0" }, diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js index 58e4613bae..b986406d76 100644 --- a/javascript/MaterialXView/source/viewer.js +++ b/javascript/MaterialXView/source/viewer.js @@ -9,7 +9,7 @@ import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'; import { prepareEnvTexture, getLightRotation, findLights, registerLights, getUniformValues } from './helper.js' import { Group } from 'three'; -import { GUI } from 'dat.gui'; +import GUI from 'lil-gui'; const ALL_GEOMETRY_SPECIFIER = "*"; const NO_GEOMETRY_SPECIFIER = ""; @@ -445,13 +445,10 @@ export class Editor // clearFolders() { - Array.from(document.getElementsByClassName('folder')).forEach( + Array.from(document.getElementsByClassName('lil-gui')).forEach( function (element, index, array) { if (element.className) { - let child = element.firstElementChild; - if (child && child.className == 'dg') { - element.remove(); - } + element.remove(); } } ); @@ -466,16 +463,7 @@ export class Editor // Search document to find GUI elements and remove them // If not done then multiple GUIs will be created from different // threads. - Array.from(document.getElementsByClassName('dg')).forEach( - function (element, index, array) { - if (element.className) { - element.remove(); - } - } - ); - - // Create new GUI. - this._gui = new GUI(); + this.clearFolders(); this._gui.open(); return this._gui; From 00e5f734315db84db28b1d3bcab63755bbc4e7d9 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 19 Dec 2023 15:27:31 -0800 Subject: [PATCH 046/128] Minor improvements to web viewer - Assign a title to the Property Editor for clarity. - Launch the viewer with the Property Editor closed. --- javascript/MaterialXView/source/viewer.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js index b986406d76..e5990b8566 100644 --- a/javascript/MaterialXView/source/viewer.js +++ b/javascript/MaterialXView/source/viewer.js @@ -460,11 +460,9 @@ export class Editor // Create the editor initialize() { - // Search document to find GUI elements and remove them - // If not done then multiple GUIs will be created from different - // threads. this.clearFolders(); - this._gui.open(); + this._gui.title("Property Editor"); + this._gui.close(); return this._gui; } From 39138cf570a9857570d995c38e6120451696a6d7 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 19 Dec 2023 17:19:08 -0800 Subject: [PATCH 047/128] Additional improvements to web viewer - Merge separate code paths for GUI initialization and folder clearing. - Use the GUI constructor for title assignment. --- javascript/MaterialXView/source/index.js | 4 +-- javascript/MaterialXView/source/viewer.js | 43 ++++++++--------------- 2 files changed, 17 insertions(+), 30 deletions(-) diff --git a/javascript/MaterialXView/source/index.js b/javascript/MaterialXView/source/index.js index 6f0b6e44b3..ddd1ec8ffc 100644 --- a/javascript/MaterialXView/source/index.js +++ b/javascript/MaterialXView/source/index.js @@ -41,7 +41,7 @@ function init() materialsSelect.value = materialFilename; materialsSelect.addEventListener('change', (e) => { materialFilename = e.target.value; - viewer.getEditor().clearFolders(); + viewer.getEditor().initialize(); viewer.getMaterial().loadMaterials(viewer, materialFilename); viewer.getEditor().updateProperties(0.9); viewer.getScene().setUpdateTransforms(); @@ -122,7 +122,7 @@ function init() setLoadingCallback(file => { materialFilename = file.fullPath || file.name; - viewer.getEditor().clearFolders(); + viewer.getEditor().initialize(); viewer.getMaterial().loadMaterials(viewer, materialFilename); viewer.getEditor().updateProperties(0.9); viewer.getScene().setUpdateTransforms(); diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js index e5990b8566..01006530c8 100644 --- a/javascript/MaterialXView/source/viewer.js +++ b/javascript/MaterialXView/source/viewer.js @@ -416,6 +416,21 @@ export class Scene */ export class Editor { + // Initialize the editor, clearing any elements from previous materials. + initialize() + { + Array.from(document.getElementsByClassName('lil-gui')).forEach( + function (element, index, array) { + if (element.className) { + element.remove(); + } + } + ); + + this._gui = new GUI( { title: "Property Editor" } ); + this._gui.close(); + } + // Update ui properties // - Hide close button // - Update transparency so scene shows through if overlapping @@ -439,34 +454,6 @@ export class Editor } } - // - // Clear folders with children contain elements for any previous material - // and recreate top gui. - // - clearFolders() - { - Array.from(document.getElementsByClassName('lil-gui')).forEach( - function (element, index, array) { - if (element.className) { - element.remove(); - } - } - ); - - // Create new GUI. - this._gui = new GUI(); - } - - // Create the editor - initialize() - { - this.clearFolders(); - this._gui.title("Property Editor"); - this._gui.close(); - - return this._gui; - } - getGUI() { return this._gui; From 77aaa8a4bc241b397ac9870467ffb9fb84d7ab51 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 20 Dec 2023 10:00:55 -0800 Subject: [PATCH 048/128] Update JavaScript packages This changelist updates all referenced JavaScript packages to their latest version via 'npm update'. --- javascript/MaterialXTest/package-lock.json | 163 +++++++++++---------- javascript/MaterialXTest/package.json | 4 +- javascript/MaterialXView/package-lock.json | 47 +++--- javascript/MaterialXView/package.json | 2 +- 4 files changed, 110 insertions(+), 106 deletions(-) diff --git a/javascript/MaterialXTest/package-lock.json b/javascript/MaterialXTest/package-lock.json index 5c3b779bc7..e7d6980fd8 100644 --- a/javascript/MaterialXTest/package-lock.json +++ b/javascript/MaterialXTest/package-lock.json @@ -9,8 +9,8 @@ "version": "1.0.0", "license": "ISC", "devDependencies": { - "@babel/core": "^7.23.5", - "@babel/preset-env": "^7.23.5", + "@babel/core": "^7.23.6", + "@babel/preset-env": "^7.23.6", "@babel/register": "^7.22.15", "chai": "^4.3.10", "copyfiles": "^2.4.1", @@ -59,21 +59,21 @@ } }, "node_modules/@babel/core": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", - "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.5", - "@babel/parser": "^7.23.5", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -89,12 +89,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "dependencies": { - "@babel/types": "^7.23.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -128,14 +128,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -144,9 +144,9 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz", - "integrity": "sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.6.tgz", + "integrity": "sha512-cBXU1vZni/CpGF29iTu4YRbOZt3Wat6zCoMDxRF1MayiEc4URxOj31tT65HUM0CRpMowA3HCJaAOVOUnMf96cw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", @@ -184,9 +184,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", - "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", + "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -409,14 +409,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", - "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5" + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" @@ -437,9 +437,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -990,12 +990,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", - "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1516,13 +1517,13 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.5.tgz", - "integrity": "sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.6.tgz", + "integrity": "sha512-2XPn/BqKkZCpzYhUUNZ1ssXw7DcXfKQEjv/uXZUXgaebCMYmkEsfZ2yY+vv+xtXv50WmL5SGhyB6/xsWxIvvOQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.23.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", @@ -1562,7 +1563,7 @@ "@babel/plugin-transform-dynamic-import": "^7.23.4", "@babel/plugin-transform-exponentiation-operator": "^7.23.3", "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.3", + "@babel/plugin-transform-for-of": "^7.23.6", "@babel/plugin-transform-function-name": "^7.23.3", "@babel/plugin-transform-json-strings": "^7.23.4", "@babel/plugin-transform-literals": "^7.23.3", @@ -1649,9 +1650,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", - "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz", + "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1675,20 +1676,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", - "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", + "@babel/generator": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.5", - "@babel/types": "^7.23.5", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -1696,9 +1697,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -1788,9 +1789,9 @@ } }, "node_modules/@types/node": { - "version": "20.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", - "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -1868,13 +1869,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", - "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz", + "integrity": "sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.3", + "@babel/helper-define-polyfill-provider": "^0.4.4", "semver": "^6.3.1" }, "peerDependencies": { @@ -1882,12 +1883,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", - "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz", + "integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3", + "@babel/helper-define-polyfill-provider": "^0.4.4", "core-js-compat": "^3.33.1" }, "peerDependencies": { @@ -1895,12 +1896,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", - "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz", + "integrity": "sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3" + "@babel/helper-define-polyfill-provider": "^0.4.4" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -2071,9 +2072,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001566", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", - "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", "dev": true, "funding": [ { @@ -2462,9 +2463,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.609", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.609.tgz", - "integrity": "sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw==", + "version": "1.4.615", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", + "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", "dev": true }, "node_modules/emoji-regex": { @@ -4012,9 +4013,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true }, "node_modules/regenerator-transform": { diff --git a/javascript/MaterialXTest/package.json b/javascript/MaterialXTest/package.json index cc67644462..122ec55338 100644 --- a/javascript/MaterialXTest/package.json +++ b/javascript/MaterialXTest/package.json @@ -16,8 +16,8 @@ "author": "", "license": "ISC", "devDependencies": { - "@babel/core": "^7.23.5", - "@babel/preset-env": "^7.23.5", + "@babel/core": "^7.23.6", + "@babel/preset-env": "^7.23.6", "@babel/register": "^7.22.15", "chai": "^4.3.10", "copyfiles": "^2.4.1", diff --git a/javascript/MaterialXView/package-lock.json b/javascript/MaterialXView/package-lock.json index 2755bef7ea..474a6ff984 100644 --- a/javascript/MaterialXView/package-lock.json +++ b/javascript/MaterialXView/package-lock.json @@ -9,14 +9,13 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "dat.gui": "^0.7.9", "lil-gui": "^0.19.1", "three": "^0.152.2", "webpack": "^5.89.0" }, "devDependencies": { "copy-webpack-plugin": "^8.1.1", - "html-webpack-plugin": "^5.5.4", + "html-webpack-plugin": "^5.6.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.15.1" } @@ -162,9 +161,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.44.9", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.9.tgz", - "integrity": "sha512-6yBxcvwnnYoYT1Uk2d+jvIfsuP4mb2EdIxFnrPABj5a/838qe5bGkNLFOiipX4ULQ7XVQvTxOh7jO+BTAiqsEw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-FlsN0p4FhuYRjIxpbdXovvHQhtlG05O1GG/RNWvdAxTboR438IOTwmrY/vLA+Xfgg06BTkP045M3vpFwTMv1dg==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -241,9 +240,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", - "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dependencies": { "undici-types": "~5.26.4" } @@ -1061,11 +1060,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/dat.gui": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/dat.gui/-/dat.gui-0.7.9.tgz", - "integrity": "sha512-sCNc1OHobc+Erc1HqiswYgHdVNpSJUlk/Hz8vzOCsER7rl+oF/4+v8GXFUyCgtXpoCX6+bnmg07DedLvBLwYKQ==" - }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1246,9 +1240,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.613", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.613.tgz", - "integrity": "sha512-r4x5+FowKG6q+/Wj0W9nidx7QO31BJwmR2uEo+Qh3YLGQ8SbBAFuDFpTxzly/I2gsbrFwBuIjrMp423L3O5U3w==" + "version": "1.4.615", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", + "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -1480,9 +1474,9 @@ } }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -1877,9 +1871,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.4.tgz", - "integrity": "sha512-3wNSaVVxdxcu0jd4FpQFoICdqgxs4zIQQvj+2yQKFfBOnLETQ6X5CDWdeasuGlSsooFlMkEioWDTqBv1wvw5Iw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", "dev": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -1896,7 +1890,16 @@ "url": "https://opencollective.com/html-webpack-plugin" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/htmlparser2": { diff --git a/javascript/MaterialXView/package.json b/javascript/MaterialXView/package.json index 4c369406bd..01049bf6c9 100644 --- a/javascript/MaterialXView/package.json +++ b/javascript/MaterialXView/package.json @@ -16,7 +16,7 @@ }, "devDependencies": { "copy-webpack-plugin": "^8.1.1", - "html-webpack-plugin": "^5.5.4", + "html-webpack-plugin": "^5.6.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.15.1" } From 5bd76a89efac609097674528ae781a586340ef22 Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Fri, 22 Dec 2023 14:19:15 -0500 Subject: [PATCH 049/128] Add support for UI attributes in web viewer (#1623) - ui min, max, step support for property editor inputs - label ui advanced folders - enable complete vs reduced to get exposure of consistent inputs as with other utils. - fix nodedef input lookup to handle non-root nodes - use x,y,z,w for vector input names vs full name and ".0". --- javascript/MaterialXView/source/viewer.js | 139 ++++++++++++++++++++-- 1 file changed, 126 insertions(+), 13 deletions(-) diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js index 01006530c8..34474aeede 100644 --- a/javascript/MaterialXView/source/viewer.js +++ b/javascript/MaterialXView/source/viewer.js @@ -723,8 +723,10 @@ export class Material var startTranspCheckTime = performance.now(); const isTransparent = mx.isTransparentSurface(elem, gen.getTarget()); genContext.getOptions().hwTransparency = isTransparent; - // Always set to reduced as the parsing of uniforms can be very expensive in WebGL - genContext.getOptions().shaderInterfaceType = mx.ShaderInterfaceType.SHADER_INTERFACE_REDUCED; + // Always set to complete. + // Can consider option to set to reduced as the parsing of large numbers of uniforms (e.g. on shading models) + // can be quite expensive. + genContext.getOptions().shaderInterfaceType = mx.ShaderInterfaceType.SHADER_INTERFACE_COMPLETE; if (logDetailedTime) console.log(" - Transparency check time: ", performance.now() - startTranspCheckTime, "ms"); @@ -776,7 +778,7 @@ export class Material // Update property editor const gui = viewer.getEditor().getGUI(); - this.updateEditor(elem, shader, newMaterial, gui); + this.updateEditor(elem, shader, newMaterial, gui, viewer); if (logDetailedTime) console.log("- Per material generate time: ", performance.now() - startGenerateMat, "ms"); @@ -790,6 +792,9 @@ export class Material // updateEditor(elem, shader, material, gui) { + const DEFAULT_MIN = 0; + const DEFAULT_MAX = 100; + var startTime = performance.now(); const elemPath = elem.getNamePath(); @@ -825,8 +830,13 @@ export class Material continue; } - let currentNode = currentElem ? currentElem.getParent() : null; - let uiname; + let currentNode = null; + if (currentElem.getParent() && currentElem.getParent().getNamePath() != "") + { + currentNode = currentElem.getParent(); + } + let uiname = ""; + let nodeDefInput = null; if (currentNode) { let currentNodePath = currentNode.getNamePath(); @@ -843,15 +853,25 @@ export class Material // Check for ui attributes var nodeDef = currentNode.getNodeDef(); if (nodeDef) { - let input = nodeDef.getActiveInput(name); - if (input) { - uiname = input.getAttribute('uiname'); - let uifolderName = input.getAttribute('uifolder'); + // Remove node name from shader uniform name for non root nodes + let lookup_name = name.replace(currentNode.getName() + '_', ''); + nodeDefInput = nodeDef.getActiveInput(lookup_name); + if (nodeDefInput) + { + uiname = nodeDefInput.getAttribute('uiname'); + let uifolderName = nodeDefInput.getAttribute('uifolder'); if (uifolderName && uifolderName.length) { let newFolderName = currentNodePath + '/' + uifolderName; currentFolder = folderList[newFolderName]; if (!currentFolder) { - currentFolder = matUI.addFolder(uifolderName); + if (nodeDefInput.hasAttribute('uiadvanced')) + { + currentFolder = matUI.addFolder(uifolderName + " (Advanced)"); + } + else + { + currentFolder = matUI.addFolder(uifolderName); + } folderList[newFolderName] = currentFolder; } } @@ -896,14 +916,86 @@ export class Material case 'float': uniformToUpdate = material.uniforms[name]; if (uniformToUpdate && value != null) { - currentFolder.add(material.uniforms[name], 'value').name(path); + + var minValue = DEFAULT_MIN; + if (value < minValue) + { + minValue = value; + } + var maxValue = DEFAULT_MAX; + if (value > maxValue) + { + maxValue = value; + } + var step = 0; + if (nodeDefInput) { + if (nodeDefInput.hasAttribute('uimin')) + minValue = parseFloat(nodeDefInput.getAttribute('uimin')); + if (nodeDefInput.hasAttribute('uimax')) + maxValue = parseFloat(nodeDefInput.getAttribute('uimax')); + if (nodeDefInput.hasAttribute('uistep')) + step = parseFloat(nodeDefInput.getAttribute('uistep')); + } + if (step == 0) + { + step = (maxValue - minValue) / 1000.0; + } + currentFolder.add(material.uniforms[name], 'value', minValue, maxValue, step).name(path); } break; case 'integer': uniformToUpdate = material.uniforms[name]; if (uniformToUpdate && value != null) { - currentFolder.add(material.uniforms[name], 'value').name(path); + + var minValue = DEFAULT_MIN; + if (value < minValue) + { + minValue = value; + } + var maxValue = DEFAULT_MAX; + if (value > maxValue) + { + maxValue = value; + } + var step = 0; + var enumList = [] + if (nodeDefInput) { + if (nodeDefInput.hasAttribute('enum')) + { + enumList = nodeDefInput.getAttribute('enum').split(','); + } + else + { + if (nodeDefInput.hasAttribute('uimin')) + minValue = parseInt(nodeDefInput.getAttribute('uimin')); + if (nodeDefInput.hasAttribute('uimax')) + maxValue = parseInt(nodeDefInput.getAttribute('uimax')); + if (nodeDefInput.hasAttribute('uistep')) + step = parseInt(nodeDefInput.getAttribute('uistep')); + } + } + if (enumList.length == 0) + { + if (step == 0) + { + step = 1 / (maxValue - minValue); + step = Math.ceil(step); + if (step == 0) + { + step = 1; + } + } + } + if (enumList.length == 0) + { + currentFolder.add(material.uniforms[name], 'value', minValue, maxValue, step).name(path); + } + else + { + // TODO: Add enum support + currentFolder.add(material.uniforms[name], 'value' ).name(path); + } } break; @@ -919,9 +1011,30 @@ export class Material case 'vector4': uniformToUpdate = material.uniforms[name]; if (uniformToUpdate && value != null) { + var minValue = [DEFAULT_MIN, DEFAULT_MIN, DEFAULT_MIN, DEFAULT_MIN]; + var maxValue = [DEFAULT_MAX, DEFAULT_MAX, DEFAULT_MAX, DEFAULT_MAX]; + var step = [0, 0, 0, 0]; + + if (nodeDefInput) + { + if (nodeDefInput.hasAttribute('uimin')) + minValue = nodeDefInput.getAttribute('uimin').split(',').map(Number); + if (nodeDefInput.hasAttribute('uimax')) + maxValue = nodeDefInput.getAttribute('uimax').split(',').map(Number); + if (nodeDefInput.hasAttribute('uistep')) + step = nodeDefInput.getAttribute('uistep').split(',').map(Number); + } + for (let i = 0; i < 4; ++i) { + if (step[i] == 0) { + step[i] = 1 / (maxValue[i] - minValue[i]); + } + } + + const keyString = ["x", "y", "z", "w"]; let vecFolder = currentFolder.addFolder(path); Object.keys(material.uniforms[name].value).forEach((key) => { - vecFolder.add(material.uniforms[name].value, key).name(path + "." + key); + let w = vecFolder.add(material.uniforms[name].value, + key, minValue[key], maxValue[key], step[key]).name(keyString[key]); }) } break; From dddf104f8706c98fa6d8fc72a10c6b908f0260f0 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Fri, 22 Dec 2023 17:29:56 -0800 Subject: [PATCH 050/128] Improvements to web property editor (#1624) - Add support for uisoftmin and uisoftmax attributes. - Minor coding style updates, harmonizing on Allman braces in new code. - Remove legacy UI logic. --- javascript/MaterialXView/source/viewer.js | 89 ++++++++++++----------- 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js index 34474aeede..b0bcd98fbf 100644 --- a/javascript/MaterialXView/source/viewer.js +++ b/javascript/MaterialXView/source/viewer.js @@ -442,16 +442,6 @@ export class Editor element.style.opacity = targetOpacity; } ); - - // Hide close button - if (this._hideCloseControl) - { - Array.from(document.getElementsByClassName('close-button')).forEach( - function (element, index, array) { - element.style.display = "none"; - } - ); - } } getGUI() @@ -460,7 +450,6 @@ export class Editor } _gui = null; - _hideCloseControl = false; } class MaterialAssign @@ -864,14 +853,7 @@ export class Material let newFolderName = currentNodePath + '/' + uifolderName; currentFolder = folderList[newFolderName]; if (!currentFolder) { - if (nodeDefInput.hasAttribute('uiadvanced')) - { - currentFolder = matUI.addFolder(uifolderName + " (Advanced)"); - } - else - { - currentFolder = matUI.addFolder(uifolderName); - } + currentFolder = matUI.addFolder(uifolderName); folderList[newFolderName] = currentFolder; } } @@ -911,12 +893,12 @@ export class Material } } - switch (variable.getType().getName()) { - + switch (variable.getType().getName()) + { case 'float': uniformToUpdate = material.uniforms[name]; - if (uniformToUpdate && value != null) { - + if (uniformToUpdate && value != null) + { var minValue = DEFAULT_MIN; if (value < minValue) { @@ -928,11 +910,18 @@ export class Material maxValue = value; } var step = 0; - if (nodeDefInput) { - if (nodeDefInput.hasAttribute('uimin')) + if (nodeDefInput) + { + if (nodeDefInput.hasAttribute('uisoftmin')) + minValue = parseFloat(nodeDefInput.getAttribute('uisoftmin')); + else if (nodeDefInput.hasAttribute('uimin')) minValue = parseFloat(nodeDefInput.getAttribute('uimin')); - if (nodeDefInput.hasAttribute('uimax')) + + if (nodeDefInput.hasAttribute('uisoftmax')) + maxValue = parseFloat(nodeDefInput.getAttribute('uisoftmax')); + else if (nodeDefInput.hasAttribute('uimax')) maxValue = parseFloat(nodeDefInput.getAttribute('uimax')); + if (nodeDefInput.hasAttribute('uistep')) step = parseFloat(nodeDefInput.getAttribute('uistep')); } @@ -946,8 +935,8 @@ export class Material case 'integer': uniformToUpdate = material.uniforms[name]; - if (uniformToUpdate && value != null) { - + if (uniformToUpdate && value != null) + { var minValue = DEFAULT_MIN; if (value < minValue) { @@ -960,17 +949,24 @@ export class Material } var step = 0; var enumList = [] - if (nodeDefInput) { + if (nodeDefInput) + { if (nodeDefInput.hasAttribute('enum')) { enumList = nodeDefInput.getAttribute('enum').split(','); } else { - if (nodeDefInput.hasAttribute('uimin')) + if (nodeDefInput.hasAttribute('uisoftmin')) + minValue = parseInt(nodeDefInput.getAttribute('uisoftmin')); + else if (nodeDefInput.hasAttribute('uimin')) minValue = parseInt(nodeDefInput.getAttribute('uimin')); - if (nodeDefInput.hasAttribute('uimax')) + + if (nodeDefInput.hasAttribute('uisoftmax')) + maxValue = parseInt(nodeDefInput.getAttribute('uisoftmax')); + else if (nodeDefInput.hasAttribute('uimax')) maxValue = parseInt(nodeDefInput.getAttribute('uimax')); + if (nodeDefInput.hasAttribute('uistep')) step = parseInt(nodeDefInput.getAttribute('uistep')); } @@ -1001,7 +997,8 @@ export class Material case 'boolean': uniformToUpdate = material.uniforms[name]; - if (uniformToUpdate && value != null) { + if (uniformToUpdate && value != null) + { currentFolder.add(material.uniforms[name], 'value').name(path); } break; @@ -1010,22 +1007,31 @@ export class Material case 'vector3': case 'vector4': uniformToUpdate = material.uniforms[name]; - if (uniformToUpdate && value != null) { + if (uniformToUpdate && value != null) + { var minValue = [DEFAULT_MIN, DEFAULT_MIN, DEFAULT_MIN, DEFAULT_MIN]; var maxValue = [DEFAULT_MAX, DEFAULT_MAX, DEFAULT_MAX, DEFAULT_MAX]; var step = [0, 0, 0, 0]; if (nodeDefInput) { - if (nodeDefInput.hasAttribute('uimin')) + if (nodeDefInput.hasAttribute('uisoftmin')) + minValue = nodeDefInput.getAttribute('uisoftmin').split(',').map(Number); + else if (nodeDefInput.hasAttribute('uimin')) minValue = nodeDefInput.getAttribute('uimin').split(',').map(Number); - if (nodeDefInput.hasAttribute('uimax')) + + if (nodeDefInput.hasAttribute('uisoftmax')) + maxValue = nodeDefInput.getAttribute('uisoftmax').split(',').map(Number); + else if (nodeDefInput.hasAttribute('uimax')) maxValue = nodeDefInput.getAttribute('uimax').split(',').map(Number); + if (nodeDefInput.hasAttribute('uistep')) step = nodeDefInput.getAttribute('uistep').split(',').map(Number); } - for (let i = 0; i < 4; ++i) { - if (step[i] == 0) { + for (let i = 0; i < 4; ++i) + { + if (step[i] == 0) + { step[i] = 1 / (maxValue[i] - minValue[i]); } } @@ -1042,8 +1048,10 @@ export class Material case 'color3': // Irksome way to mape arrays to colors and back uniformToUpdate = material.uniforms[name]; - if (uniformToUpdate && value != null) { - var dummy = { + if (uniformToUpdate && value != null) + { + var dummy = + { color: 0xFF0000 }; const color3 = new THREE.Color(dummy.color); @@ -1053,8 +1061,7 @@ export class Material .onChange(function (value) { const color3 = new THREE.Color(value); material.uniforms[name].value.set(color3.toArray()); - } - ); + }); } break; From eae062a038bcd8f8172b1725e93e35641dc73f61 Mon Sep 17 00:00:00 2001 From: Apoorva Joshi Date: Fri, 29 Dec 2023 07:02:58 +0100 Subject: [PATCH 051/128] Improvements to prefiltered environment maps (#1420) This changelist adds support for prefiltering environment maps on the GPU, using filtered VNDF sampling for efficiency. The MaterialX Viewer can be used to test the new functionality by unchecking the Environment FIS option in Advanced Settings. --- .../genglsl/lib/mx_environment_fis.glsl | 10 -- .../genglsl/lib/mx_environment_prefilter.glsl | 9 +- .../genglsl/lib/mx_microfacet_specular.glsl | 24 +++++ .../genglsl/lib/mx_prefilter_environment.glsl | 76 +++++++++++++ .../JsMaterialXGenShader/JsGenOptions.cpp | 1 + .../MaterialXGenGlsl/GlslShaderGenerator.cpp | 13 ++- source/MaterialXGenMsl/MslShaderGenerator.cpp | 11 ++ source/MaterialXGenShader/GenOptions.h | 5 + .../MaterialXGenShader/HwShaderGenerator.cpp | 13 +++ source/MaterialXGenShader/HwShaderGenerator.h | 2 + source/MaterialXRender/ImageHandler.cpp | 2 +- source/MaterialXRender/ImageHandler.h | 2 +- source/MaterialXRender/LightHandler.h | 27 +++++ source/MaterialXRender/Util.cpp | 20 ++++ source/MaterialXRender/Util.h | 5 + .../MaterialXRenderGlsl/GLTextureHandler.cpp | 2 +- source/MaterialXRenderGlsl/GLTextureHandler.h | 2 +- source/MaterialXRenderGlsl/GlslProgram.cpp | 13 ++- .../MaterialXRenderMsl/MetalTextureHandler.h | 2 +- .../MaterialXRenderMsl/MetalTextureHandler.mm | 6 +- .../MslPipelineStateObject.mm | 2 +- source/MaterialXView/RenderPipeline.h | 1 + source/MaterialXView/RenderPipelineGL.cpp | 102 +++++++++++++++++- source/MaterialXView/RenderPipelineGL.h | 1 + source/MaterialXView/RenderPipelineMetal.h | 2 + source/MaterialXView/RenderPipelineMetal.mm | 98 ++++++++++++++++- source/MaterialXView/Viewer.cpp | 5 + .../PyMaterialXGenShader/PyGenOptions.cpp | 1 + 28 files changed, 425 insertions(+), 32 deletions(-) create mode 100644 libraries/pbrlib/genglsl/lib/mx_prefilter_environment.glsl diff --git a/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl b/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl index 575991e28d..85c88c3280 100644 --- a/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl @@ -1,15 +1,5 @@ #include "mx_microfacet_specular.glsl" -// https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html -// Section 20.4 Equation 13 -float mx_latlong_compute_lod(vec3 dir, float pdf, float maxMipLevel, int envSamples) -{ - const float MIP_LEVEL_OFFSET = 1.5; - float effectiveMaxMipLevel = maxMipLevel - MIP_LEVEL_OFFSET; - float distortion = sqrt(1.0 - mx_square(dir.y)); - return max(effectiveMaxMipLevel - 0.5 * log2(float(envSamples) * pdf * distortion), 0.0); -} - vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd) { // Generate tangent frame. diff --git a/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl b/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl index 6def6fb439..e448ae247e 100644 --- a/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl @@ -1,12 +1,5 @@ #include "mx_microfacet_specular.glsl" -float mx_latlong_compute_lod(float alpha) -{ - // Select a mip level based on input alpha. - float lodBias = alpha < 0.25 ? sqrt(alpha) : 0.5*alpha + 0.375; - return lodBias * float($envRadianceMips); -} - vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd) { N = mx_forward_facing_normal(N, V); @@ -19,7 +12,7 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio float G = mx_ggx_smith_G2(NdotV, NdotV, avgAlpha); vec3 FG = fd.refraction ? vec3(1.0) - (F * G) : F * G; - vec3 Li = mx_latlong_map_lookup(L, $envMatrix, mx_latlong_compute_lod(avgAlpha), $envRadiance); + vec3 Li = mx_latlong_map_lookup(L, $envMatrix, mx_latlong_alpha_to_lod(avgAlpha), $envRadiance); return Li * FG; } diff --git a/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl b/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl index 63aba17869..85430c00ca 100644 --- a/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl @@ -593,3 +593,27 @@ vec3 mx_latlong_map_lookup(vec3 dir, mat4 transform, float lod, sampler2D envSam vec2 uv = mx_latlong_projection(envDir); return textureLod(envSampler, uv, lod).rgb; } + +// https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html +// Section 20.4 Equation 13 +float mx_latlong_compute_lod(vec3 dir, float pdf, float maxMipLevel, int envSamples) +{ + const float MIP_LEVEL_OFFSET = 1.5; + float effectiveMaxMipLevel = maxMipLevel - MIP_LEVEL_OFFSET; + float distortion = sqrt(1.0 - mx_square(dir.y)); + return max(effectiveMaxMipLevel - 0.5 * log2(float(envSamples) * pdf * distortion), 0.0); +} + +float mx_latlong_alpha_to_lod(float alpha) +{ + // Return the mip level associated with the given alpha in a prefiltered environment. + float lodBias = (alpha < 0.25) ? sqrt(alpha) : 0.5 * alpha + 0.375; + return lodBias * float($envRadianceMips - 1); +} + +float mx_latlong_lod_to_alpha(float lod) +{ + // Return the alpha associated with the given mip level in a prefiltered environment. + float lodBias = lod / float($envRadianceMips - 1); + return (lodBias < 0.5) ? mx_square(lodBias) : 2.0 * (lodBias - 0.375); +} diff --git a/libraries/pbrlib/genglsl/lib/mx_prefilter_environment.glsl b/libraries/pbrlib/genglsl/lib/mx_prefilter_environment.glsl new file mode 100644 index 0000000000..fd608871ed --- /dev/null +++ b/libraries/pbrlib/genglsl/lib/mx_prefilter_environment.glsl @@ -0,0 +1,76 @@ +#include "mx_microfacet_specular.glsl" + +// Construct an orthonormal basis from a unit vector. +// https://graphics.pixar.com/library/OrthonormalB/paper.pdf +mat3 mx_orthonormal_basis(vec3 N) +{ + float sign = (N.z < 0.0) ? -1.0 : 1.0; + float a = -1.0 / (sign + N.z); + float b = N.x * N.y * a; + vec3 X = vec3(1.0 + sign * N.x * N.x * a, sign * b, -sign * N.x); + vec3 Y = vec3(b, sign + N.y * N.y * a, -N.y); + return mat3(X, Y, N); +} + +// The inverse of mx_latlong_projection. +vec3 mx_latlong_map_projection_inverse(vec2 uv) +{ + float latitude = (uv.y - 0.5) * M_PI; + float longitude = (uv.x - 0.5) * M_PI * 2.0; + + float x = -cos(latitude) * sin(longitude); + float y = -sin(latitude); + float z = cos(latitude) * cos(longitude); + + return vec3(x, y, z); +} + +vec3 mx_prefilter_environment() +{ + vec2 uv = gl_FragCoord.xy * pow(2.0, $envPrefilterMip) / vec2(2048.0, 1024.0); + float alpha = mx_latlong_lod_to_alpha(float($envPrefilterMip)); + if ($envPrefilterMip == 0) + { + return textureLod($envRadiance, uv, 0).rgb; + } + + // Compute world normal and transform. + vec3 worldN = mx_latlong_map_projection_inverse(uv); + mat3 tangentToWorld = mx_orthonormal_basis(worldN); + + // Local normal and view vectors are constant and aligned. + vec3 V = vec3(0.0, 0.0, 1.0); + float NdotV = 1.0; + float G1V = mx_ggx_smith_G1(NdotV, alpha); + + // Integrate the LD term for the given environment and alpha. + vec3 radiance = vec3(0.0, 0.0, 0.0); + float weight = 0.0; + int envRadianceSamples = 1024; + for (int i = 0; i < envRadianceSamples; i++) + { + vec2 Xi = mx_spherical_fibonacci(i, envRadianceSamples); + + // Compute the half vector and incoming light direction. + vec3 H = mx_ggx_importance_sample_VNDF(Xi, V, vec2(alpha)); + vec3 L = -V + 2.0 * H.z * H; + + // Compute dot products for this sample. + float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0); + + // Compute the geometric term. + float G = mx_ggx_smith_G2(NdotL, NdotV, alpha); + + // Sample the environment light from the given direction. + vec3 Lw = tangentToWorld * L; + float pdf = mx_ggx_NDF(H, vec2(alpha)) * G1V / (4.0 * NdotV); + float lod = mx_latlong_compute_lod(Lw, pdf, float($envRadianceMips - 1), envRadianceSamples); + vec3 sampleColor = mx_latlong_map_lookup(Lw, $envMatrix, lod, $envRadiance); + + // Add the radiance contribution of this sample. + radiance += G * sampleColor; + weight += G; + } + + return radiance / weight; +} diff --git a/source/JsMaterialX/JsMaterialXGenShader/JsGenOptions.cpp b/source/JsMaterialX/JsMaterialXGenShader/JsGenOptions.cpp index 7e3313cdf7..9b28a6f534 100644 --- a/source/JsMaterialX/JsMaterialXGenShader/JsGenOptions.cpp +++ b/source/JsMaterialX/JsMaterialXGenShader/JsGenOptions.cpp @@ -42,5 +42,6 @@ EMSCRIPTEN_BINDINGS(GenOptions) .property("hwMaxActiveLightSources", &mx::GenOptions::hwMaxActiveLightSources) .property("hwNormalizeUdimTexCoords", &mx::GenOptions::hwNormalizeUdimTexCoords) .property("hwWriteAlbedoTable", &mx::GenOptions::hwWriteAlbedoTable) + .property("hwWriteEnvPrefilter", &mx::GenOptions::hwWriteEnvPrefilter) ; } diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp index ea78e1bee3..b9351ddc08 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp @@ -553,7 +553,7 @@ void GlslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& c bool lighting = requiresLighting(graph); // Define directional albedo approach - if (lighting || context.getOptions().hwWriteAlbedoTable) + if (lighting || context.getOptions().hwWriteAlbedoTable || context.getOptions().hwWriteEnvPrefilter) { emitLine("#define DIRECTIONAL_ALBEDO_METHOD " + std::to_string(int(context.getOptions().hwDirectionalAlbedoMethod)), stage, false); emitLineBreak(stage); @@ -591,6 +591,13 @@ void GlslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& c emitLineBreak(stage); } + // Emit environment prefiltering code + if (context.getOptions().hwWriteEnvPrefilter) + { + emitLibraryInclude("pbrlib/genglsl/lib/mx_prefilter_environment.glsl", context, stage); + emitLineBreak(stage); + } + // Set the include file to use for uv transformations, // depending on the vertical flip flag. if (context.getOptions().fileTextureVerticalFlip) @@ -636,6 +643,10 @@ void GlslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& c { emitLine(outputSocket->getVariable() + " = vec4(mx_generate_dir_albedo_table(), 1.0)", stage); } + else if (context.getOptions().hwWriteEnvPrefilter) + { + emitLine(outputSocket->getVariable() + " = vec4(mx_prefilter_environment(), 1.0)", stage); + } else { // Add all function calls. diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index 7fe50fef4a..5749f0d211 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -1059,6 +1059,13 @@ void MslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& co emitLineBreak(stage); } + // Emit environment prefiltering code + if (context.getOptions().hwWriteEnvPrefilter) + { + emitLibraryInclude("pbrlib/genglsl/lib/mx_prefilter_environment.glsl", context, stage); + emitLineBreak(stage); + } + // Set the include file to use for uv transformations, // depending on the vertical flip flag. if (context.getOptions().fileTextureVerticalFlip) @@ -1104,6 +1111,10 @@ void MslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& co { emitLine(outputSocket->getVariable() + " = float4(mx_generate_dir_albedo_table(), 1.0)", stage); } + else if (context.getOptions().hwWriteEnvPrefilter) + { + emitLine(outputSocket->getVariable() + " = float4(mx_prefilter_environment(), 1.0)", stage); + } else { // Add all function calls. diff --git a/source/MaterialXGenShader/GenOptions.h b/source/MaterialXGenShader/GenOptions.h index 34a1efde0b..6af73d62a8 100644 --- a/source/MaterialXGenShader/GenOptions.h +++ b/source/MaterialXGenShader/GenOptions.h @@ -90,6 +90,7 @@ class MX_GENSHADER_API GenOptions hwMaxActiveLightSources(3), hwNormalizeUdimTexCoords(false), hwWriteAlbedoTable(false), + hwWriteEnvPrefilter(false), hwImplicitBitangents(true), emitColorTransforms(true) { @@ -174,6 +175,10 @@ class MX_GENSHADER_API GenOptions /// Defaults to false. bool hwWriteAlbedoTable; + /// Enables the generation of a prefiltered environment map. + /// Defaults to false. + bool hwWriteEnvPrefilter; + /// Calculate fallback bitangents from existing normals and tangents /// inside the bitangent node. bool hwImplicitBitangents; diff --git a/source/MaterialXGenShader/HwShaderGenerator.cpp b/source/MaterialXGenShader/HwShaderGenerator.cpp index 0db78eda27..6ba94d1280 100644 --- a/source/MaterialXGenShader/HwShaderGenerator.cpp +++ b/source/MaterialXGenShader/HwShaderGenerator.cpp @@ -59,6 +59,7 @@ const string T_ENV_RADIANCE = "$envRadiance"; const string T_ENV_RADIANCE_MIPS = "$envRadianceMips"; const string T_ENV_RADIANCE_SAMPLES = "$envRadianceSamples"; const string T_ENV_IRRADIANCE = "$envIrradiance"; +const string T_ENV_PREFILTER_MIP = "$envPrefilterMip"; const string T_REFRACTION_TWO_SIDED = "$refractionTwoSided"; const string T_ALBEDO_TABLE = "$albedoTable"; const string T_ALBEDO_TABLE_SIZE = "$albedoTableSize"; @@ -113,6 +114,7 @@ const string ENV_RADIANCE = "u_envRadiance"; const string ENV_RADIANCE_MIPS = "u_envRadianceMips"; const string ENV_RADIANCE_SAMPLES = "u_envRadianceSamples"; const string ENV_IRRADIANCE = "u_envIrradiance"; +const string ENV_PREFILTER_MIP = "u_envPrefilterMip"; const string REFRACTION_TWO_SIDED = "u_refractionTwoSided"; const string ALBEDO_TABLE = "u_albedoTable"; const string ALBEDO_TABLE_SIZE = "u_albedoTableSize"; @@ -222,6 +224,7 @@ HwShaderGenerator::HwShaderGenerator(SyntaxPtr syntax) : _tokenSubstitutions[HW::T_AMB_OCC_GAIN] = HW::AMB_OCC_GAIN; _tokenSubstitutions[HW::T_VERTEX_DATA_INSTANCE] = HW::VERTEX_DATA_INSTANCE; _tokenSubstitutions[HW::T_LIGHT_DATA_INSTANCE] = HW::LIGHT_DATA_INSTANCE; + _tokenSubstitutions[HW::T_ENV_PREFILTER_MIP] = HW::ENV_PREFILTER_MIP; // Setup closure contexts for defining closure functions // @@ -359,6 +362,16 @@ ShaderPtr HwShaderGenerator::createShader(const string& name, ElementPtr element psPrivateUniforms->add(Type::INTEGER, HW::T_ALBEDO_TABLE_SIZE, Value::createValue(64)); } + // Add uniforms for environment prefiltering. + if (context.getOptions().hwWriteEnvPrefilter) + { + psPrivateUniforms->add(Type::FILENAME, HW::T_ENV_RADIANCE); + psPrivateUniforms->add(Type::INTEGER, HW::T_ENV_PREFILTER_MIP, Value::createValue(1)); + const Matrix44 yRotationPI = Matrix44::createScale(Vector3(-1, 1, -1)); + psPrivateUniforms->add(Type::MATRIX44, HW::T_ENV_MATRIX, Value::createValue(yRotationPI)); + psPrivateUniforms->add(Type::INTEGER, HW::T_ENV_RADIANCE_MIPS, Value::createValue(1)); + } + // Create uniforms for the published graph interface for (ShaderGraphInputSocket* inputSocket : graph->getInputSockets()) { diff --git a/source/MaterialXGenShader/HwShaderGenerator.h b/source/MaterialXGenShader/HwShaderGenerator.h index bba572c631..f839ac56bd 100644 --- a/source/MaterialXGenShader/HwShaderGenerator.h +++ b/source/MaterialXGenShader/HwShaderGenerator.h @@ -126,6 +126,7 @@ extern MX_GENSHADER_API const string T_ENV_RADIANCE; extern MX_GENSHADER_API const string T_ENV_RADIANCE_MIPS; extern MX_GENSHADER_API const string T_ENV_RADIANCE_SAMPLES; extern MX_GENSHADER_API const string T_ENV_IRRADIANCE; +extern MX_GENSHADER_API const string T_ENV_PREFILTER_MIP; extern MX_GENSHADER_API const string T_REFRACTION_TWO_SIDED; extern MX_GENSHADER_API const string T_ALBEDO_TABLE; extern MX_GENSHADER_API const string T_ALBEDO_TABLE_SIZE; @@ -182,6 +183,7 @@ extern MX_GENSHADER_API const string ENV_RADIANCE; extern MX_GENSHADER_API const string ENV_RADIANCE_MIPS; extern MX_GENSHADER_API const string ENV_RADIANCE_SAMPLES; extern MX_GENSHADER_API const string ENV_IRRADIANCE; +extern MX_GENSHADER_API const string ENV_PREFILTER_MIP; extern MX_GENSHADER_API const string REFRACTION_TWO_SIDED; extern MX_GENSHADER_API const string ALBEDO_TABLE; extern MX_GENSHADER_API const string ALBEDO_TABLE_SIZE; diff --git a/source/MaterialXRender/ImageHandler.cpp b/source/MaterialXRender/ImageHandler.cpp index 2d56207f32..b148bf63d9 100644 --- a/source/MaterialXRender/ImageHandler.cpp +++ b/source/MaterialXRender/ImageHandler.cpp @@ -165,7 +165,7 @@ void ImageHandler::unbindImages() } } -bool ImageHandler::createRenderResources(ImagePtr, bool) +bool ImageHandler::createRenderResources(ImagePtr, bool, bool) { return false; } diff --git a/source/MaterialXRender/ImageHandler.h b/source/MaterialXRender/ImageHandler.h index e8eaf99b2f..e5d2082f8d 100644 --- a/source/MaterialXRender/ImageHandler.h +++ b/source/MaterialXRender/ImageHandler.h @@ -230,7 +230,7 @@ class MX_RENDER_API ImageHandler } /// Create rendering resources for the given image. - virtual bool createRenderResources(ImagePtr image, bool generateMipMaps); + virtual bool createRenderResources(ImagePtr image, bool generateMipMaps, bool useAsRenderTarget = false); /// Release rendering resources for the given image, or for all cached images /// if no image pointer is specified. diff --git a/source/MaterialXRender/LightHandler.h b/source/MaterialXRender/LightHandler.h index 852ccfa41d..a080c72081 100644 --- a/source/MaterialXRender/LightHandler.h +++ b/source/MaterialXRender/LightHandler.h @@ -37,6 +37,7 @@ class MX_RENDER_API LightHandler _lightTransform(Matrix44::IDENTITY), _directLighting(true), _indirectLighting(true), + _usePrefilteredMap(false), _envSampleCount(DEFAULT_ENV_SAMPLE_COUNT), _refractionTwoSided(false) { @@ -101,6 +102,30 @@ class MX_RENDER_API LightHandler return _envRadianceMap; } + /// Set the environment radiance map for the prefiltered environment lighting model. + void setEnvPrefilteredMap(ImagePtr map) + { + _envPrefilteredMap = map; + } + + /// Return the environment radiance map for the prefiltered environment lighting model. + ImagePtr getEnvPrefilteredMap() const + { + return _envPrefilteredMap; + } + + /// Set whether to use the prefiltered environment lighting model. + void setUsePrefilteredMap(bool val) + { + _usePrefilteredMap = val; + } + + /// Return whether to use the prefiltered environment lighting model. + bool getUsePrefilteredMap() + { + return _usePrefilteredMap; + } + /// Set the environment irradiance map void setEnvIrradianceMap(ImagePtr map) { @@ -216,8 +241,10 @@ class MX_RENDER_API LightHandler Matrix44 _lightTransform; bool _directLighting; bool _indirectLighting; + bool _usePrefilteredMap; ImagePtr _envRadianceMap; + ImagePtr _envPrefilteredMap; ImagePtr _envIrradianceMap; int _envSampleCount; diff --git a/source/MaterialXRender/Util.cpp b/source/MaterialXRender/Util.cpp index e8ec0f7c48..f33c67173e 100644 --- a/source/MaterialXRender/Util.cpp +++ b/source/MaterialXRender/Util.cpp @@ -76,6 +76,26 @@ ShaderPtr createAlbedoTableShader(GenContext& context, return shader; } +ShaderPtr createEnvPrefilterShader(GenContext& context, + DocumentPtr stdLib, + const string& shaderName) +{ + // Construct a dummy nodegraph. + DocumentPtr doc = createDocument(); + doc->importLibrary(stdLib); + NodeGraphPtr nodeGraph = doc->addNodeGraph(); + NodePtr constant = nodeGraph->addNode("constant"); + OutputPtr output = nodeGraph->addOutput(); + output->setConnectedNode(constant); + + // Generate the shader + GenContext tableContext = context; + tableContext.getOptions().hwWriteEnvPrefilter = true; + ShaderPtr shader = createShader(shaderName, tableContext, output); + + return shader; +} + ShaderPtr createBlurShader(GenContext& context, DocumentPtr stdLib, const string& shaderName, diff --git a/source/MaterialXRender/Util.h b/source/MaterialXRender/Util.h index 922c06e529..bf1a3d543c 100644 --- a/source/MaterialXRender/Util.h +++ b/source/MaterialXRender/Util.h @@ -47,6 +47,11 @@ MX_RENDER_API ShaderPtr createAlbedoTableShader(GenContext& context, DocumentPtr stdLib, const string& shaderName); +/// Create a shader that generates a prefiltered environment map. +MX_RENDER_API ShaderPtr createEnvPrefilterShader(GenContext& context, + DocumentPtr stdLib, + const string& shaderName); + /// Create a blur shader, using the given standard libraries for code generation. MX_RENDER_API ShaderPtr createBlurShader(GenContext& context, DocumentPtr stdLib, diff --git a/source/MaterialXRenderGlsl/GLTextureHandler.cpp b/source/MaterialXRenderGlsl/GLTextureHandler.cpp index 314a78c257..02a0a53927 100644 --- a/source/MaterialXRenderGlsl/GLTextureHandler.cpp +++ b/source/MaterialXRenderGlsl/GLTextureHandler.cpp @@ -91,7 +91,7 @@ bool GLTextureHandler::unbindImage(ImagePtr image) return false; } -bool GLTextureHandler::createRenderResources(ImagePtr image, bool generateMipMaps) +bool GLTextureHandler::createRenderResources(ImagePtr image, bool generateMipMaps, bool) { if (image->getResourceId() == GlslProgram::UNDEFINED_OPENGL_RESOURCE_ID) { diff --git a/source/MaterialXRenderGlsl/GLTextureHandler.h b/source/MaterialXRenderGlsl/GLTextureHandler.h index 942d6dc446..13eaab098f 100644 --- a/source/MaterialXRenderGlsl/GLTextureHandler.h +++ b/source/MaterialXRenderGlsl/GLTextureHandler.h @@ -37,7 +37,7 @@ class MX_RENDERGLSL_API GLTextureHandler : public ImageHandler bool unbindImage(ImagePtr image) override; /// Create rendering resources for the given image. - bool createRenderResources(ImagePtr image, bool generateMipMaps) override; + bool createRenderResources(ImagePtr image, bool generateMipMaps, bool useAsRenderTarget = false) override; /// Release rendering resources for the given image, or for all cached images /// if no image pointer is specified. diff --git a/source/MaterialXRenderGlsl/GlslProgram.cpp b/source/MaterialXRenderGlsl/GlslProgram.cpp index 4497019e91..eecab8036e 100644 --- a/source/MaterialXRenderGlsl/GlslProgram.cpp +++ b/source/MaterialXRenderGlsl/GlslProgram.cpp @@ -578,9 +578,20 @@ void GlslProgram::bindLighting(LightHandlerPtr lightHandler, ImageHandlerPtr ima Matrix44 envRotation = Matrix44::createRotationY(PI) * lightHandler->getLightTransform().getTranspose(); bindUniform(HW::ENV_MATRIX, Value::createValue(envRotation), false); bindUniform(HW::ENV_RADIANCE_SAMPLES, Value::createValue(lightHandler->getEnvSampleCount()), false); + ImagePtr envRadiance = nullptr; + if (lightHandler->getIndirectLighting()) + { + envRadiance = lightHandler->getUsePrefilteredMap() ? + lightHandler->getEnvPrefilteredMap() : + lightHandler->getEnvRadianceMap(); + } + else + { + envRadiance = imageHandler->getZeroImage(); + } ImageMap envImages = { - { HW::ENV_RADIANCE, lightHandler->getIndirectLighting() ? lightHandler->getEnvRadianceMap() : imageHandler->getZeroImage() }, + { HW::ENV_RADIANCE, envRadiance }, { HW::ENV_IRRADIANCE, lightHandler->getIndirectLighting() ? lightHandler->getEnvIrradianceMap() : imageHandler->getZeroImage() } }; for (const auto& env : envImages) diff --git a/source/MaterialXRenderMsl/MetalTextureHandler.h b/source/MaterialXRenderMsl/MetalTextureHandler.h index 4c329f3f6d..c78469a4ce 100644 --- a/source/MaterialXRenderMsl/MetalTextureHandler.h +++ b/source/MaterialXRenderMsl/MetalTextureHandler.h @@ -57,7 +57,7 @@ class MX_RENDERMSL_API MetalTextureHandler : public ImageHandler id getMTLSamplerStateForImage(unsigned int index); /// Create rendering resources for the given image. - bool createRenderResources(ImagePtr image, bool generateMipMaps) override; + bool createRenderResources(ImagePtr image, bool generateMipMaps, bool useAsRenderTarget = false) override; /// Release rendering resources for the given image, or for all cached images /// if no image pointer is specified. diff --git a/source/MaterialXRenderMsl/MetalTextureHandler.mm b/source/MaterialXRenderMsl/MetalTextureHandler.mm index 745019ac92..ab8da46f1f 100644 --- a/source/MaterialXRenderMsl/MetalTextureHandler.mm +++ b/source/MaterialXRenderMsl/MetalTextureHandler.mm @@ -128,7 +128,7 @@ return false; } -bool MetalTextureHandler::createRenderResources(ImagePtr image, bool generateMipMaps) +bool MetalTextureHandler::createRenderResources(ImagePtr image, bool generateMipMaps, bool useAsRenderTarget) { id texture = nil; @@ -149,9 +149,7 @@ texDesc.height = image->getHeight(); texDesc.mipmapLevelCount = generateMipMaps ? image->getMaxMipCount() : 1; texDesc.usage = MTLTextureUsageShaderRead | - // For now, we set generate mip maps flag off, - // when we want to use the texture as render target - (!generateMipMaps ? MTLTextureUsageRenderTarget : 0); + (useAsRenderTarget ? MTLTextureUsageRenderTarget : 0); texDesc.resourceOptions = MTLResourceStorageModePrivate; texDesc.pixelFormat = pixelFormat; if(generateMipMaps) diff --git a/source/MaterialXRenderMsl/MslPipelineStateObject.mm b/source/MaterialXRenderMsl/MslPipelineStateObject.mm index 4f8378ae46..f0cc8e47bb 100644 --- a/source/MaterialXRenderMsl/MslPipelineStateObject.mm +++ b/source/MaterialXRenderMsl/MslPipelineStateObject.mm @@ -594,7 +594,7 @@ int GetStrideOfMetalType(MTLDataType type) // Bind environment lights. ImageMap envLights = { - { HW::ENV_RADIANCE, lightHandler->getEnvRadianceMap() }, + { HW::ENV_RADIANCE, lightHandler->getUsePrefilteredMap() ? lightHandler->getEnvPrefilteredMap() : lightHandler->getEnvRadianceMap() }, { HW::ENV_IRRADIANCE, lightHandler->getEnvIrradianceMap() } }; for (const auto& env : envLights) diff --git a/source/MaterialXView/RenderPipeline.h b/source/MaterialXView/RenderPipeline.h index 87baac3fa4..3b7e7a48b7 100644 --- a/source/MaterialXView/RenderPipeline.h +++ b/source/MaterialXView/RenderPipeline.h @@ -50,6 +50,7 @@ class RenderPipeline virtual void bakeTextures() = 0; virtual void updateAlbedoTable(int tableSize) = 0; + virtual void updatePrefilteredMap() = 0; virtual std::shared_ptr createTextureBaker(unsigned int width, unsigned int height, mx::Image::BaseType baseType) = 0; diff --git a/source/MaterialXView/RenderPipelineGL.cpp b/source/MaterialXView/RenderPipelineGL.cpp index f08704d0a3..68ac0be040 100644 --- a/source/MaterialXView/RenderPipelineGL.cpp +++ b/source/MaterialXView/RenderPipelineGL.cpp @@ -110,6 +110,100 @@ void GLRenderPipeline::updateAlbedoTable(int tableSize) glDrawBuffer(GL_BACK); } +void GLRenderPipeline::updatePrefilteredMap() +{ + auto& genContext = _viewer->_genContext; + auto& lightHandler = _viewer->_lightHandler; + auto& imageHandler = _viewer->_imageHandler; + + if (lightHandler->getEnvPrefilteredMap()) + { + return; + } + + // Create the prefilter shader. + mx::GlslMaterialPtr material = nullptr; + try + { + mx::ShaderPtr hwShader = mx::createEnvPrefilterShader(genContext, _viewer->_stdLib, "__ENV_PREFILTER__"); + material = mx::GlslMaterial::create(); + material->generateShader(hwShader); + } + catch (std::exception& e) + { + new ng::MessageDialog(_viewer, ng::MessageDialog::Type::Warning, "Failed to generate prefilter shader", e.what()); + } + + mx::ImagePtr srcTex = lightHandler->getEnvRadianceMap(); + + int w = srcTex->getWidth(); + int h = srcTex->getHeight(); + int numMips = srcTex->getMaxMipCount(); + + // Create texture to hold the prefiltered environment. + mx::GLTextureHandlerPtr glImageHandler = std::dynamic_pointer_cast(imageHandler); + mx::ImagePtr outTex = mx::Image::create(w, h, 3, mx::Image::BaseType::HALF); + glImageHandler->createRenderResources(outTex, true, true); + + mx::GlslProgramPtr program = material->getProgram(); + + try + { + int i = 0; + while (w > 0 && h > 0) + { + // Create framebuffer + unsigned int framebuffer; + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, outTex->getResourceId(), i); + glViewport(0, 0, w, h); + material->bindShader(); + + // Bind the source texture + mx::ImageSamplingProperties samplingProperties; + samplingProperties.uaddressMode = mx::ImageSamplingProperties::AddressMode::PERIODIC; + samplingProperties.vaddressMode = mx::ImageSamplingProperties::AddressMode::CLAMP; + samplingProperties.filterType = mx::ImageSamplingProperties::FilterType::LINEAR; + imageHandler->bindImage(srcTex, samplingProperties); + int textureLocation = glImageHandler->getBoundTextureLocation(srcTex->getResourceId()); + assert(textureLocation >= 0); + material->getProgram()->bindUniform(mx::HW::ENV_RADIANCE, mx::Value::createValue(textureLocation)); + // Bind other uniforms + program->bindUniform(mx::HW::ENV_PREFILTER_MIP, mx::Value::createValue(i)); + const mx::Matrix44 yRotationPI = mx::Matrix44::createScale(mx::Vector3(-1, 1, -1)); + program->bindUniform(mx::HW::ENV_MATRIX, mx::Value::createValue(yRotationPI)); + program->bindUniform(mx::HW::ENV_RADIANCE_MIPS, mx::Value::createValue(numMips)); + + _viewer->renderScreenSpaceQuad(material); + + glDeleteFramebuffers(1, &framebuffer); + + w /= 2; + h /= 2; + i++; + } + } + catch (mx::ExceptionRenderError& e) + { + for (const std::string& error : e.errorLog()) + { + std::cerr << error << std::endl; + } + new ng::MessageDialog(_viewer, ng::MessageDialog::Type::Warning, "Failed to render prefiltered environment", e.what()); + } + catch (std::exception& e) + { + new ng::MessageDialog(_viewer, ng::MessageDialog::Type::Warning, "Failed to render prefiltered environment", e.what()); + } + + // Clean up. + glViewport(0, 0, _viewer->m_fbsize[0], _viewer->m_fbsize[1]); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + lightHandler->setEnvPrefilteredMap(outTex); +} + mx::ImagePtr GLRenderPipeline::getShadowMap(int shadowMapSize) { auto& genContext = _viewer->_genContext; @@ -219,7 +313,13 @@ void GLRenderPipeline::renderFrame(void*, int shadowMapSize, const char* dirLigh float lightRotation = _viewer->_lightRotation; auto& searchPath = _viewer->_searchPath; auto& geometryHandler = _viewer->_geometryHandler; - + + // Update prefiltered environment. + if (lightHandler->getUsePrefilteredMap() && !_viewer->_materialAssignments.empty()) + { + updatePrefilteredMap(); + } + // Initialize OpenGL state glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); diff --git a/source/MaterialXView/RenderPipelineGL.h b/source/MaterialXView/RenderPipelineGL.h index fcb64a6436..00ebcbc6eb 100644 --- a/source/MaterialXView/RenderPipelineGL.h +++ b/source/MaterialXView/RenderPipelineGL.h @@ -31,6 +31,7 @@ class GLRenderPipeline : public RenderPipeline mx::ImageHandlerPtr createImageHandler() override; mx::MaterialPtr createMaterial() override; void updateAlbedoTable(int tableSize) override; + void updatePrefilteredMap() override; std::shared_ptr createTextureBaker(unsigned int width, unsigned int height, mx::Image::BaseType baseType) override; diff --git a/source/MaterialXView/RenderPipelineMetal.h b/source/MaterialXView/RenderPipelineMetal.h index 1ed8c063bd..9cd2b2f6b3 100644 --- a/source/MaterialXView/RenderPipelineMetal.h +++ b/source/MaterialXView/RenderPipelineMetal.h @@ -40,6 +40,7 @@ class MetalRenderPipeline : public RenderPipeline mx::ImageHandlerPtr createImageHandler() override; mx::MaterialPtr createMaterial() override; void updateAlbedoTable(int tableSize) override; + void updatePrefilteredMap() override; void renderFrame(void* color_texture, int shadowMapSize, const char* dirLightNodeCat) override; void bakeTextures() override; mx::ImagePtr getFrameImage() override; @@ -50,6 +51,7 @@ class MetalRenderPipeline : public RenderPipeline protected: mx::ImagePtr getShadowMap(int shadowMapSize) override; mx::MetalFramebufferPtr _shadowMapFramebuffer; + mx::MetalFramebufferPtr _prefilterFramebuffer; mx::ImagePtr _shadowMap[SHADOWMAP_TEX_COUNT]; }; diff --git a/source/MaterialXView/RenderPipelineMetal.mm b/source/MaterialXView/RenderPipelineMetal.mm index 026e35720a..0dc85b8aa4 100644 --- a/source/MaterialXView/RenderPipelineMetal.mm +++ b/source/MaterialXView/RenderPipelineMetal.mm @@ -155,6 +155,96 @@ } } +void MetalRenderPipeline::updatePrefilteredMap() +{ + auto& genContext = _viewer->_genContext; + auto& lightHandler = _viewer->_lightHandler; + auto& imageHandler = _viewer->_imageHandler; + + if (lightHandler->getEnvPrefilteredMap()) + { + return; + } + + mx::ImagePtr srcTex = lightHandler->getEnvRadianceMap(); + int w = srcTex->getWidth(); + int h = srcTex->getHeight(); + + mx::MetalTextureHandlerPtr mtlImageHandler = std::dynamic_pointer_cast(imageHandler); + mx::ImagePtr outTex = mx::Image::create(w, h, 3, mx::Image::BaseType::HALF); + mtlImageHandler->createRenderResources(outTex, true, true); + id metalTex = mtlImageHandler->getAssociatedMetalTexture(outTex); + + // Create framebuffer. + _prefilterFramebuffer = mx::MetalFramebuffer::create( + MTL(device), + w, h, + 4, + mx::Image::BaseType::HALF, + metalTex + ); + + MTL_PUSH_FRAMEBUFFER(_prefilterFramebuffer); + + // Create shader. + mx::ShaderPtr hwShader = mx::createEnvPrefilterShader(genContext, _viewer->_stdLib, "__ENV_PREFILTER__"); + mx::MslMaterialPtr material = mx::MslMaterial::create(); + try + { + material->generateShader(hwShader); + } + catch (std::exception& e) + { + new ng::MessageDialog(_viewer, ng::MessageDialog::Type::Warning, "Failed to generate convolution shader", e.what()); + } + + int i = 0; + + while (w > 0 && h > 0) + { + MTL(beginCommandBuffer()); + MTLRenderPassDescriptor* desc = [MTLRenderPassDescriptor new]; + [desc.colorAttachments[0] setTexture:metalTex]; + [desc.colorAttachments[0] setLevel:i]; + [desc.colorAttachments[0] setLoadAction:MTLLoadActionDontCare]; + [desc.colorAttachments[0] setStoreAction:MTLStoreActionStore]; + [desc.depthAttachment setTexture:_prefilterFramebuffer->getDepthTexture()]; + [desc.depthAttachment setLoadAction:MTLLoadActionDontCare]; + [desc.depthAttachment setStoreAction:MTLStoreActionDontCare]; + [desc setStencilAttachment:nil]; + + MTL(beginEncoder(desc)); + [MTL(renderCmdEncoder) setDepthStencilState:MTL_DEPTHSTENCIL_STATE(opaque)]; + + _prefilterFramebuffer->bind(desc); + material->bindShader(); + material->getProgram()->bindUniform(mx::HW::ENV_PREFILTER_MIP, mx::Value::createValue(i)); + + bool prevValue = lightHandler->getUsePrefilteredMap(); + lightHandler->setUsePrefilteredMap(false); + material->getProgram()->prepareUsedResources( + MTL(renderCmdEncoder), + _viewer->_identityCamera, + nullptr, + imageHandler, + lightHandler); + lightHandler->setUsePrefilteredMap(prevValue); + + _viewer->renderScreenSpaceQuad(material); + + MTL(endCommandBuffer()); + [desc release]; + + w /= 2; + h /= 2; + i++; + } + + MTL_POP_FRAMEBUFFER(); + + lightHandler->setEnvPrefilteredMap(outTex); +} + mx::ImagePtr MetalRenderPipeline::getShadowMap(int shadowMapSize) { auto& genContext = _viewer->_genContext; @@ -175,7 +265,7 @@ !mtlImageHandler->getAssociatedMetalTexture(_shadowMap[i])) { _shadowMap[i] = mx::Image::create(shadowMapSize, shadowMapSize, 2, mx::Image::BaseType::FLOAT); - _viewer->_imageHandler->createRenderResources(_shadowMap[i], false); + _viewer->_imageHandler->createRenderResources(_shadowMap[i], false, true); } shadowMapTex[i] = @@ -315,6 +405,12 @@ auto& searchPath = _viewer->_searchPath; auto& geometryHandler = _viewer->_geometryHandler; + // Update prefiltered environment. + if (lightHandler->getUsePrefilteredMap() && !_viewer->_materialAssignments.empty()) + { + updatePrefilteredMap(); + } + // Update lighting state. lightHandler->setLightTransform(mx::Matrix44::createRotationY(lightRotation / 180.0f * M_PI)); diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp index c06846f2ce..eeaf7a82b0 100644 --- a/source/MaterialXView/Viewer.cpp +++ b/source/MaterialXView/Viewer.cpp @@ -485,9 +485,12 @@ void Viewer::loadEnvironmentLight() // Release any existing environment maps and store the new ones. _imageHandler->releaseRenderResources(_lightHandler->getEnvRadianceMap()); + _imageHandler->releaseRenderResources(_lightHandler->getEnvPrefilteredMap()); _imageHandler->releaseRenderResources(_lightHandler->getEnvIrradianceMap()); + _lightHandler->setEnvRadianceMap(envRadianceMap); _lightHandler->setEnvIrradianceMap(envIrradianceMap); + _lightHandler->setEnvPrefilteredMap(nullptr); // Look for a light rig using an expected filename convention. if (!_splitDirectLight) @@ -746,12 +749,14 @@ void Viewer::createAdvancedSettings(Widget* parent) ng::CheckBox* importanceSampleBox = new ng::CheckBox(advancedPopup, "Environment FIS"); importanceSampleBox->set_checked(_genContext.getOptions().hwSpecularEnvironmentMethod == mx::SPECULAR_ENVIRONMENT_FIS); + _lightHandler->setUsePrefilteredMap(_genContext.getOptions().hwSpecularEnvironmentMethod != mx::SPECULAR_ENVIRONMENT_FIS); importanceSampleBox->set_callback([this](bool enable) { _genContext.getOptions().hwSpecularEnvironmentMethod = enable ? mx::SPECULAR_ENVIRONMENT_FIS : mx::SPECULAR_ENVIRONMENT_PREFILTER; #ifndef MATERIALXVIEW_METAL_BACKEND _genContextEssl.getOptions().hwSpecularEnvironmentMethod = _genContext.getOptions().hwSpecularEnvironmentMethod; #endif + _lightHandler->setUsePrefilteredMap(!enable); reloadShaders(); }); diff --git a/source/PyMaterialX/PyMaterialXGenShader/PyGenOptions.cpp b/source/PyMaterialX/PyMaterialXGenShader/PyGenOptions.cpp index 75b5fb11bb..c40728ad26 100644 --- a/source/PyMaterialX/PyMaterialXGenShader/PyGenOptions.cpp +++ b/source/PyMaterialX/PyMaterialXGenShader/PyGenOptions.cpp @@ -38,6 +38,7 @@ void bindPyGenOptions(py::module& mod) .def_readwrite("hwNormalizeUdimTexCoords", &mx::GenOptions::hwNormalizeUdimTexCoords) .def_readwrite("hwAmbientOcclusion", &mx::GenOptions::hwAmbientOcclusion) .def_readwrite("hwWriteAlbedoTable", &mx::GenOptions::hwWriteAlbedoTable) + .def_readwrite("hwWriteEnvPrefilter", &mx::GenOptions::hwWriteEnvPrefilter) .def_readwrite("hwImplicitBitangents", &mx::GenOptions::hwImplicitBitangents) .def_readwrite("emitColorTransforms", &mx::GenOptions::emitColorTransforms) .def(py::init<>()); From 438f65ddb800ace92f5082607d9e30ffeac3e42d Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sat, 30 Dec 2023 11:23:55 -0800 Subject: [PATCH 052/128] Clarify GLSL data generation shaders - Use the word "generate" consistently in GLSL data generation files and functions, e.g. mx_generate_albedo_table.glsl, mx_generate_prefilter_env.glsl. - Improve documentation for GLSL data generation functions. - Replace constant texture dimensions with the textureSize call. --- ...ble.glsl => mx_generate_albedo_table.glsl} | 0 ...nt.glsl => mx_generate_prefilter_env.glsl} | 19 +++++++------------ .../genglsl/lib/mx_microfacet_specular.glsl | 5 +++-- .../MaterialXGenGlsl/GlslShaderGenerator.cpp | 6 +++--- source/MaterialXGenMsl/MslShaderGenerator.cpp | 6 +++--- 5 files changed, 16 insertions(+), 20 deletions(-) rename libraries/pbrlib/genglsl/lib/{mx_table.glsl => mx_generate_albedo_table.glsl} (100%) rename libraries/pbrlib/genglsl/lib/{mx_prefilter_environment.glsl => mx_generate_prefilter_env.glsl} (90%) diff --git a/libraries/pbrlib/genglsl/lib/mx_table.glsl b/libraries/pbrlib/genglsl/lib/mx_generate_albedo_table.glsl similarity index 100% rename from libraries/pbrlib/genglsl/lib/mx_table.glsl rename to libraries/pbrlib/genglsl/lib/mx_generate_albedo_table.glsl diff --git a/libraries/pbrlib/genglsl/lib/mx_prefilter_environment.glsl b/libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl similarity index 90% rename from libraries/pbrlib/genglsl/lib/mx_prefilter_environment.glsl rename to libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl index fd608871ed..e437e886af 100644 --- a/libraries/pbrlib/genglsl/lib/mx_prefilter_environment.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl @@ -25,22 +25,17 @@ vec3 mx_latlong_map_projection_inverse(vec2 uv) return vec3(x, y, z); } -vec3 mx_prefilter_environment() +vec3 mx_generate_prefilter_env() { - vec2 uv = gl_FragCoord.xy * pow(2.0, $envPrefilterMip) / vec2(2048.0, 1024.0); - float alpha = mx_latlong_lod_to_alpha(float($envPrefilterMip)); - if ($envPrefilterMip == 0) - { - return textureLod($envRadiance, uv, 0).rgb; - } + // The tangent view vector is aligned with the normal. + vec3 V = vec3(0.0, 0.0, 1.0); + float NdotV = 1.0; - // Compute world normal and transform. + // Compute derived properties. + vec2 uv = gl_FragCoord.xy * pow(2.0, $envPrefilterMip) / vec2(textureSize($envRadiance, 0)); vec3 worldN = mx_latlong_map_projection_inverse(uv); mat3 tangentToWorld = mx_orthonormal_basis(worldN); - - // Local normal and view vectors are constant and aligned. - vec3 V = vec3(0.0, 0.0, 1.0); - float NdotV = 1.0; + float alpha = mx_latlong_lod_to_alpha(float($envPrefilterMip)); float G1V = mx_ggx_smith_G1(NdotV, alpha); // Integrate the LD term for the given environment and alpha. diff --git a/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl b/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl index 85430c00ca..a27f717a24 100644 --- a/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl @@ -594,6 +594,7 @@ vec3 mx_latlong_map_lookup(vec3 dir, mat4 transform, float lod, sampler2D envSam return textureLod(envSampler, uv, lod).rgb; } +// Return the mip level with the appropriate coverage for a filtered importance sample. // https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html // Section 20.4 Equation 13 float mx_latlong_compute_lod(vec3 dir, float pdf, float maxMipLevel, int envSamples) @@ -604,16 +605,16 @@ float mx_latlong_compute_lod(vec3 dir, float pdf, float maxMipLevel, int envSamp return max(effectiveMaxMipLevel - 0.5 * log2(float(envSamples) * pdf * distortion), 0.0); } +// Return the mip level associated with the given alpha in a prefiltered environment. float mx_latlong_alpha_to_lod(float alpha) { - // Return the mip level associated with the given alpha in a prefiltered environment. float lodBias = (alpha < 0.25) ? sqrt(alpha) : 0.5 * alpha + 0.375; return lodBias * float($envRadianceMips - 1); } +// Return the alpha associated with the given mip level in a prefiltered environment. float mx_latlong_lod_to_alpha(float lod) { - // Return the alpha associated with the given mip level in a prefiltered environment. float lodBias = lod / float($envRadianceMips - 1); return (lodBias < 0.5) ? mx_square(lodBias) : 2.0 * (lodBias - 0.375); } diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp index b9351ddc08..e506c700c7 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp @@ -587,14 +587,14 @@ void GlslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& c // Emit directional albedo table code. if (context.getOptions().hwWriteAlbedoTable) { - emitLibraryInclude("pbrlib/genglsl/lib/mx_table.glsl", context, stage); + emitLibraryInclude("pbrlib/genglsl/lib/mx_generate_albedo_table.glsl", context, stage); emitLineBreak(stage); } // Emit environment prefiltering code if (context.getOptions().hwWriteEnvPrefilter) { - emitLibraryInclude("pbrlib/genglsl/lib/mx_prefilter_environment.glsl", context, stage); + emitLibraryInclude("pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl", context, stage); emitLineBreak(stage); } @@ -645,7 +645,7 @@ void GlslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& c } else if (context.getOptions().hwWriteEnvPrefilter) { - emitLine(outputSocket->getVariable() + " = vec4(mx_prefilter_environment(), 1.0)", stage); + emitLine(outputSocket->getVariable() + " = vec4(mx_generate_prefilter_env(), 1.0)", stage); } else { diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index 5749f0d211..10c368177c 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -1055,14 +1055,14 @@ void MslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& co // Emit directional albedo table code. if (context.getOptions().hwWriteAlbedoTable) { - emitLibraryInclude("pbrlib/genglsl/lib/mx_table.glsl", context, stage); + emitLibraryInclude("pbrlib/genglsl/lib/mx_generate_albedo_table.glsl", context, stage); emitLineBreak(stage); } // Emit environment prefiltering code if (context.getOptions().hwWriteEnvPrefilter) { - emitLibraryInclude("pbrlib/genglsl/lib/mx_prefilter_environment.glsl", context, stage); + emitLibraryInclude("pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl", context, stage); emitLineBreak(stage); } @@ -1113,7 +1113,7 @@ void MslShaderGenerator::emitPixelStage(const ShaderGraph& graph, GenContext& co } else if (context.getOptions().hwWriteEnvPrefilter) { - emitLine(outputSocket->getVariable() + " = float4(mx_prefilter_environment(), 1.0)", stage); + emitLine(outputSocket->getVariable() + " = float4(mx_generate_prefilter_env(), 1.0)", stage); } else { From d4c6f60984b9ec4d7be69d8402b97b0d18e63591 Mon Sep 17 00:00:00 2001 From: ld-kerley <154285602+ld-kerley@users.noreply.github.com> Date: Tue, 2 Jan 2024 12:11:01 -0800 Subject: [PATCH 053/128] Fix missing MSL case in PyMaterialX build (#1630) Fix missing MATERIALX_BUILD_GEN_MSL in CMakeLists.txt for PyMaterialX. --- source/PyMaterialX/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/PyMaterialX/CMakeLists.txt b/source/PyMaterialX/CMakeLists.txt index eda1ba0db4..2bbe2c9506 100644 --- a/source/PyMaterialX/CMakeLists.txt +++ b/source/PyMaterialX/CMakeLists.txt @@ -44,7 +44,7 @@ endif() add_subdirectory(PyMaterialXCore) add_subdirectory(PyMaterialXFormat) -if (MATERIALX_BUILD_GEN_GLSL OR MATERIALX_BUILD_GEN_OSL OR MATERIALX_BUILD_GEN_MDL) +if (MATERIALX_BUILD_GEN_GLSL OR MATERIALX_BUILD_GEN_OSL OR MATERIALX_BUILD_GEN_MDL OR MATERIALX_BUILD_GEN_MSL) add_subdirectory(PyMaterialXGenShader) if (MATERIALX_BUILD_GEN_GLSL) add_subdirectory(PyMaterialXGenGlsl) From 473d563896a4accb1d570726704ba7aba137779a Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Wed, 3 Jan 2024 19:22:12 -0500 Subject: [PATCH 054/128] Add enumeration support to web viewer (#1632) - Scan for `enum` and `enumvalues` if attributes exist on input. If no `enumvalues` exist then map to "default" of 0..<enum list size>. - Create a drop-down for each enumerated input. --- javascript/MaterialXView/source/viewer.js | 34 +++++++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js index b0bcd98fbf..3eff576be3 100644 --- a/javascript/MaterialXView/source/viewer.js +++ b/javascript/MaterialXView/source/viewer.js @@ -949,11 +949,17 @@ export class Material } var step = 0; var enumList = [] + var enumValues = [] if (nodeDefInput) { if (nodeDefInput.hasAttribute('enum')) { + // Get enum and enum values attributes (if present) enumList = nodeDefInput.getAttribute('enum').split(','); + if (nodeDefInput.hasAttribute('enumvalues')) + { + enumValues = nodeDefInput.getAttribute('enumvalues').split(',').map(Number); + } } else { @@ -989,8 +995,30 @@ export class Material } else { - // TODO: Add enum support - currentFolder.add(material.uniforms[name], 'value' ).name(path); + // Map enumList strings to values + // Map to 0..N if no values are specified via enumvalues attribute + if (enumValues.length == 0) + { + for (let i = 0; i < enumList.length; ++i) + { + enumValues.push(i); + } + } + const enumeration = {}; + enumList.forEach((str, index) => { + enumeration[str] = enumValues[index]; + }); + + // Function to handle enum drop-down + function handleDropdownChange(value) { + if (material.uniforms[name]) + { + material.uniforms[name].value = value; + } + } + const defaultOption = enumList[value]; // Set the default selected option + const dropdownController = gui.add(enumeration, defaultOption, enumeration).name(path); + dropdownController.onChange(handleDropdownChange); } } break; @@ -1046,7 +1074,7 @@ export class Material break; case 'color3': - // Irksome way to mape arrays to colors and back + // Irksome way to map arrays to colors and back uniformToUpdate = material.uniforms[name]; if (uniformToUpdate && value != null) { From 39d6d5b614d7f9e77fe82d36f18c70f5139a81a3 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 3 Jan 2024 16:23:31 -0800 Subject: [PATCH 055/128] Initial nprlib with viewdirection node (#1631) This changelist introduces an NPR (non-photorealistic rendering) data library to MaterialX, initially consisting of a single `viewdirection` node. The NPR data library is designed for the portable expression of artistic, non-physically-based materials, with common examples being cartoon shading, architectural diagrams, and edge highlighting. In future versions of MaterialX, we expect this data library to be extended with additional primitives and artist-facing graphs as they are requested by the graphics community and approved by the MaterialX TSC. For shader generation, MaterialX initially supports the NPR data library in GLSL, ESSL, MSL, and OSL, with MDL being omitted for now, based on intentional restrictions in its design philosophy. --- .../nprlib/genglsl/nprlib_genglsl_impl.mtlx | 17 ++++++ .../nprlib/genmdl/nprlib_genmdl_impl.mtlx | 17 ++++++ .../nprlib/genmsl/nprlib_genmsl_impl.mtlx | 17 ++++++ .../nprlib/genosl/nprlib_genosl_impl.mtlx | 17 ++++++ libraries/nprlib/nprlib_defs.mtlx | 23 ++++++++ ...nvmap_shader.mtlx => environment_map.mtlx} | 21 +++---- resources/Materials/TestSuite/_options.mtlx | 2 +- .../TestSuite/nprlib/edge_brighten.mtlx | 28 ++++++++++ .../Materials/TestSuite/nprlib/starfield.mtlx | 25 +++++++++ .../MaterialXGenGlsl/GlslShaderGenerator.cpp | 3 + .../Nodes/ViewDirectionNodeGlsl.cpp | 55 +++++++++++++++++++ .../Nodes/ViewDirectionNodeGlsl.h | 26 +++++++++ .../MaterialXGenMdl/mdl/materialx/stdlib.mdl | 16 ++++++ source/MaterialXGenMsl/MslShaderGenerator.cpp | 3 + .../Nodes/ViewDirectionNodeMsl.cpp | 55 +++++++++++++++++++ .../Nodes/ViewDirectionNodeMsl.h | 26 +++++++++ source/MaterialXRender/ShaderMaterial.cpp | 2 +- source/MaterialXView/Viewer.cpp | 54 +----------------- 18 files changed, 338 insertions(+), 69 deletions(-) create mode 100644 libraries/nprlib/genglsl/nprlib_genglsl_impl.mtlx create mode 100644 libraries/nprlib/genmdl/nprlib_genmdl_impl.mtlx create mode 100644 libraries/nprlib/genmsl/nprlib_genmsl_impl.mtlx create mode 100644 libraries/nprlib/genosl/nprlib_genosl_impl.mtlx create mode 100644 libraries/nprlib/nprlib_defs.mtlx rename resources/Lights/{envmap_shader.mtlx => environment_map.mtlx} (69%) create mode 100644 resources/Materials/TestSuite/nprlib/edge_brighten.mtlx create mode 100644 resources/Materials/TestSuite/nprlib/starfield.mtlx create mode 100644 source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp create mode 100644 source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.h create mode 100644 source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp create mode 100644 source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.h diff --git a/libraries/nprlib/genglsl/nprlib_genglsl_impl.mtlx b/libraries/nprlib/genglsl/nprlib_genglsl_impl.mtlx new file mode 100644 index 0000000000..7ddc4cee83 --- /dev/null +++ b/libraries/nprlib/genglsl/nprlib_genglsl_impl.mtlx @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/libraries/nprlib/genmdl/nprlib_genmdl_impl.mtlx b/libraries/nprlib/genmdl/nprlib_genmdl_impl.mtlx new file mode 100644 index 0000000000..b6472e0c51 --- /dev/null +++ b/libraries/nprlib/genmdl/nprlib_genmdl_impl.mtlx @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/libraries/nprlib/genmsl/nprlib_genmsl_impl.mtlx b/libraries/nprlib/genmsl/nprlib_genmsl_impl.mtlx new file mode 100644 index 0000000000..b8f9a4e3aa --- /dev/null +++ b/libraries/nprlib/genmsl/nprlib_genmsl_impl.mtlx @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/libraries/nprlib/genosl/nprlib_genosl_impl.mtlx b/libraries/nprlib/genosl/nprlib_genosl_impl.mtlx new file mode 100644 index 0000000000..0b077b6406 --- /dev/null +++ b/libraries/nprlib/genosl/nprlib_genosl_impl.mtlx @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/libraries/nprlib/nprlib_defs.mtlx b/libraries/nprlib/nprlib_defs.mtlx new file mode 100644 index 0000000000..e724658ae5 --- /dev/null +++ b/libraries/nprlib/nprlib_defs.mtlx @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + diff --git a/resources/Lights/envmap_shader.mtlx b/resources/Lights/environment_map.mtlx similarity index 69% rename from resources/Lights/envmap_shader.mtlx rename to resources/Lights/environment_map.mtlx index 8c9c6ec0f5..abd14d546b 100644 --- a/resources/Lights/envmap_shader.mtlx +++ b/resources/Lights/environment_map.mtlx @@ -1,17 +1,10 @@ - + - - - - - - - - + - + @@ -46,11 +39,11 @@ - + - - - + + + diff --git a/resources/Materials/TestSuite/_options.mtlx b/resources/Materials/TestSuite/_options.mtlx index bb29fbd7c1..1da00394e6 100644 --- a/resources/Materials/TestSuite/_options.mtlx +++ b/resources/Materials/TestSuite/_options.mtlx @@ -91,7 +91,7 @@ - + diff --git a/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx b/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx new file mode 100644 index 0000000000..7e9aca7f22 --- /dev/null +++ b/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Materials/TestSuite/nprlib/starfield.mtlx b/resources/Materials/TestSuite/nprlib/starfield.mtlx new file mode 100644 index 0000000000..6898054a6d --- /dev/null +++ b/resources/Materials/TestSuite/nprlib/starfield.mtlx @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp index e506c700c7..5b20ee1b03 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -196,6 +197,8 @@ GlslShaderGenerator::GlslShaderGenerator() : registerImplementation("IM_frame_float_" + GlslShaderGenerator::TARGET, FrameNodeGlsl::create); // registerImplementation("IM_time_float_" + GlslShaderGenerator::TARGET, TimeNodeGlsl::create); + // + registerImplementation("IM_viewdirection_vector3_" + GlslShaderGenerator::TARGET, ViewDirectionNodeGlsl::create); // registerImplementation("IM_surface_" + GlslShaderGenerator::TARGET, SurfaceNodeGlsl::create); diff --git a/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp new file mode 100644 index 0000000000..198465c9af --- /dev/null +++ b/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp @@ -0,0 +1,55 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +MATERIALX_NAMESPACE_BEGIN + +ShaderNodeImplPtr ViewDirectionNodeGlsl::create() +{ + return std::make_shared(); +} + +void ViewDirectionNodeGlsl::createVariables(const ShaderNode&, GenContext&, Shader& shader) const +{ + ShaderStage& vs = shader.getStage(Stage::VERTEX); + ShaderStage& ps = shader.getStage(Stage::PIXEL); + + addStageInput(HW::VERTEX_INPUTS, Type::VECTOR3, HW::T_IN_POSITION, vs); + addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_POSITION_WORLD, vs, ps); + addStageUniform(HW::PRIVATE_UNIFORMS, Type::VECTOR3, HW::T_VIEW_POSITION, ps); +} + +void ViewDirectionNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +{ + const ShaderGenerator& shadergen = context.getShaderGenerator(); + + DEFINE_SHADER_STAGE(stage, Stage::VERTEX) + { + VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); + const string prefix = vertexData.getInstance() + "."; + ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; + if (!position->isEmitted()) + { + position->setEmitted(); + shadergen.emitLine(prefix + position->getVariable() + " = hPositionWorld.xyz", stage); + } + } + + DEFINE_SHADER_STAGE(stage, Stage::PIXEL) + { + VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); + const string prefix = vertexData.getInstance() + "."; + ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; + shadergen.emitLineBegin(stage); + shadergen.emitOutput(node.getOutput(), true, false, context, stage); + shadergen.emitString(" = normalize(" + prefix + position->getVariable() + " - " + HW::T_VIEW_POSITION + ")", stage); + shadergen.emitLineEnd(stage); + } +} + +MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.h new file mode 100644 index 0000000000..24cafe2f1d --- /dev/null +++ b/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.h @@ -0,0 +1,26 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#ifndef MATERIALX_VIEWDIRECTIONNODEGLSL_H +#define MATERIALX_VIEWDIRECTIONNODEGLSL_H + +#include + +MATERIALX_NAMESPACE_BEGIN + +/// ViewDirection node implementation for GLSL +class MX_GENGLSL_API ViewDirectionNodeGlsl : public GlslImplementation +{ + public: + static ShaderNodeImplPtr create(); + + void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; + + void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; +}; + +MATERIALX_NAMESPACE_END + +#endif diff --git a/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl b/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl index 4ba4f0875a..4cae1547aa 100644 --- a/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/stdlib.mdl @@ -1366,6 +1366,22 @@ export float mx_time_float( return ::state::animation_time(); } +export float3 mx_viewdirection_vector3( + uniform mx_coordinatespace_type mxp_space = mx_coordinatespace_type(mx_coordinatespace_type_world) + [[ + anno::description("Enumeration {model,object,world}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: nprlib") + ]] +{ + // Not implemented: mx_viewdirection_vector3 + float3 defaultValue = float3(0.0, 0.0, 1.0); + return defaultValue; +} + export color mx_modulo_color3( color mxp_in1 = color(0.0, 0.0, 0.0), color mxp_in2 = color(1.0, 1.0, 1.0) diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index 10c368177c..7a2461a5a8 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -200,6 +201,8 @@ MslShaderGenerator::MslShaderGenerator() : registerImplementation("IM_frame_float_" + MslShaderGenerator::TARGET, FrameNodeMsl::create); // registerImplementation("IM_time_float_" + MslShaderGenerator::TARGET, TimeNodeMsl::create); + // + registerImplementation("IM_viewdirection_vector3_" + MslShaderGenerator::TARGET, ViewDirectionNodeMsl::create); // registerImplementation("IM_surface_" + MslShaderGenerator::TARGET, SurfaceNodeMsl::create); diff --git a/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp new file mode 100644 index 0000000000..84a6b02b4f --- /dev/null +++ b/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp @@ -0,0 +1,55 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +MATERIALX_NAMESPACE_BEGIN + +ShaderNodeImplPtr ViewDirectionNodeMsl::create() +{ + return std::make_shared(); +} + +void ViewDirectionNodeMsl::createVariables(const ShaderNode&, GenContext&, Shader& shader) const +{ + ShaderStage& vs = shader.getStage(Stage::VERTEX); + ShaderStage& ps = shader.getStage(Stage::PIXEL); + + addStageInput(HW::VERTEX_INPUTS, Type::VECTOR3, HW::T_IN_POSITION, vs); + addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_POSITION_WORLD, vs, ps); + addStageUniform(HW::PRIVATE_UNIFORMS, Type::VECTOR3, HW::T_VIEW_POSITION, ps); +} + +void ViewDirectionNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +{ + const ShaderGenerator& shadergen = context.getShaderGenerator(); + + DEFINE_SHADER_STAGE(stage, Stage::VERTEX) + { + VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); + const string prefix = vertexData.getInstance() + "."; + ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; + if (!position->isEmitted()) + { + position->setEmitted(); + shadergen.emitLine(prefix + position->getVariable() + " = hPositionWorld.xyz", stage); + } + } + + DEFINE_SHADER_STAGE(stage, Stage::PIXEL) + { + VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); + const string prefix = vertexData.getInstance() + "."; + ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; + shadergen.emitLineBegin(stage); + shadergen.emitOutput(node.getOutput(), true, false, context, stage); + shadergen.emitString(" = normalize(" + prefix + position->getVariable() + " - " + HW::T_VIEW_POSITION + ")", stage); + shadergen.emitLineEnd(stage); + } +} + +MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.h b/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.h new file mode 100644 index 0000000000..be7a40108a --- /dev/null +++ b/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.h @@ -0,0 +1,26 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#ifndef MATERIALX_VIEWDIRECTIONNODEMSL_H +#define MATERIALX_VIEWDIRECTIONNODEMSL_H + +#include + +MATERIALX_NAMESPACE_BEGIN + +/// ViewDirection node implementation for MSL +class MX_GENMSL_API ViewDirectionNodeMsl : public MslImplementation +{ + public: + static ShaderNodeImplPtr create(); + + void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; + + void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; +}; + +MATERIALX_NAMESPACE_END + +#endif diff --git a/source/MaterialXRender/ShaderMaterial.cpp b/source/MaterialXRender/ShaderMaterial.cpp index 4e8ccc491f..c61c6d3c04 100644 --- a/source/MaterialXRender/ShaderMaterial.cpp +++ b/source/MaterialXRender/ShaderMaterial.cpp @@ -73,7 +73,7 @@ bool ShaderMaterial::generateEnvironmentShader(GenContext& context, readFromXmlFile(envDoc, filename); doc->importLibrary(envDoc); - NodeGraphPtr envGraph = doc->getNodeGraph("environmentDraw"); + NodeGraphPtr envGraph = doc->getNodeGraph("envMap"); if (!envGraph) { return false; diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp index eeaf7a82b0..f6da076f17 100644 --- a/source/MaterialXView/Viewer.cpp +++ b/source/MaterialXView/Viewer.cpp @@ -137,55 +137,6 @@ void applyModifiers(mx::DocumentPtr doc, const DocumentModifiers& modifiers) } } -// ViewDir implementation for GLSL -// as needed for the environment shader. -template -class ViewDir : public NodeGraphImpl -{ -public: - static mx::ShaderNodeImplPtr create() - { - return std::make_shared(); - } - - void createVariables(const mx::ShaderNode&, mx::GenContext&, mx::Shader& shader) const override - { - mx::ShaderStage& vs = shader.getStage(mx::Stage::VERTEX); - mx::ShaderStage& ps = shader.getStage(mx::Stage::PIXEL); - addStageInput(mx::HW::VERTEX_INPUTS, mx::Type::VECTOR3, mx::HW::T_IN_POSITION, vs); - addStageConnector(mx::HW::VERTEX_DATA, mx::Type::VECTOR3, mx::HW::T_POSITION_WORLD, vs, ps); - addStageUniform(mx::HW::PRIVATE_UNIFORMS, mx::Type::VECTOR3, mx::HW::T_VIEW_POSITION, ps); - } - - void emitFunctionCall(const mx::ShaderNode& node, mx::GenContext& context, mx::ShaderStage& stage) const override - { - const mx::ShaderGenerator& shadergen = context.getShaderGenerator(); - - DEFINE_SHADER_STAGE(stage, mx::Stage::VERTEX) - { - mx::VariableBlock& vertexData = stage.getOutputBlock(mx::HW::VERTEX_DATA); - const mx::string prefix = vertexData.getInstance() + "."; - mx::ShaderPort* position = vertexData[mx::HW::T_POSITION_WORLD]; - if (!position->isEmitted()) - { - position->setEmitted(); - shadergen.emitLine(prefix + position->getVariable() + " = hPositionWorld.xyz", stage); - } - } - - DEFINE_SHADER_STAGE(stage, mx::Stage::PIXEL) - { - mx::VariableBlock& vertexData = stage.getInputBlock(mx::HW::VERTEX_DATA); - const mx::string prefix = vertexData.getInstance() + "."; - mx::ShaderPort* position = vertexData[mx::HW::T_POSITION_WORLD]; - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = normalize(" + prefix + position->getVariable() + " - " + mx::HW::T_VIEW_POSITION + ")", stage); - shadergen.emitLineEnd(stage); - } - } -}; - } // anonymous namespace // @@ -297,10 +248,8 @@ Viewer::Viewer(const std::string& materialFilename, _renderPipeline = MetalRenderPipeline::create(this); _renderPipeline->initialize(ng::metal_device(), ng::metal_command_queue()); - _genContext.getShaderGenerator().registerImplementation("IM_viewdir_vector3_" + _genContext.getShaderGenerator().getTarget(), ViewDir::create); #else _renderPipeline = GLRenderPipeline::create(this); - _genContext.getShaderGenerator().registerImplementation("IM_viewdir_vector3_" + _genContext.getShaderGenerator().getTarget(), ViewDir::create); // Set Essl generator options _genContextEssl.getOptions().targetColorSpaceOverride = "lin_rec709"; @@ -317,7 +266,6 @@ Viewer::Viewer(const std::string& materialFilename, _genContextMdl.getOptions().targetColorSpaceOverride = "lin_rec709"; _genContextMdl.getOptions().fileTextureVerticalFlip = false; #endif - // Register the API Spcefic implementation for used by the environment shader. } void Viewer::initialize() @@ -2395,7 +2343,7 @@ mx::MaterialPtr Viewer::getEnvironmentMaterial() { if (!_envMaterial) { - mx::FilePath envFilename = _searchPath.find(mx::FilePath("resources/Lights/envmap_shader.mtlx")); + mx::FilePath envFilename = _searchPath.find(mx::FilePath("resources/Lights/environment_map.mtlx")); try { _envMaterial = _renderPipeline->createMaterial(); From 8ab122f8cda6a98a094294b1494e423589afdfc9 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 3 Jan 2024 17:39:05 -0800 Subject: [PATCH 056/128] Improve shader generation for viewdirection This changelist improves shader generation logic for the new viewdirection node, allowing it to work correctly in derived hardware languages such as ESSL. --- source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp | 6 +++--- source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp index 198465c9af..f9714b5d33 100644 --- a/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp +++ b/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp @@ -26,12 +26,12 @@ void ViewDirectionNodeGlsl::createVariables(const ShaderNode&, GenContext&, Shad void ViewDirectionNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const { - const ShaderGenerator& shadergen = context.getShaderGenerator(); + const GlslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); DEFINE_SHADER_STAGE(stage, Stage::VERTEX) { VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); - const string prefix = vertexData.getInstance() + "."; + const string prefix = shadergen.getVertexDataPrefix(vertexData); ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; if (!position->isEmitted()) { @@ -43,7 +43,7 @@ void ViewDirectionNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& DEFINE_SHADER_STAGE(stage, Stage::PIXEL) { VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); - const string prefix = vertexData.getInstance() + "."; + const string prefix = shadergen.getVertexDataPrefix(vertexData); ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; shadergen.emitLineBegin(stage); shadergen.emitOutput(node.getOutput(), true, false, context, stage); diff --git a/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp index 84a6b02b4f..1443b5c320 100644 --- a/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp +++ b/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp @@ -26,12 +26,12 @@ void ViewDirectionNodeMsl::createVariables(const ShaderNode&, GenContext&, Shade void ViewDirectionNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const { - const ShaderGenerator& shadergen = context.getShaderGenerator(); + const MslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); DEFINE_SHADER_STAGE(stage, Stage::VERTEX) { VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); - const string prefix = vertexData.getInstance() + "."; + const string prefix = shadergen.getVertexDataPrefix(vertexData); ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; if (!position->isEmitted()) { @@ -43,7 +43,7 @@ void ViewDirectionNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& DEFINE_SHADER_STAGE(stage, Stage::PIXEL) { VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); - const string prefix = vertexData.getInstance() + "."; + const string prefix = shadergen.getVertexDataPrefix(vertexData); ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; shadergen.emitLineBegin(stage); shadergen.emitOutput(node.getOutput(), true, false, context, stage); From 5def239b82c20a7bf4875686e03743bc421a68f6 Mon Sep 17 00:00:00 2001 From: Frieder Erdmann <55715326+friedererdmann@users.noreply.github.com> Date: Thu, 4 Jan 2024 04:03:03 +0100 Subject: [PATCH 057/128] Add creatematrix nodes to build matrices from vectors (#1553) I'm opening this PR to add creatematrix, a constructor for Matrix33 from 3 Vector3s, Matrix44 from 4 Vector3s and Matrix44 from 4 Vector4s from the specification document (https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/documents/Specification/MaterialX.Specification.md#math-nodes). --- .../mx_creatematrix_vector3_matrix33.glsl | 6 +++ .../mx_creatematrix_vector3_matrix44.glsl | 7 ++++ .../mx_creatematrix_vector4_matrix44.glsl | 7 ++++ .../stdlib/genglsl/stdlib_genglsl_impl.mtlx | 5 +++ .../stdlib/genmdl/stdlib_genmdl_impl.mtlx | 5 +++ .../stdlib/genmsl/stdlib_genmsl_impl.mtlx | 5 +++ libraries/stdlib/genosl/mx_creatematrix.osl | 23 +++++++++++ .../stdlib/genosl/stdlib_genosl_impl.mtlx | 5 +++ libraries/stdlib/stdlib_defs.mtlx | 27 +++++++++++++ .../TestSuite/stdlib/math/matrix.mtlx | 29 ++++++++++++++ .../MaterialXGenMdl/mdl/materialx/stdlib.mdl | 40 +++++++++++++++++++ 11 files changed, 159 insertions(+) create mode 100644 libraries/stdlib/genglsl/mx_creatematrix_vector3_matrix33.glsl create mode 100644 libraries/stdlib/genglsl/mx_creatematrix_vector3_matrix44.glsl create mode 100644 libraries/stdlib/genglsl/mx_creatematrix_vector4_matrix44.glsl create mode 100644 libraries/stdlib/genosl/mx_creatematrix.osl create mode 100644 resources/Materials/TestSuite/stdlib/math/matrix.mtlx diff --git a/libraries/stdlib/genglsl/mx_creatematrix_vector3_matrix33.glsl b/libraries/stdlib/genglsl/mx_creatematrix_vector3_matrix33.glsl new file mode 100644 index 0000000000..aa10ef5b98 --- /dev/null +++ b/libraries/stdlib/genglsl/mx_creatematrix_vector3_matrix33.glsl @@ -0,0 +1,6 @@ +void mx_creatematrix_vector3_matrix33(vec3 in1, vec3 in2, vec3 in3, out mat3 result) +{ + result = mat3(in1.x, in1.y, in1.z, + in2.x, in2.y, in2.z, + in3.x, in3.y, in3.z); +} diff --git a/libraries/stdlib/genglsl/mx_creatematrix_vector3_matrix44.glsl b/libraries/stdlib/genglsl/mx_creatematrix_vector3_matrix44.glsl new file mode 100644 index 0000000000..194fad421a --- /dev/null +++ b/libraries/stdlib/genglsl/mx_creatematrix_vector3_matrix44.glsl @@ -0,0 +1,7 @@ +void mx_creatematrix_vector3_matrix44(vec3 in1, vec3 in2, vec3 in3, vec3 in4, out mat4 result) +{ + result = mat4(in1.x, in1.y, in1.z, 0.0, + in2.x, in2.y, in2.z, 0.0, + in3.x, in3.y, in3.z, 0.0, + in4.x, in4.y, in4.z, 1.0); +} diff --git a/libraries/stdlib/genglsl/mx_creatematrix_vector4_matrix44.glsl b/libraries/stdlib/genglsl/mx_creatematrix_vector4_matrix44.glsl new file mode 100644 index 0000000000..665a22212b --- /dev/null +++ b/libraries/stdlib/genglsl/mx_creatematrix_vector4_matrix44.glsl @@ -0,0 +1,7 @@ +void mx_creatematrix_vector4_matrix44(vec4 in1, vec4 in2, vec4 in3, vec4 in4, out mat4 result) +{ + result = mat4(in1.x, in1.y, in1.z, in1.w, + in2.x, in2.y, in2.z, in2.w, + in3.x, in3.y, in3.z, in3.w, + in4.x, in4.y, in4.z, in4.w); +} diff --git a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx index 07aae6ce66..6f67b21d33 100644 --- a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx +++ b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx @@ -748,6 +748,11 @@ + + + + + diff --git a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx index 022f0896f1..6c550c92db 100644 --- a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx +++ b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx @@ -754,6 +754,11 @@ + + + + + diff --git a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx index dea1c49636..40be6f8c46 100644 --- a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx +++ b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx @@ -748,6 +748,11 @@ + + + + + diff --git a/libraries/stdlib/genosl/mx_creatematrix.osl b/libraries/stdlib/genosl/mx_creatematrix.osl new file mode 100644 index 0000000000..933dce00ba --- /dev/null +++ b/libraries/stdlib/genosl/mx_creatematrix.osl @@ -0,0 +1,23 @@ +void mx_creatematrix_vector3_matrix33(vector in1, vector in2, vector in3, out matrix result) +{ + result = matrix(in1.x, in1.y, in1.z, 0.0, + in2.x, in2.y, in2.z, 0.0, + in3.x, in3.y, in3.z, 0.0, + 0.0, 0.0, 0.0, 1.0); +} + +void mx_creatematrix_vector3_matrix44(vector3 in1, vector3 in2, vector3 in3, vector3 in4, out matrix result) +{ + result = matrix(in1.x, in1.y, in1.z, 0.0, + in2.x, in2.y, in2.z, 0.0, + in3.x, in3.y, in3.z, 0.0, + in4.x, in4.y, in4.z, 1.0); +} + +void mx_creatematrix_vector4_matrix44(vector4 in1, vector4 in2, vector4 in3, vector4 in4, out matrix result) +{ + result = matrix(in1.x, in1.y, in1.z, in1.w, + in2.x, in2.y, in2.z, in2.w, + in3.x, in3.y, in3.z, in3.w, + in4.x, in4.y, in4.z, in4.w); +} diff --git a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx index 42828ce641..a984d912b8 100644 --- a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx +++ b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx @@ -751,6 +751,11 @@ + + + + + diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index 3f187e2be1..90ccb57a98 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -4359,6 +4359,33 @@
+ + + + + + + + + + + + + + + + + + + + + + + + - registerImplementation("IM_position_vector3_" + GlslShaderGenerator::TARGET, PositionNodeGlsl::create); + registerImplementation("IM_position_vector3_" + GlslShaderGenerator::TARGET, HwPositionNode::create); // - registerImplementation("IM_normal_vector3_" + GlslShaderGenerator::TARGET, NormalNodeGlsl::create); + registerImplementation("IM_normal_vector3_" + GlslShaderGenerator::TARGET, HwNormalNode::create); // - registerImplementation("IM_tangent_vector3_" + GlslShaderGenerator::TARGET, TangentNodeGlsl::create); + registerImplementation("IM_tangent_vector3_" + GlslShaderGenerator::TARGET, HwTangentNode::create); // - registerImplementation("IM_bitangent_vector3_" + GlslShaderGenerator::TARGET, BitangentNodeGlsl::create); + registerImplementation("IM_bitangent_vector3_" + GlslShaderGenerator::TARGET, HwBitangentNode::create); // registerImplementation("IM_texcoord_vector2_" + GlslShaderGenerator::TARGET, HwTexCoordNode::create); registerImplementation("IM_texcoord_vector3_" + GlslShaderGenerator::TARGET, HwTexCoordNode::create); diff --git a/source/MaterialXGenGlsl/Nodes/BitangentNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/BitangentNodeGlsl.cpp deleted file mode 100644 index 6f515824e7..0000000000 --- a/source/MaterialXGenGlsl/Nodes/BitangentNodeGlsl.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr BitangentNodeGlsl::create() -{ - return std::make_shared(); -} - -void BitangentNodeGlsl::createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const -{ - const GenOptions& options = context.getOptions(); - - ShaderStage& vs = shader.getStage(Stage::VERTEX); - ShaderStage& ps = shader.getStage(Stage::PIXEL); - - if (options.hwImplicitBitangents) - { - addStageInput(HW::VERTEX_INPUTS, Type::VECTOR3, HW::T_IN_NORMAL, vs); - addStageInput(HW::VERTEX_INPUTS, Type::VECTOR3, HW::T_IN_TANGENT, vs); - } - else - { - addStageInput(HW::VERTEX_INPUTS, Type::VECTOR3, HW::T_IN_BITANGENT, vs); - } - - const ShaderInput* spaceInput = node.getInput(SPACE); - const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; - if (space == WORLD_SPACE) - { - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_BITANGENT_WORLD, vs, ps); - addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, HW::T_WORLD_MATRIX, vs); - - if (options.hwImplicitBitangents) - { - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_NORMAL_WORLD, vs, ps); - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_TANGENT_WORLD, vs, ps); - addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX, vs); - } - } - else - { - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_BITANGENT_OBJECT, vs, ps); - } -} - -void BitangentNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - const GlslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); - const GenOptions& options = context.getOptions(); - - const ShaderInput* spaceInput = node.getInput(SPACE); - const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; - - DEFINE_SHADER_STAGE(stage, Stage::VERTEX) - { - VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - if (space == WORLD_SPACE) - { - ShaderPort* bitangent = vertexData[HW::T_BITANGENT_WORLD]; - - if (!bitangent->isEmitted()) - { - bitangent->setEmitted(); - - if (options.hwImplicitBitangents) - { - ShaderPort* normal = vertexData[HW::T_NORMAL_WORLD]; - if (!normal->isEmitted()) - { - normal->setEmitted(); - shadergen.emitLine(prefix + normal->getVariable() + " = normalize((" + HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX + " * vec4(" + HW::T_IN_NORMAL + ", 0.0)).xyz)", stage); - } - ShaderPort* tangent = vertexData[HW::T_TANGENT_WORLD]; - if (!tangent->isEmitted()) - { - tangent->setEmitted(); - shadergen.emitLine(prefix + tangent->getVariable() + " = normalize((" + HW::T_WORLD_MATRIX + " * vec4(" + HW::T_IN_TANGENT + ", 0.0)).xyz)", stage); - } - shadergen.emitLine(prefix + bitangent->getVariable() + " = cross(" + prefix + normal->getVariable() + ", " + prefix + tangent->getVariable() + ")", stage); - } - else - { - shadergen.emitLine(prefix + bitangent->getVariable() + " = normalize((" + HW::T_WORLD_MATRIX + " * vec4(" + HW::T_IN_BITANGENT + ", 0.0)).xyz)", stage); - } - } - } - else - { - ShaderPort* bitangent = vertexData[HW::T_BITANGENT_OBJECT]; - if (!bitangent->isEmitted()) - { - bitangent->setEmitted(); - - if (options.hwImplicitBitangents) - { - shadergen.emitLine(prefix + bitangent->getVariable() + " = cross(" + HW::T_IN_NORMAL + ", " + HW::T_IN_TANGENT + ")", stage); - } - else - { - shadergen.emitLine(prefix + bitangent->getVariable() + " = " + HW::T_IN_BITANGENT, stage); - } - } - } - } - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - if (space == WORLD_SPACE) - { - const ShaderPort* bitangent = vertexData[HW::T_BITANGENT_WORLD]; - shadergen.emitString(" = normalize(" + prefix + bitangent->getVariable() + ")", stage); - } - else - { - const ShaderPort* bitangent = vertexData[HW::T_BITANGENT_OBJECT]; - shadergen.emitString(" = normalize(" + prefix + bitangent->getVariable() + ")", stage); - } - shadergen.emitLineEnd(stage); - } -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/PositionNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/PositionNodeGlsl.cpp deleted file mode 100644 index d37af520b2..0000000000 --- a/source/MaterialXGenGlsl/Nodes/PositionNodeGlsl.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr PositionNodeGlsl::create() -{ - return std::make_shared(); -} - -void PositionNodeGlsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const -{ - ShaderStage vs = shader.getStage(Stage::VERTEX); - ShaderStage ps = shader.getStage(Stage::PIXEL); - - addStageInput(HW::VERTEX_INPUTS, Type::VECTOR3, HW::T_IN_POSITION, vs); - - const ShaderInput* spaceInput = node.getInput(SPACE); - const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; - if (space == WORLD_SPACE) - { - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_POSITION_WORLD, vs, ps); - } - else - { - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_POSITION_OBJECT, vs, ps); - } -} - -void PositionNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - const GlslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); - - const ShaderInput* spaceInput = node.getInput(SPACE); - const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; - - DEFINE_SHADER_STAGE(stage, Stage::VERTEX) - { - VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - if (space == WORLD_SPACE) - { - ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; - if (!position->isEmitted()) - { - position->setEmitted(); - shadergen.emitLine(prefix + position->getVariable() + " = hPositionWorld.xyz", stage); - } - } - else - { - ShaderPort* position = vertexData[HW::T_POSITION_OBJECT]; - if (!position->isEmitted()) - { - position->setEmitted(); - shadergen.emitLine(prefix + position->getVariable() + " = " + HW::T_IN_POSITION, stage); - } - } - } - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - if (space == WORLD_SPACE) - { - const ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; - shadergen.emitString(" = " + prefix + position->getVariable(), stage); - } - else - { - const ShaderPort* position = vertexData[HW::T_POSITION_OBJECT]; - shadergen.emitString(" = " + prefix + position->getVariable(), stage); - } - shadergen.emitLineEnd(stage); - } -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp index c83fbe1d78..c31b7ec663 100644 --- a/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp +++ b/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp @@ -45,7 +45,7 @@ void SurfaceNodeGlsl::createVariables(const ShaderNode&, GenContext& context, Sh { // TODO: // The surface shader needs position, normal, view position and light sources. We should solve this by adding some - // dependency mechanism so this implementation can be set to depend on the PositionNodeGlsl, NormalNodeGlsl + // dependency mechanism so this implementation can be set to depend on the HwPositionNode, HwNormalNode // ViewDirectionNodeGlsl and LightNodeGlsl nodes instead? This is where the MaterialX attribute "internalgeomprops" // is needed. // diff --git a/source/MaterialXGenGlsl/Nodes/SurfaceShaderNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/SurfaceShaderNodeGlsl.cpp index 00362b1cab..33d1b3407d 100644 --- a/source/MaterialXGenGlsl/Nodes/SurfaceShaderNodeGlsl.cpp +++ b/source/MaterialXGenGlsl/Nodes/SurfaceShaderNodeGlsl.cpp @@ -24,7 +24,7 @@ void SurfaceShaderNodeGlsl::createVariables(const ShaderNode&, GenContext& conte { // TODO: // The surface shader needs position, view position and light sources. We should solve this by adding some - // dependency mechanism so this implementation can be set to depend on the PositionNodeGlsl, + // dependency mechanism so this implementation can be set to depend on the HwPositionNode, // ViewDirectionNodeGlsl and LightNodeGlsl nodes instead? This is where the MaterialX attribute "internalgeomprops" // is needed. // diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index fd5a13d07a..4bfcac2733 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -6,10 +6,6 @@ #include #include -#include -#include -#include -#include #include #include #include @@ -33,6 +29,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -169,13 +169,13 @@ MslShaderGenerator::MslShaderGenerator() : registerImplementation(elementNames, CombineNode::create); // - registerImplementation("IM_position_vector3_" + MslShaderGenerator::TARGET, PositionNodeMsl::create); + registerImplementation("IM_position_vector3_" + MslShaderGenerator::TARGET, HwPositionNode::create); // - registerImplementation("IM_normal_vector3_" + MslShaderGenerator::TARGET, NormalNodeMsl::create); + registerImplementation("IM_normal_vector3_" + MslShaderGenerator::TARGET, HwNormalNode::create); // - registerImplementation("IM_tangent_vector3_" + MslShaderGenerator::TARGET, TangentNodeMsl::create); + registerImplementation("IM_tangent_vector3_" + MslShaderGenerator::TARGET, HwTangentNode::create); // - registerImplementation("IM_bitangent_vector3_" + MslShaderGenerator::TARGET, BitangentNodeMsl::create); + registerImplementation("IM_bitangent_vector3_" + MslShaderGenerator::TARGET, HwBitangentNode::create); // registerImplementation("IM_texcoord_vector2_" + MslShaderGenerator::TARGET, HwTexCoordNode::create); registerImplementation("IM_texcoord_vector3_" + MslShaderGenerator::TARGET, HwTexCoordNode::create); diff --git a/source/MaterialXGenMsl/Nodes/BitangentNodeMsl.h b/source/MaterialXGenMsl/Nodes/BitangentNodeMsl.h deleted file mode 100644 index 7239bb36d4..0000000000 --- a/source/MaterialXGenMsl/Nodes/BitangentNodeMsl.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_BITANGENTNODEMSL_H -#define MATERIALX_BITANGENTNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// Bitangent node implementation for MSL -class MX_GENMSL_API BitangentNodeMsl : public MslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/Nodes/NormalNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/NormalNodeMsl.cpp deleted file mode 100644 index 6250290960..0000000000 --- a/source/MaterialXGenMsl/Nodes/NormalNodeMsl.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr NormalNodeMsl::create() -{ - return std::make_shared(); -} - -void NormalNodeMsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const -{ - ShaderStage& vs = shader.getStage(Stage::VERTEX); - ShaderStage& ps = shader.getStage(Stage::PIXEL); - - addStageInput(HW::VERTEX_INPUTS, Type::VECTOR3, HW::T_IN_NORMAL, vs); - - const ShaderInput* spaceInput = node.getInput(SPACE); - const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; - if (space == WORLD_SPACE) - { - addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX, vs); - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_NORMAL_WORLD, vs, ps); - } - else - { - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_NORMAL_OBJECT, vs, ps); - } -} - -void NormalNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - const MslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); - - const ShaderInput* spaceInput = node.getInput(SPACE); - const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; - - DEFINE_SHADER_STAGE(stage, Stage::VERTEX) - { - VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - if (space == WORLD_SPACE) - { - ShaderPort* normal = vertexData[HW::T_NORMAL_WORLD]; - if (!normal->isEmitted()) - { - normal->setEmitted(); - shadergen.emitLine(prefix + normal->getVariable() + " = normalize((" + HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX + " * float4(" + HW::T_IN_NORMAL + ", 0.0)).xyz)", stage); - } - } - else - { - ShaderPort* normal = vertexData[HW::T_NORMAL_OBJECT]; - if (!normal->isEmitted()) - { - normal->setEmitted(); - shadergen.emitLine(prefix + normal->getVariable() + " = " + HW::T_IN_NORMAL, stage); - } - } - } - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - if (space == WORLD_SPACE) - { - const ShaderPort* normal = vertexData[HW::T_NORMAL_WORLD]; - shadergen.emitString(" = normalize(" + prefix + normal->getVariable() + ")", stage); - } - else - { - const ShaderPort* normal = vertexData[HW::T_NORMAL_OBJECT]; - shadergen.emitString(" = normalize(" + prefix + normal->getVariable() + ")", stage); - } - shadergen.emitLineEnd(stage); - } -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/Nodes/NormalNodeMsl.h b/source/MaterialXGenMsl/Nodes/NormalNodeMsl.h deleted file mode 100644 index 7248613a74..0000000000 --- a/source/MaterialXGenMsl/Nodes/NormalNodeMsl.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_NORMALNODEMSL_H -#define MATERIALX_NORMALNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// Normal node implementation for MSL -class MX_GENMSL_API NormalNodeMsl : public MslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/Nodes/PositionNodeMsl.h b/source/MaterialXGenMsl/Nodes/PositionNodeMsl.h deleted file mode 100644 index 1dada988be..0000000000 --- a/source/MaterialXGenMsl/Nodes/PositionNodeMsl.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_POSITIONNODEMSL_H -#define MATERIALX_POSITIONNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// Position node implementation for MSL -class MX_GENMSL_API PositionNodeMsl : public MslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/Nodes/SurfaceNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/SurfaceNodeMsl.cpp index c7fb7745b7..f67e5e211f 100644 --- a/source/MaterialXGenMsl/Nodes/SurfaceNodeMsl.cpp +++ b/source/MaterialXGenMsl/Nodes/SurfaceNodeMsl.cpp @@ -45,7 +45,7 @@ void SurfaceNodeMsl::createVariables(const ShaderNode&, GenContext& context, Sha { // TODO: // The surface shader needs position, normal, view position and light sources. We should solve this by adding some - // dependency mechanism so this implementation can be set to depend on the PositionNodeMsl, NormalNodeMsl + // dependency mechanism so this implementation can be set to depend on the HwPositionNode, HwNormalNode // ViewDirectionNodeMsl and LightNodeMsl nodes instead? This is where the MaterialX attribute "internalgeomprops" // is needed. // diff --git a/source/MaterialXGenMsl/Nodes/SurfaceShaderNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/SurfaceShaderNodeMsl.cpp index a579c46f1b..f4d418bc9c 100644 --- a/source/MaterialXGenMsl/Nodes/SurfaceShaderNodeMsl.cpp +++ b/source/MaterialXGenMsl/Nodes/SurfaceShaderNodeMsl.cpp @@ -24,7 +24,7 @@ void SurfaceShaderNodeMsl::createVariables(const ShaderNode&, GenContext& contex { // TODO: // The surface shader needs position, view position and light sources. We should solve this by adding some - // dependency mechanism so this implementation can be set to depend on the PositionNodeMsl, + // dependency mechanism so this implementation can be set to depend on the HwPositionNode, // ViewDirectionNodeMsl and LightNodeMsl nodes instead? This is where the MaterialX attribute "internalgeomprops" // is needed. // diff --git a/source/MaterialXGenMsl/Nodes/TangentNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TangentNodeMsl.cpp deleted file mode 100644 index 5e557e4e30..0000000000 --- a/source/MaterialXGenMsl/Nodes/TangentNodeMsl.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TangentNodeMsl::create() -{ - return std::make_shared(); -} - -void TangentNodeMsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const -{ - ShaderStage& vs = shader.getStage(Stage::VERTEX); - ShaderStage& ps = shader.getStage(Stage::PIXEL); - - addStageInput(HW::VERTEX_INPUTS, Type::VECTOR3, HW::T_IN_TANGENT, vs); - - const ShaderInput* spaceInput = node.getInput(SPACE); - const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; - if (space == WORLD_SPACE) - { - addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, HW::T_WORLD_MATRIX, vs); - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_TANGENT_WORLD, vs, ps); - } - else - { - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_TANGENT_OBJECT, vs, ps); - } -} - -void TangentNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - const MslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); - - const ShaderInput* spaceInput = node.getInput(SPACE); - const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; - - DEFINE_SHADER_STAGE(stage, Stage::VERTEX) - { - VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - if (space == WORLD_SPACE) - { - ShaderPort* tangent = vertexData[HW::T_TANGENT_WORLD]; - if (!tangent->isEmitted()) - { - tangent->setEmitted(); - shadergen.emitLine(prefix + tangent->getVariable() + " = normalize((" + HW::T_WORLD_MATRIX + " * float4(" + HW::T_IN_TANGENT + ", 0.0)).xyz)", stage); - } - } - else - { - ShaderPort* tangent = vertexData[HW::T_TANGENT_OBJECT]; - if (!tangent->isEmitted()) - { - tangent->setEmitted(); - shadergen.emitLine(prefix + tangent->getVariable() + " = " + HW::T_IN_TANGENT, stage); - } - } - } - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - if (space == WORLD_SPACE) - { - const ShaderPort* tangent = vertexData[HW::T_TANGENT_WORLD]; - shadergen.emitString(" = normalize(" + prefix + tangent->getVariable() + ")", stage); - } - else - { - const ShaderPort* tangent = vertexData[HW::T_TANGENT_OBJECT]; - shadergen.emitString(" = normalize(" + prefix + tangent->getVariable() + ")", stage); - } - shadergen.emitLineEnd(stage); - } -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/Nodes/TangentNodeMsl.h b/source/MaterialXGenMsl/Nodes/TangentNodeMsl.h deleted file mode 100644 index 42e2c7ef7c..0000000000 --- a/source/MaterialXGenMsl/Nodes/TangentNodeMsl.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TANGENTNODEMSL_H -#define MATERIALX_TANGENTNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// Tangent node implementation for MSL -class MX_GENMSL_API TangentNodeMsl : public MslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/Nodes/BitangentNodeMsl.cpp b/source/MaterialXGenShader/Nodes/HwBitangentNode.cpp similarity index 91% rename from source/MaterialXGenMsl/Nodes/BitangentNodeMsl.cpp rename to source/MaterialXGenShader/Nodes/HwBitangentNode.cpp index 97ca079d35..83c43a3398 100644 --- a/source/MaterialXGenMsl/Nodes/BitangentNodeMsl.cpp +++ b/source/MaterialXGenShader/Nodes/HwBitangentNode.cpp @@ -3,18 +3,18 @@ // SPDX-License-Identifier: Apache-2.0 // -#include +#include #include MATERIALX_NAMESPACE_BEGIN -ShaderNodeImplPtr BitangentNodeMsl::create() +ShaderNodeImplPtr HwBitangentNode::create() { - return std::make_shared(); + return std::make_shared(); } -void BitangentNodeMsl::createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const +void HwBitangentNode::createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const { const GenOptions& options = context.getOptions(); @@ -51,9 +51,9 @@ void BitangentNodeMsl::createVariables(const ShaderNode& node, GenContext& conte } } -void BitangentNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +void HwBitangentNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const { - const MslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); + const HwShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); const GenOptions& options = context.getOptions(); const ShaderInput* spaceInput = node.getInput(SPACE); diff --git a/source/MaterialXGenGlsl/Nodes/NormalNodeGlsl.h b/source/MaterialXGenShader/Nodes/HwBitangentNode.h similarity index 63% rename from source/MaterialXGenGlsl/Nodes/NormalNodeGlsl.h rename to source/MaterialXGenShader/Nodes/HwBitangentNode.h index acb4d5085d..a8bfa0bf11 100644 --- a/source/MaterialXGenGlsl/Nodes/NormalNodeGlsl.h +++ b/source/MaterialXGenShader/Nodes/HwBitangentNode.h @@ -3,15 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#ifndef MATERIALX_NORMALNODEGLSL_H -#define MATERIALX_NORMALNODEGLSL_H +#ifndef MATERIALX_HWBITANGENTNODE_H +#define MATERIALX_HWBITANGENTNODE_H -#include +#include MATERIALX_NAMESPACE_BEGIN -/// Normal node implementation for GLSL -class MX_GENGLSL_API NormalNodeGlsl : public GlslImplementation +/// Bitangent node implementation for hardware languages +class MX_GENSHADER_API HwBitangentNode : public HwImplementation { public: static ShaderNodeImplPtr create(); diff --git a/source/MaterialXGenGlsl/Nodes/NormalNodeGlsl.cpp b/source/MaterialXGenShader/Nodes/HwNormalNode.cpp similarity index 85% rename from source/MaterialXGenGlsl/Nodes/NormalNodeGlsl.cpp rename to source/MaterialXGenShader/Nodes/HwNormalNode.cpp index d9e27b87df..01234dcb46 100644 --- a/source/MaterialXGenGlsl/Nodes/NormalNodeGlsl.cpp +++ b/source/MaterialXGenShader/Nodes/HwNormalNode.cpp @@ -3,18 +3,18 @@ // SPDX-License-Identifier: Apache-2.0 // -#include +#include #include MATERIALX_NAMESPACE_BEGIN -ShaderNodeImplPtr NormalNodeGlsl::create() +ShaderNodeImplPtr HwNormalNode::create() { - return std::make_shared(); + return std::make_shared(); } -void NormalNodeGlsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const +void HwNormalNode::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const { ShaderStage& vs = shader.getStage(Stage::VERTEX); ShaderStage& ps = shader.getStage(Stage::PIXEL); @@ -34,9 +34,9 @@ void NormalNodeGlsl::createVariables(const ShaderNode& node, GenContext&, Shader } } -void NormalNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +void HwNormalNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const { - const GlslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); + const HwShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); const ShaderInput* spaceInput = node.getInput(SPACE); const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; diff --git a/source/MaterialXGenGlsl/Nodes/PositionNodeGlsl.h b/source/MaterialXGenShader/Nodes/HwNormalNode.h similarity index 64% rename from source/MaterialXGenGlsl/Nodes/PositionNodeGlsl.h rename to source/MaterialXGenShader/Nodes/HwNormalNode.h index 95dddbce8e..fb19050600 100644 --- a/source/MaterialXGenGlsl/Nodes/PositionNodeGlsl.h +++ b/source/MaterialXGenShader/Nodes/HwNormalNode.h @@ -3,15 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#ifndef MATERIALX_POSITIONNODEGLSL_H -#define MATERIALX_POSITIONNODEGLSL_H +#ifndef MATERIALX_HWNORMALNODE_H +#define MATERIALX_HWNORMALNODE_H -#include +#include MATERIALX_NAMESPACE_BEGIN -/// Position node implementation for GLSL -class MX_GENGLSL_API PositionNodeGlsl : public GlslImplementation +/// Normal node implementation for hardware languages +class MX_GENSHADER_API HwNormalNode : public HwImplementation { public: static ShaderNodeImplPtr create(); diff --git a/source/MaterialXGenMsl/Nodes/PositionNodeMsl.cpp b/source/MaterialXGenShader/Nodes/HwPositionNode.cpp similarity index 84% rename from source/MaterialXGenMsl/Nodes/PositionNodeMsl.cpp rename to source/MaterialXGenShader/Nodes/HwPositionNode.cpp index 6f45f4364b..df7c11f4e6 100644 --- a/source/MaterialXGenMsl/Nodes/PositionNodeMsl.cpp +++ b/source/MaterialXGenShader/Nodes/HwPositionNode.cpp @@ -3,18 +3,18 @@ // SPDX-License-Identifier: Apache-2.0 // -#include +#include #include MATERIALX_NAMESPACE_BEGIN -ShaderNodeImplPtr PositionNodeMsl::create() +ShaderNodeImplPtr HwPositionNode::create() { - return std::make_shared(); + return std::make_shared(); } -void PositionNodeMsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const +void HwPositionNode::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const { ShaderStage vs = shader.getStage(Stage::VERTEX); ShaderStage ps = shader.getStage(Stage::PIXEL); @@ -33,9 +33,9 @@ void PositionNodeMsl::createVariables(const ShaderNode& node, GenContext&, Shade } } -void PositionNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +void HwPositionNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const { - const MslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); + const HwShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); const ShaderInput* spaceInput = node.getInput(SPACE); const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; diff --git a/source/MaterialXGenGlsl/Nodes/TangentNodeGlsl.h b/source/MaterialXGenShader/Nodes/HwPositionNode.h similarity index 63% rename from source/MaterialXGenGlsl/Nodes/TangentNodeGlsl.h rename to source/MaterialXGenShader/Nodes/HwPositionNode.h index 90a5b3aaad..ae2ce5c3f5 100644 --- a/source/MaterialXGenGlsl/Nodes/TangentNodeGlsl.h +++ b/source/MaterialXGenShader/Nodes/HwPositionNode.h @@ -3,15 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#ifndef MATERIALX_TANGENTNODEGLSL_H -#define MATERIALX_TANGENTNODEGLSL_H +#ifndef MATERIALX_HWPOSITIONNODE_H +#define MATERIALX_HWPOSITIONNODE_H -#include +#include MATERIALX_NAMESPACE_BEGIN -/// Tangent node implementation for GLSL -class MX_GENGLSL_API TangentNodeGlsl : public GlslImplementation +/// Position node implementation for hardware languages +class MX_GENSHADER_API HwPositionNode : public HwImplementation { public: static ShaderNodeImplPtr create(); diff --git a/source/MaterialXGenGlsl/Nodes/TangentNodeGlsl.cpp b/source/MaterialXGenShader/Nodes/HwTangentNode.cpp similarity index 85% rename from source/MaterialXGenGlsl/Nodes/TangentNodeGlsl.cpp rename to source/MaterialXGenShader/Nodes/HwTangentNode.cpp index daffaf0e2c..6e80537932 100644 --- a/source/MaterialXGenGlsl/Nodes/TangentNodeGlsl.cpp +++ b/source/MaterialXGenShader/Nodes/HwTangentNode.cpp @@ -3,18 +3,18 @@ // SPDX-License-Identifier: Apache-2.0 // -#include +#include #include MATERIALX_NAMESPACE_BEGIN -ShaderNodeImplPtr TangentNodeGlsl::create() +ShaderNodeImplPtr HwTangentNode::create() { - return std::make_shared(); + return std::make_shared(); } -void TangentNodeGlsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const +void HwTangentNode::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const { ShaderStage& vs = shader.getStage(Stage::VERTEX); ShaderStage& ps = shader.getStage(Stage::PIXEL); @@ -34,9 +34,9 @@ void TangentNodeGlsl::createVariables(const ShaderNode& node, GenContext&, Shade } } -void TangentNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +void HwTangentNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const { - const GlslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); + const HwShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); const ShaderInput* spaceInput = node.getInput(SPACE); const int space = spaceInput ? spaceInput->getValue()->asA() : OBJECT_SPACE; diff --git a/source/MaterialXGenGlsl/Nodes/BitangentNodeGlsl.h b/source/MaterialXGenShader/Nodes/HwTangentNode.h similarity index 64% rename from source/MaterialXGenGlsl/Nodes/BitangentNodeGlsl.h rename to source/MaterialXGenShader/Nodes/HwTangentNode.h index 905b2808e0..b36d7f3c56 100644 --- a/source/MaterialXGenGlsl/Nodes/BitangentNodeGlsl.h +++ b/source/MaterialXGenShader/Nodes/HwTangentNode.h @@ -3,15 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#ifndef MATERIALX_BITANGENTNODEGLSL_H -#define MATERIALX_BITANGENTNODEGLSL_H +#ifndef MATERIALX_HWTANGENTNODE_H +#define MATERIALX_HWTANGENTNODE_H -#include +#include MATERIALX_NAMESPACE_BEGIN -/// Bitangent node implementation for GLSL -class MX_GENGLSL_API BitangentNodeGlsl : public GlslImplementation +/// Tangent node implementation for hardware languages +class MX_GENSHADER_API HwTangentNode : public HwImplementation { public: static ShaderNodeImplPtr create(); From feecfe05a4fd15a71bb3d0c7c61cde744fc65d7d Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sat, 6 Jan 2024 22:05:46 -0800 Subject: [PATCH 062/128] Merge application node implementations This changelist merges the implementations of application and NPR nodes across hardware shading languages, allowing a greater degree of code sharing. --- .../MaterialXGenGlsl/GlslShaderGenerator.cpp | 12 ++-- .../MaterialXGenGlsl/Nodes/FrameNodeGlsl.cpp | 35 ------------ .../Nodes/SurfaceNodeGlsl.cpp | 2 +- .../Nodes/SurfaceShaderNodeGlsl.cpp | 2 +- .../MaterialXGenGlsl/Nodes/TimeNodeGlsl.cpp | 38 ------------- source/MaterialXGenGlsl/Nodes/TimeNodeGlsl.h | 26 --------- .../Nodes/ViewDirectionNodeGlsl.cpp | 55 ------------------- source/MaterialXGenMsl/MslShaderGenerator.cpp | 12 ++-- .../MaterialXGenMsl/Nodes/SurfaceNodeMsl.cpp | 2 +- .../Nodes/SurfaceShaderNodeMsl.cpp | 2 +- source/MaterialXGenMsl/Nodes/TimeNodeMsl.h | 26 --------- .../Nodes/ViewDirectionNodeMsl.h | 26 --------- .../Nodes/HwFrameNode.cpp} | 10 ++-- .../Nodes/HwFrameNode.h} | 10 ++-- .../Nodes/HwTimeNode.cpp} | 10 ++-- .../Nodes/HwTimeNode.h} | 10 ++-- .../Nodes/HwViewDirectionNode.cpp} | 12 ++-- .../Nodes/HwViewDirectionNode.h} | 10 ++-- 18 files changed, 47 insertions(+), 253 deletions(-) delete mode 100644 source/MaterialXGenGlsl/Nodes/FrameNodeGlsl.cpp delete mode 100644 source/MaterialXGenGlsl/Nodes/TimeNodeGlsl.cpp delete mode 100644 source/MaterialXGenGlsl/Nodes/TimeNodeGlsl.h delete mode 100644 source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp delete mode 100644 source/MaterialXGenMsl/Nodes/TimeNodeMsl.h delete mode 100644 source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.h rename source/{MaterialXGenMsl/Nodes/FrameNodeMsl.cpp => MaterialXGenShader/Nodes/HwFrameNode.cpp} (67%) rename source/{MaterialXGenGlsl/Nodes/FrameNodeGlsl.h => MaterialXGenShader/Nodes/HwFrameNode.h} (65%) rename source/{MaterialXGenMsl/Nodes/TimeNodeMsl.cpp => MaterialXGenShader/Nodes/HwTimeNode.cpp} (72%) rename source/{MaterialXGenMsl/Nodes/FrameNodeMsl.h => MaterialXGenShader/Nodes/HwTimeNode.h} (65%) rename source/{MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp => MaterialXGenShader/Nodes/HwViewDirectionNode.cpp} (76%) rename source/{MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.h => MaterialXGenShader/Nodes/HwViewDirectionNode.h} (61%) diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp index 015edbc3ce..f0126f10d9 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp @@ -8,9 +8,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -33,6 +30,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -194,11 +194,11 @@ GlslShaderGenerator::GlslShaderGenerator() : registerImplementation("IM_geompropvalue_string_" + GlslShaderGenerator::TARGET, GeomPropValueNodeGlslAsUniform::create); // - registerImplementation("IM_frame_float_" + GlslShaderGenerator::TARGET, FrameNodeGlsl::create); + registerImplementation("IM_frame_float_" + GlslShaderGenerator::TARGET, HwFrameNode::create); // - registerImplementation("IM_time_float_" + GlslShaderGenerator::TARGET, TimeNodeGlsl::create); + registerImplementation("IM_time_float_" + GlslShaderGenerator::TARGET, HwTimeNode::create); // - registerImplementation("IM_viewdirection_vector3_" + GlslShaderGenerator::TARGET, ViewDirectionNodeGlsl::create); + registerImplementation("IM_viewdirection_vector3_" + GlslShaderGenerator::TARGET, HwViewDirectionNode::create); // registerImplementation("IM_surface_" + GlslShaderGenerator::TARGET, SurfaceNodeGlsl::create); diff --git a/source/MaterialXGenGlsl/Nodes/FrameNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/FrameNodeGlsl.cpp deleted file mode 100644 index b6dbb2002b..0000000000 --- a/source/MaterialXGenGlsl/Nodes/FrameNodeGlsl.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr FrameNodeGlsl::create() -{ - return std::make_shared(); -} - -void FrameNodeGlsl::createVariables(const ShaderNode&, GenContext&, Shader& shader) const -{ - ShaderStage& ps = shader.getStage(Stage::PIXEL); - addStageUniform(HW::PRIVATE_UNIFORMS, Type::FLOAT, HW::T_FRAME, ps); -} - -void FrameNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = " + HW::T_FRAME, stage); - shadergen.emitLineEnd(stage); - } -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp index c31b7ec663..2e222f6bcc 100644 --- a/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp +++ b/source/MaterialXGenGlsl/Nodes/SurfaceNodeGlsl.cpp @@ -46,7 +46,7 @@ void SurfaceNodeGlsl::createVariables(const ShaderNode&, GenContext& context, Sh // TODO: // The surface shader needs position, normal, view position and light sources. We should solve this by adding some // dependency mechanism so this implementation can be set to depend on the HwPositionNode, HwNormalNode - // ViewDirectionNodeGlsl and LightNodeGlsl nodes instead? This is where the MaterialX attribute "internalgeomprops" + // HwViewDirectionNode and LightNodeGlsl nodes instead? This is where the MaterialX attribute "internalgeomprops" // is needed. // ShaderStage& vs = shader.getStage(Stage::VERTEX); diff --git a/source/MaterialXGenGlsl/Nodes/SurfaceShaderNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/SurfaceShaderNodeGlsl.cpp index 33d1b3407d..5e97b8ffc6 100644 --- a/source/MaterialXGenGlsl/Nodes/SurfaceShaderNodeGlsl.cpp +++ b/source/MaterialXGenGlsl/Nodes/SurfaceShaderNodeGlsl.cpp @@ -25,7 +25,7 @@ void SurfaceShaderNodeGlsl::createVariables(const ShaderNode&, GenContext& conte // TODO: // The surface shader needs position, view position and light sources. We should solve this by adding some // dependency mechanism so this implementation can be set to depend on the HwPositionNode, - // ViewDirectionNodeGlsl and LightNodeGlsl nodes instead? This is where the MaterialX attribute "internalgeomprops" + // HwViewDirectionNode and LightNodeGlsl nodes instead? This is where the MaterialX attribute "internalgeomprops" // is needed. // ShaderStage& vs = shader.getStage(Stage::VERTEX); diff --git a/source/MaterialXGenGlsl/Nodes/TimeNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TimeNodeGlsl.cpp deleted file mode 100644 index e508391141..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TimeNodeGlsl.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TimeNodeGlsl::create() -{ - return std::make_shared(); -} - -void TimeNodeGlsl::createVariables(const ShaderNode&, GenContext&, Shader& shader) const -{ - ShaderStage& ps = shader.getStage(Stage::PIXEL); - addStageUniform(HW::PRIVATE_UNIFORMS, Type::FLOAT, HW::T_FRAME, ps); -} - -void TimeNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = " + HW::T_FRAME + " / ", stage); - const ShaderInput* fpsInput = node.getInput("fps"); - const string fps = fpsInput->getValue()->getValueString(); - shadergen.emitString(fps, stage); - shadergen.emitLineEnd(stage); - } -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/TimeNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/TimeNodeGlsl.h deleted file mode 100644 index c97f6b4741..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TimeNodeGlsl.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TIMENODEGLSL_H -#define MATERIALX_TIMENODEGLSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// Time node implementation for GLSL -class MX_GENGLSL_API TimeNodeGlsl : public GlslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp deleted file mode 100644 index f9714b5d33..0000000000 --- a/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr ViewDirectionNodeGlsl::create() -{ - return std::make_shared(); -} - -void ViewDirectionNodeGlsl::createVariables(const ShaderNode&, GenContext&, Shader& shader) const -{ - ShaderStage& vs = shader.getStage(Stage::VERTEX); - ShaderStage& ps = shader.getStage(Stage::PIXEL); - - addStageInput(HW::VERTEX_INPUTS, Type::VECTOR3, HW::T_IN_POSITION, vs); - addStageConnector(HW::VERTEX_DATA, Type::VECTOR3, HW::T_POSITION_WORLD, vs, ps); - addStageUniform(HW::PRIVATE_UNIFORMS, Type::VECTOR3, HW::T_VIEW_POSITION, ps); -} - -void ViewDirectionNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - const GlslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); - - DEFINE_SHADER_STAGE(stage, Stage::VERTEX) - { - VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; - if (!position->isEmitted()) - { - position->setEmitted(); - shadergen.emitLine(prefix + position->getVariable() + " = hPositionWorld.xyz", stage); - } - } - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); - const string prefix = shadergen.getVertexDataPrefix(vertexData); - ShaderPort* position = vertexData[HW::T_POSITION_WORLD]; - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = normalize(" + prefix + position->getVariable() + " - " + HW::T_VIEW_POSITION + ")", stage); - shadergen.emitLineEnd(stage); - } -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index 4bfcac2733..e07c0fc6ad 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -8,9 +8,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -33,6 +30,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -198,11 +198,11 @@ MslShaderGenerator::MslShaderGenerator() : registerImplementation("IM_geompropvalue_string_" + MslShaderGenerator::TARGET, GeomPropValueNodeMslAsUniform::create); // - registerImplementation("IM_frame_float_" + MslShaderGenerator::TARGET, FrameNodeMsl::create); + registerImplementation("IM_frame_float_" + MslShaderGenerator::TARGET, HwFrameNode::create); // - registerImplementation("IM_time_float_" + MslShaderGenerator::TARGET, TimeNodeMsl::create); + registerImplementation("IM_time_float_" + MslShaderGenerator::TARGET, HwTimeNode::create); // - registerImplementation("IM_viewdirection_vector3_" + MslShaderGenerator::TARGET, ViewDirectionNodeMsl::create); + registerImplementation("IM_viewdirection_vector3_" + MslShaderGenerator::TARGET, HwViewDirectionNode::create); // registerImplementation("IM_surface_" + MslShaderGenerator::TARGET, SurfaceNodeMsl::create); diff --git a/source/MaterialXGenMsl/Nodes/SurfaceNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/SurfaceNodeMsl.cpp index f67e5e211f..bd0cd91fb1 100644 --- a/source/MaterialXGenMsl/Nodes/SurfaceNodeMsl.cpp +++ b/source/MaterialXGenMsl/Nodes/SurfaceNodeMsl.cpp @@ -46,7 +46,7 @@ void SurfaceNodeMsl::createVariables(const ShaderNode&, GenContext& context, Sha // TODO: // The surface shader needs position, normal, view position and light sources. We should solve this by adding some // dependency mechanism so this implementation can be set to depend on the HwPositionNode, HwNormalNode - // ViewDirectionNodeMsl and LightNodeMsl nodes instead? This is where the MaterialX attribute "internalgeomprops" + // HwViewDirectionNode and LightNodeMsl nodes instead? This is where the MaterialX attribute "internalgeomprops" // is needed. // ShaderStage& vs = shader.getStage(Stage::VERTEX); diff --git a/source/MaterialXGenMsl/Nodes/SurfaceShaderNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/SurfaceShaderNodeMsl.cpp index f4d418bc9c..a09796a557 100644 --- a/source/MaterialXGenMsl/Nodes/SurfaceShaderNodeMsl.cpp +++ b/source/MaterialXGenMsl/Nodes/SurfaceShaderNodeMsl.cpp @@ -25,7 +25,7 @@ void SurfaceShaderNodeMsl::createVariables(const ShaderNode&, GenContext& contex // TODO: // The surface shader needs position, view position and light sources. We should solve this by adding some // dependency mechanism so this implementation can be set to depend on the HwPositionNode, - // ViewDirectionNodeMsl and LightNodeMsl nodes instead? This is where the MaterialX attribute "internalgeomprops" + // HwViewDirectionNode and LightNodeMsl nodes instead? This is where the MaterialX attribute "internalgeomprops" // is needed. // ShaderStage& vs = shader.getStage(Stage::VERTEX); diff --git a/source/MaterialXGenMsl/Nodes/TimeNodeMsl.h b/source/MaterialXGenMsl/Nodes/TimeNodeMsl.h deleted file mode 100644 index 07c505a082..0000000000 --- a/source/MaterialXGenMsl/Nodes/TimeNodeMsl.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TIMENODEMSL_H -#define MATERIALX_TIMENODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// Time node implementation for MSL -class MX_GENMSL_API TimeNodeMsl : public MslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.h b/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.h deleted file mode 100644 index be7a40108a..0000000000 --- a/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_VIEWDIRECTIONNODEMSL_H -#define MATERIALX_VIEWDIRECTIONNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// ViewDirection node implementation for MSL -class MX_GENMSL_API ViewDirectionNodeMsl : public MslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/Nodes/FrameNodeMsl.cpp b/source/MaterialXGenShader/Nodes/HwFrameNode.cpp similarity index 67% rename from source/MaterialXGenMsl/Nodes/FrameNodeMsl.cpp rename to source/MaterialXGenShader/Nodes/HwFrameNode.cpp index faac05027a..cd6a3319a8 100644 --- a/source/MaterialXGenMsl/Nodes/FrameNodeMsl.cpp +++ b/source/MaterialXGenShader/Nodes/HwFrameNode.cpp @@ -3,24 +3,24 @@ // SPDX-License-Identifier: Apache-2.0 // -#include +#include #include MATERIALX_NAMESPACE_BEGIN -ShaderNodeImplPtr FrameNodeMsl::create() +ShaderNodeImplPtr HwFrameNode::create() { - return std::make_shared(); + return std::make_shared(); } -void FrameNodeMsl::createVariables(const ShaderNode&, GenContext&, Shader& shader) const +void HwFrameNode::createVariables(const ShaderNode&, GenContext&, Shader& shader) const { ShaderStage& ps = shader.getStage(Stage::PIXEL); addStageUniform(HW::PRIVATE_UNIFORMS, Type::FLOAT, HW::T_FRAME, ps); } -void FrameNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +void HwFrameNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const { DEFINE_SHADER_STAGE(stage, Stage::PIXEL) { diff --git a/source/MaterialXGenGlsl/Nodes/FrameNodeGlsl.h b/source/MaterialXGenShader/Nodes/HwFrameNode.h similarity index 65% rename from source/MaterialXGenGlsl/Nodes/FrameNodeGlsl.h rename to source/MaterialXGenShader/Nodes/HwFrameNode.h index f3a5197eae..4487a6a0b9 100644 --- a/source/MaterialXGenGlsl/Nodes/FrameNodeGlsl.h +++ b/source/MaterialXGenShader/Nodes/HwFrameNode.h @@ -3,15 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#ifndef MATERIALX_FRAMENODEGLSL_H -#define MATERIALX_FRAMENODEGLSL_H +#ifndef MATERIALX_HWFRAMENODE_H +#define MATERIALX_HWFRAMENODE_H -#include +#include MATERIALX_NAMESPACE_BEGIN -/// Frame node implementation for GLSL -class MX_GENGLSL_API FrameNodeGlsl : public GlslImplementation +/// Frame node implementation for hardware languages +class MX_GENSHADER_API HwFrameNode : public HwImplementation { public: static ShaderNodeImplPtr create(); diff --git a/source/MaterialXGenMsl/Nodes/TimeNodeMsl.cpp b/source/MaterialXGenShader/Nodes/HwTimeNode.cpp similarity index 72% rename from source/MaterialXGenMsl/Nodes/TimeNodeMsl.cpp rename to source/MaterialXGenShader/Nodes/HwTimeNode.cpp index 0c54861b40..8f802a0764 100644 --- a/source/MaterialXGenMsl/Nodes/TimeNodeMsl.cpp +++ b/source/MaterialXGenShader/Nodes/HwTimeNode.cpp @@ -3,24 +3,24 @@ // SPDX-License-Identifier: Apache-2.0 // -#include +#include #include MATERIALX_NAMESPACE_BEGIN -ShaderNodeImplPtr TimeNodeMsl::create() +ShaderNodeImplPtr HwTimeNode::create() { - return std::make_shared(); + return std::make_shared(); } -void TimeNodeMsl::createVariables(const ShaderNode&, GenContext&, Shader& shader) const +void HwTimeNode::createVariables(const ShaderNode&, GenContext&, Shader& shader) const { ShaderStage& ps = shader.getStage(Stage::PIXEL); addStageUniform(HW::PRIVATE_UNIFORMS, Type::FLOAT, HW::T_FRAME, ps); } -void TimeNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +void HwTimeNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const { DEFINE_SHADER_STAGE(stage, Stage::PIXEL) { diff --git a/source/MaterialXGenMsl/Nodes/FrameNodeMsl.h b/source/MaterialXGenShader/Nodes/HwTimeNode.h similarity index 65% rename from source/MaterialXGenMsl/Nodes/FrameNodeMsl.h rename to source/MaterialXGenShader/Nodes/HwTimeNode.h index 4ad554102b..e5e1a2fcd4 100644 --- a/source/MaterialXGenMsl/Nodes/FrameNodeMsl.h +++ b/source/MaterialXGenShader/Nodes/HwTimeNode.h @@ -3,15 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#ifndef MATERIALX_FRAMENODEMSL_H -#define MATERIALX_FRAMENODEMSL_H +#ifndef MATERIALX_HWTIMENODE_H +#define MATERIALX_HWTIMENODE_H -#include +#include MATERIALX_NAMESPACE_BEGIN -/// Frame node implementation for MSL -class MX_GENMSL_API FrameNodeMsl : public MslImplementation +/// Time node implementation for hardware languages +class MX_GENSHADER_API HwTimeNode : public HwImplementation { public: static ShaderNodeImplPtr create(); diff --git a/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp b/source/MaterialXGenShader/Nodes/HwViewDirectionNode.cpp similarity index 76% rename from source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp rename to source/MaterialXGenShader/Nodes/HwViewDirectionNode.cpp index 1443b5c320..819ac93029 100644 --- a/source/MaterialXGenMsl/Nodes/ViewDirectionNodeMsl.cpp +++ b/source/MaterialXGenShader/Nodes/HwViewDirectionNode.cpp @@ -3,18 +3,18 @@ // SPDX-License-Identifier: Apache-2.0 // -#include +#include #include MATERIALX_NAMESPACE_BEGIN -ShaderNodeImplPtr ViewDirectionNodeMsl::create() +ShaderNodeImplPtr HwViewDirectionNode::create() { - return std::make_shared(); + return std::make_shared(); } -void ViewDirectionNodeMsl::createVariables(const ShaderNode&, GenContext&, Shader& shader) const +void HwViewDirectionNode::createVariables(const ShaderNode&, GenContext&, Shader& shader) const { ShaderStage& vs = shader.getStage(Stage::VERTEX); ShaderStage& ps = shader.getStage(Stage::PIXEL); @@ -24,9 +24,9 @@ void ViewDirectionNodeMsl::createVariables(const ShaderNode&, GenContext&, Shade addStageUniform(HW::PRIVATE_UNIFORMS, Type::VECTOR3, HW::T_VIEW_POSITION, ps); } -void ViewDirectionNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +void HwViewDirectionNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const { - const MslShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); + const HwShaderGenerator& shadergen = static_cast(context.getShaderGenerator()); DEFINE_SHADER_STAGE(stage, Stage::VERTEX) { diff --git a/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.h b/source/MaterialXGenShader/Nodes/HwViewDirectionNode.h similarity index 61% rename from source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.h rename to source/MaterialXGenShader/Nodes/HwViewDirectionNode.h index 24cafe2f1d..143d89d437 100644 --- a/source/MaterialXGenGlsl/Nodes/ViewDirectionNodeGlsl.h +++ b/source/MaterialXGenShader/Nodes/HwViewDirectionNode.h @@ -3,15 +3,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#ifndef MATERIALX_VIEWDIRECTIONNODEGLSL_H -#define MATERIALX_VIEWDIRECTIONNODEGLSL_H +#ifndef MATERIALX_HWVIEWDIRECTIONNODE_H +#define MATERIALX_HWVIEWDIRECTIONNODE_H -#include +#include MATERIALX_NAMESPACE_BEGIN -/// ViewDirection node implementation for GLSL -class MX_GENGLSL_API ViewDirectionNodeGlsl : public GlslImplementation +/// ViewDirection node implementation for hardware languages +class MX_GENSHADER_API HwViewDirectionNode : public HwImplementation { public: static ShaderNodeImplPtr create(); From 96276bb07c2b0a5515d18ec06ac01a0a259ee4c3 Mon Sep 17 00:00:00 2001 From: mnikelsky Date: Tue, 9 Jan 2024 00:48:22 +0100 Subject: [PATCH 063/128] Add vector2 variant of normalmap (#1355) The materialx specification defines the scale attribute of the normalmap to be either a float or a vector2 but the vector2 variant was missing from the implementation. This PR adds it. --- libraries/stdlib/genglsl/mx_normalmap.glsl | 7 +++++- .../stdlib/genglsl/stdlib_genglsl_impl.mtlx | 4 ++- .../stdlib/genmdl/stdlib_genmdl_impl.mtlx | 3 ++- libraries/stdlib/genmsl/mx_normalmap.metal | 7 +++++- .../stdlib/genmsl/stdlib_genmsl_impl.mtlx | 3 ++- libraries/stdlib/genosl/mx_normalmap.osl | 9 +++++-- .../stdlib/genosl/stdlib_genosl_impl.mtlx | 3 ++- libraries/stdlib/stdlib_defs.mtlx | 8 ++++++ .../normalmapped_surfaceshader.mtlx | 25 +++++++++++++++++++ .../MaterialXGenMdl/mdl/materialx/stdlib.mdl | 23 ++++++++++++++--- 10 files changed, 81 insertions(+), 11 deletions(-) diff --git a/libraries/stdlib/genglsl/mx_normalmap.glsl b/libraries/stdlib/genglsl/mx_normalmap.glsl index 86d5610fea..19e0797c4f 100644 --- a/libraries/stdlib/genglsl/mx_normalmap.glsl +++ b/libraries/stdlib/genglsl/mx_normalmap.glsl @@ -1,4 +1,4 @@ -void mx_normalmap(vec3 value, int map_space, float normal_scale, vec3 N, vec3 T, out vec3 result) +void mx_normalmap_vector2(vec3 value, int map_space, vec2 normal_scale, vec3 N, vec3 T, out vec3 result) { // Decode the normal map. value = (value == vec3(0.0f)) ? vec3(0.0, 0.0, 1.0) : value * 2.0 - 1.0; @@ -14,3 +14,8 @@ void mx_normalmap(vec3 value, int map_space, float normal_scale, vec3 N, vec3 T, // Normalize the result. result = normalize(value); } + +void mx_normalmap_float(vec3 value, int map_space, float normal_scale, vec3 N, vec3 T, out vec3 result) +{ + mx_normalmap_vector2(value, map_space, vec2(normal_scale), N, T, result); +} diff --git a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx index 6f67b21d33..dc4f52e3b6 100644 --- a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx +++ b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx @@ -42,7 +42,9 @@ - + + + diff --git a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx index 6c550c92db..96fd768e25 100644 --- a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx +++ b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx @@ -44,7 +44,8 @@ - + + diff --git a/libraries/stdlib/genmsl/mx_normalmap.metal b/libraries/stdlib/genmsl/mx_normalmap.metal index c9c7bd5546..a3ffedaad5 100644 --- a/libraries/stdlib/genmsl/mx_normalmap.metal +++ b/libraries/stdlib/genmsl/mx_normalmap.metal @@ -1,4 +1,4 @@ -void mx_normalmap(vec3 value, int map_space, float normal_scale, vec3 N, vec3 T, out vec3 result) +void mx_normalmap_vector2(vec3 value, int map_space, vec2 normal_scale, vec3 N, vec3 T, out vec3 result) { // Decode the normal map. value = all(value == vec3(0.0f)) ? vec3(0.0, 0.0, 1.0) : value * 2.0 - 1.0; @@ -14,3 +14,8 @@ void mx_normalmap(vec3 value, int map_space, float normal_scale, vec3 N, vec3 T, // Normalize the result. result = normalize(value); } + +void mx_normalmap_float(vec3 value, int map_space, float normal_scale, vec3 N, vec3 T, out vec3 result) +{ + mx_normalmap_vector2(value, map_space, vec2(normal_scale), N, T, result); +} diff --git a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx index 40be6f8c46..1875c2b617 100644 --- a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx +++ b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx @@ -42,7 +42,8 @@ - + + diff --git a/libraries/stdlib/genosl/mx_normalmap.osl b/libraries/stdlib/genosl/mx_normalmap.osl index a1f276faf1..bf75781f51 100644 --- a/libraries/stdlib/genosl/mx_normalmap.osl +++ b/libraries/stdlib/genosl/mx_normalmap.osl @@ -1,4 +1,4 @@ -void mx_normalmap(vector value, string map_space, float normal_scale, vector N, vector U, output vector result) +void mx_normalmap_vector2(vector value, string map_space, vector2 normal_scale, vector N, vector U, output vector result) { // Tangent space if (map_space == "tangent") @@ -6,7 +6,7 @@ void mx_normalmap(vector value, string map_space, float normal_scale, vector N, vector v = value * 2.0 - 1.0; vector T = normalize(U - dot(U, N) * N); vector B = normalize(cross(N, T)); - result = normalize(T * v[0] * normal_scale + B * v[1] * normal_scale + N * v[2]); + result = normalize(T * v[0] * normal_scale[0] + B * v[1] * normal_scale[1] + N * v[2]); } // Object space else @@ -15,3 +15,8 @@ void mx_normalmap(vector value, string map_space, float normal_scale, vector N, result = normalize(n); } } + +void mx_normalmap_float(vector value, string map_space, float normal_scale, vector N, vector U, output vector result) +{ + mx_normalmap_vector2(value, map_space, vector2(normal_scale, normal_scale), N, U, result); +} diff --git a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx index a984d912b8..ae3f6777cf 100644 --- a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx +++ b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx @@ -44,7 +44,8 @@ - + + diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index 90ccb57a98..051891cf83 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -2505,6 +2505,14 @@
+ + + + + + + + - + diff --git a/resources/Materials/TestSuite/stdlib/noise/noise.mtlx b/resources/Materials/TestSuite/stdlib/noise/noise.mtlx index 14ab1b9702..f5df8ef9ed 100644 --- a/resources/Materials/TestSuite/stdlib/noise/noise.mtlx +++ b/resources/Materials/TestSuite/stdlib/noise/noise.mtlx @@ -1,208 +1,232 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Materials/TestSuite/stdlib/texture/noise.mtlx b/resources/Materials/TestSuite/stdlib/texture/noise.mtlx deleted file mode 100644 index 760e508896..0000000000 --- a/resources/Materials/TestSuite/stdlib/texture/noise.mtlx +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From c9a069c1a385ca929732fc1eac2bff33b3723858 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sat, 13 Jan 2024 19:58:52 -0800 Subject: [PATCH 068/128] Static analysis optimizations This changelist addresses a handful of static analysis optimizations flagged by PVS-Studio and cppcheck, including the following: - Pass immutable std::string, FilePath, and FileSearchPath arguments by const reference. - Mark immutable ShaderGenerator references as const. - Prefer std::string::empty over comparison against an empty string. - Remove unused private methods Graph::findLinkId, Graph::findInput, and Graph::selectMaterial. - Remove variable assignments with no impact on code behavior. --- source/MaterialXFormat/XmlIo.cpp | 2 +- source/MaterialXFormat/XmlIo.h | 2 +- .../GlslResourceBindingContext.cpp | 4 +- .../VkResourceBindingContext.cpp | 6 +- .../MslResourceBindingContext.cpp | 4 +- source/MaterialXGenOsl/OslShaderGenerator.cpp | 2 +- source/MaterialXGraphEditor/Graph.cpp | 90 +------------------ source/MaterialXGraphEditor/Graph.h | 9 +- 8 files changed, 16 insertions(+), 103 deletions(-) diff --git a/source/MaterialXFormat/XmlIo.cpp b/source/MaterialXFormat/XmlIo.cpp index 67d41225a4..2bc0908008 100644 --- a/source/MaterialXFormat/XmlIo.cpp +++ b/source/MaterialXFormat/XmlIo.cpp @@ -353,7 +353,7 @@ void readFromXmlFile(DocumentPtr doc, FilePath filename, FileSearchPath searchPa documentFromXml(doc, xmlDoc, searchPath, readOptions); } -void readFromXmlString(DocumentPtr doc, const string& str, FileSearchPath searchPath, const XmlReadOptions* readOptions) +void readFromXmlString(DocumentPtr doc, const string& str, const FileSearchPath& searchPath, const XmlReadOptions* readOptions) { std::istringstream stream(str); readFromXmlStream(doc, stream, searchPath, readOptions); diff --git a/source/MaterialXFormat/XmlIo.h b/source/MaterialXFormat/XmlIo.h index b098c0fb3a..3aa8d41ed5 100644 --- a/source/MaterialXFormat/XmlIo.h +++ b/source/MaterialXFormat/XmlIo.h @@ -146,7 +146,7 @@ MX_FORMAT_API void readFromXmlFile(DocumentPtr doc, /// If provided, then the given options will affect the behavior of the /// read function. Defaults to a null pointer. /// @throws ExceptionParseError if the document cannot be parsed. -MX_FORMAT_API void readFromXmlString(DocumentPtr doc, const string& str, FileSearchPath searchPath = FileSearchPath(), const XmlReadOptions* readOptions = nullptr); +MX_FORMAT_API void readFromXmlString(DocumentPtr doc, const string& str, const FileSearchPath& searchPath = FileSearchPath(), const XmlReadOptions* readOptions = nullptr); /// @} /// @name Write Functions diff --git a/source/MaterialXGenGlsl/GlslResourceBindingContext.cpp b/source/MaterialXGenGlsl/GlslResourceBindingContext.cpp index 3aad355d60..925aa2cd0c 100644 --- a/source/MaterialXGenGlsl/GlslResourceBindingContext.cpp +++ b/source/MaterialXGenGlsl/GlslResourceBindingContext.cpp @@ -58,7 +58,7 @@ void GlslResourceBindingContext::emitDirectives(GenContext& context, ShaderStage void GlslResourceBindingContext::emitResourceBindings(GenContext& context, const VariableBlock& uniforms, ShaderStage& stage) { - ShaderGenerator& generator = context.getShaderGenerator(); + const ShaderGenerator& generator = context.getShaderGenerator(); const Syntax& syntax = generator.getSyntax(); // First, emit all value uniforms in a block with single layout binding @@ -108,7 +108,7 @@ void GlslResourceBindingContext::emitStructuredResourceBindings(GenContext& cont ShaderStage& stage, const std::string& structInstanceName, const std::string& arraySuffix) { - ShaderGenerator& generator = context.getShaderGenerator(); + const ShaderGenerator& generator = context.getShaderGenerator(); const Syntax& syntax = generator.getSyntax(); // Glsl structures need to be aligned. We make a best effort to base align struct members and add diff --git a/source/MaterialXGenGlsl/VkResourceBindingContext.cpp b/source/MaterialXGenGlsl/VkResourceBindingContext.cpp index 38e7186f4a..3c5d8b6bb0 100644 --- a/source/MaterialXGenGlsl/VkResourceBindingContext.cpp +++ b/source/MaterialXGenGlsl/VkResourceBindingContext.cpp @@ -24,7 +24,7 @@ void VkResourceBindingContext::initialize() void VkResourceBindingContext::emitDirectives(GenContext& context, ShaderStage& stage) { - ShaderGenerator& generator = context.getShaderGenerator(); + const ShaderGenerator& generator = context.getShaderGenerator(); // Write shader stage directives for Vulkan compliance std::string shaderStage; @@ -45,7 +45,7 @@ void VkResourceBindingContext::emitDirectives(GenContext& context, ShaderStage& void VkResourceBindingContext::emitResourceBindings(GenContext& context, const VariableBlock& uniforms, ShaderStage& stage) { - ShaderGenerator& generator = context.getShaderGenerator(); + const ShaderGenerator& generator = context.getShaderGenerator(); const Syntax& syntax = generator.getSyntax(); // First, emit all value uniforms in a block with single layout binding @@ -95,7 +95,7 @@ void VkResourceBindingContext::emitStructuredResourceBindings(GenContext& contex ShaderStage& stage, const std::string& structInstanceName, const std::string& arraySuffix) { - ShaderGenerator& generator = context.getShaderGenerator(); + const ShaderGenerator& generator = context.getShaderGenerator(); const Syntax& syntax = generator.getSyntax(); // Glsl structures need to be aligned. We make a best effort to base align struct members and add diff --git a/source/MaterialXGenMsl/MslResourceBindingContext.cpp b/source/MaterialXGenMsl/MslResourceBindingContext.cpp index 7b61f41854..5d6cbab6f9 100644 --- a/source/MaterialXGenMsl/MslResourceBindingContext.cpp +++ b/source/MaterialXGenMsl/MslResourceBindingContext.cpp @@ -32,7 +32,7 @@ void MslResourceBindingContext::emitDirectives(GenContext&, ShaderStage&) void MslResourceBindingContext::emitResourceBindings(GenContext& context, const VariableBlock& uniforms, ShaderStage& stage) { - ShaderGenerator& generator = context.getShaderGenerator(); + const ShaderGenerator& generator = context.getShaderGenerator(); // First, emit all value uniforms in a block with single layout binding bool hasValueUniforms = false; @@ -69,7 +69,7 @@ void MslResourceBindingContext::emitStructuredResourceBindings(GenContext& conte ShaderStage& stage, const std::string& structInstanceName, const std::string& arraySuffix) { - ShaderGenerator& generator = context.getShaderGenerator(); + const ShaderGenerator& generator = context.getShaderGenerator(); const size_t baseAlignment = 16; // Values are adjusted based on diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp index f16770174b..0ef647246a 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.cpp +++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp @@ -651,7 +651,7 @@ void OslShaderGenerator::emitMetadata(const ShaderPort* port, ShaderStage& stage { emitLineEnd(stage, false); emitScopeBegin(stage, Syntax::DOUBLE_SQUARE_BRACKETS); - for (auto line : metadataLines) + for (const auto& line : metadataLines) { emitLine(line, stage, false); } diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index f0d1791143..181ea9e591 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -200,7 +200,7 @@ void Graph::loadStandardLibraries() } } -mx::DocumentPtr Graph::loadDocument(mx::FilePath filename) +mx::DocumentPtr Graph::loadDocument(const mx::FilePath& filename) { mx::FilePathVec libraryFolders = { "libraries" }; _libraryFolders = libraryFolders; @@ -430,14 +430,8 @@ int Graph::findLinkPosition(int id) bool Graph::checkPosition(UiNodePtr node) { - if (node->getMxElement() != nullptr) - { - if (node->getMxElement()->getAttribute("xpos") != "") - { - return true; - } - } - return false; + return node->getMxElement() && + !node->getMxElement()->getAttribute("xpos").empty(); } // Calculate the total vertical space the node level takes up @@ -710,23 +704,6 @@ void Graph::setPinColor() _pinColor.insert(std::make_pair("stringarray", ImColor(120, 180, 100))); } -void Graph::selectMaterial(UiNodePtr uiNode) -{ - // Find renderable element that corresponds with material UiNode - std::vector elems = mx::findRenderableElements(_graphDoc); - mx::TypedElementPtr typedElem = nullptr; - for (mx::TypedElementPtr elem : elems) - { - mx::TypedElementPtr renderableElem = elem; - mx::NodePtr node = elem->asA(); - if (node == uiNode->getNode()) - { - typedElem = elem; - } - } - _renderer->setMaterial(typedElem); -} - void Graph::setRenderMaterial(UiNodePtr node) { // For now only surface shaders and materials are considered renderable. @@ -2028,7 +2005,7 @@ UiPinPtr Graph::getPin(ed::PinId pinId) return nullPin; } -void Graph::drawPinIcon(std::string type, bool connected, int alpha) +void Graph::drawPinIcon(const std::string& type, bool connected, int alpha) { ax::Drawing::IconType iconType = ax::Drawing::IconType::Flow; ImColor color = ImColor(0, 0, 0, 255); @@ -2105,50 +2082,6 @@ bool Graph::readOnly() return _currGraphElem->getActiveSourceUri() != _graphDoc->getActiveSourceUri(); } -mx::InputPtr Graph::findInput(mx::InputPtr nodeInput, const std::string& name) -{ - if (_isNodeGraph) - { - for (UiNodePtr uiNode : _graphNodes) - { - if (uiNode->getNode()) - { - for (mx::InputPtr input : uiNode->getNode()->getActiveInputs()) - { - if (input->getInterfaceInput()) - { - if (input->getInterfaceInput() == nodeInput) - { - return input; - } - } - } - } - } - } - else - { - if (_currUiNode->getNodeGraph()) - { - for (mx::NodePtr node : _currUiNode->getNodeGraph()->getNodes()) - { - for (mx::InputPtr input : node->getActiveInputs()) - { - if (input->getInterfaceInput()) - { - - if (input->getInterfaceName() == name) - { - return input; - } - } - } - } - } - } - return nullptr; -} - void Graph::drawOutputPins(UiNodePtr node, const std::string& longestInputLabel) { std::string longestLabel = longestInputLabel; @@ -3736,7 +3669,6 @@ void Graph::addNodePopup(bool cursor) } } } - cursor = false; ImGui::EndPopup(); open_AddPopup = false; } @@ -3778,7 +3710,6 @@ void Graph::searchNodePopup(bool cursor) } } } - cursor = false; ImGui::EndPopup(); } } @@ -4349,19 +4280,6 @@ int Graph::findNode(int nodeId) return -1; } -std::vector Graph::findLinkId(int id) -{ - std::vector ids; - for (const Link& link : _currLinks) - { - if (link._startAttr == id || link._endAttr == id) - { - ids.push_back(link.id); - } - } - return ids; -} - bool Graph::edgeExists(UiEdge newEdge) { if (_currEdge.size() > 0) diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index 821ecf71fd..965ec519b7 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -66,7 +66,7 @@ class Graph int viewWidth, int viewHeight); - mx::DocumentPtr loadDocument(mx::FilePath filename); + mx::DocumentPtr loadDocument(const mx::FilePath& filename); void drawGraph(ImVec2 mousePos); RenderViewPtr getRenderer() @@ -106,9 +106,6 @@ class Graph // Find link position in current links vector from link id int findLinkPosition(int id); - // Find link from attribute id - std::vector findLinkId(int attrId); - // Check if link exists in the current link vector bool linkExists(Link newLink); @@ -139,7 +136,7 @@ class Graph void setPinColor(); // Based on the pin icon function in the ImGui Node Editor blueprints-example.cpp - void drawPinIcon(std::string type, bool connected, int alpha); + void drawPinIcon(const std::string& type, bool connected, int alpha); UiPinPtr getPin(ed::PinId id); void drawInputPin(UiPinPtr pin); @@ -189,7 +186,6 @@ class Graph // Add input pointer to node based on input pin void addNodeInput(UiNodePtr node, mx::InputPtr& input); - mx::InputPtr findInput(mx::InputPtr input, const std::string& name); void upNodeGraph(); // Set the value of the selected node constants in the node property editor @@ -222,7 +218,6 @@ class Graph void shaderPopup(); void updateMaterials(mx::InputPtr input = nullptr, mx::ValuePtr value = nullptr); - void selectMaterial(UiNodePtr node); // Allow for camera manipulation of render view window void handleRenderViewInputs(); From 6773cb59f9ece4fe2d19331f8f7d24fa0058d934 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 17 Jan 2024 10:43:13 -0800 Subject: [PATCH 069/128] Improvements to noise implementations (#1653) - Leverage node graphs to share the conversion aspects of noise implementations across languages. - Simplify noise unit tests to cover only unique implementations. --- .../genglsl/mx_fractal3d_fa_vector2.glsl | 7 - .../genglsl/mx_fractal3d_fa_vector3.glsl | 7 - .../genglsl/mx_fractal3d_fa_vector4.glsl | 7 - .../stdlib/genglsl/mx_noise2d_fa_vector2.glsl | 7 - .../stdlib/genglsl/mx_noise2d_fa_vector3.glsl | 7 - .../stdlib/genglsl/mx_noise2d_fa_vector4.glsl | 8 - .../stdlib/genglsl/mx_noise3d_fa_vector2.glsl | 7 - .../stdlib/genglsl/mx_noise3d_fa_vector3.glsl | 7 - .../stdlib/genglsl/mx_noise3d_fa_vector4.glsl | 8 - .../stdlib/genglsl/stdlib_genglsl_impl.mtlx | 21 -- .../stdlib/genmdl/stdlib_genmdl_impl.mtlx | 21 -- .../stdlib/genmsl/stdlib_genmsl_impl.mtlx | 21 -- .../stdlib/genosl/mx_fractal3d_color3.osl | 5 - .../stdlib/genosl/mx_fractal3d_color4.osl | 5 - .../stdlib/genosl/mx_fractal3d_fa_color3.osl | 5 - .../stdlib/genosl/mx_fractal3d_fa_color4.osl | 5 - .../stdlib/genosl/mx_fractal3d_fa_vector2.osl | 5 - .../stdlib/genosl/mx_fractal3d_fa_vector3.osl | 5 - .../stdlib/genosl/mx_fractal3d_fa_vector4.osl | 5 - libraries/stdlib/genosl/mx_noise2d_color3.osl | 5 - libraries/stdlib/genosl/mx_noise2d_color4.osl | 5 - .../stdlib/genosl/mx_noise2d_fa_color3.osl | 5 - .../stdlib/genosl/mx_noise2d_fa_color4.osl | 5 - .../stdlib/genosl/mx_noise2d_fa_vector2.osl | 5 - .../stdlib/genosl/mx_noise2d_fa_vector3.osl | 5 - .../stdlib/genosl/mx_noise2d_fa_vector4.osl | 5 - libraries/stdlib/genosl/mx_noise3d_color3.osl | 5 - libraries/stdlib/genosl/mx_noise3d_color4.osl | 5 - .../stdlib/genosl/mx_noise3d_fa_color3.osl | 5 - .../stdlib/genosl/mx_noise3d_fa_color4.osl | 5 - .../stdlib/genosl/mx_noise3d_fa_vector2.osl | 5 - .../stdlib/genosl/mx_noise3d_fa_vector3.osl | 5 - .../stdlib/genosl/mx_noise3d_fa_vector4.osl | 5 - .../stdlib/genosl/stdlib_genosl_impl.mtlx | 21 -- libraries/stdlib/stdlib_ng.mtlx | 194 ++++++++++++++++++ .../TestSuite/stdlib/noise/noise.mtlx | 105 ---------- 36 files changed, 194 insertions(+), 359 deletions(-) delete mode 100644 libraries/stdlib/genglsl/mx_fractal3d_fa_vector2.glsl delete mode 100644 libraries/stdlib/genglsl/mx_fractal3d_fa_vector3.glsl delete mode 100644 libraries/stdlib/genglsl/mx_fractal3d_fa_vector4.glsl delete mode 100644 libraries/stdlib/genglsl/mx_noise2d_fa_vector2.glsl delete mode 100644 libraries/stdlib/genglsl/mx_noise2d_fa_vector3.glsl delete mode 100644 libraries/stdlib/genglsl/mx_noise2d_fa_vector4.glsl delete mode 100644 libraries/stdlib/genglsl/mx_noise3d_fa_vector2.glsl delete mode 100644 libraries/stdlib/genglsl/mx_noise3d_fa_vector3.glsl delete mode 100644 libraries/stdlib/genglsl/mx_noise3d_fa_vector4.glsl delete mode 100644 libraries/stdlib/genosl/mx_fractal3d_color3.osl delete mode 100644 libraries/stdlib/genosl/mx_fractal3d_color4.osl delete mode 100644 libraries/stdlib/genosl/mx_fractal3d_fa_color3.osl delete mode 100644 libraries/stdlib/genosl/mx_fractal3d_fa_color4.osl delete mode 100644 libraries/stdlib/genosl/mx_fractal3d_fa_vector2.osl delete mode 100644 libraries/stdlib/genosl/mx_fractal3d_fa_vector3.osl delete mode 100644 libraries/stdlib/genosl/mx_fractal3d_fa_vector4.osl delete mode 100644 libraries/stdlib/genosl/mx_noise2d_color3.osl delete mode 100644 libraries/stdlib/genosl/mx_noise2d_color4.osl delete mode 100644 libraries/stdlib/genosl/mx_noise2d_fa_color3.osl delete mode 100644 libraries/stdlib/genosl/mx_noise2d_fa_color4.osl delete mode 100644 libraries/stdlib/genosl/mx_noise2d_fa_vector2.osl delete mode 100644 libraries/stdlib/genosl/mx_noise2d_fa_vector3.osl delete mode 100644 libraries/stdlib/genosl/mx_noise2d_fa_vector4.osl delete mode 100644 libraries/stdlib/genosl/mx_noise3d_color3.osl delete mode 100644 libraries/stdlib/genosl/mx_noise3d_color4.osl delete mode 100644 libraries/stdlib/genosl/mx_noise3d_fa_color3.osl delete mode 100644 libraries/stdlib/genosl/mx_noise3d_fa_color4.osl delete mode 100644 libraries/stdlib/genosl/mx_noise3d_fa_vector2.osl delete mode 100644 libraries/stdlib/genosl/mx_noise3d_fa_vector3.osl delete mode 100644 libraries/stdlib/genosl/mx_noise3d_fa_vector4.osl diff --git a/libraries/stdlib/genglsl/mx_fractal3d_fa_vector2.glsl b/libraries/stdlib/genglsl/mx_fractal3d_fa_vector2.glsl deleted file mode 100644 index 59dbbee127..0000000000 --- a/libraries/stdlib/genglsl/mx_fractal3d_fa_vector2.glsl +++ /dev/null @@ -1,7 +0,0 @@ -#include "lib/mx_noise.glsl" - -void mx_fractal3d_fa_vector2(float amplitude, int octaves, float lacunarity, float diminish, vec3 position, out vec2 result) -{ - vec2 value = mx_fractal_noise_vec2(position, octaves, lacunarity, diminish); - result = value * amplitude; -} diff --git a/libraries/stdlib/genglsl/mx_fractal3d_fa_vector3.glsl b/libraries/stdlib/genglsl/mx_fractal3d_fa_vector3.glsl deleted file mode 100644 index d0f30defd4..0000000000 --- a/libraries/stdlib/genglsl/mx_fractal3d_fa_vector3.glsl +++ /dev/null @@ -1,7 +0,0 @@ -#include "lib/mx_noise.glsl" - -void mx_fractal3d_fa_vector3(float amplitude, int octaves, float lacunarity, float diminish, vec3 position, out vec3 result) -{ - vec3 value = mx_fractal_noise_vec3(position, octaves, lacunarity, diminish); - result = value * amplitude; -} diff --git a/libraries/stdlib/genglsl/mx_fractal3d_fa_vector4.glsl b/libraries/stdlib/genglsl/mx_fractal3d_fa_vector4.glsl deleted file mode 100644 index b9c66c4465..0000000000 --- a/libraries/stdlib/genglsl/mx_fractal3d_fa_vector4.glsl +++ /dev/null @@ -1,7 +0,0 @@ -#include "lib/mx_noise.glsl" - -void mx_fractal3d_fa_vector4(float amplitude, int octaves, float lacunarity, float diminish, vec3 position, out vec4 result) -{ - vec4 value = mx_fractal_noise_vec4(position, octaves, lacunarity, diminish); - result = value * amplitude; -} diff --git a/libraries/stdlib/genglsl/mx_noise2d_fa_vector2.glsl b/libraries/stdlib/genglsl/mx_noise2d_fa_vector2.glsl deleted file mode 100644 index f5a81565d7..0000000000 --- a/libraries/stdlib/genglsl/mx_noise2d_fa_vector2.glsl +++ /dev/null @@ -1,7 +0,0 @@ -#include "lib/mx_noise.glsl" - -void mx_noise2d_fa_vector2(float amplitude, float pivot, vec2 texcoord, out vec2 result) -{ - vec3 value = mx_perlin_noise_vec3(texcoord); - result = value.xy * amplitude + pivot; -} diff --git a/libraries/stdlib/genglsl/mx_noise2d_fa_vector3.glsl b/libraries/stdlib/genglsl/mx_noise2d_fa_vector3.glsl deleted file mode 100644 index 0735965ca0..0000000000 --- a/libraries/stdlib/genglsl/mx_noise2d_fa_vector3.glsl +++ /dev/null @@ -1,7 +0,0 @@ -#include "lib/mx_noise.glsl" - -void mx_noise2d_fa_vector3(float amplitude, float pivot, vec2 texcoord, out vec3 result) -{ - vec3 value = mx_perlin_noise_vec3(texcoord); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genglsl/mx_noise2d_fa_vector4.glsl b/libraries/stdlib/genglsl/mx_noise2d_fa_vector4.glsl deleted file mode 100644 index 6d51a59e4a..0000000000 --- a/libraries/stdlib/genglsl/mx_noise2d_fa_vector4.glsl +++ /dev/null @@ -1,8 +0,0 @@ -#include "lib/mx_noise.glsl" - -void mx_noise2d_fa_vector4(float amplitude, float pivot, vec2 texcoord, out vec4 result) -{ - vec3 xyz = mx_perlin_noise_vec3(texcoord); - float w = mx_perlin_noise_float(texcoord + vec2(19, 73)); - result = vec4(xyz, w) * amplitude + pivot; -} diff --git a/libraries/stdlib/genglsl/mx_noise3d_fa_vector2.glsl b/libraries/stdlib/genglsl/mx_noise3d_fa_vector2.glsl deleted file mode 100644 index 06d91f9135..0000000000 --- a/libraries/stdlib/genglsl/mx_noise3d_fa_vector2.glsl +++ /dev/null @@ -1,7 +0,0 @@ -#include "lib/mx_noise.glsl" - -void mx_noise3d_fa_vector2(float amplitude, float pivot, vec3 position, out vec2 result) -{ - vec3 value = mx_perlin_noise_vec3(position); - result = value.xy * amplitude + pivot; -} diff --git a/libraries/stdlib/genglsl/mx_noise3d_fa_vector3.glsl b/libraries/stdlib/genglsl/mx_noise3d_fa_vector3.glsl deleted file mode 100644 index 168bf572f1..0000000000 --- a/libraries/stdlib/genglsl/mx_noise3d_fa_vector3.glsl +++ /dev/null @@ -1,7 +0,0 @@ -#include "lib/mx_noise.glsl" - -void mx_noise3d_fa_vector3(float amplitude, float pivot, vec3 position, out vec3 result) -{ - vec3 value = mx_perlin_noise_vec3(position); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genglsl/mx_noise3d_fa_vector4.glsl b/libraries/stdlib/genglsl/mx_noise3d_fa_vector4.glsl deleted file mode 100644 index 680410f9d3..0000000000 --- a/libraries/stdlib/genglsl/mx_noise3d_fa_vector4.glsl +++ /dev/null @@ -1,8 +0,0 @@ -#include "lib/mx_noise.glsl" - -void mx_noise3d_fa_vector4(float amplitude, float pivot, vec3 position, out vec4 result) -{ - vec3 xyz = mx_perlin_noise_vec3(position); - float w = mx_perlin_noise_float(position + vec3(19, 73, 29)); - result = vec4(xyz, w) * amplitude + pivot; -} diff --git a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx index dc4f52e3b6..3cd3ae305d 100644 --- a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx +++ b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx @@ -98,42 +98,21 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx index 96fd768e25..5250501320 100644 --- a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx +++ b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx @@ -99,42 +99,21 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx index 1875c2b617..c373a7392b 100644 --- a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx +++ b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx @@ -97,42 +97,21 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/libraries/stdlib/genosl/mx_fractal3d_color3.osl b/libraries/stdlib/genosl/mx_fractal3d_color3.osl deleted file mode 100644 index bf1744890b..0000000000 --- a/libraries/stdlib/genosl/mx_fractal3d_color3.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_fractal3d_color3(vector amplitude, int octaves, float lacunarity, float diminish, vector position, output color result) -{ - color f = mx_fbm(position, octaves, lacunarity, diminish, "snoise"); - result = f * amplitude; -} diff --git a/libraries/stdlib/genosl/mx_fractal3d_color4.osl b/libraries/stdlib/genosl/mx_fractal3d_color4.osl deleted file mode 100644 index 9943a92dfd..0000000000 --- a/libraries/stdlib/genosl/mx_fractal3d_color4.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_fractal3d_color4(vector4 amplitude, int octaves, float lacunarity, float diminish, vector position, output color4 result) -{ - color4 f = mx_fbm(position, octaves, lacunarity, diminish, "snoise"); - result = f * color4(color(amplitude.x, amplitude.y, amplitude.z), amplitude.w); -} diff --git a/libraries/stdlib/genosl/mx_fractal3d_fa_color3.osl b/libraries/stdlib/genosl/mx_fractal3d_fa_color3.osl deleted file mode 100644 index 889848c692..0000000000 --- a/libraries/stdlib/genosl/mx_fractal3d_fa_color3.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_fractal3d_fa_color3(float amplitude, int octaves, float lacunarity, float diminish, vector position, output color result) -{ - color f = mx_fbm(position, octaves, lacunarity, diminish, "snoise"); - result = f * amplitude; -} diff --git a/libraries/stdlib/genosl/mx_fractal3d_fa_color4.osl b/libraries/stdlib/genosl/mx_fractal3d_fa_color4.osl deleted file mode 100644 index d2a8f49291..0000000000 --- a/libraries/stdlib/genosl/mx_fractal3d_fa_color4.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_fractal3d_fa_color4(float amplitude, int octaves, float lacunarity, float diminish, vector position, output color4 result) -{ - color4 f = mx_fbm(position, octaves, lacunarity, diminish, "snoise"); - result = f * amplitude; -} diff --git a/libraries/stdlib/genosl/mx_fractal3d_fa_vector2.osl b/libraries/stdlib/genosl/mx_fractal3d_fa_vector2.osl deleted file mode 100644 index c1266d473c..0000000000 --- a/libraries/stdlib/genosl/mx_fractal3d_fa_vector2.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_fractal3d_fa_vector2(float amplitude, int octaves, float lacunarity, float diminish, vector position, output vector2 result) -{ - vector2 f = mx_fbm(position, octaves, lacunarity, diminish, "snoise"); - result = f * amplitude; -} diff --git a/libraries/stdlib/genosl/mx_fractal3d_fa_vector3.osl b/libraries/stdlib/genosl/mx_fractal3d_fa_vector3.osl deleted file mode 100644 index 34f6515ca8..0000000000 --- a/libraries/stdlib/genosl/mx_fractal3d_fa_vector3.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_fractal3d_fa_vector3(float amplitude, int octaves, float lacunarity, float diminish, vector position, output vector result) -{ - vector f = mx_fbm(position, octaves, lacunarity, diminish, "snoise"); - result = f * amplitude; -} diff --git a/libraries/stdlib/genosl/mx_fractal3d_fa_vector4.osl b/libraries/stdlib/genosl/mx_fractal3d_fa_vector4.osl deleted file mode 100644 index fb5a8c73d6..0000000000 --- a/libraries/stdlib/genosl/mx_fractal3d_fa_vector4.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_fractal3d_fa_vector4(float amplitude, int octaves, float lacunarity, float diminish, vector position, output vector4 result) -{ - vector4 f = mx_fbm(position, octaves, lacunarity, diminish, "snoise"); - result = f * amplitude; -} diff --git a/libraries/stdlib/genosl/mx_noise2d_color3.osl b/libraries/stdlib/genosl/mx_noise2d_color3.osl deleted file mode 100644 index 37421ee810..0000000000 --- a/libraries/stdlib/genosl/mx_noise2d_color3.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise2d_color3(vector amplitude, float pivot, vector2 texcoord, output color result) -{ - color value = noise("snoise", texcoord.x, texcoord.y); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise2d_color4.osl b/libraries/stdlib/genosl/mx_noise2d_color4.osl deleted file mode 100644 index ec8064c577..0000000000 --- a/libraries/stdlib/genosl/mx_noise2d_color4.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise2d_color4(vector4 amplitude, float pivot, vector2 texcoord, output color4 result) -{ - color4 value = mx_noise("snoise", texcoord.x, texcoord.y); - result = value * color4(color(amplitude.x, amplitude.y, amplitude.z), amplitude.w) + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise2d_fa_color3.osl b/libraries/stdlib/genosl/mx_noise2d_fa_color3.osl deleted file mode 100644 index 29c09c1ae2..0000000000 --- a/libraries/stdlib/genosl/mx_noise2d_fa_color3.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise2d_fa_color3(float amplitude, float pivot, vector2 texcoord, output color result) -{ - color value = noise("snoise", texcoord.x, texcoord.y); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise2d_fa_color4.osl b/libraries/stdlib/genosl/mx_noise2d_fa_color4.osl deleted file mode 100644 index 35d3463ff7..0000000000 --- a/libraries/stdlib/genosl/mx_noise2d_fa_color4.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise2d_fa_color4(float amplitude, float pivot, vector2 texcoord, output color4 result) -{ - color4 value = mx_noise("snoise", texcoord.x, texcoord.y); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise2d_fa_vector2.osl b/libraries/stdlib/genosl/mx_noise2d_fa_vector2.osl deleted file mode 100644 index b64dc6de7a..0000000000 --- a/libraries/stdlib/genosl/mx_noise2d_fa_vector2.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise2d_fa_vector2(float amplitude, float pivot, vector2 texcoord, output vector2 result) -{ - vector2 value = mx_noise("snoise", texcoord.x, texcoord.y); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise2d_fa_vector3.osl b/libraries/stdlib/genosl/mx_noise2d_fa_vector3.osl deleted file mode 100644 index c1f060a265..0000000000 --- a/libraries/stdlib/genosl/mx_noise2d_fa_vector3.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise2d_fa_vector3(float amplitude, float pivot, vector2 texcoord, output vector result) -{ - vector value = noise("snoise", texcoord.x, texcoord.y); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise2d_fa_vector4.osl b/libraries/stdlib/genosl/mx_noise2d_fa_vector4.osl deleted file mode 100644 index 9cb9f57c7c..0000000000 --- a/libraries/stdlib/genosl/mx_noise2d_fa_vector4.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise2d_fa_vector4(float amplitude, float pivot, vector2 texcoord, output vector4 result) -{ - vector4 value = mx_noise("snoise", texcoord.x, texcoord.y); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise3d_color3.osl b/libraries/stdlib/genosl/mx_noise3d_color3.osl deleted file mode 100644 index f4649a598a..0000000000 --- a/libraries/stdlib/genosl/mx_noise3d_color3.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise3d_color3(vector amplitude, float pivot, vector position, output color result) -{ - color value = noise("snoise", position); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise3d_color4.osl b/libraries/stdlib/genosl/mx_noise3d_color4.osl deleted file mode 100644 index c522f81493..0000000000 --- a/libraries/stdlib/genosl/mx_noise3d_color4.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise3d_color4(vector4 amplitude, float pivot, vector position, output color4 result) -{ - color4 value = mx_noise("snoise", position); - result = value * color4(color(amplitude.x, amplitude.y, amplitude.z), amplitude.w) + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise3d_fa_color3.osl b/libraries/stdlib/genosl/mx_noise3d_fa_color3.osl deleted file mode 100644 index 83b777b2f2..0000000000 --- a/libraries/stdlib/genosl/mx_noise3d_fa_color3.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise3d_fa_color3(float amplitude, float pivot, vector position, output color result) -{ - color value = noise("snoise", position); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise3d_fa_color4.osl b/libraries/stdlib/genosl/mx_noise3d_fa_color4.osl deleted file mode 100644 index ee1a48ea0c..0000000000 --- a/libraries/stdlib/genosl/mx_noise3d_fa_color4.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise3d_fa_color4(float amplitude, float pivot, vector position, output color4 result) -{ - color4 value = mx_noise("snoise", position); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise3d_fa_vector2.osl b/libraries/stdlib/genosl/mx_noise3d_fa_vector2.osl deleted file mode 100644 index 9317d8933b..0000000000 --- a/libraries/stdlib/genosl/mx_noise3d_fa_vector2.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise3d_fa_vector2(float amplitude, float pivot, vector position, output vector2 result) -{ - vector2 value = mx_noise("snoise", position); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise3d_fa_vector3.osl b/libraries/stdlib/genosl/mx_noise3d_fa_vector3.osl deleted file mode 100644 index 4e235febce..0000000000 --- a/libraries/stdlib/genosl/mx_noise3d_fa_vector3.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise3d_fa_vector3(float amplitude, float pivot, vector position, output vector result) -{ - vector value = noise("snoise", position); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/mx_noise3d_fa_vector4.osl b/libraries/stdlib/genosl/mx_noise3d_fa_vector4.osl deleted file mode 100644 index 177fc3f286..0000000000 --- a/libraries/stdlib/genosl/mx_noise3d_fa_vector4.osl +++ /dev/null @@ -1,5 +0,0 @@ -void mx_noise3d_fa_vector4(float amplitude, float pivot, vector position, output vector4 result) -{ - vector4 value = mx_noise("snoise", position); - result = value * amplitude + pivot; -} diff --git a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx index ae3f6777cf..bc63d946da 100644 --- a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx +++ b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx @@ -99,42 +99,21 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/libraries/stdlib/stdlib_ng.mtlx b/libraries/stdlib/stdlib_ng.mtlx index 4983aaa477..2e900bb334 100644 --- a/libraries/stdlib/stdlib_ng.mtlx +++ b/libraries/stdlib/stdlib_ng.mtlx @@ -1309,6 +1309,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -79,53 +44,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -136,53 +66,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 03752490a388968e539cc840a50d3f9cc89a6b3a Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 17 Jan 2024 10:46:22 -0800 Subject: [PATCH 070/128] Fix shader generation typos This changelist fixes a handful of minor typos in shader generation, introduced in #1355 and #1553. --- libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx | 6 +++--- libraries/stdlib/genosl/mx_creatematrix.osl | 6 +++--- libraries/stdlib/genosl/mx_normalmap.osl | 2 +- libraries/stdlib/genosl/stdlib_genosl_impl.mtlx | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx index c373a7392b..8526330d47 100644 --- a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx +++ b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx @@ -729,9 +729,9 @@ - - - + + + diff --git a/libraries/stdlib/genosl/mx_creatematrix.osl b/libraries/stdlib/genosl/mx_creatematrix.osl index 933dce00ba..3e567d3b5b 100644 --- a/libraries/stdlib/genosl/mx_creatematrix.osl +++ b/libraries/stdlib/genosl/mx_creatematrix.osl @@ -1,4 +1,4 @@ -void mx_creatematrix_vector3_matrix33(vector in1, vector in2, vector in3, out matrix result) +void mx_creatematrix_vector3_matrix33(vector in1, vector in2, vector in3, output matrix result) { result = matrix(in1.x, in1.y, in1.z, 0.0, in2.x, in2.y, in2.z, 0.0, @@ -6,7 +6,7 @@ void mx_creatematrix_vector3_matrix33(vector in1, vector in2, vector in3, out ma 0.0, 0.0, 0.0, 1.0); } -void mx_creatematrix_vector3_matrix44(vector3 in1, vector3 in2, vector3 in3, vector3 in4, out matrix result) +void mx_creatematrix_vector3_matrix44(vector in1, vector in2, vector in3, vector in4, output matrix result) { result = matrix(in1.x, in1.y, in1.z, 0.0, in2.x, in2.y, in2.z, 0.0, @@ -14,7 +14,7 @@ void mx_creatematrix_vector3_matrix44(vector3 in1, vector3 in2, vector3 in3, vec in4.x, in4.y, in4.z, 1.0); } -void mx_creatematrix_vector4_matrix44(vector4 in1, vector4 in2, vector4 in3, vector4 in4, out matrix result) +void mx_creatematrix_vector4_matrix44(vector4 in1, vector4 in2, vector4 in3, vector4 in4, output matrix result) { result = matrix(in1.x, in1.y, in1.z, in1.w, in2.x, in2.y, in2.z, in2.w, diff --git a/libraries/stdlib/genosl/mx_normalmap.osl b/libraries/stdlib/genosl/mx_normalmap.osl index bf75781f51..79b31df69d 100644 --- a/libraries/stdlib/genosl/mx_normalmap.osl +++ b/libraries/stdlib/genosl/mx_normalmap.osl @@ -6,7 +6,7 @@ void mx_normalmap_vector2(vector value, string map_space, vector2 normal_scale, vector v = value * 2.0 - 1.0; vector T = normalize(U - dot(U, N) * N); vector B = normalize(cross(N, T)); - result = normalize(T * v[0] * normal_scale[0] + B * v[1] * normal_scale[1] + N * v[2]); + result = normalize(T * v[0] * normal_scale.x + B * v[1] * normal_scale.y + N * v[2]); } // Object space else diff --git a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx index bc63d946da..7268ee61dd 100644 --- a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx +++ b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx @@ -732,9 +732,9 @@ - - - + + + From c0ccd34cf72dbd26996335e9e7ef4d4092f9771c Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Wed, 17 Jan 2024 17:00:56 -0500 Subject: [PATCH 071/128] Add frame capture to web viewer (#1636) Add frame capture code to trigger on 'f' key. This is the same key as used for the desktop viewer. --- javascript/MaterialXView/source/index.js | 30 ++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/javascript/MaterialXView/source/index.js b/javascript/MaterialXView/source/index.js index d11ba9691e..d46bd2350f 100644 --- a/javascript/MaterialXView/source/index.js +++ b/javascript/MaterialXView/source/index.js @@ -21,6 +21,8 @@ let turntableEnabled = false; let turntableSteps = 360; let turntableStep = 0; +let captureRequested = false; + // Get URL options. Fallback to defaults if not specified. let materialFilename = new URLSearchParams(document.location.search).get("file"); if (!materialFilename) { @@ -31,6 +33,18 @@ let viewer = Viewer.create(); init(); viewer.getEditor().updateProperties(0.9); +// Capture the current frame and save an image file. +function captureFrame() +{ + let canvas = document.getElementById('webglcanvas'); + var url = canvas.toDataURL(); + var link = document.createElement('a'); + link.setAttribute('href', url); + link.setAttribute('target', '_blank'); + link.setAttribute('download', 'screenshot.png'); + link.click(); +} + function init() { let canvas = document.getElementById('webglcanvas'); @@ -82,9 +96,15 @@ function init() orbitControls = new OrbitControls(scene.getCamera(), renderer.domElement); orbitControls.addEventListener('change', () => { viewer.getScene().setUpdateTransforms(); - }) + }) - // Load model and shaders + // Add hotkey 'f' to capture the current frame and save an image file. + // See check inside the render loop when a capture can be performed. + document.addEventListener('keydown', (event) => { + if (event.key === 'f') { + captureRequested = true; + } + }); // Initialize editor viewer.getEditor().initialize(); @@ -160,6 +180,12 @@ function animate() composer.render(); viewer.getScene().updateTransforms(); + + if (captureRequested) + { + captureFrame(); + captureRequested = false; + } } function handleKeyEvents(event) From 931cda2529214e578118ebe726aa4d9011ad5724 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 17 Jan 2024 16:18:53 -0800 Subject: [PATCH 072/128] Document format updates This changelist applies the mxformat.py script to the libraries and resources folders in the repository, updating formatting for a handful of documents. --- libraries/bxdf/gltf_pbr.mtlx | 2 +- libraries/nprlib/genglsl/nprlib_genglsl_impl.mtlx | 2 +- libraries/nprlib/genmdl/nprlib_genmdl_impl.mtlx | 2 +- libraries/nprlib/genmsl/nprlib_genmsl_impl.mtlx | 2 +- libraries/stdlib/stdlib_ng.mtlx | 6 +++--- .../Materials/TestSuite/stdlib/procedural/tiledshape.mtlx | 2 +- .../Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libraries/bxdf/gltf_pbr.mtlx b/libraries/bxdf/gltf_pbr.mtlx index 6654e63454..b42054a185 100644 --- a/libraries/bxdf/gltf_pbr.mtlx +++ b/libraries/bxdf/gltf_pbr.mtlx @@ -359,7 +359,7 @@ - + diff --git a/libraries/nprlib/genglsl/nprlib_genglsl_impl.mtlx b/libraries/nprlib/genglsl/nprlib_genglsl_impl.mtlx index 7ddc4cee83..1a96f315e5 100644 --- a/libraries/nprlib/genglsl/nprlib_genglsl_impl.mtlx +++ b/libraries/nprlib/genglsl/nprlib_genglsl_impl.mtlx @@ -12,6 +12,6 @@ - + diff --git a/libraries/nprlib/genmdl/nprlib_genmdl_impl.mtlx b/libraries/nprlib/genmdl/nprlib_genmdl_impl.mtlx index b6472e0c51..73a9d22945 100644 --- a/libraries/nprlib/genmdl/nprlib_genmdl_impl.mtlx +++ b/libraries/nprlib/genmdl/nprlib_genmdl_impl.mtlx @@ -12,6 +12,6 @@ - + diff --git a/libraries/nprlib/genmsl/nprlib_genmsl_impl.mtlx b/libraries/nprlib/genmsl/nprlib_genmsl_impl.mtlx index b8f9a4e3aa..615e9d8ce0 100644 --- a/libraries/nprlib/genmsl/nprlib_genmsl_impl.mtlx +++ b/libraries/nprlib/genmsl/nprlib_genmsl_impl.mtlx @@ -12,6 +12,6 @@ - + diff --git a/libraries/stdlib/stdlib_ng.mtlx b/libraries/stdlib/stdlib_ng.mtlx index 2e900bb334..b34dc71e5d 100644 --- a/libraries/stdlib/stdlib_ng.mtlx +++ b/libraries/stdlib/stdlib_ng.mtlx @@ -1863,7 +1863,7 @@ - + @@ -2555,7 +2555,7 @@ - + @@ -2673,7 +2673,7 @@ - + - - - - - - - - - - + + + diff --git a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx index 5250501320..80f3aa3509 100644 --- a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx +++ b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx @@ -483,16 +483,9 @@ - - - - - - - diff --git a/libraries/stdlib/genmsl/mx_smoothstep_vec2FA.metal b/libraries/stdlib/genmsl/mx_smoothstep_vec2FA.metal deleted file mode 100644 index a05a10d746..0000000000 --- a/libraries/stdlib/genmsl/mx_smoothstep_vec2FA.metal +++ /dev/null @@ -1,8 +0,0 @@ -#include "mx_smoothstep_float.metal" - -void mx_smoothstep_vec2FA(vec2 val, float low, float high, out vec2 result) -{ - float f; - mx_smoothstep_float(val.x, low, high, f); result.x = f; - mx_smoothstep_float(val.y, low, high, f); result.y = f; -} diff --git a/libraries/stdlib/genmsl/mx_smoothstep_vec3FA.metal b/libraries/stdlib/genmsl/mx_smoothstep_vec3FA.metal deleted file mode 100644 index 4a1922d5af..0000000000 --- a/libraries/stdlib/genmsl/mx_smoothstep_vec3FA.metal +++ /dev/null @@ -1,9 +0,0 @@ -#include "mx_smoothstep_float.metal" - -void mx_smoothstep_vec3FA(vec3 val, float low, float high, out vec3 result) -{ - float f; - mx_smoothstep_float(val.x, low, high, f); result.x = f; - mx_smoothstep_float(val.y, low, high, f); result.y = f; - mx_smoothstep_float(val.z, low, high, f); result.z = f; -} diff --git a/libraries/stdlib/genmsl/mx_smoothstep_vec4FA.metal b/libraries/stdlib/genmsl/mx_smoothstep_vec4FA.metal deleted file mode 100644 index a7c27cb0e6..0000000000 --- a/libraries/stdlib/genmsl/mx_smoothstep_vec4FA.metal +++ /dev/null @@ -1,10 +0,0 @@ -#include "mx_smoothstep_float.metal" - -void mx_smoothstep_vec4FA(vec4 val, float low, float high, out vec4 result) -{ - float f; - mx_smoothstep_float(val.x, low, high, f); result.x = f; - mx_smoothstep_float(val.y, low, high, f); result.y = f; - mx_smoothstep_float(val.z, low, high, f); result.z = f; - mx_smoothstep_float(val.w, low, high, f); result.w = f; -} diff --git a/libraries/stdlib/genmsl/mx_smoothstep_vec2.metal b/libraries/stdlib/genmsl/mx_smoothstep_vector2.metal similarity index 70% rename from libraries/stdlib/genmsl/mx_smoothstep_vec2.metal rename to libraries/stdlib/genmsl/mx_smoothstep_vector2.metal index 0baa763137..34fec594ee 100644 --- a/libraries/stdlib/genmsl/mx_smoothstep_vec2.metal +++ b/libraries/stdlib/genmsl/mx_smoothstep_vector2.metal @@ -1,6 +1,6 @@ #include "mx_smoothstep_float.metal" -void mx_smoothstep_vec2(vec2 val, vec2 low, vec2 high, out vec2 result) +void mx_smoothstep_vector2(vec2 val, vec2 low, vec2 high, out vec2 result) { float f; mx_smoothstep_float(val.x, low.x, high.x, f); result.x = f; diff --git a/libraries/stdlib/genmsl/mx_smoothstep_vec3.metal b/libraries/stdlib/genmsl/mx_smoothstep_vector3.metal similarity index 77% rename from libraries/stdlib/genmsl/mx_smoothstep_vec3.metal rename to libraries/stdlib/genmsl/mx_smoothstep_vector3.metal index b0f969751b..5b0a9b62cf 100644 --- a/libraries/stdlib/genmsl/mx_smoothstep_vec3.metal +++ b/libraries/stdlib/genmsl/mx_smoothstep_vector3.metal @@ -1,6 +1,6 @@ #include "mx_smoothstep_float.metal" -void mx_smoothstep_vec3(vec3 val, vec3 low, vec3 high, thread vec3& result) +void mx_smoothstep_vector3(vec3 val, vec3 low, vec3 high, thread vec3& result) { float f; mx_smoothstep_float(val.x, low.x, high.x, f); result.x = f; diff --git a/libraries/stdlib/genmsl/mx_smoothstep_vec4.metal b/libraries/stdlib/genmsl/mx_smoothstep_vector4.metal similarity index 80% rename from libraries/stdlib/genmsl/mx_smoothstep_vec4.metal rename to libraries/stdlib/genmsl/mx_smoothstep_vector4.metal index 8bf2f3d025..04dc755149 100644 --- a/libraries/stdlib/genmsl/mx_smoothstep_vec4.metal +++ b/libraries/stdlib/genmsl/mx_smoothstep_vector4.metal @@ -1,6 +1,6 @@ #include "mx_smoothstep_float.metal" -void mx_smoothstep_vec4(vec4 val, vec4 low, vec4 high, out vec4 result) +void mx_smoothstep_vector4(vec4 val, vec4 low, vec4 high, out vec4 result) { float f; mx_smoothstep_float(val.x, low.x, high.x, f); result.x = f; diff --git a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx index 8526330d47..2a17cc06fd 100644 --- a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx +++ b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx @@ -478,16 +478,9 @@ - - - - - - - - - - + + + diff --git a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx index 7268ee61dd..177b28cfab 100644 --- a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx +++ b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx @@ -478,16 +478,9 @@ - - - - - - - diff --git a/libraries/stdlib/stdlib_ng.mtlx b/libraries/stdlib/stdlib_ng.mtlx index b34dc71e5d..5dae14c270 100644 --- a/libraries/stdlib/stdlib_ng.mtlx +++ b/libraries/stdlib/stdlib_ng.mtlx @@ -2704,6 +2704,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -20,38 +20,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -60,14 +28,6 @@ - - - - - - - - @@ -76,14 +36,6 @@ - - - - - - - - @@ -92,12 +44,4 @@ - - - - - - - - From ed219dc3f51088f964fa2a34b339d2d83e54e84d Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sun, 21 Jan 2024 16:23:44 -0800 Subject: [PATCH 076/128] Update changelog for recent work --- CHANGELOG.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47b1bfe8b8..ab826e291d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,42 @@ ## [1.38.9] - Development +### Added + +- Added a [non-photorealistic rendering](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1631) data library to MaterialX, initially consisting of a single 'viewdirection' node. +- Added support for the generation of [pre-filtered environment maps](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1420) in MaterialX GLSL and MSL. +- Added support for the [creatematrix node](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1553) in shader generation. +- Added [floating popups](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1565) for hovered pins in the MaterialX Graph Editor. +- Added support for [UI attributes](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1623) and [enumerated values](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1632) in the MaterialX Web Viewer. +- Added [UI ranges](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1646) to the 'useSpecularWorkflow' and 'normal' inputs of the UsdPreviewSurface shading model. +- Added [versioning rules](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1664) for the MaterialX API and data libraries to the developer guide. +- Added initial C++ [fuzz tests](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1605) and [coverage tests](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1548) to GitHub Actions CI. +- Added [GCC 13, Clang 15](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1602), and [Python 3.12](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1588) builds to GitHub Actions CI. + +### Changed + +- Improved the logic for [connecting pins](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1569) in the MaterialX Graph Editor. +- Improved the robustness of [type pointer comparisons](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1665) in shader generation. +- Improved the handling of [filename inputs](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1547) in OSL shader generation. +- Reduced the size of the MaterialX data libraries, improving the use of [graph definitions](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1653) and merging [duplicate implementations](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1642). +- Updated the MaterialX Web Viewer to [three.js r152](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1615). +- Switched to a more efficient representation of [HDR images](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1616) in the MaterialX Web Viewer. +- Raised the minimum CMake version to [CMake 3.16](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1607). +- Updated the C++ unit test library to [Catch 2.13.10](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1566). + +### Fixed + +- Fixed the attenuation of [coated emission](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1534) in the Standard Surface shading model. +- Fixed the implementation of the [overlay node](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1539) in shader generation. +- Fixed an edge case for [transform nodes](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1560) in GLSL and MSL shader generation. +- Fixed the implementation of [mx_hsvtorgb](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1584) in MDL shader generation. +- Fixed [scroll wheel interactions](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1578) across windows of the MaterialX Graph Editor. +- Fixed the generation of unused [imgui.ini files](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1570) in the MaterialX Graph Editor. +- Fixed a dependency on [module import order](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1595) in MaterialX Python. +- Fixed an [off-by-one index check](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1582) in Element::setChildIndex. +- Fixed a [missing null check](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1601) in Graph::propertyEditor. +- Fixed cases where [absolute paths](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1603) were stored in MaterialXConfig.cmake. + ## [1.38.8] - 2023-09-08 ### Added From 1a50d0bb67f7424eb0656ad44e7b166aba1f1268 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Mon, 22 Jan 2024 15:10:57 -0800 Subject: [PATCH 077/128] Update comments in stdlib_ng.mtlx This changelist updates the comments in stdlib_ng, aligning them with the conventions for nodegraph definitions in the data libraries. --- libraries/stdlib/stdlib_ng.mtlx | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/libraries/stdlib/stdlib_ng.mtlx b/libraries/stdlib/stdlib_ng.mtlx index 5dae14c270..61c32c7a00 100644 --- a/libraries/stdlib/stdlib_ng.mtlx +++ b/libraries/stdlib/stdlib_ng.mtlx @@ -4,15 +4,15 @@ Copyright Contributors to the MaterialX Project SPDX-License-Identifier: Apache-2.0 - Nodegraph implementations for Supplemental Nodes included in the MaterialX specification. + Graph definitions of standard nodes included in the MaterialX specification. --> - + @@ -196,7 +196,7 @@ @@ -1310,7 +1310,7 @@ @@ -1370,7 +1370,7 @@ @@ -1430,7 +1430,7 @@ @@ -1574,7 +1574,7 @@ @@ -1770,7 +1770,7 @@ @@ -2560,6 +2560,9 @@ + @@ -3554,7 +3557,7 @@ From 300b308430ba8dbbc1eec8773730b7a7c7553998 Mon Sep 17 00:00:00 2001 From: Leo Belda Date: Tue, 23 Jan 2024 23:46:05 +0100 Subject: [PATCH 078/128] Fix orphaned links when deleting node in graph editor (#1667) This PR introduces fixes related to the removal of orphaned links when deleting a node in the Graph Editor: - remove the attribute `INTERFACE_NAME_ATTRIBUTE` of input pins that were connected to the deleted node (Fixes #1577) - iterate over all of the output pins instead of only handling the first one. (Fixes #1666) --- source/MaterialXGraphEditor/Graph.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 181ea9e591..43a94edefb 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -2854,10 +2854,10 @@ void Graph::deleteNode(UiNodePtr node) } } - if (node->outputPins.size() > 0) + for (UiPinPtr outputPin : node->outputPins) { // Update downNode info - for (UiPinPtr pin : node->outputPins.front()->getConnections()) + for (UiPinPtr pin : outputPin.get()->getConnections()) { mx::ValuePtr val; if (pin->_pinNode->getNode()) @@ -2872,6 +2872,13 @@ void Graph::deleteNode(UiNodePtr node) { pin->_input->setConnectedNode(nullptr); } + if (node->getInput()) + { + // Remove interface value in order to set the default of the input + pin->_input->removeAttribute(mx::ValueElement::INTERFACE_NAME_ATTRIBUTE); + setDefaults(pin->_input); + setDefaults(node->getInput()); + } } else if (pin->_pinNode->getNodeGraph()) { From 5caf170568f7c8990e2805dcd697c4c3652b4a78 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 23 Jan 2024 19:43:38 -0800 Subject: [PATCH 079/128] Add facingratio node to nprlib (#1671) This changelist adds a `facingratio` node to the NPR data library, providing an additional intermediate node for building NPR graphs. --- CHANGELOG.md | 2 +- libraries/nprlib/nprlib_defs.mtlx | 19 ++++++++ libraries/nprlib/nprlib_ng.mtlx | 48 +++++++++++++++++++ .../TestSuite/nprlib/edge_brighten.mtlx | 13 +---- 4 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 libraries/nprlib/nprlib_ng.mtlx diff --git a/CHANGELOG.md b/CHANGELOG.md index ab826e291d..bd414573ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Added -- Added a [non-photorealistic rendering](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1631) data library to MaterialX, initially consisting of a single 'viewdirection' node. +- Added a [non-photorealistic rendering](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1631) data library to MaterialX, initially supporting the 'viewdirection' and 'facingratio' nodes. - Added support for the generation of [pre-filtered environment maps](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1420) in MaterialX GLSL and MSL. - Added support for the [creatematrix node](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1553) in shader generation. - Added [floating popups](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1565) for hovered pins in the MaterialX Graph Editor. diff --git a/libraries/nprlib/nprlib_defs.mtlx b/libraries/nprlib/nprlib_defs.mtlx index e724658ae5..a8d282d0c4 100644 --- a/libraries/nprlib/nprlib_defs.mtlx +++ b/libraries/nprlib/nprlib_defs.mtlx @@ -7,6 +7,12 @@ Declarations of standard data types and nodes included in the MaterialX specification. --> + + + + + + @@ -20,4 +26,17 @@ + + + + + + + + + diff --git a/libraries/nprlib/nprlib_ng.mtlx b/libraries/nprlib/nprlib_ng.mtlx new file mode 100644 index 0000000000..c287c2ef79 --- /dev/null +++ b/libraries/nprlib/nprlib_ng.mtlx @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx b/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx index 7e9aca7f22..dc06b76d98 100644 --- a/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx +++ b/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx @@ -1,18 +1,9 @@ - - - - - - - - - - + - + From 8dbabce8cd0e63380cae6f004316a358dcd026ed Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Tue, 23 Jan 2024 23:15:23 -0500 Subject: [PATCH 080/128] Add geometry drag & drop to web viewer (#1663) - Add support to recognize dropping of individual geometry (glb) files. - Minor cleanup to stop if no MTLX or GLB files loaded. --- .../MaterialXView/source/dropHandling.js | 56 ++++++++++++++++--- javascript/MaterialXView/source/index.js | 10 +++- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/javascript/MaterialXView/source/dropHandling.js b/javascript/MaterialXView/source/dropHandling.js index adcbef2ca1..8e4b674e0e 100644 --- a/javascript/MaterialXView/source/dropHandling.js +++ b/javascript/MaterialXView/source/dropHandling.js @@ -2,12 +2,18 @@ import * as THREE from 'three'; import * as fflate from 'three/examples/jsm/libs/fflate.module.js'; const debugFileHandling = false; -let loadingCallback; +let loadingCallback = null; +let sceneLoadingCallback = null; export function setLoadingCallback(cb) { loadingCallback = cb; } +export function setSceneLoadingCallback(cb) +{ + sceneLoadingCallback = cb; +} + export function dropHandler(ev) { if (debugFileHandling) console.log('File(s) dropped', ev.dataTransfer.items, ev.dataTransfer.files); @@ -130,14 +136,22 @@ async function handleFilesystemEntries(entries) { 'node_modules', ] + let isGLB = false; + let haveMtlx = false; for (let entry of entries) { if (debugFileHandling) console.log("file entry", entry) if (entry.isFile) { - if (debugFileHandling) console.log("single file", entry); + if (debugFileHandling) + console.log("single file", entry); if (fileIgnoreList.includes(entry.name)) { continue; } allFiles.push(entry); + + if (entry.name.endsWith('glb')) { + isGLB = true; + break; + } } else if (entry.isDirectory) { if (dirIgnoreList.includes(entry.name)) { @@ -198,7 +212,28 @@ async function handleFilesystemEntries(entries) { return 0; }); - if (debugFileHandling) console.log("all files", allFiles); + if (isGLB) + { + console.log("Load GLB file", allFiles[0]); + + const rootFile = allFiles[0]; + THREE.Cache.add(rootFile.fullPath, await getBufferFromFile(rootFile)); + + if (debugFileHandling) console.log("CACHE", THREE.Cache.files); + + sceneLoadingCallback(rootFile); + return; + } + + if (!allFiles[0].name.endsWith('mtlx')) + { + console.log("No MaterialX files dropped. Skipping content."); + return; + } + + if (debugFileHandling) { + console.log("- All files", allFiles); + } // put all files in three' Cache for (const fileEntry of allFiles) { @@ -222,12 +257,19 @@ async function handleFilesystemEntries(entries) { // TODO we could also allow dropping of multiple MaterialX files (or folders with them inside) // and seed the dropdown from that. // At that point, actually reading files and textures into memory should be deferred until they are actually used. - const rootFile = allFiles[0]; - THREE.Cache.add(rootFile.fullPath, await getBufferFromFile(rootFile)); + if (allFiles.length > 0) + { + const rootFile = allFiles[0]; + THREE.Cache.add(rootFile.fullPath, await getBufferFromFile(rootFile)); - if (debugFileHandling) console.log("CACHE", THREE.Cache.files); + if (debugFileHandling) console.log("CACHE", THREE.Cache.files); - loadingCallback(rootFile); + loadingCallback(rootFile); + } + else + { + console.log('No files to add cache.') + } } async function readDirectory(directory) { diff --git a/javascript/MaterialXView/source/index.js b/javascript/MaterialXView/source/index.js index d46bd2350f..bffae2db8d 100644 --- a/javascript/MaterialXView/source/index.js +++ b/javascript/MaterialXView/source/index.js @@ -12,7 +12,7 @@ import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader.js'; import { Viewer } from './viewer.js' -import { dropHandler, dragOverHandler, setLoadingCallback } from './dropHandling.js'; +import { dropHandler, dragOverHandler, setLoadingCallback, setSceneLoadingCallback } from './dropHandling.js'; let renderer, composer, orbitControls; @@ -66,6 +66,7 @@ function init() let geometrySelect = document.getElementById('geometry'); geometrySelect.value = scene.getGeometryURL(); geometrySelect.addEventListener('change', (e) => { + console.log('Change geometry to:', e.target.value); scene.setGeometryURL(e.target.value); scene.loadGeometry(viewer, orbitControls); }); @@ -155,6 +156,13 @@ function init() viewer.getScene().setUpdateTransforms(); }); + setSceneLoadingCallback(file => { + let glbFileName = file.fullPath || file.name; + console.log('Drop geometry to:', glbFileName); + scene.setGeometryURL(glbFileName); + scene.loadGeometry(viewer, orbitControls); + }); + // enable three.js Cache so that dropped files can reference each other THREE.Cache.enabled = true; } From 9e92e1eb282a6c21a04feb5d3739c2bfac3a2b6c Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 23 Jan 2024 20:23:57 -0800 Subject: [PATCH 081/128] Apply JavaScript formatting This changelist applies automated formatting to the MaterialX JavaScript codebase, aligning it with the 4-space indentation and Allman braces used in MaterialX C++. --- .../browser/esslShaderGenerator.spec.js | 20 +- .../MaterialXTest/browser/karma.conf.js | 5 +- javascript/MaterialXTest/codeExamples.spec.js | 21 +- .../MaterialXTest/customBindings.spec.js | 41 ++- javascript/MaterialXTest/document.spec.js | 21 +- javascript/MaterialXTest/element.spec.js | 269 +++++++------- javascript/MaterialXTest/environ.spec.js | 9 +- javascript/MaterialXTest/testHelpers.js | 6 +- javascript/MaterialXTest/traversal.spec.js | 98 +++-- javascript/MaterialXTest/types.spec.js | 66 ++-- javascript/MaterialXTest/value.spec.js | 12 +- javascript/MaterialXTest/xmlIo.spec.js | 84 +++-- .../MaterialXView/source/dropHandling.js | 246 ++++++++----- javascript/MaterialXView/source/helper.js | 81 ++--- javascript/MaterialXView/source/index.js | 56 +-- javascript/MaterialXView/source/viewer.js | 339 ++++++++++-------- javascript/MaterialXView/webpack.config.js | 98 ++--- 17 files changed, 858 insertions(+), 614 deletions(-) diff --git a/javascript/MaterialXTest/browser/esslShaderGenerator.spec.js b/javascript/MaterialXTest/browser/esslShaderGenerator.spec.js index 657310aeeb..dceba112e0 100644 --- a/javascript/MaterialXTest/browser/esslShaderGenerator.spec.js +++ b/javascript/MaterialXTest/browser/esslShaderGenerator.spec.js @@ -1,6 +1,6 @@ // MaterialX is served through a script tag in the test setup. -function createStandardSurfaceMaterial(mx) +function createStandardSurfaceMaterial(mx) { const doc = mx.createDocument(); const ssName = 'SR_default'; @@ -15,19 +15,21 @@ function createStandardSurfaceMaterial(mx) return doc; } -describe('Generate ESSL Shaders', function () +describe('Generate ESSL Shaders', function () { let mx; const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl2'); - + this.timeout(60000); - before(async function () { + before(async function () + { mx = await MaterialX(); }); - it('Compile Shaders', () => { + it('Compile Shaders', () => + { const doc = createStandardSurfaceMaterial(mx); const gen = new mx.EsslShaderGenerator(); @@ -37,7 +39,7 @@ describe('Generate ESSL Shaders', function () doc.importLibrary(stdlib); const elem = mx.findRenderableElement(doc); - try + try { const mxShader = gen.generate(elem.getNamePath(), elem, genContext); @@ -47,7 +49,7 @@ describe('Generate ESSL Shaders', function () const glVertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(glVertexShader, vShader); gl.compileShader(glVertexShader); - if (!gl.getShaderParameter(glVertexShader, gl.COMPILE_STATUS)) + if (!gl.getShaderParameter(glVertexShader, gl.COMPILE_STATUS)) { console.error("-------- VERTEX SHADER FAILED TO COMPILE: ----------------"); console.error("--- VERTEX SHADER LOG ---"); @@ -61,7 +63,7 @@ describe('Generate ESSL Shaders', function () const glPixelShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(glPixelShader, fShader); gl.compileShader(glPixelShader); - if (!gl.getShaderParameter(glPixelShader, gl.COMPILE_STATUS)) + if (!gl.getShaderParameter(glPixelShader, gl.COMPILE_STATUS)) { console.error("-------- PIXEL SHADER FAILED TO COMPILE: ----------------"); console.error("--- PIXEL SHADER LOG ---"); @@ -75,7 +77,7 @@ describe('Generate ESSL Shaders', function () catch (errPtr) { console.error("-------- Failed code generation: ----------------"); - console.error(mx.getExceptionMessage(errPtr)); + console.error(mx.getExceptionMessage(errPtr)); } }); }); diff --git a/javascript/MaterialXTest/browser/karma.conf.js b/javascript/MaterialXTest/browser/karma.conf.js index aec860e8b5..6dd8051319 100644 --- a/javascript/MaterialXTest/browser/karma.conf.js +++ b/javascript/MaterialXTest/browser/karma.conf.js @@ -1,10 +1,11 @@ -module.exports = function(config) { +module.exports = function (config) +{ config.set({ basePath: '../', // base is the javascript folder files: [ { pattern: '_build/JsMaterialXGenShader.js', watched: false, included: true, served: true }, { pattern: '_build/JsMaterialXGenShader.wasm', watched: false, included: false, served: true }, - {pattern: '_build/JsMaterialXGenShader.data', watched: false, included: false, served: true, nocache: true }, + { pattern: '_build/JsMaterialXGenShader.data', watched: false, included: false, served: true, nocache: true }, { pattern: 'browser/*.spec.js', watched: true, included: true, served: true }, ], mime: { diff --git a/javascript/MaterialXTest/codeExamples.spec.js b/javascript/MaterialXTest/codeExamples.spec.js index 17f2559b49..8cff44c3fe 100644 --- a/javascript/MaterialXTest/codeExamples.spec.js +++ b/javascript/MaterialXTest/codeExamples.spec.js @@ -2,8 +2,10 @@ import { expect } from 'chai'; import Module from './_build/JsMaterialXCore.js'; import { getMtlxStrings } from './testHelpers'; -describe('Code Examples', () => { - it('Building a MaterialX Document', async () => { +describe('Code Examples', () => +{ + it('Building a MaterialX Document', async () => + { const mx = await Module(); // Create a document. const doc = mx.createDocument(); @@ -76,7 +78,8 @@ describe('Code Examples', () => { // expect(roughness.getBoundValue(material).getValueString()).to.equal('0.5'); }); - it('Traversing a Document Tree', async () => { + it('Traversing a Document Tree', async () => + { const xmlStr = getMtlxStrings( ['standard_surface_greysphere_calibration.mtlx'], '../../resources/Materials/Examples/StandardSurface' @@ -92,13 +95,16 @@ describe('Code Examples', () => { let elementCount = 0; let nodeCount = 0; let fileCount = 0; - for(let elem of elements) { + for (let elem of elements) + { elementCount++; // Display the filename of each image node. - if (elem.isANode('image')) { + if (elem.isANode('image')) + { nodeCount++; const input = elem.getInput('file'); - if (input) { + if (input) + { fileCount++; const filename = input.getValueString(); expect(elem.getName()).to.equal('image1'); @@ -111,7 +117,8 @@ describe('Code Examples', () => { expect(fileCount).to.equal(1); }); - it('Building a MaterialX Document', async () => { + it('Building a MaterialX Document', async () => + { const xmlStr = getMtlxStrings(['standard_surface_marble_solid.mtlx'], '../../resources/Materials/Examples/StandardSurface')[0]; const mx = await Module(); diff --git a/javascript/MaterialXTest/customBindings.spec.js b/javascript/MaterialXTest/customBindings.spec.js index e44cc7e85e..740189f0ef 100644 --- a/javascript/MaterialXTest/customBindings.spec.js +++ b/javascript/MaterialXTest/customBindings.spec.js @@ -2,15 +2,18 @@ import { expect } from 'chai'; import Module from './_build/JsMaterialXCore.js'; import { getMtlxStrings } from './testHelpers'; -describe('Custom Bindings', () => { +describe('Custom Bindings', () => +{ const examplesPath = '../../resources/Materials/Examples/StandardSurface'; - let mx; - before(async () => { + let mx; + before(async () => + { mx = await Module(); }); - it('Optional parameters work as expected', () => { + it('Optional parameters work as expected', () => + { const doc = mx.createDocument(); // Call a method without optional argument const nodeGraph = doc.addNodeGraph(); @@ -29,7 +32,8 @@ describe('Custom Bindings', () => { expect(() => { nodeGraph.addNode(); }).to.throw; }); - it('Vector <-> Array conversion', () => { + it('Vector <-> Array conversion', () => + { // Functions that return vectors in C++ should return an array in JS const doc = mx.createDocument(); const nodeGraph = doc.addNodeGraph(); @@ -66,7 +70,8 @@ describe('Custom Bindings', () => { expect(nodes[2].getName()).to.equal('anotherNode'); // Name set explicitly at creation time }); - it('C++ exception handling', () => { + it('C++ exception handling', () => + { // Exceptions that are thrown and caught in C++ shouldn't bubble up to JS const doc = mx.createDocument(); const nodeGraph1 = doc.addNodeGraph(); @@ -79,15 +84,18 @@ describe('Custom Bindings', () => { // Exceptions that are not caught in C++ should throw with an exception pointer nodeGraph1.addNode('node', 'node1'); expect(() => { nodeGraph1.addNode('node', 'node1'); }).to.throw; - try { + try + { nodeGraph1.addNode('node', 'node1'); - } catch (errPtr) { + } catch (errPtr) + { expect(errPtr).to.be.a('number'); expect(mx.getExceptionMessage(errPtr)).to.be.a('string'); } }); - it('getReferencedSourceUris', async () => { + it('getReferencedSourceUris', async () => + { const doc = mx.createDocument(); const filename = 'standard_surface_look_brass_tiled.mtlx'; await mx.readFromXmlFile(doc, filename, examplesPath); @@ -98,7 +106,8 @@ describe('Custom Bindings', () => { expect(sourceUris.includes('standard_surface_brass_tiled.mtlx')).to.be.true; }); - it('Should invoke correct instance of \'validate\'', () => { + it('Should invoke correct instance of \'validate\'', () => + { // We check whether the correct function is called by provoking an error message that is specific to the // function that we expect to be called. const message = {}; @@ -126,7 +135,8 @@ describe('Custom Bindings', () => { expect(message.message).to.include('Unit type definition does not exist in document') }); - it('StringResolver name substitution getters', () => { + it('StringResolver name substitution getters', () => + { const fnTestData = { fnKey: 'fnValue', fnKey1: 'fnValue1' @@ -156,7 +166,8 @@ describe('Custom Bindings', () => { expect(gnSubs).to.deep.equal(gnTestData); }); - it('getShaderNodes', async () => { + it('getShaderNodes', async () => + { const doc = mx.createDocument(); const fileNames = ['standard_surface_marble_solid.mtlx']; const mtlxStrs = getMtlxStrings(fileNames, examplesPath); @@ -175,14 +186,16 @@ describe('Custom Bindings', () => { expect(shaderNodes.length).to.equal(0); }); - it('createValidName', () => { + it('createValidName', () => + { const testString = '_Note_:Please,turn.this+-into*1#valid\nname for_me'; const replaceRegex = /[^a-zA-Z0-9_:]/g expect(mx.createValidName(testString)).to.equal(testString.replace(replaceRegex, '_')); expect(mx.createValidName(testString, '-')).to.equal(testString.replace(replaceRegex, '-')); }); - it('getVersionIntegers', () => { + it('getVersionIntegers', () => + { const versionStringArr = mx.getVersionString().split('.').map((value) => parseInt(value, 10)); // Global getVersionIntegers diff --git a/javascript/MaterialXTest/document.spec.js b/javascript/MaterialXTest/document.spec.js index 01dc828f3f..ac2adba9ff 100644 --- a/javascript/MaterialXTest/document.spec.js +++ b/javascript/MaterialXTest/document.spec.js @@ -1,30 +1,37 @@ import { expect } from 'chai'; import Module from './_build/JsMaterialXCore.js'; -describe('Document', () => { +describe('Document', () => +{ let mx, doc; - before(async () => { + before(async () => + { mx = await Module(); // Create a document. doc = mx.createDocument(); }); - function expectError(type, cb) { - try { + function expectError(type, cb) + { + try + { cb(); throw new Error('Expected function to throw!'); - } catch (exceptionPtr) { + } catch (exceptionPtr) + { const message = mx.getExceptionMessage(exceptionPtr); expect(message.indexOf(type) !== -1).to.be.true; } } let nodeGraph; - it('Build document', () => { + it('Build document', () => + { // Create a node graph with constant and image sources. nodeGraph = doc.addNodeGraph(); expect(nodeGraph).to.exist; - expectError('Child name is not unique: nodegraph1', () => { + expectError('Child name is not unique: nodegraph1', () => + { doc.addNodeGraph(nodeGraph.getName()); }); const constant = nodeGraph.addNode('constant'); diff --git a/javascript/MaterialXTest/element.spec.js b/javascript/MaterialXTest/element.spec.js index e22c374851..cbb672c5c2 100644 --- a/javascript/MaterialXTest/element.spec.js +++ b/javascript/MaterialXTest/element.spec.js @@ -1,145 +1,166 @@ import { expect } from 'chai'; import Module from './_build/JsMaterialXCore.js'; -describe('Element', () => { - let mx, doc, valueTypes; +describe('Element', () => +{ + let mx, doc, valueTypes; - const primitiveValueTypes = { - Integer: 10, - Boolean: true, - String: 'test', - Float: 15, - IntegerArray: [1,2,3,4,5], - FloatArray: [12, 14], // Not using actual floats to avoid precision problems - StringArray: ['first', 'second'], - BooleanArray:[true, true, false], - } + const primitiveValueTypes = { + Integer: 10, + Boolean: true, + String: 'test', + Float: 15, + IntegerArray: [1, 2, 3, 4, 5], + FloatArray: [12, 14], // Not using actual floats to avoid precision problems + StringArray: ['first', 'second'], + BooleanArray: [true, true, false], + } - before(async () => { - mx = await Module(); - doc = mx.createDocument(); - valueTypes = { - Color3: new mx.Color3(1, 0, 0.5), - Color4: new mx.Color4(0, 1, 0.5, 1), - Vector2: new mx.Vector2(0, 1), - Vector3: new mx.Vector3(0, 1, 2), - Vector4: new mx.Vector4(0, 1, 2, 1), - Matrix33: new mx.Matrix33(0, 1, 2, 3, 4, 5, 6, 7, 8), - Matrix44: new mx.Matrix44(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), - }; - }); + before(async () => + { + mx = await Module(); + doc = mx.createDocument(); + valueTypes = { + Color3: new mx.Color3(1, 0, 0.5), + Color4: new mx.Color4(0, 1, 0.5, 1), + Vector2: new mx.Vector2(0, 1), + Vector3: new mx.Vector3(0, 1, 2), + Vector4: new mx.Vector4(0, 1, 2, 1), + Matrix33: new mx.Matrix33(0, 1, 2, 3, 4, 5, 6, 7, 8), + Matrix44: new mx.Matrix44(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), + }; + }); - describe('value setters', () => { - const checkValue = (types, assertionCallback) => { - const elem = doc.addChildOfCategory('geomprop'); - Object.keys(types).forEach((typeName) => { - const setFn = `setValue${typeName}`; - elem[setFn](types[typeName]); - assertionCallback(elem.getValue().getData(), typeName); - }); - }; + describe('value setters', () => + { + const checkValue = (types, assertionCallback) => + { + const elem = doc.addChildOfCategory('geomprop'); + Object.keys(types).forEach((typeName) => + { + const setFn = `setValue${typeName}`; + elem[setFn](types[typeName]); + assertionCallback(elem.getValue().getData(), typeName); + }); + }; - it('should work with expected type', () => { - checkValue(valueTypes, (returnedValue, typeName) => { - expect(returnedValue).to.be.an.instanceof(mx[`${typeName}`]); - expect(returnedValue.equals(valueTypes[typeName])).to.equal(true); - }); - }); + it('should work with expected type', () => + { + checkValue(valueTypes, (returnedValue, typeName) => + { + expect(returnedValue).to.be.an.instanceof(mx[`${typeName}`]); + expect(returnedValue.equals(valueTypes[typeName])).to.equal(true); + }); + }); - it('should work with expected primitive type', () => { - checkValue(primitiveValueTypes, (returnedValue, typeName) => { - expect(returnedValue).to.eql(primitiveValueTypes[typeName]); - }); - }); + it('should work with expected primitive type', () => + { + checkValue(primitiveValueTypes, (returnedValue, typeName) => + { + expect(returnedValue).to.eql(primitiveValueTypes[typeName]); + }); + }); - it('should fail for incorrect type', () => { - const elem = doc.addChildOfCategory('geomprop'); - expect(()=>elem.Matrix33(true)).to.throw(); + it('should fail for incorrect type', () => + { + const elem = doc.addChildOfCategory('geomprop'); + expect(() => elem.Matrix33(true)).to.throw(); + }); }); - }); - describe('typed value setters', () => { - const checkTypes = (types, assertionCallback) => { - const elem = doc.addChildOfCategory('geomprop'); - Object.keys(types).forEach((typeName) => { - const setFn = `setTypedAttribute${typeName}`; - const getFn = `getTypedAttribute${typeName}`; - elem[setFn](typeName, types[typeName]); - assertionCallback(elem[getFn](typeName), types[typeName]); - }); - }; + describe('typed value setters', () => + { + const checkTypes = (types, assertionCallback) => + { + const elem = doc.addChildOfCategory('geomprop'); + Object.keys(types).forEach((typeName) => + { + const setFn = `setTypedAttribute${typeName}`; + const getFn = `getTypedAttribute${typeName}`; + elem[setFn](typeName, types[typeName]); + assertionCallback(elem[getFn](typeName), types[typeName]); + }); + }; - it('should work with expected custom type', () => { - checkTypes(valueTypes, (returnedValue, originalValue) => { - expect(returnedValue.equals(originalValue)).to.equal(true); - }); - }); + it('should work with expected custom type', () => + { + checkTypes(valueTypes, (returnedValue, originalValue) => + { + expect(returnedValue.equals(originalValue)).to.equal(true); + }); + }); - it('should work with expected primitive type', () => { - checkTypes(primitiveValueTypes, (returnedValue, originalValue) => { - expect(returnedValue).to.eql(originalValue); - }); - }); + it('should work with expected primitive type', () => + { + checkTypes(primitiveValueTypes, (returnedValue, originalValue) => + { + expect(returnedValue).to.eql(originalValue); + }); + }); - it('should fail for incorrect type', () => { - const elem = doc.addChildOfCategory('geomprop'); - expect(()=>elem.setTypedAttributeColor3('wrongType', true)).to.throw(); + it('should fail for incorrect type', () => + { + const elem = doc.addChildOfCategory('geomprop'); + expect(() => elem.setTypedAttributeColor3('wrongType', true)).to.throw(); + }); }); - }); - it('factory invocation should match specialized functions', () => { - // List based in source/MaterialXCore/Element.cpp - const elemtypeArr = [ - 'Backdrop', - 'Collection', - 'GeomInfo', - 'MaterialAssign', - 'PropertySetAssign', - 'Visibility', - 'GeomPropDef', - 'Look', - 'LookGroup', - 'PropertySet', - 'TypeDef', - 'AttributeDef', - 'NodeGraph', - 'Implementation', - 'Node', - 'NodeDef', - 'Variant', - 'Member', - 'TargetDef', - 'GeomProp', - 'Input', - 'Output', - 'Property', - 'PropertyAssign', - 'Unit', - 'UnitDef', - 'UnitTypeDef', - 'VariantAssign', - 'VariantSet', - ]; + it('factory invocation should match specialized functions', () => + { + // List based in source/MaterialXCore/Element.cpp + const elemtypeArr = [ + 'Backdrop', + 'Collection', + 'GeomInfo', + 'MaterialAssign', + 'PropertySetAssign', + 'Visibility', + 'GeomPropDef', + 'Look', + 'LookGroup', + 'PropertySet', + 'TypeDef', + 'AttributeDef', + 'NodeGraph', + 'Implementation', + 'Node', + 'NodeDef', + 'Variant', + 'Member', + 'TargetDef', + 'GeomProp', + 'Input', + 'Output', + 'Property', + 'PropertyAssign', + 'Unit', + 'UnitDef', + 'UnitTypeDef', + 'VariantAssign', + 'VariantSet', + ]; - elemtypeArr.forEach((typeName) => { - const specializedFn = `addChild${typeName}`; - const factoryName = typeName.toLowerCase(); - const type = mx[typeName]; - expect(doc[specializedFn]()).to.be.an.instanceof(type); - expect(doc.addChildOfCategory(factoryName)).to.be.an.instanceof(type); - }); + elemtypeArr.forEach((typeName) => + { + const specializedFn = `addChild${typeName}`; + const factoryName = typeName.toLowerCase(); + const type = mx[typeName]; + expect(doc[specializedFn]()).to.be.an.instanceof(type); + expect(doc.addChildOfCategory(factoryName)).to.be.an.instanceof(type); + }); - const specialElemType = { - 'MaterialX': mx.Document, - 'Comment': mx.CommentElement, - 'Generic': mx.GenericElement, - }; + const specialElemType = { + 'MaterialX': mx.Document, + 'Comment': mx.CommentElement, + 'Generic': mx.GenericElement, + }; - Object.keys(specialElemType).forEach((typeName) => { - const specializedFn = `addChild${typeName}`; - const factoryName = typeName.toLowerCase(); - expect(doc[specializedFn]()).to.be.an.instanceof(specialElemType[typeName]); - expect(doc.addChildOfCategory(factoryName)).to.be.an.instanceof(specialElemType[typeName]); + Object.keys(specialElemType).forEach((typeName) => + { + const specializedFn = `addChild${typeName}`; + const factoryName = typeName.toLowerCase(); + expect(doc[specializedFn]()).to.be.an.instanceof(specialElemType[typeName]); + expect(doc.addChildOfCategory(factoryName)).to.be.an.instanceof(specialElemType[typeName]); + }); }); - }); }); diff --git a/javascript/MaterialXTest/environ.spec.js b/javascript/MaterialXTest/environ.spec.js index 2ac71dc044..2277e0b259 100644 --- a/javascript/MaterialXTest/environ.spec.js +++ b/javascript/MaterialXTest/environ.spec.js @@ -1,13 +1,16 @@ import { expect } from 'chai';; import Module from './_build/JsMaterialXCore.js'; -describe('Environ', () => { +describe('Environ', () => +{ let mx; - before(async () => { + before(async () => + { mx = await Module(); }); - it('Environment variables', () => { + it('Environment variables', () => + { expect(mx.getEnviron(mx.MATERIALX_SEARCH_PATH_ENV_VAR)).to.equal(''); mx.setEnviron(mx.MATERIALX_SEARCH_PATH_ENV_VAR, 'test'); expect(mx.getEnviron(mx.MATERIALX_SEARCH_PATH_ENV_VAR)).to.equal('test'); diff --git a/javascript/MaterialXTest/testHelpers.js b/javascript/MaterialXTest/testHelpers.js index c434400c6a..a75c2e6144 100644 --- a/javascript/MaterialXTest/testHelpers.js +++ b/javascript/MaterialXTest/testHelpers.js @@ -1,9 +1,11 @@ var fs = require('fs'); var path = require('path'); -export function getMtlxStrings(fileNames, subPath) { +export function getMtlxStrings(fileNames, subPath) +{ const mtlxStrs = []; - for (let i = 0; i < fileNames.length; i++) { + for (let i = 0; i < fileNames.length; i++) + { const p = path.resolve(subPath, fileNames[parseInt(i, 10)]); const t = fs.readFileSync(p, 'utf8'); mtlxStrs.push(t); diff --git a/javascript/MaterialXTest/traversal.spec.js b/javascript/MaterialXTest/traversal.spec.js index 4f422bb5cc..62a895f852 100644 --- a/javascript/MaterialXTest/traversal.spec.js +++ b/javascript/MaterialXTest/traversal.spec.js @@ -1,13 +1,16 @@ import { expect } from 'chai'; import Module from './_build/JsMaterialXCore.js'; -describe('Traversal', () => { +describe('Traversal', () => +{ let mx; - before(async () => { + before(async () => + { mx = await Module(); }); - it('Traverse Graph', () => { + it('Traverse Graph', () => + { // Create a document. const doc = mx.createDocument(); // Create a node graph with the following structure: @@ -36,67 +39,79 @@ describe('Traversal', () => { mix.setConnectedNode('bg', contrast); mix.setConnectedNode('mask', noise3d); output.setConnectedNode(mix); - + expect(doc.validate()).to.be.true; - + // Traverse the document tree (implicit iterator). let nodeCount = 0; - for (let elem of doc.traverseTree()) { - if (elem instanceof mx.Node) { + for (let elem of doc.traverseTree()) + { + if (elem instanceof mx.Node) + { nodeCount++; } } expect(nodeCount).to.equal(7); - + // Traverse the document tree (explicit iterator) let treeIter = doc.traverseTree(); nodeCount = 0; let maxElementDepth = 0; - for (let elem of treeIter) { - if (elem instanceof mx.Node) { + for (let elem of treeIter) + { + if (elem instanceof mx.Node) + { nodeCount++; } maxElementDepth = Math.max(maxElementDepth, treeIter.getElementDepth()); } expect(nodeCount).to.equal(7); expect(maxElementDepth).to.equal(3); - + // Traverse the document tree (prune subtree). nodeCount = 0; treeIter = doc.traverseTree(); - for (let elem of treeIter) { - if (elem instanceof mx.Node) { + for (let elem of treeIter) + { + if (elem instanceof mx.Node) + { nodeCount++; } - if (elem instanceof mx.NodeGraph) { + if (elem instanceof mx.NodeGraph) + { treeIter.setPruneSubtree(true); } } expect(nodeCount).to.equal(0); - + // Traverse upstream from the graph output (implicit iterator) nodeCount = 0; - for (let edge of output.traverseGraph()) { + for (let edge of output.traverseGraph()) + { const upstreamElem = edge.getUpstreamElement(); const connectingElem = edge.getConnectingElement(); const downstreamElem = edge.getDownstreamElement(); - if (upstreamElem instanceof mx.Node) { + if (upstreamElem instanceof mx.Node) + { nodeCount++; - if (downstreamElem instanceof mx.Node) { + if (downstreamElem instanceof mx.Node) + { expect(connectingElem instanceof mx.Input).to.be.true; } } } expect(nodeCount).to.equal(7); - + // Traverse upstream from the graph output (explicit iterator) nodeCount = 0; maxElementDepth = 0; let maxNodeDepth = 0; let graphIter = output.traverseGraph(); - for (let edge of graphIter) { + for (let edge of graphIter) + { const upstreamElem = edge.getUpstreamElement(); - if (upstreamElem instanceof mx.Node) { + if (upstreamElem instanceof mx.Node) + { nodeCount++; } maxElementDepth = Math.max(maxElementDepth, graphIter.getElementDepth()); @@ -105,22 +120,25 @@ describe('Traversal', () => { expect(nodeCount).to.equal(7); expect(maxElementDepth).to.equal(3); expect(maxNodeDepth).to.equal(3); - + // Traverse upstream from the graph output (prune subgraph) nodeCount = 0; graphIter = output.traverseGraph(); - for (let edge of graphIter) { + for (let edge of graphIter) + { const upstreamElem = edge.getUpstreamElement(); expect(upstreamElem.getSelf()).to.be.an.instanceof(mx.Element); - if (upstreamElem instanceof mx.Node) { + if (upstreamElem instanceof mx.Node) + { nodeCount++; } - if (upstreamElem.getCategory() === 'multiply') { + if (upstreamElem.getCategory() === 'multiply') + { graphIter.setPruneSubgraph(true); } } expect(nodeCount).to.equal(5); - + // Create and detect a cycle multiply.setConnectedNode('in2', mix); expect(output.hasUpstreamCycle()).to.be.true; @@ -128,7 +146,7 @@ describe('Traversal', () => { multiply.setConnectedNode('in2', constant); expect(output.hasUpstreamCycle()).to.be.false; expect(doc.validate()).to.be.true; - + // Create and detect a loop contrast.setConnectedNode('in', contrast); expect(output.hasUpstreamCycle()).to.be.true; @@ -137,10 +155,12 @@ describe('Traversal', () => { expect(output.hasUpstreamCycle()).to.be.false; expect(doc.validate()).to.be.true; }); - - describe("Traverse inheritance", () => { + + describe("Traverse inheritance", () => + { let nodeDefInheritanceLevel2, nodeDefInheritanceLevel1, nodeDefParent; - beforeEach(() => { + beforeEach(() => + { const doc = mx.createDocument(); nodeDefParent = doc.addNodeDef(); nodeDefParent.setName('BaseClass'); @@ -152,23 +172,29 @@ describe('Traversal', () => { nodeDefInheritanceLevel1.setInheritsFrom(nodeDefParent); }); - it('for of loop', () => { + it('for of loop', () => + { const inheritanceIterator = nodeDefInheritanceLevel2.traverseInheritance(); let inheritanceChainLength = 0; - for(const elem of inheritanceIterator) { - if (elem instanceof mx.NodeDef) { + for (const elem of inheritanceIterator) + { + if (elem instanceof mx.NodeDef) + { inheritanceChainLength++; } } expect(inheritanceChainLength).to.equal(2);; }); - it('while loop', () => { + it('while loop', () => + { const inheritanceIterator = nodeDefInheritanceLevel2.traverseInheritance(); let inheritanceChainLength = 0; let elem = inheritanceIterator.next(); - while (!elem.done) { - if (elem.value instanceof mx.NodeDef) { + while (!elem.done) + { + if (elem.value instanceof mx.NodeDef) + { inheritanceChainLength++; } elem = inheritanceIterator.next(); diff --git a/javascript/MaterialXTest/types.spec.js b/javascript/MaterialXTest/types.spec.js index 7fae8b30c7..fc909c8c94 100644 --- a/javascript/MaterialXTest/types.spec.js +++ b/javascript/MaterialXTest/types.spec.js @@ -1,13 +1,16 @@ import { expect } from 'chai';; import Module from './_build/JsMaterialXCore.js'; -describe('Types', () => { +describe('Types', () => +{ let mx; - before(async () => { + before(async () => + { mx = await Module(); }); - it('Vectors', () => { + it('Vectors', () => + { const v1 = new mx.Vector3(1, 2, 3); let v2 = new mx.Vector3(2, 4, 6); @@ -59,10 +62,13 @@ describe('Types', () => { expect(v4.notEquals(v2)).to.be.true; }); - function multiplyMatrix(matrix, val) { + function multiplyMatrix(matrix, val) + { const clonedMatrix = matrix.copy(); - for (let i = 0; i < clonedMatrix.numRows(); ++i) { - for (let k = 0; k < clonedMatrix.numColumns(); ++k) { + for (let i = 0; i < clonedMatrix.numRows(); ++i) + { + for (let k = 0; k < clonedMatrix.numColumns(); ++k) + { const v = clonedMatrix.getItem(i, k); clonedMatrix.setItem(i, k, v * val); } @@ -70,10 +76,13 @@ describe('Types', () => { return clonedMatrix; } - function divideMatrix(matrix, val) { + function divideMatrix(matrix, val) + { const clonedMatrix = matrix.copy(); - for (let i = 0; i < clonedMatrix.numRows(); ++i) { - for (let k = 0; k < clonedMatrix.numColumns(); ++k) { + for (let i = 0; i < clonedMatrix.numRows(); ++i) + { + for (let k = 0; k < clonedMatrix.numColumns(); ++k) + { const v = clonedMatrix.getItem(i, k); clonedMatrix.setItem(i, k, v / val); } @@ -81,18 +90,19 @@ describe('Types', () => { return clonedMatrix; } - it('Matrices', () => { + it('Matrices', () => + { // Translation and scale const trans = mx.Matrix44.createTranslation(new mx.Vector3(1, 2, 3)); const scale = mx.Matrix44.createScale(new mx.Vector3(2, 2, 2)); expect(trans.equals(new mx.Matrix44(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 1, 2, 3, 1))); + 0, 1, 0, 0, + 0, 0, 1, 0, + 1, 2, 3, 1))); expect(scale.equals(new mx.Matrix44(2, 0, 0, 0, - 0, 2, 0, 0, - 0, 0, 2, 0, - 0, 0, 0, 1))); + 0, 2, 0, 0, + 0, 0, 2, 0, + 0, 0, 0, 1))); // Indexing operators expect(trans.getItem(3, 2)).to.equal(3); @@ -103,9 +113,9 @@ describe('Types', () => { // Matrix methods expect(trans.getTranspose().equals( new mx.Matrix44(1, 0, 0, 1, - 0, 1, 0, 2, - 0, 0, 1, 3, - 0, 0, 0, 1) + 0, 1, 0, 2, + 0, 0, 1, 3, + 0, 0, 0, 1) )).to.be.true; expect(scale.getTranspose().equals(scale)).to.be.true; expect(trans.getDeterminant()).to.equal(1); @@ -120,17 +130,17 @@ describe('Types', () => { let prod4 = trans; prod4 = prod4.multiply(scale); expect(prod1.equals(new mx.Matrix44(2, 0, 0, 0, - 0, 2, 0, 0, - 0, 0, 2, 0, - 2, 4, 6, 1))); + 0, 2, 0, 0, + 0, 0, 2, 0, + 2, 4, 6, 1))); expect(prod2.equals(new mx.Matrix44(2, 0, 0, 0, - 0, 2, 0, 0, - 0, 0, 2, 0, - 1, 2, 3, 1))); + 0, 2, 0, 0, + 0, 0, 2, 0, + 1, 2, 3, 1))); expect(prod3.equals(new mx.Matrix44(2, 0, 0, 0, - 0, 2, 0, 0, - 0, 0, 2, 0, - 2, 4, 6, 2))); + 0, 2, 0, 0, + 0, 0, 2, 0, + 2, 4, 6, 2))); expect(prod4.equals(prod1)); // Matrix division diff --git a/javascript/MaterialXTest/value.spec.js b/javascript/MaterialXTest/value.spec.js index 1b06d3f59b..6a9091ce47 100644 --- a/javascript/MaterialXTest/value.spec.js +++ b/javascript/MaterialXTest/value.spec.js @@ -1,13 +1,16 @@ import { expect } from 'chai';; import Module from './_build/JsMaterialXCore.js'; -describe('Value', () => { +describe('Value', () => +{ let mx; - before(async () => { + before(async () => + { mx = await Module(); }); - it('Create values of different types', () => { + it('Create values of different types', () => + { const testValues = { integer: '1', boolean: 'true', @@ -26,7 +29,8 @@ describe('Value', () => { stringarray: "'one', 'two', 'three'", }; - for (let type in testValues) { + for (let type in testValues) + { const value = testValues[String(type)]; const newValue = mx.Value.createValueFromStrings(value, type); const typeString = newValue.getTypeString(); diff --git a/javascript/MaterialXTest/xmlIo.spec.js b/javascript/MaterialXTest/xmlIo.spec.js index e569b9be76..670b0df43d 100644 --- a/javascript/MaterialXTest/xmlIo.spec.js +++ b/javascript/MaterialXTest/xmlIo.spec.js @@ -4,7 +4,8 @@ import { getMtlxStrings } from './testHelpers'; const TIMEOUT = 60000; -describe('XmlIo', () => { +describe('XmlIo', () => +{ let mx; // These should be relative to cwd @@ -24,18 +25,23 @@ describe('XmlIo', () => { 'UsdPreviewSurface/usd_preview_surface_plastic.mtlx', ]; - async function readStdLibrary(asString = false) { + async function readStdLibrary(asString = false) + { const libs = []; let iterable = libraryFilenames; - if (asString) { + if (asString) + { const libraryMtlxStrings = getMtlxStrings(libraryFilenames, libraryPath); iterable = libraryMtlxStrings; } - for (let file of iterable) { + for (let file of iterable) + { const lib = mx.createDocument(); - if (asString) { + if (asString) + { await mx.readFromXmlString(lib, file, libraryPath); - } else { + } else + { await mx.readFromXmlFile(lib, file, libraryPath); } libs.push(lib); @@ -43,12 +49,15 @@ describe('XmlIo', () => { return libs; } - async function readAndValidateExamples(examples, libraries, readFunc, searchPath = undefined) { - for (let file of examples) { + async function readAndValidateExamples(examples, libraries, readFunc, searchPath = undefined) + { + for (let file of examples) + { const doc = mx.createDocument(); await readFunc(doc, file, searchPath); // Import stdlib into the current document and validate it. - for (let lib of libraries) { + for (let lib of libraries) + { doc.importLibrary(lib); } expect(doc.validate()).to.be.true; @@ -56,8 +65,10 @@ describe('XmlIo', () => { // Make sure the document does actually contain something. let valueElementCount = 0; const treeIter = doc.traverseTree(); - for(const elem of treeIter) { - if (elem instanceof mx.ValueElement) { + for (const elem of treeIter) + { + if (elem instanceof mx.ValueElement) + { valueElementCount++; } } @@ -65,17 +76,20 @@ describe('XmlIo', () => { }; } - before(async () => { + before(async () => + { mx = await Module(); }); - it('Read XML from file', async () => { + it('Read XML from file', async () => + { // Read the standard library const libs = await readStdLibrary(false); // Read and validate the example documents. await readAndValidateExamples(exampleFilenames, libs, - async (document, file, sp) => { + async (document, file, sp) => + { await mx.readFromXmlFile(document, file, sp); }, examplesPath); @@ -90,14 +104,16 @@ describe('XmlIo', () => { expect(copy.equals(doc)).to.be.true; }).timeout(TIMEOUT); - it('Read XML from string', async () => { + it('Read XML from string', async () => + { // Read the standard library const libs = await readStdLibrary(true); // Read and validate each example document. const examplesStrings = getMtlxStrings(exampleFilenames, examplesPath); await readAndValidateExamples(examplesStrings, libs, - async (document, file) => { + async (document, file) => + { await mx.readFromXmlString(document, file); }); @@ -112,14 +128,16 @@ describe('XmlIo', () => { expect(copy.equals(doc)).to.be.true; }).timeout(TIMEOUT); - it('Read XML with recursive includes', async () => { + it('Read XML with recursive includes', async () => + { const doc = mx.createDocument(); await mx.readFromXmlFile(doc, includeTestPath + '/root.mtlx'); expect(doc.getChild('paint_semigloss')).to.exist; expect(doc.validate()).to.be.true; }); - it('Locate XML includes via search path', async () => { + it('Locate XML includes via search path', async () => + { const searchPath = includeTestPath + ';' + includeTestPath + '/folder'; const filename = 'non_relative_includes.mtlx'; const doc = mx.createDocument(); @@ -137,7 +155,8 @@ describe('XmlIo', () => { expect(doc2.equals(doc)).to.be.true; }); - it('Locate XML includes via environment variable', async () => { + it('Locate XML includes via environment variable', async () => + { const searchPath = includeTestPath + ';' + includeTestPath + '/folder'; const filename = 'non_relative_includes.mtlx'; @@ -160,13 +179,16 @@ describe('XmlIo', () => { expect(doc2.equals(doc)).to.be.true; }); - it('Locate XML includes via absolute search paths', async () => { + it('Locate XML includes via absolute search paths', async () => + { let absolutePath; - if (typeof window === 'object') { + if (typeof window === 'object') + { // We're in the browser const cwd = window.location.origin + window.location.pathname; absolutePath = cwd + '/' + includeTestPath; - } else if (typeof process === 'object') { + } else if (typeof process === 'object') + { // We're in Node const nodePath = require('path'); absolutePath = nodePath.resolve(includeTestPath); @@ -175,22 +197,26 @@ describe('XmlIo', () => { await mx.readFromXmlFile(doc, 'root.mtlx', absolutePath); }); - it('Detect XML include cycles', async () => { + it('Detect XML include cycles', async () => + { const doc = mx.createDocument(); expect(async () => await mx.readFromXmlFile(doc, includeTestPath + '/cycle.mtlx')).to.throw; }); - it('Disabling XML includes', async () => { + it('Disabling XML includes', async () => + { const doc = mx.createDocument(); const readOptions = new mx.XmlReadOptions(); readOptions.readXIncludes = false; expect(async () => await mx.readFromXmlFile(doc, includeTestPath + '/cycle.mtlx', readOptions)).to.not.throw; }); - it('Write to XML string', async () => { + it('Write to XML string', async () => + { // Read all example documents and write them to an XML string const searchPath = libraryPath + ';' + examplesPath; - for (let filename of exampleFilenames) { + for (let filename of exampleFilenames) + { const doc = mx.createDocument(); await mx.readFromXmlFile(doc, filename, searchPath); @@ -206,7 +232,8 @@ describe('XmlIo', () => { }; }); - it('Prepend include tag', () => { + it('Prepend include tag', () => + { const doc = mx.createDocument(); const includePath = "SomePath"; const writeOptions = new mx.XmlWriteOptions(); @@ -216,7 +243,8 @@ describe('XmlIo', () => { }); // Node only, because we cannot read from a downloaded file in the browser - it('Write XML to file', async () => { + it('Write XML to file', async () => + { const filename = '_build/testFile.mtlx'; const includeRegex = //g; const doc = mx.createDocument(); diff --git a/javascript/MaterialXView/source/dropHandling.js b/javascript/MaterialXView/source/dropHandling.js index 8e4b674e0e..f54b77115c 100644 --- a/javascript/MaterialXView/source/dropHandling.js +++ b/javascript/MaterialXView/source/dropHandling.js @@ -5,7 +5,8 @@ const debugFileHandling = false; let loadingCallback = null; let sceneLoadingCallback = null; -export function setLoadingCallback(cb) { +export function setLoadingCallback(cb) +{ loadingCallback = cb; } @@ -14,7 +15,8 @@ export function setSceneLoadingCallback(cb) sceneLoadingCallback = cb; } -export function dropHandler(ev) { +export function dropHandler(ev) +{ if (debugFileHandling) console.log('File(s) dropped', ev.dataTransfer.items, ev.dataTransfer.files); // Prevent default behavior (Prevent file from being opened) @@ -26,14 +28,15 @@ export function dropHandler(ev) { let haveGetAsEntry = false; if (ev.dataTransfer.items.length > 0) - haveGetAsEntry = - ("getAsEntry" in ev.dataTransfer.items[0]) || - ("webkitGetAsEntry" in ev.dataTransfer.items[0]); + haveGetAsEntry = + ("getAsEntry" in ev.dataTransfer.items[0]) || + ("webkitGetAsEntry" in ev.dataTransfer.items[0]); // Useful for debugging file handling on platforms that don't support newer file system APIs // haveGetAsEntry = false; - if (haveGetAsEntry) { + if (haveGetAsEntry) + { for (var i = 0; i < ev.dataTransfer.items.length; i++) { let item = ev.dataTransfer.items[i]; @@ -47,7 +50,7 @@ export function dropHandler(ev) { for (var i = 0; i < ev.dataTransfer.items.length; i++) { let item = ev.dataTransfer.items[i]; - + // API when there's no "getAsEntry" support console.log(item.kind, item); if (item.kind === 'file') @@ -59,32 +62,40 @@ export function dropHandler(ev) { else if (item.kind === 'directory') { var dirReader = item.createReader(); - dirReader.readEntries(function(entries) { - for (var i = 0; i < entries.length; i++) { - console.log(entries[i].name); - var entry = entries[i]; - if (entry.isFile) { - entry.file(function(file) { - testAndLoadFile(file); - }); + dirReader.readEntries(function (entries) + { + for (var i = 0; i < entries.length; i++) + { + console.log(entries[i].name); + var entry = entries[i]; + if (entry.isFile) + { + entry.file(function (file) + { + testAndLoadFile(file); + }); + } } - } }); } } - } else { - for (var i = 0; i < ev.dataTransfer.files.length; i++) { + } else + { + for (var i = 0; i < ev.dataTransfer.files.length; i++) + { let file = ev.dataTransfer.files[i]; testAndLoadFile(file); } } } -export function dragOverHandler(ev) { +export function dragOverHandler(ev) +{ ev.preventDefault(); } -async function getBufferFromFile(fileEntry) { +async function getBufferFromFile(fileEntry) +{ if (fileEntry instanceof ArrayBuffer) return fileEntry; if (fileEntry instanceof String) return fileEntry; @@ -96,98 +107,120 @@ async function getBufferFromFile(fileEntry) { if (debugFileHandling) console.log("reading ", fileEntry, "as text?", readAsText); if (debugFileHandling) console.log("getBufferFromFile", fileEntry); - const buffer = await new Promise((resolve, reject) => { - function readFile(file) { + const buffer = await new Promise((resolve, reject) => + { + function readFile(file) + { var reader = new FileReader(); - reader.onloadend = function(e) { + reader.onloadend = function (e) + { if (debugFileHandling) console.log("loaded", "should be text?", readAsText, this.result); resolve(this.result); }; - + if (readAsText) reader.readAsText(file); else reader.readAsArrayBuffer(file); } - if ("file" in fileEntry) { - fileEntry.file(function(file) { + if ("file" in fileEntry) + { + fileEntry.file(function (file) + { readFile(file); - }, (e) => { + }, (e) => + { console.error("Error reading file ", e); }); } - else { + else + { readFile(fileEntry); } }); return buffer; } -async function handleFilesystemEntries(entries) { +async function handleFilesystemEntries(entries) +{ const allFiles = []; const fileIgnoreList = [ - '.gitignore', - 'README.md', - '.DS_Store', + '.gitignore', + 'README.md', + '.DS_Store', ] const dirIgnoreList = [ - '.git', - 'node_modules', + '.git', + 'node_modules', ] let isGLB = false; let haveMtlx = false; - for (let entry of entries) { - if (debugFileHandling) console.log("file entry", entry) - if (entry.isFile) { - if (debugFileHandling) - console.log("single file", entry); - if (fileIgnoreList.includes(entry.name)) { - continue; - } - allFiles.push(entry); - - if (entry.name.endsWith('glb')) { - isGLB = true; - break; - } - } - else if (entry.isDirectory) { - if (dirIgnoreList.includes(entry.name)) { - continue; + for (let entry of entries) + { + if (debugFileHandling) console.log("file entry", entry) + if (entry.isFile) + { + if (debugFileHandling) + console.log("single file", entry); + if (fileIgnoreList.includes(entry.name)) + { + continue; + } + allFiles.push(entry); + + if (entry.name.endsWith('glb')) + { + isGLB = true; + break; + } } - const files = await readDirectory(entry); - if (debugFileHandling) console.log("all files", files); - for (const file of files) { - if (fileIgnoreList.includes(file.name)) { - continue; - } - allFiles.push(file); + else if (entry.isDirectory) + { + if (dirIgnoreList.includes(entry.name)) + { + continue; + } + const files = await readDirectory(entry); + if (debugFileHandling) console.log("all files", files); + for (const file of files) + { + if (fileIgnoreList.includes(file.name)) + { + continue; + } + allFiles.push(file); + } } - } } const imageLoader = new THREE.ImageLoader(); // unpack zip files first - for (const fileEntry of allFiles) { + for (const fileEntry of allFiles) + { // special case: zip archives - if (fileEntry.fullPath.toLowerCase().endsWith('.zip')) { - await new Promise(async (resolve, reject) => { + if (fileEntry.fullPath.toLowerCase().endsWith('.zip')) + { + await new Promise(async (resolve, reject) => + { const arrayBuffer = await getBufferFromFile(fileEntry); // use fflate to unpack them and add the files to the cache - fflate.unzip(new Uint8Array(arrayBuffer), (error, unzipped) => { + fflate.unzip(new Uint8Array(arrayBuffer), (error, unzipped) => + { // push these files into allFiles - for (const [filePath, buffer] of Object.entries(unzipped)) { + for (const [filePath, buffer] of Object.entries(unzipped)) + { // mock FileEntry for easier usage downstream const blob = new Blob([buffer]); const newFileEntry = { fullPath: "/" + filePath, name: filePath.split('/').pop(), - file: (callback) => { + file: (callback) => + { callback(blob); }, isFile: true, @@ -202,11 +235,14 @@ async function handleFilesystemEntries(entries) { } // sort so mtlx files come first - allFiles.sort((a, b) => { - if (a.name.endsWith('.mtlx') && !b.name.endsWith('.mtlx')) { + allFiles.sort((a, b) => + { + if (a.name.endsWith('.mtlx') && !b.name.endsWith('.mtlx')) + { return -1; } - if (!a.name.endsWith('.mtlx') && b.name.endsWith('.mtlx')) { + if (!a.name.endsWith('.mtlx') && b.name.endsWith('.mtlx')) + { return 1; } return 0; @@ -231,19 +267,22 @@ async function handleFilesystemEntries(entries) { return; } - if (debugFileHandling) { + if (debugFileHandling) + { console.log("- All files", allFiles); } // put all files in three' Cache - for (const fileEntry of allFiles) { + for (const fileEntry of allFiles) + { const allowedFileTypes = [ 'png', 'jpg', 'jpeg' ]; const ext = fileEntry.fullPath.split('.').pop(); - if (!allowedFileTypes.includes(ext)) { + if (!allowedFileTypes.includes(ext)) + { // console.log("skipping file", fileEntry.fullPath); continue; } @@ -272,37 +311,49 @@ async function handleFilesystemEntries(entries) { } } -async function readDirectory(directory) { +async function readDirectory(directory) +{ let entries = []; - let getEntries = async (directory) => { + let getEntries = async (directory) => + { let dirReader = directory.createReader(); - await new Promise((resolve, reject) => { - dirReader.readEntries( - async (results) => { - if (results.length) { - // entries = entries.concat(results); - for (let entry of results) { - if (entry.isDirectory) { - await getEntries(entry); - } - else { - entries.push(entry); - } - } - } - resolve(); - }, - (error) => { - /* handle error — error is a FileError object */ - }, - )} - )}; + await new Promise((resolve, reject) => + { + dirReader.readEntries( + async (results) => + { + if (results.length) + { + // entries = entries.concat(results); + for (let entry of results) + { + if (entry.isDirectory) + { + await getEntries(entry); + } + else + { + entries.push(entry); + } + } + } + resolve(); + }, + (error) => + { + /* handle error — error is a FileError object */ + }, + ) + } + ) + }; await getEntries(directory); return entries; } -async function testAndLoadFile(file) { +async function testAndLoadFile(file) +{ let ext = file.name.split('.').pop(); if (debugFileHandling) console.log(file.name + ", " + file.size + ", " + ext); @@ -314,7 +365,8 @@ async function testAndLoadFile(file) { fullPath: "/" + file.name, name: file.name.split('/').pop(), isFile: true, - file: (callback) => { + file: (callback) => + { callback(file); } }; diff --git a/javascript/MaterialXView/source/helper.js b/javascript/MaterialXView/source/helper.js index 98441a605f..2b7f0f7d5b 100644 --- a/javascript/MaterialXView/source/helper.js +++ b/javascript/MaterialXView/source/helper.js @@ -45,8 +45,8 @@ function fromVector(value, dimension) } else { - outValue = []; - for(let i = 0; i < dimension; ++i) + outValue = []; + for (let i = 0; i < dimension; ++i) outValue.push(0.0); } @@ -69,13 +69,13 @@ function fromMatrix(matrix, dimension) { vec.push(matrix.getItem(i, k)); } - } + } } else { for (let i = 0; i < dimension; ++i) vec.push(0.0); } - + return vec; } @@ -89,7 +89,7 @@ function fromMatrix(matrix, dimension) */ function toThreeUniform(type, value, name, uniforms, textureLoader, searchPath, flipY) { - let outValue; + let outValue; switch (type) { case 'float': @@ -97,7 +97,7 @@ function toThreeUniform(type, value, name, uniforms, textureLoader, searchPath, case 'boolean': outValue = value; break; - case 'vector2': + case 'vector2': outValue = fromVector(value, 2); break; case 'vector3': @@ -123,11 +123,11 @@ function toThreeUniform(type, value, name, uniforms, textureLoader, searchPath, if (texture) setTextureParameters(texture, name, uniforms, flipY); outValue = texture; - } + } break; case 'samplerCube': case 'string': - break; + break; default: // struct outValue = toThreeUniform(value); @@ -184,33 +184,33 @@ function getMinFilter(type, generateMipmaps) * @param {mx.Uniforms} uniforms * @param {mx.TextureFilter.generateMipmaps} generateMipmaps */ - function setTextureParameters(texture, name, uniforms, flipY = true, generateMipmaps = true) - { - const idx = name.lastIndexOf(IMAGE_PROPERTY_SEPARATOR); - const base = name.substring(0, idx) || name; - - texture.generateMipmaps = generateMipmaps; - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - texture.magFilter = THREE.LinearFilter; - texture.flipY = flipY; - - if (uniforms.find(base + UADDRESS_MODE_SUFFIX)) - { - const uaddressmode = uniforms.find(base + UADDRESS_MODE_SUFFIX).getValue().getData(); - texture.wrapS = getWrapping(uaddressmode); - } - - if (uniforms.find(base + VADDRESS_MODE_SUFFIX)) - { - const vaddressmode = uniforms.find(base + VADDRESS_MODE_SUFFIX).getValue().getData(); - texture.wrapT = getWrapping(vaddressmode); - } - - const filterType = uniforms.find(base + FILTER_TYPE_SUFFIX) ? uniforms.get(base + FILTER_TYPE_SUFFIX).value : -1; - texture.minFilter = getMinFilter(filterType, generateMipmaps); - } - +function setTextureParameters(texture, name, uniforms, flipY = true, generateMipmaps = true) +{ + const idx = name.lastIndexOf(IMAGE_PROPERTY_SEPARATOR); + const base = name.substring(0, idx) || name; + + texture.generateMipmaps = generateMipmaps; + texture.wrapS = THREE.RepeatWrapping; + texture.wrapT = THREE.RepeatWrapping; + texture.magFilter = THREE.LinearFilter; + texture.flipY = flipY; + + if (uniforms.find(base + UADDRESS_MODE_SUFFIX)) + { + const uaddressmode = uniforms.find(base + UADDRESS_MODE_SUFFIX).getValue().getData(); + texture.wrapS = getWrapping(uaddressmode); + } + + if (uniforms.find(base + VADDRESS_MODE_SUFFIX)) + { + const vaddressmode = uniforms.find(base + VADDRESS_MODE_SUFFIX).getValue().getData(); + texture.wrapT = getWrapping(vaddressmode); + } + + const filterType = uniforms.find(base + FILTER_TYPE_SUFFIX) ? uniforms.get(base + FILTER_TYPE_SUFFIX).value : -1; + texture.minFilter = getMinFilter(filterType, generateMipmaps); +} + /** * Return the global light rotation matrix */ @@ -269,7 +269,7 @@ export function registerLights(mx, lights, genContext) lightData.push({ type: lightTypesBound[nodeName], direction: rotatedLightDirection, - color: new THREE.Vector3(...lightColor), + color: new THREE.Vector3(...lightColor), intensity: lightIntensity }); } @@ -290,16 +290,17 @@ export function getUniformValues(shaderStage, textureLoader, searchPath, flipY) let threeUniforms = {}; const uniformBlocks = Object.values(shaderStage.getUniformBlocks()); - uniformBlocks.forEach(uniforms => { + uniformBlocks.forEach(uniforms => + { if (!uniforms.empty()) { for (let i = 0; i < uniforms.size(); ++i) { - const variable = uniforms.get(i); + const variable = uniforms.get(i); const value = variable.getValue()?.getData(); const name = variable.getVariable(); - threeUniforms[name] = new THREE.Uniform(toThreeUniform(variable.getType().getName(), value, name, uniforms, - textureLoader, searchPath, flipY)); + threeUniforms[name] = new THREE.Uniform(toThreeUniform(variable.getType().getName(), value, name, uniforms, + textureLoader, searchPath, flipY)); } } }); diff --git a/javascript/MaterialXView/source/index.js b/javascript/MaterialXView/source/index.js index bffae2db8d..026653ca60 100644 --- a/javascript/MaterialXView/source/index.js +++ b/javascript/MaterialXView/source/index.js @@ -25,7 +25,8 @@ let captureRequested = false; // Get URL options. Fallback to defaults if not specified. let materialFilename = new URLSearchParams(document.location.search).get("file"); -if (!materialFilename) { +if (!materialFilename) +{ materialFilename = 'Materials/Examples/StandardSurface/standard_surface_default.mtlx'; } @@ -37,7 +38,7 @@ viewer.getEditor().updateProperties(0.9); function captureFrame() { let canvas = document.getElementById('webglcanvas'); - var url = canvas.toDataURL(); + var url = canvas.toDataURL(); var link = document.createElement('a'); link.setAttribute('href', url); link.setAttribute('target', '_blank'); @@ -45,7 +46,7 @@ function captureFrame() link.click(); } -function init() +function init() { let canvas = document.getElementById('webglcanvas'); let context = canvas.getContext('webgl2'); @@ -53,7 +54,8 @@ function init() // Handle material selection changes let materialsSelect = document.getElementById('materials'); materialsSelect.value = materialFilename; - materialsSelect.addEventListener('change', (e) => { + materialsSelect.addEventListener('change', (e) => + { materialFilename = e.target.value; viewer.getEditor().initialize(); viewer.getMaterial().loadMaterials(viewer, materialFilename); @@ -65,7 +67,8 @@ function init() const scene = viewer.getScene(); let geometrySelect = document.getElementById('geometry'); geometrySelect.value = scene.getGeometryURL(); - geometrySelect.addEventListener('change', (e) => { + geometrySelect.addEventListener('change', (e) => + { console.log('Change geometry to:', e.target.value); scene.setGeometryURL(e.target.value); scene.loadGeometry(viewer, orbitControls); @@ -95,14 +98,17 @@ function init() // Set up controls orbitControls = new OrbitControls(scene.getCamera(), renderer.domElement); - orbitControls.addEventListener('change', () => { + orbitControls.addEventListener('change', () => + { viewer.getScene().setUpdateTransforms(); }) // Add hotkey 'f' to capture the current frame and save an image file. // See check inside the render loop when a capture can be performed. - document.addEventListener('keydown', (event) => { - if (event.key === 'f') { + document.addEventListener('keydown', (event) => + { + if (event.key === 'f') + { captureRequested = true; } }); @@ -116,12 +122,14 @@ function init() new Promise(resolve => hdrLoader.load('Lights/san_giuseppe_bridge_split.hdr', resolve)), new Promise(resolve => hdrLoader.load('Lights/irradiance/san_giuseppe_bridge_split.hdr', resolve)), new Promise(resolve => fileLoader.load('Lights/san_giuseppe_bridge_split.mtlx', resolve)), - new Promise(function (resolve) { - MaterialX().then((module) => { + new Promise(function (resolve) + { + MaterialX().then((module) => + { resolve(module); }); - }) - ]).then(async ([radianceTexture, irradianceTexture, lightRigXml, mxIn]) => + }) + ]).then(async ([radianceTexture, irradianceTexture, lightRigXml, mxIn]) => { // Initialize viewer + lighting await viewer.initialize(mxIn, renderer, radianceTexture, irradianceTexture, lightRigXml); @@ -137,10 +145,12 @@ function init() viewer.getMaterial().updateMaterialAssignments(viewer); canvas.addEventListener("keydown", handleKeyEvents, true); - - }).then(() => { + + }).then(() => + { animate(); - }).catch(err => { + }).catch(err => + { console.error(Number.isInteger(err) ? this.getMx().getExceptionMessage(err) : err); }) @@ -148,7 +158,8 @@ function init() document.addEventListener('drop', dropHandler, false); document.addEventListener('dragover', dragOverHandler, false); - setLoadingCallback(file => { + setLoadingCallback(file => + { materialFilename = file.fullPath || file.name; viewer.getEditor().initialize(); viewer.getMaterial().loadMaterials(viewer, materialFilename); @@ -156,25 +167,26 @@ function init() viewer.getScene().setUpdateTransforms(); }); - setSceneLoadingCallback(file => { + setSceneLoadingCallback(file => + { let glbFileName = file.fullPath || file.name; console.log('Drop geometry to:', glbFileName); scene.setGeometryURL(glbFileName); - scene.loadGeometry(viewer, orbitControls); + scene.loadGeometry(viewer, orbitControls); }); // enable three.js Cache so that dropped files can reference each other THREE.Cache.enabled = true; } -function onWindowResize() +function onWindowResize() { viewer.getScene().updateCamera(); - viewer.getScene().setUpdateTransforms(); + viewer.getScene().setUpdateTransforms(); renderer.setSize(window.innerWidth, window.innerHeight); } -function animate() +function animate() { requestAnimationFrame(animate); @@ -182,7 +194,7 @@ function animate() { turntableStep = (turntableStep + 1) % 360; var turntableAngle = turntableStep * (360.0 / turntableSteps) / 180.0 * Math.PI; - viewer.getScene()._scene.rotation.y = turntableAngle ; + viewer.getScene()._scene.rotation.y = turntableAngle; viewer.getScene().setUpdateTransforms(); } diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js index 9992dd6985..06236fdac9 100644 --- a/javascript/MaterialXView/source/viewer.js +++ b/javascript/MaterialXView/source/viewer.js @@ -9,7 +9,7 @@ import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'; import { prepareEnvTexture, getLightRotation, findLights, registerLights, getUniformValues } from './helper.js' import { Group } from 'three'; -import GUI from 'lil-gui'; +import GUI from 'lil-gui'; const ALL_GEOMETRY_SPECIFIER = "*"; const NO_GEOMETRY_SPECIFIER = ""; @@ -21,18 +21,18 @@ var logDetailedTime = false; /* Scene management */ -export class Scene +export class Scene { - constructor() + constructor() { this._geometryURL = new URLSearchParams(document.location.search).get("geom"); if (!this._geometryURL) { - this._geometryURL = 'Geometry/shaderball.glb'; + this._geometryURL = 'Geometry/shaderball.glb'; } } - initialize() + initialize() { this._scene = new THREE.Scene(); this._scene.background = new THREE.Color(this.#_backgroundColor); @@ -64,9 +64,10 @@ export class Scene } // Utility to perform geometry file load - loadGeometryFile(geometryFilename, loader) + loadGeometryFile(geometryFilename, loader) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => + { loader.load(geometryFilename, data => resolve(data), null, reject); }); } @@ -82,8 +83,9 @@ export class Scene const gltfData = await this.loadGeometryFile(this.getGeometryURL(), this.#_gltfLoader); - const scene = this.getScene(); - while (scene.children.length > 0) { + const scene = this.getScene(); + while (scene.children.length > 0) + { scene.remove(scene.children[0]); } @@ -100,7 +102,7 @@ export class Scene else { this.#_rootNode = model; - } + } scene.add(model); console.log("- Scene load time: ", performance.now() - geomLoadTime, "ms"); @@ -123,7 +125,7 @@ export class Scene { var startUpdateSceneTime = performance.now(); var uvTime = 0; - var normalTime = 0 ; + var normalTime = 0; var tangentTime = 0; var streamTime = 0; var bboxTime = 0; @@ -136,41 +138,47 @@ export class Scene let theScene = viewer.getScene(); let flipV = theScene.getFlipGeometryV(); - - this._scene.traverse((child) => { - if (child.isMesh) { + + this._scene.traverse((child) => + { + if (child.isMesh) + { var startUVTime = performance.now(); - if (!child.geometry.attributes.uv) { + if (!child.geometry.attributes.uv) + { const posCount = child.geometry.attributes.position.count; const uvs = []; const pos = child.geometry.attributes.position.array; - - for (let i = 0; i < posCount; i++) { + + for (let i = 0; i < posCount; i++) + { uvs.push((pos[i * 3] - bsphere.center.x) / bsphere.radius); uvs.push((pos[i * 3 + 1] - bsphere.center.y) / bsphere.radius); } - + child.geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2)); } else if (flipV) { const uvCount = child.geometry.attributes.position.count; const uvs = child.geometry.attributes.uv.array; - for (let i = 0; i < uvCount; i++) { - let v = 1.0-(uvs[i*2 +1]); - uvs[i*2+1] = v; + for (let i = 0; i < uvCount; i++) + { + let v = 1.0 - (uvs[i * 2 + 1]); + uvs[i * 2 + 1] = v; } } uvTime += performance.now() - startUVTime; - - if (!child.geometry.attributes.normal) { + + if (!child.geometry.attributes.normal) + { var startNormalTime = performance.new(); child.geometry.computeVertexNormals(); normalTime += performance.now() - startNormalTime; } - - if (child.geometry.getIndex()) + + if (child.geometry.getIndex()) { if (!child.geometry.attributes.tangent) { @@ -179,7 +187,7 @@ export class Scene tangentTime += performance.now() - startTangentTime; } } - + // Use default MaterialX naming convention. var startStreamTime = performance.now(); child.geometry.attributes.i_position = child.geometry.attributes.position; @@ -199,7 +207,7 @@ export class Scene console.log(' - Stream Update time: ', streamTime); console.log(' - Bounds compute time: ', bboxTime); } - + // Update the background this._scene.background = this.getBackground(); @@ -208,10 +216,10 @@ export class Scene camera.position.y = bsphere.center.y; camera.position.z = bsphere.radius * 2.0; camera.updateProjectionMatrix(); - + orbitControls.target = bsphere.center; orbitControls.update(); - } + } setUpdateTransforms() { @@ -231,10 +239,13 @@ export class Scene const scene = this.getScene(); const camera = this.getCamera(); - scene.traverse((child) => { - if (child.isMesh) { + scene.traverse((child) => + { + if (child.isMesh) + { const uniforms = child.material.uniforms; - if (uniforms) { + if (uniforms) + { uniforms.u_worldMatrix.value = child.matrixWorld; uniforms.u_viewProjectionMatrix.value = this.#_viewProjMat.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); @@ -242,8 +253,8 @@ export class Scene uniforms.u_viewPosition.value = camera.getWorldPosition(this.#_worldViewPos); if (uniforms.u_worldInverseTransposeMatrix) - uniforms.u_worldInverseTransposeMatrix.value = - new THREE.Matrix4().setFromMatrix3(this.#_normalMat.getNormalMatrix(child.matrixWorld)); + uniforms.u_worldInverseTransposeMatrix.value = + new THREE.Matrix4().setFromMatrix3(this.#_normalMat.getNormalMatrix(child.matrixWorld)); } } }); @@ -283,9 +294,9 @@ export class Scene const scene = this.getScene(); const camera = this.getCamera(); - scene.traverse((child) => + scene.traverse((child) => { - if (child.isMesh) + if (child.isMesh) { const dagPath = this.getDagPath(child).join('/'); @@ -336,19 +347,23 @@ export class Scene camera.updateProjectionMatrix(); } - getScene() { + getScene() + { return this._scene; } - getCamera() { + getCamera() + { return this._camera; } - getGeometryURL() { + getGeometryURL() + { return this._geometryURL; } - setGeometryURL(url) { + setGeometryURL(url) + { this._geometryURL = url; } @@ -367,7 +382,7 @@ export class Scene this.#_showBackgroundTexture = enable; } - getBackground() + getBackground() { if (this.#_backgroundTexture && this.#_showBackgroundTexture) { @@ -424,31 +439,34 @@ export class Editor initialize() { Array.from(document.getElementsByClassName('lil-gui')).forEach( - function (element, index, array) { - if (element.className) { + function (element, index, array) + { + if (element.className) + { element.remove(); } } ); - this._gui = new GUI( { title: "Property Editor" } ); + this._gui = new GUI({ title: "Property Editor" }); this._gui.close(); } // Update ui properties // - Hide close button // - Update transparency so scene shows through if overlapping - updateProperties(targetOpacity = 1) + updateProperties(targetOpacity = 1) { // Set opacity Array.from(document.getElementsByClassName('dg')).forEach( - function (element, index, array) { + function (element, index, array) + { element.style.opacity = targetOpacity; } ); } - getGUI() + getGUI() { return this._gui; } @@ -491,7 +509,7 @@ class MaterialAssign { return this._material; } - + getGeometry() { return this._geometry; @@ -547,13 +565,13 @@ export class Material } // If no material file is selected, we programmatically create a default material as a fallback - static createFallbackMaterial(doc) + static createFallbackMaterial(doc) { let ssNode = doc.getChild('Generated_Default_Shader'); if (ssNode) { return ssNode; - } + } const ssName = 'Generated_Default_Shader'; ssNode = doc.addChildOfCategory('standard_surface', ssName); ssNode.setType('surfaceshader'); @@ -568,7 +586,8 @@ export class Material async loadMaterialFile(loader, materialFilename) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => + { loader.load(materialFilename, data => resolve(data), null, reject); }); } @@ -585,7 +604,7 @@ export class Material doc.importLibrary(viewer.getLibrary()); viewer.setDocument(doc); - const fileloader = viewer.getFileLoader(); + const fileloader = viewer.getFileLoader(); let mtlxMaterial = await viewer.getMaterial().loadMaterialFile(fileloader, materialFilename); @@ -598,7 +617,7 @@ export class Material // location. if (!materialFilename) materialFilename = "/"; const paths = materialFilename.split('/'); - paths.pop(); + paths.pop(); const searchPath = paths.join('/'); // Load material @@ -613,18 +632,18 @@ export class Material // and assign to the associated geometry. If there are no looks // then the first material is found and assignment to all the // geometry. - this.clearMaterials(); + this.clearMaterials(); var looks = doc.getLooks(); if (looks.length) { for (let look of looks) { const materialAssigns = look.getMaterialAssigns(); - for (let materialAssign of materialAssigns) + for (let materialAssign of materialAssigns) { let matName = materialAssign.getMaterial(); if (matName) - { + { let mat = doc.getChild(matName); var shader; if (mat) @@ -672,8 +691,8 @@ export class Material // The identifier used is "*" to mean the entire scene. const materialNodes = doc.getMaterialNodes(); let shaderList = []; - let foundRenderable = false; - for (let i=0; i 0) { continue } let outputs = nodeGraph.getOutputs(); - for (let j=0; j + uniformBlocks.forEach(uniforms => { - if (!uniforms.empty()) + if (!uniforms.empty()) { - for (let i = 0; i < uniforms.size(); ++i) + for (let i = 0; i < uniforms.size(); ++i) { const variable = uniforms.get(i); const value = variable.getValue()?.getData(); let name = variable.getVariable(); - if (ignoreList.includes(name)) { + if (ignoreList.includes(name)) + { continue; } let currentFolder = matUI; let currentElemPath = variable.getPath(); - if (!currentElemPath || currentElemPath.length == 0) { + if (!currentElemPath || currentElemPath.length == 0) + { continue; } let currentElem = elem.getDocument().getDescendant(currentElemPath); - if (!currentElem) { + if (!currentElem) + { continue; } let currentNode = null; if (currentElem.getParent() && currentElem.getParent().getNamePath() != "") - { + { currentNode = currentElem.getParent(); } let uiname = ""; let nodeDefInput = null; - if (currentNode) { + if (currentNode) + { let currentNodePath = currentNode.getNamePath(); var pathSplit = currentNodePath.split('/'); - if (pathSplit.length) { + if (pathSplit.length) + { currentNodePath = pathSplit[0]; } currentFolder = folderList[currentNodePath]; - if (!currentFolder) { + if (!currentFolder) + { currentFolder = matUI.addFolder(currentNodePath); folderList[currentNodePath] = currentFolder; } // Check for ui attributes var nodeDef = currentNode.getNodeDef(); - if (nodeDef) { + if (nodeDef) + { // Remove node name from shader uniform name for non root nodes let lookup_name = name.replace(currentNode.getName() + '_', ''); nodeDefInput = nodeDef.getActiveInput(lookup_name); - if (nodeDefInput) + if (nodeDefInput) { uiname = nodeDefInput.getAttribute('uiname'); let uifolderName = nodeDefInput.getAttribute('uifolder'); - if (uifolderName && uifolderName.length) { + if (uifolderName && uifolderName.length) + { let newFolderName = currentNodePath + '/' + uifolderName; currentFolder = folderList[newFolderName]; - if (!currentFolder) + if (!currentFolder) { currentFolder = matUI.addFolder(uifolderName); - currentFolder.domElement.classList.add('peditorfolder'); + currentFolder.domElement.classList.add('peditorfolder'); folderList[newFolderName] = currentFolder; } } @@ -1106,17 +1135,21 @@ export class Material // Determine UI name to use let path = name; let interfaceName = currentElem.getAttribute("interfacename"); - if (interfaceName && interfaceName.length) { + if (interfaceName && interfaceName.length) + { const graph = currentNode.getParent(); if (graph) { const graphInput = graph.getInput(interfaceName); - if (graphInput) { + if (graphInput) + { let uiname = graphInput.getAttribute('uiname'); - if (uiname.length) { + if (uiname.length) + { path = uiname; } - else { + else + { path = graphInput.getName(); } } @@ -1126,11 +1159,14 @@ export class Material path = interfaceName; } } - else { - if (!uiname) { + else + { + if (!uiname) + { uiname = currentElem.getAttribute('uiname'); } - if (uiname && uiname.length) { + if (uiname && uiname.length) + { path = uiname; } } @@ -1236,33 +1272,35 @@ export class Material { let w = currentFolder.add(material.uniforms[name], 'value', minValue, maxValue, step).name(path); w.domElement.classList.add('peditoritem'); - } + } else { // Map enumList strings to values // Map to 0..N if no values are specified via enumvalues attribute if (enumValues.length == 0) - { + { for (let i = 0; i < enumList.length; ++i) { enumValues.push(i); } } const enumeration = {}; - enumList.forEach((str, index) => { + enumList.forEach((str, index) => + { enumeration[str] = enumValues[index]; }); - + // Function to handle enum drop-down - function handleDropdownChange(value) { + function handleDropdownChange(value) + { if (material.uniforms[name]) { material.uniforms[name].value = value; - } - } + } + } const defaultOption = enumList[value]; // Set the default selected option const dropdownController = currentFolder.add(enumeration, defaultOption, enumeration).name(path); - dropdownController.onChange(handleDropdownChange); + dropdownController.onChange(handleDropdownChange); dropdownController.domElement.classList.add('peditoritem'); } } @@ -1273,7 +1311,7 @@ export class Material if (uniformToUpdate && value != null) { let w = currentFolder.add(material.uniforms[name], 'value').name(path); - w.domElement.classList.add('peditoritem'); + w.domElement.classList.add('peditoritem'); } break; @@ -1287,7 +1325,7 @@ export class Material var maxValue = [DEFAULT_MAX, DEFAULT_MAX, DEFAULT_MAX, DEFAULT_MAX]; var step = [0, 0, 0, 0]; - if (nodeDefInput) + if (nodeDefInput) { if (nodeDefInput.hasAttribute('uisoftmin')) minValue = nodeDefInput.getAttribute('uisoftmin').split(',').map(Number); @@ -1300,7 +1338,7 @@ export class Material maxValue = nodeDefInput.getAttribute('uimax').split(',').map(Number); if (nodeDefInput.hasAttribute('uistep')) - step = nodeDefInput.getAttribute('uistep').split(',').map(Number); + step = nodeDefInput.getAttribute('uistep').split(',').map(Number); } for (let i = 0; i < 4; ++i) { @@ -1312,10 +1350,11 @@ export class Material const keyString = ["x", "y", "z", "w"]; let vecFolder = currentFolder.addFolder(path); - Object.keys(material.uniforms[name].value).forEach((key) => { - let w = vecFolder.add(material.uniforms[name].value, + Object.keys(material.uniforms[name].value).forEach((key) => + { + let w = vecFolder.add(material.uniforms[name].value, key, minValue[key], maxValue[key], step[key]).name(keyString[key]); - w.domElement.classList.add('peditoritem'); + w.domElement.classList.add('peditoritem'); }) } break; @@ -1333,11 +1372,12 @@ export class Material color3.fromArray(material.uniforms[name].value); dummy.color = color3.getHex(); let w = currentFolder.addColor(dummy, 'color').name(path) - .onChange(function (value) { + .onChange(function (value) + { const color3 = new THREE.Color(value); material.uniforms[name].value.set(color3.toArray()); }); - w.domElement.classList.add('peditoritem'); + w.domElement.classList.add('peditoritem'); } break; @@ -1351,7 +1391,8 @@ export class Material break; case 'string': console.log('String: ', name); - if (value != null) { + if (value != null) + { var dummy = { thevalue: value @@ -1359,7 +1400,7 @@ export class Material let item = currentFolder.add(dummy, 'thevalue'); item.name(path); item.disable(true); - item.domElement.classList.add('peditoritem'); + item.domElement.classList.add('peditoritem'); } break; default: @@ -1388,7 +1429,7 @@ export class Material Keeps track of local scene, and property editor as well as current MaterialX document and assocaited material, shader and lighting information. */ -export class Viewer +export class Viewer { static create() { @@ -1402,7 +1443,7 @@ export class Viewer this.materials.push(new Material()); this.fileLoader = new THREE.FileLoader(); - this.hdrLoader = new RGBELoader(); + this.hdrLoader = new RGBELoader(); } // @@ -1447,15 +1488,18 @@ export class Viewer this.irradianceTexture = prepareEnvTexture(irradianceTexture, renderer.capabilities); } - getEditor() { + getEditor() + { return this.editor; } - getScene() { + getScene() + { return this.scene; } - getMaterial() { + getMaterial() + { return this.materials[0]; } @@ -1469,46 +1513,57 @@ export class Viewer return this.hdrLoader; } - setDocument(doc) { + setDocument(doc) + { this.doc = doc; } - getDocument() { + getDocument() + { return this.doc; } - getLibrary() { + getLibrary() + { return this.stdlib; } - getLightRig() { + getLightRig() + { return this.lightRigDoc; } - getMx() { + getMx() + { return this.mx; } - getGenerator() { + getGenerator() + { return this.generator; } - getGenContext() { + getGenContext() + { return this.genContext; } - getLights() { + getLights() + { return this.lights; } - getLightData() { + getLightData() + { return this.lightData; } - getRadianceTexture() { + getRadianceTexture() + { return this.radianceTexture; } - getIrradianceTexture() { + getIrradianceTexture() + { return this.irradianceTexture; } diff --git a/javascript/MaterialXView/webpack.config.js b/javascript/MaterialXView/webpack.config.js index bf6673284a..cd33a443f2 100644 --- a/javascript/MaterialXView/webpack.config.js +++ b/javascript/MaterialXView/webpack.config.js @@ -6,75 +6,75 @@ const HtmlWebpackPlugin = require('html-webpack-plugin') const stdSurfaceMaterials = "../../resources/Materials/Examples/StandardSurface"; const stdSurfaceMaterialsBaseURL = "Materials/Examples/StandardSurface"; let dirent = fs.readdirSync(stdSurfaceMaterials).filter( - function (file) { if (file.lastIndexOf(".mtlx") > -1) return file; } + function (file) { if (file.lastIndexOf(".mtlx") > -1) return file; } ) let materials = dirent - .map((fileName) => ({name: fileName, value: `${stdSurfaceMaterialsBaseURL}/${fileName}`})); + .map((fileName) => ({ name: fileName, value: `${stdSurfaceMaterialsBaseURL}/${fileName}` })); const usdSurfaceMaterials = "../../resources/Materials/Examples/UsdPreviewSurface"; const usdSurfaceMaterialsBaseURL = "Materials/Examples/UsdPreviewSurface"; dirent = fs.readdirSync(usdSurfaceMaterials).filter( - function (file) { if (file.lastIndexOf(".mtlx") > -1) return file; } + function (file) { if (file.lastIndexOf(".mtlx") > -1) return file; } ) let usdMaterials = dirent - .map((fileName) => ({name: fileName, value: `${usdSurfaceMaterialsBaseURL}/${fileName}`})); + .map((fileName) => ({ name: fileName, value: `${usdSurfaceMaterialsBaseURL}/${fileName}` })); const gltfSurfaceMaterials = "../../resources/Materials/Examples/GltfPbr"; const gltfSurfaceMaterialsBaseURL = "Materials/Examples/GltfPbr"; dirent = fs.readdirSync(gltfSurfaceMaterials).filter( - function (file) { if (file.lastIndexOf(".mtlx") > -1) return file; } + function (file) { if (file.lastIndexOf(".mtlx") > -1) return file; } ) let gltfMaterials = dirent - .map((fileName) => ({name: fileName, value: `${gltfSurfaceMaterialsBaseURL}/${fileName}`})); + .map((fileName) => ({ name: fileName, value: `${gltfSurfaceMaterialsBaseURL}/${fileName}` })); -materials = materials.concat( usdMaterials ); -materials = materials.concat( gltfMaterials ); +materials = materials.concat(usdMaterials); +materials = materials.concat(gltfMaterials); const geometryFiles = "../../resources/Geometry"; const geometryFilesURL = "Geometry"; dirent = fs.readdirSync(geometryFiles).filter( - function (file) { if (file.lastIndexOf(".glb") > -1) return file; } + function (file) { if (file.lastIndexOf(".glb") > -1) return file; } ) let geometry = dirent - .map((fileName) => ({name: fileName, value: `${geometryFilesURL}/${fileName}`})); - + .map((fileName) => ({ name: fileName, value: `${geometryFilesURL}/${fileName}` })); + module.exports = { - entry: './source/index.js', - output: { - filename: 'main.js', - path: path.resolve(__dirname, 'dist') - }, - mode: "development", - plugins: [ - new HtmlWebpackPlugin({ - templateParameters: { - materials, - geometry - }, - template: 'index.ejs' - }), - new CopyPlugin({ - patterns: [ - { - context: "../../resources/Images", - from: "*.*", - to: "Images", - }, - { - context: "../../resources/Geometry/", - from: "*.glb", - to: "Geometry", - }, - { from: "./public", to: 'public' }, - { context: "../../resources/Lights", from: "*.*", to: "Lights" }, - { context: "../../resources/Lights/irradiance", from: "*.*", to: "Lights/irradiance" }, - { from: stdSurfaceMaterials, to: stdSurfaceMaterialsBaseURL }, - { from: usdSurfaceMaterials, to: usdSurfaceMaterialsBaseURL }, - { from: gltfSurfaceMaterials, to: gltfSurfaceMaterialsBaseURL }, - { from: "../build/bin/JsMaterialXGenShader.wasm" }, - { from: "../build/bin/JsMaterialXGenShader.js" }, - { from: "../build/bin/JsMaterialXGenShader.data" }, - ], - }), - ] + entry: './source/index.js', + output: { + filename: 'main.js', + path: path.resolve(__dirname, 'dist') + }, + mode: "development", + plugins: [ + new HtmlWebpackPlugin({ + templateParameters: { + materials, + geometry + }, + template: 'index.ejs' + }), + new CopyPlugin({ + patterns: [ + { + context: "../../resources/Images", + from: "*.*", + to: "Images", + }, + { + context: "../../resources/Geometry/", + from: "*.glb", + to: "Geometry", + }, + { from: "./public", to: 'public' }, + { context: "../../resources/Lights", from: "*.*", to: "Lights" }, + { context: "../../resources/Lights/irradiance", from: "*.*", to: "Lights/irradiance" }, + { from: stdSurfaceMaterials, to: stdSurfaceMaterialsBaseURL }, + { from: usdSurfaceMaterials, to: usdSurfaceMaterialsBaseURL }, + { from: gltfSurfaceMaterials, to: gltfSurfaceMaterialsBaseURL }, + { from: "../build/bin/JsMaterialXGenShader.wasm" }, + { from: "../build/bin/JsMaterialXGenShader.js" }, + { from: "../build/bin/JsMaterialXGenShader.data" }, + ], + }), + ] }; From 36be87205ee01e6f81dc26b8fe7c79ba5d6c840b Mon Sep 17 00:00:00 2001 From: Dhruv Govil Date: Thu, 25 Jan 2024 08:13:53 -0800 Subject: [PATCH 082/128] Add missing classification of VolumeShader nodes (#1675) ShaderNodes.cpp had missing classification information for Volume Shaders. This PR is a simple addition of that classification. --- source/MaterialXGenShader/ShaderNode.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/MaterialXGenShader/ShaderNode.cpp b/source/MaterialXGenShader/ShaderNode.cpp index ff3c8fdb10..6e951b06e6 100644 --- a/source/MaterialXGenShader/ShaderNode.cpp +++ b/source/MaterialXGenShader/ShaderNode.cpp @@ -244,6 +244,10 @@ ShaderNodePtr ShaderNode::create(const ShaderGraph* parent, const string& name, newNode->_classification = Classification::SHADER | Classification::SURFACE | Classification::CLOSURE; } } + else if (*primaryOutput->getType() == *Type::VOLUMESHADER) + { + newNode->_classification = Classification::SHADER | Classification::VOLUME | Classification::CLOSURE; + } else if (*primaryOutput->getType() == *Type::LIGHTSHADER) { newNode->_classification = Classification::LIGHT | Classification::SHADER | Classification::CLOSURE; From 2f169d152f295114efe982ab06a74bfd930bb540 Mon Sep 17 00:00:00 2001 From: ld-kerley <154285602+ld-kerley@users.noreply.github.com> Date: Fri, 26 Jan 2024 15:19:06 -0800 Subject: [PATCH 083/128] Add invert node to specification (#1676) The node exists in the standard library code, but is missing from the specification. --- documents/Specification/MaterialX.Specification.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/documents/Specification/MaterialX.Specification.md b/documents/Specification/MaterialX.Specification.md index 895b4756c5..42b6cbbcaf 100644 --- a/documents/Specification/MaterialX.Specification.md +++ b/documents/Specification/MaterialX.Specification.md @@ -1084,6 +1084,12 @@ Math nodes have one or two spatially-varying inputs, and are used to perform a m * `in1` (float or colorN or vectorN): the value or nodename for the primary input * `in2` (same type as `in1` or float): the modulo value or nodename to divide by, cannot be 0 in any channel; default is 1.0 in all channels, which effectively returns the fractional part of a float value + + +* **`invert`**: subtract the incoming float/color/vector from "amount" in all channels, outputting: `amount - in`. + * `in` (float or colorN or vectorN): the value or nodename for the primary input + * `amount` (same type as `in` or float): the value or nodename to subtract from; default is 1.0 in all channels + * **`absval`**: the per-channel absolute value of the incoming float/color/vector. From d1e08f3e9141fd1d40b018c5230175967c930dcc Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sat, 27 Jan 2024 16:42:31 -0800 Subject: [PATCH 084/128] Improvements to facingratio - Fix syntax of input default values. - Use the invert node in facingratio for compactness. - Clarify the edge brighten example material. --- libraries/nprlib/nprlib_defs.mtlx | 4 ++-- libraries/nprlib/nprlib_ng.mtlx | 7 +++---- .../Materials/TestSuite/nprlib/edge_brighten.mtlx | 15 +++++++-------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/libraries/nprlib/nprlib_defs.mtlx b/libraries/nprlib/nprlib_defs.mtlx index a8d282d0c4..dfbaa5b5f6 100644 --- a/libraries/nprlib/nprlib_defs.mtlx +++ b/libraries/nprlib/nprlib_defs.mtlx @@ -34,8 +34,8 @@ - - + + diff --git a/libraries/nprlib/nprlib_ng.mtlx b/libraries/nprlib/nprlib_ng.mtlx index c287c2ef79..0bd7e334e5 100644 --- a/libraries/nprlib/nprlib_ng.mtlx +++ b/libraries/nprlib/nprlib_ng.mtlx @@ -32,10 +32,9 @@ - - - - + + + diff --git a/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx b/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx index dc06b76d98..8ce3affd40 100644 --- a/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx +++ b/resources/Materials/TestSuite/nprlib/edge_brighten.mtlx @@ -1,17 +1,16 @@ - - - - + + + - - + + - - + + From 8828578d0a4f1281132cee1b855f017fd5aab118 Mon Sep 17 00:00:00 2001 From: ld-kerley <154285602+ld-kerley@users.noreply.github.com> Date: Mon, 29 Jan 2024 19:55:06 -0800 Subject: [PATCH 085/128] Always build GLFW as a static library (#1680) Currently the embedded glfw build for MaterialXGraphEditor inherits the value of BUILD_SHARED_LIBS from MATERIALX_BUILD_SHARED_LIBS, but we're not installing libglfw, per #1245 the intention was to statically link. --- source/MaterialXGraphEditor/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/MaterialXGraphEditor/CMakeLists.txt b/source/MaterialXGraphEditor/CMakeLists.txt index f5f22be2c5..557b134cff 100644 --- a/source/MaterialXGraphEditor/CMakeLists.txt +++ b/source/MaterialXGraphEditor/CMakeLists.txt @@ -60,6 +60,9 @@ set(GLFW_BUILD_TESTS OFF) set(GLFW_BUILD_DOCS OFF) set(GLFW_INSTALL OFF) +# Explicitly build GLFW with static libraries, independent of the broader build settings. +set(BUILD_SHARED_LIBS OFF) + add_subdirectory(External/Glfw) if(MSVC) From 2edc358ae5d941fecffed7a859e7e37ff8084aa8 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 30 Jan 2024 20:53:56 -0800 Subject: [PATCH 086/128] Improvements to Link class (#1681) This changelist implements minor improvements to the Link class, moving static variable storage into the module, and aligning member variable naming conventions with the codebase. --- source/MaterialXGraphEditor/Graph.cpp | 20 ++++++++++++++++++-- source/MaterialXGraphEditor/Graph.h | 18 +++++++----------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 43a94edefb..4ddeff5ced 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -106,6 +106,22 @@ std::string getUserNodeDefName(const std::string& val) } // anonymous namespace +// +// Link methods +// + +Link::Link() : + _startAttr(-1), + _endAttr(-1) +{ + static int nextId = 1; + _id = nextId++; +} + +// +// Graph methods +// + Graph::Graph(const std::string& materialFilename, const std::string& meshFilename, const mx::FileSearchPath& searchPath, @@ -410,7 +426,7 @@ void Graph::connectLinks() { for (Link const& link : _currLinks) { - ed::Link(link.id, link._startAttr, link._endAttr); + ed::Link(link._id, link._startAttr, link._endAttr); } } @@ -419,7 +435,7 @@ int Graph::findLinkPosition(int id) int count = 0; for (size_t i = 0; i < _currLinks.size(); i++) { - if (_currLinks[i].id == id) + if (_currLinks[i]._id == id) { return count; } diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index 965ec519b7..f225f5e686 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -14,6 +14,9 @@ #include +namespace ed = ax::NodeEditor; +namespace mx = MaterialX; + class MenuItem { public: @@ -38,22 +41,15 @@ class MenuItem std::string category; std::string group; }; -namespace ed = ax::NodeEditor; -namespace mx = MaterialX; // A link connects two pins and includes a unique id and the ids of the two pins it connects -// Based off Link struct from ImGui Node Editor blueprints-examples.cpp +// Based on the Link struct from ImGui Node Editor blueprints-examples.cpp struct Link { - int id; + Link(); + int _startAttr, _endAttr; - Link() : - _startAttr(-1), - _endAttr(-1) - { - static int _id = 0; - id = ++_id; - } + int _id; }; class Graph From 7bec19fe04ac76df3b1a62e609f48b7c0a6f495d Mon Sep 17 00:00:00 2001 From: Ashwin Bhat <1727158+ashwinbhat@users.noreply.github.com> Date: Tue, 30 Jan 2024 20:58:00 -0800 Subject: [PATCH 087/128] Add Gooch Shading node to NPR library (#1674) Initial implementation of a gooch_shade node to the NPR data library that represents Gooch Shading used for technical illustration. --- libraries/nprlib/nprlib_defs.mtlx | 13 ++++ libraries/nprlib/nprlib_ng.mtlx | 75 +++++++++++++++++++ .../TestSuite/nprlib/gooch_shade.mtlx | 30 ++++++++ 3 files changed, 118 insertions(+) create mode 100644 resources/Materials/TestSuite/nprlib/gooch_shade.mtlx diff --git a/libraries/nprlib/nprlib_defs.mtlx b/libraries/nprlib/nprlib_defs.mtlx index dfbaa5b5f6..384ebec140 100644 --- a/libraries/nprlib/nprlib_defs.mtlx +++ b/libraries/nprlib/nprlib_defs.mtlx @@ -39,4 +39,17 @@
+ + + + + + + + + + diff --git a/libraries/nprlib/nprlib_ng.mtlx b/libraries/nprlib/nprlib_ng.mtlx index 0bd7e334e5..580432ac77 100644 --- a/libraries/nprlib/nprlib_ng.mtlx +++ b/libraries/nprlib/nprlib_ng.mtlx @@ -44,4 +44,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Materials/TestSuite/nprlib/gooch_shade.mtlx b/resources/Materials/TestSuite/nprlib/gooch_shade.mtlx new file mode 100644 index 0000000000..9e723e2de6 --- /dev/null +++ b/resources/Materials/TestSuite/nprlib/gooch_shade.mtlx @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a043d9f3e19bbedb1db6d5ec21205515157762b3 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 30 Jan 2024 21:06:39 -0800 Subject: [PATCH 088/128] Update cibuildwheel to v2.16.5 --- .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 1af8012ef0..a9d6675d3c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -402,7 +402,7 @@ jobs: path: sdist - name: Build Wheel - uses: pypa/cibuildwheel@v2.13.1 + uses: pypa/cibuildwheel@v2.16.5 with: package-dir: ${{ github.workspace }}/sdist/${{ needs.sdist.outputs.sdist_filename }} env: From dce2e4bff843429ccb19b3aa41d2d116de383ae2 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 31 Jan 2024 17:00:13 -0800 Subject: [PATCH 089/128] Initial support for signed integer textures This changelist adds initial support for signed integer textures (e.g. INT8 and INT16) in MaterialXRender and MaterialXRenderGlsl, allowing these textures to be leveraged in MaterialXView, MaterialXGraphEditor, and Shader Translation Graphs. --- source/MaterialXRender/Image.cpp | 74 ++++++++++++++++++- source/MaterialXRender/Image.h | 10 ++- source/MaterialXRender/ImageHandler.cpp | 7 +- source/MaterialXRender/OiioImageLoader.cpp | 12 +++ .../MaterialXRenderGlsl/GLTextureHandler.cpp | 8 +- 5 files changed, 97 insertions(+), 14 deletions(-) diff --git a/source/MaterialXRender/Image.cpp b/source/MaterialXRender/Image.cpp index e3b0e4365c..eec4461aea 100644 --- a/source/MaterialXRender/Image.cpp +++ b/source/MaterialXRender/Image.cpp @@ -112,11 +112,13 @@ unsigned int Image::getBaseStride() const return 4; } if (_baseType == BaseType::HALF || - _baseType == BaseType::UINT16) + _baseType == BaseType::UINT16 || + _baseType == BaseType::INT16) { return 2; } - if (_baseType == BaseType::UINT8) + if (_baseType == BaseType::UINT8 || + _baseType == BaseType::INT8) { return 1; } @@ -164,6 +166,14 @@ void Image::setTexelColor(unsigned int x, unsigned int y, const Color4& color) data[c] = (uint16_t) std::round(color[c] * (float) std::numeric_limits::max()); } } + else if (_baseType == BaseType::INT16) + { + int16_t* data = static_cast(_resourceBuffer) + (y * _width + x) * _channelCount; + for (unsigned int c = 0; c < writeChannels; c++) + { + data[c] = (int16_t) std::round(color[c] * (float) std::numeric_limits::max()); + } + } else if (_baseType == BaseType::UINT8) { uint8_t* data = static_cast(_resourceBuffer) + (y * _width + x) * _channelCount; @@ -172,6 +182,14 @@ void Image::setTexelColor(unsigned int x, unsigned int y, const Color4& color) data[c] = (uint8_t) std::round(color[c] * (float) std::numeric_limits::max()); } } + else if (_baseType == BaseType::INT8) + { + int8_t* data = static_cast(_resourceBuffer) + (y * _width + x) * _channelCount; + for (unsigned int c = 0; c < writeChannels; c++) + { + data[c] = (int8_t) std::round(color[c] * (float) std::numeric_limits::max()); + } + } else { throw Exception("Unsupported base type in setTexelColor"); @@ -263,6 +281,32 @@ Color4 Image::getTexelColor(unsigned int x, unsigned int y) const throw Exception("Unsupported channel count in getTexelColor"); } } + else if (_baseType == BaseType::INT16) + { + int16_t* data = static_cast(_resourceBuffer) + (y * _width + x) * _channelCount; + const float MAX_VALUE = (float) std::numeric_limits::max(); + if (_channelCount == 4) + { + return Color4(data[0] / MAX_VALUE, data[1] / MAX_VALUE, data[2] / MAX_VALUE, data[3] / MAX_VALUE); + } + else if (_channelCount == 3) + { + return Color4(data[0] / MAX_VALUE, data[1] / MAX_VALUE, data[2] / MAX_VALUE, 1.0f); + } + else if (_channelCount == 2) + { + return Color4(data[0] / MAX_VALUE, data[1] / MAX_VALUE, 0.0f, 1.0f); + } + else if (_channelCount == 1) + { + float scalar = data[0] / MAX_VALUE; + return Color4(scalar, scalar, scalar, 1.0f); + } + else + { + throw Exception("Unsupported channel count in getTexelColor"); + } + } else if (_baseType == BaseType::UINT8) { uint8_t* data = static_cast(_resourceBuffer) + (y * _width + x) * _channelCount; @@ -289,6 +333,32 @@ Color4 Image::getTexelColor(unsigned int x, unsigned int y) const throw Exception("Unsupported channel count in getTexelColor"); } } + else if (_baseType == BaseType::INT8) + { + int8_t* data = static_cast(_resourceBuffer) + (y * _width + x) * _channelCount; + const float MAX_VALUE = (float) std::numeric_limits::max(); + if (_channelCount == 4) + { + return Color4(data[0] / MAX_VALUE, data[1] / MAX_VALUE, data[2] / MAX_VALUE, data[3] / MAX_VALUE); + } + else if (_channelCount == 3) + { + return Color4(data[0] / MAX_VALUE, data[1] / MAX_VALUE, data[2] / MAX_VALUE, 1.0f); + } + else if (_channelCount == 2) + { + return Color4(data[0] / MAX_VALUE, data[1] / MAX_VALUE, 0.0f, 1.0f); + } + else if (_channelCount == 1) + { + float scalar = data[0] / MAX_VALUE; + return Color4(scalar, scalar, scalar, 1.0f); + } + else + { + throw Exception("Unsupported channel count in getTexelColor"); + } + } else { throw Exception("Unsupported base type in getTexelColor"); diff --git a/source/MaterialXRender/Image.h b/source/MaterialXRender/Image.h index e5857d2af8..43bbbed123 100644 --- a/source/MaterialXRender/Image.h +++ b/source/MaterialXRender/Image.h @@ -47,10 +47,12 @@ class MX_RENDER_API Image public: enum class BaseType { - UINT8 = 0, - UINT16 = 1, - HALF = 2, - FLOAT = 3 + UINT8, + INT8, + UINT16, + INT16, + HALF, + FLOAT }; public: diff --git a/source/MaterialXRender/ImageHandler.cpp b/source/MaterialXRender/ImageHandler.cpp index b148bf63d9..71721c4775 100644 --- a/source/MaterialXRender/ImageHandler.cpp +++ b/source/MaterialXRender/ImageHandler.cpp @@ -184,11 +184,10 @@ ImageVec ImageHandler::getReferencedImages(ConstDocumentPtr doc) continue; } - NodePtr node = elem->asA(); - InputPtr file = node ? node->getInput("file") : nullptr; - if (file) + InputPtr input = elem->asA(); + if (input && input->getType() == FILENAME_TYPE_STRING) { - ImagePtr image = acquireImage(file->getResolvedValueString()); + ImagePtr image = acquireImage(input->getResolvedValueString()); if (image) { imageVec.push_back(image); diff --git a/source/MaterialXRender/OiioImageLoader.cpp b/source/MaterialXRender/OiioImageLoader.cpp index d4d949f0be..703d81cd79 100644 --- a/source/MaterialXRender/OiioImageLoader.cpp +++ b/source/MaterialXRender/OiioImageLoader.cpp @@ -31,9 +31,15 @@ bool OiioImageLoader::saveImage(const FilePath& filePath, case Image::BaseType::UINT8: format = OIIO::TypeDesc::UINT8; break; + case Image::BaseType::INT8: + format = OIIO::TypeDesc::INT8; + break; case Image::BaseType::UINT16: format = OIIO::TypeDesc::UINT16; break; + case Image::BaseType::INT16: + format = OIIO::TypeDesc::INT16; + break; case Image::BaseType::HALF: format = OIIO::TypeDesc::HALF; break; @@ -90,9 +96,15 @@ ImagePtr OiioImageLoader::loadImage(const FilePath& filePath) case OIIO::TypeDesc::UINT8: baseType = Image::BaseType::UINT8; break; + case OIIO::TypeDesc::INT8: + baseType = Image::BaseType::INT8; + break; case OIIO::TypeDesc::UINT16: baseType = Image::BaseType::UINT16; break; + case OIIO::TypeDesc::INT16: + baseType = Image::BaseType::INT16; + break; case OIIO::TypeDesc::HALF: baseType = Image::BaseType::HALF; break; diff --git a/source/MaterialXRenderGlsl/GLTextureHandler.cpp b/source/MaterialXRenderGlsl/GLTextureHandler.cpp index 02a0a53927..cd130654f6 100644 --- a/source/MaterialXRenderGlsl/GLTextureHandler.cpp +++ b/source/MaterialXRenderGlsl/GLTextureHandler.cpp @@ -230,9 +230,9 @@ void GLTextureHandler::mapTextureFormatToGL(Image::BaseType baseType, unsigned i default: throw Exception("Unsupported channel count in mapTextureFormatToGL"); } - if (baseType == Image::BaseType::UINT8) + if (baseType == Image::BaseType::UINT8 || baseType == Image::BaseType::INT8) { - glType = GL_UNSIGNED_BYTE; + glType = baseType == Image::BaseType::UINT8 ? GL_UNSIGNED_BYTE : GL_BYTE; switch (channelCount) { case 4: glInternalFormat = srgb ? GL_SRGB8_ALPHA8 : GL_RGBA8; break; @@ -242,9 +242,9 @@ void GLTextureHandler::mapTextureFormatToGL(Image::BaseType baseType, unsigned i default: throw Exception("Unsupported channel count in mapTextureFormatToGL"); } } - else if (baseType == Image::BaseType::UINT16) + else if (baseType == Image::BaseType::UINT16 || baseType == Image::BaseType::INT16) { - glType = GL_UNSIGNED_SHORT; + glType = baseType == Image::BaseType::UINT16 ? GL_UNSIGNED_SHORT : GL_SHORT; switch (channelCount) { case 4: glInternalFormat = GL_RGBA16; break; From 18b6dc278afe4f93bf80767f4e7c96862bda75a7 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Thu, 1 Feb 2024 18:08:06 -0800 Subject: [PATCH 090/128] Add negative color guards in GLSL This changelist adds negative color guards to the GLSL/MSL implementations of dielectric_bsdf and generalized_schlick_bsdf, which were previously susceptible to rendering artifacts from slightly negative color inputs. --- .../pbrlib/genglsl/mx_dielectric_bsdf.glsl | 9 ++++-- .../genglsl/mx_generalized_schlick_bsdf.glsl | 28 +++++++++++-------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl b/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl index dcaaadf1fa..d8bc1ba637 100644 --- a/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl +++ b/libraries/pbrlib/genglsl/mx_dielectric_bsdf.glsl @@ -22,6 +22,7 @@ void mx_dielectric_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, floa vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N)); FresnelData fd; + vec3 safeTint = max(tint, 0.0); if (bsdf.thickness > 0.0) { fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior); @@ -40,7 +41,7 @@ void mx_dielectric_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, floa bsdf.throughput = 1.0 - dirAlbedo * weight; // Note: NdotL is cancelled out - bsdf.response = D * F * G * comp * tint * occlusion * weight / (4.0 * NdotV); + bsdf.response = D * F * G * comp * safeTint * occlusion * weight / (4.0 * NdotV); } void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf) @@ -54,6 +55,7 @@ void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior, float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); FresnelData fd; + vec3 safeTint = max(tint, 0.0); if (bsdf.thickness > 0.0) { fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior); @@ -74,7 +76,7 @@ void mx_dielectric_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior, if (scatter_mode != 0) { - bsdf.response = mx_surface_transmission(N, V, X, safeAlpha, distribution, fd, tint) * weight; + bsdf.response = mx_surface_transmission(N, V, X, safeAlpha, distribution, fd, safeTint) * weight; } } @@ -90,6 +92,7 @@ void mx_dielectric_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); FresnelData fd; + vec3 safeTint = max(tint, 0.0); if (bsdf.thickness > 0.0) { fd = mx_init_fresnel_dielectric_airy(ior, bsdf.thickness, bsdf.ior); @@ -109,5 +112,5 @@ void mx_dielectric_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec bsdf.throughput = 1.0 - dirAlbedo * weight; vec3 Li = mx_environment_radiance(N, V, X, safeAlpha, distribution, fd); - bsdf.response = Li * tint * comp * weight; + bsdf.response = Li * safeTint * comp * weight; } diff --git a/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl b/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl index ebeaa66f7a..544e479faa 100644 --- a/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl +++ b/libraries/pbrlib/genglsl/mx_generalized_schlick_bsdf.glsl @@ -22,20 +22,22 @@ void mx_generalized_schlick_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlus vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N)); FresnelData fd; + vec3 safeColor0 = max(color0, 0.0); + vec3 safeColor90 = max(color90, 0.0); if (bsdf.thickness > 0.0) { - fd = mx_init_fresnel_schlick_airy(color0, color90, exponent, bsdf.thickness, bsdf.ior); + fd = mx_init_fresnel_schlick_airy(safeColor0, safeColor90, exponent, bsdf.thickness, bsdf.ior); } else { - fd = mx_init_fresnel_schlick(color0, color90, exponent); + fd = mx_init_fresnel_schlick(safeColor0, safeColor90, exponent); } vec3 F = mx_compute_fresnel(VdotH, fd); float D = mx_ggx_NDF(Ht, safeAlpha); float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha); vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); - vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, color0, color90) * comp; + vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp; float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0)); bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight); @@ -54,13 +56,15 @@ void mx_generalized_schlick_bsdf_transmission(vec3 V, float weight, vec3 color0, float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); FresnelData fd; + vec3 safeColor0 = max(color0, 0.0); + vec3 safeColor90 = max(color90, 0.0); if (bsdf.thickness > 0.0) { - fd = mx_init_fresnel_schlick_airy(color0, color90, exponent, bsdf.thickness, bsdf.ior); + fd = mx_init_fresnel_schlick_airy(safeColor0, safeColor90, exponent, bsdf.thickness, bsdf.ior); } else { - fd = mx_init_fresnel_schlick(color0, color90, exponent); + fd = mx_init_fresnel_schlick(safeColor0, safeColor90, exponent); } vec3 F = mx_compute_fresnel(NdotV, fd); @@ -68,15 +72,15 @@ void mx_generalized_schlick_bsdf_transmission(vec3 V, float weight, vec3 color0, float avgAlpha = mx_average_alpha(safeAlpha); vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); - vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, color0, color90) * comp; + vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp; float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0)); bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight); if (scatter_mode != 0) { - float avgF0 = dot(color0, vec3(1.0 / 3.0)); + float avgF0 = dot(safeColor0, vec3(1.0 / 3.0)); fd.ior = vec3(mx_f0_to_ior(avgF0)); - bsdf.response = mx_surface_transmission(N, V, X, safeAlpha, distribution, fd, color0) * weight; + bsdf.response = mx_surface_transmission(N, V, X, safeAlpha, distribution, fd, safeColor0) * weight; } } @@ -91,20 +95,22 @@ void mx_generalized_schlick_bsdf_indirect(vec3 V, float weight, vec3 color0, vec float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); FresnelData fd; + vec3 safeColor0 = max(color0, 0.0); + vec3 safeColor90 = max(color90, 0.0); if (bsdf.thickness > 0.0) { - fd = mx_init_fresnel_schlick_airy(color0, color90, exponent, bsdf.thickness, bsdf.ior); + fd = mx_init_fresnel_schlick_airy(safeColor0, safeColor90, exponent, bsdf.thickness, bsdf.ior); } else { - fd = mx_init_fresnel_schlick(color0, color90, exponent); + fd = mx_init_fresnel_schlick(safeColor0, safeColor90, exponent); } vec3 F = mx_compute_fresnel(NdotV, fd); vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); float avgAlpha = mx_average_alpha(safeAlpha); vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); - vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, color0, color90) * comp; + vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp; float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0)); bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight); From f17f41b8a9a8615df1f0d693c893c3931f655b37 Mon Sep 17 00:00:00 2001 From: Leo Belda Date: Sat, 3 Feb 2024 22:25:46 +0100 Subject: [PATCH 091/128] Fix nodegraph to nodegraph linking in graph editor (#1691) The fix comes in two parts: 1. In Graph::buildUiBaseGraph called during material load, edges between nodegraphs and nodes are created, but not between nodegraphs and nodegraphs. Fixing this partially solves the issue as the down node now knows about the connection. However the actual link still doesn't exist 2. When building links in Graph::linkGraph, the call to getOutputPin fails to return an ID when both nodes are nodegraphs. Modifying getOutputPin to handle this case solves the issue. It also fixes issues happening on other contexts involving calls to linkGraph (e.g. adding a new node was breaking nodegraph to nodegraph links). --- source/MaterialXGraphEditor/Graph.cpp | 40 +++++++++++++++++++-------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 4ddeff5ced..9b9426f9d7 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -307,8 +307,17 @@ ed::PinId Graph::getOutputPin(UiNodePtr node, UiNodePtr upNode, UiPinPtr input) { if (upNode->getNodeGraph() != nullptr) { - // For nodegraph need to get the correct ouput pin accorinding to the names of the output nodes - mx::OutputPtr output = input->_pinNode->getNode() ? input->_pinNode->getNode()->getConnectedOutput(input->_name) : nullptr; + // For nodegraph need to get the correct ouput pin according to the names of the output nodes + mx::OutputPtr output; + if (input->_pinNode->getNode()) + { + output = input->_pinNode->getNode()->getConnectedOutput(input->_name); + } + else if (input->_pinNode->getNodeGraph()) + { + output = input->_pinNode->getNodeGraph()->getConnectedOutput(input->_name); + } + if (output) { std::string outName = output->getName(); @@ -1342,21 +1351,28 @@ void Graph::buildUiBaseGraph(mx::DocumentPtr doc) { int downNum = -1; int upNum = -1; + mx::string nodeGraphName = input->getNodeGraphString(); mx::NodePtr connectedNode = input->getConnectedNode(); - if (connectedNode) + if (!nodeGraphName.empty()) + { + downNum = findNode(graph->getName(), "nodegraph"); + upNum = findNode(nodeGraphName, "nodegraph"); + } + else if (connectedNode) { downNum = findNode(graph->getName(), "nodegraph"); upNum = findNode(connectedNode->getName(), "node"); - if (upNum > -1) + } + + if (upNum > -1) + { + UiEdge newEdge = UiEdge(_graphNodes[upNum], _graphNodes[downNum], input); + if (!edgeExists(newEdge)) { - UiEdge newEdge = UiEdge(_graphNodes[upNum], _graphNodes[downNum], input); - if (!edgeExists(newEdge)) - { - _graphNodes[downNum]->edges.push_back(newEdge); - _graphNodes[downNum]->setInputNodeNum(1); - _graphNodes[upNum]->setOutputConnection(_graphNodes[downNum]); - _currEdge.push_back(newEdge); - } + _graphNodes[downNum]->edges.push_back(newEdge); + _graphNodes[downNum]->setInputNodeNum(1); + _graphNodes[upNum]->setOutputConnection(_graphNodes[downNum]); + _currEdge.push_back(newEdge); } } } From d8f4af304a25e8fffe9d6b36f0684649b588ea7a Mon Sep 17 00:00:00 2001 From: ld-kerley <154285602+ld-kerley@users.noreply.github.com> Date: Sun, 4 Feb 2024 11:29:31 -0800 Subject: [PATCH 092/128] Add safepower node to data libraries (#1689) Add node definition and nodegraph for safepower which is already in the v1.39 specification, but currently missing in the source code. As this is an additive change we can safely add this to main for inclusion in any v.138 release. --- libraries/stdlib/stdlib_defs.mtlx | 61 ++++++ libraries/stdlib/stdlib_ng.mtlx | 193 ++++++++++++++++++ .../TestSuite/stdlib/math/math_operators.mtlx | 77 +++++++ 3 files changed, 331 insertions(+) diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index 051891cf83..0c24fac77e 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -1974,6 +1974,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx b/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx index 800e32edd0..a4277bf675 100644 --- a/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx +++ b/libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx @@ -2,98 +2,98 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - - + + + - - - + + + - - - - - - + + + + + + - + - + - + - + diff --git a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx index 80f3aa3509..24e6070071 100644 --- a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx +++ b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx @@ -15,37 +15,37 @@ - + - + - + - + - + - + - + - - + + @@ -66,123 +66,123 @@ - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - + - + - - - + + + - - - + + + - + - + - + - + - + - - + + - - - + + + - - - - - - - - - + + + + + + + + + - + - + @@ -254,10 +254,10 @@ - - - - + + + + @@ -269,8 +269,8 @@ - - + + @@ -281,15 +281,15 @@ - + - - + + @@ -297,8 +297,8 @@ - - + + @@ -308,8 +308,8 @@ - - + + @@ -366,8 +366,8 @@ - - + + @@ -376,8 +376,8 @@ - - + + @@ -389,8 +389,8 @@ - - + + @@ -402,8 +402,8 @@ - - + + @@ -430,37 +430,37 @@ - + - + - + - - - - + + + + - - + + - - + + - + - + @@ -469,95 +469,95 @@ - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + - - + + - - + + - - + + - + - + - + - + - + - - - + + + - - - + + + - + - + - + - + - + - + - + @@ -573,85 +573,85 @@ - - + + - - - + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + @@ -728,9 +728,9 @@ - - - + + + diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.cpp b/source/MaterialXGenMdl/MdlShaderGenerator.cpp index 7d52e9e973..039b82ec6a 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.cpp +++ b/source/MaterialXGenMdl/MdlShaderGenerator.cpp @@ -32,8 +32,6 @@ MATERIALX_NAMESPACE_BEGIN namespace { -const string MDL_VERSION = "1.6"; - const vector DEFAULT_IMPORTS = { "import ::df::*", @@ -42,16 +40,30 @@ const vector DEFAULT_IMPORTS = "import ::state::*", "import ::anno::*", "import ::tex::*", - "import ::mx::swizzle::*", - "using ::mx::core import *", - "using ::mx::stdlib import *", - "using ::mx::pbrlib import *", - "using ::mx::sampling import *", + "import ::materialx::swizzle::*", + "using ::materialx::core import *", + "using ::materialx::sampling import *", +}; + +const vector DEFAULT_VERSIONED_IMPORTS = { + "using ::materialx::stdlib_", + "using ::materialx::pbrlib_", }; +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_SUFFIX_1_6 = "1_6"; +const string MDL_VERSION_SUFFIX_1_7 = "1_7"; +const string MDL_VERSION_SUFFIX_1_8 = "1_8"; + } // anonymous namespace const string MdlShaderGenerator::TARGET = "genmdl"; +const string GenMdlOptions::GEN_CONTEXT_USER_DATA_KEY = "genmdloptions"; const std::unordered_map MdlShaderGenerator::GEOMPROP_DEFINITIONS = { @@ -214,16 +226,21 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G ShaderStage& stage = shader->getStage(Stage::PIXEL); // Emit version - emitLine("mdl " + MDL_VERSION, stage); + emitMdlVersionNumber(context, stage); emitLineBreak(stage); - emitLine("using mx = materialx", stage); - // Emit module imports for (const string& module : DEFAULT_IMPORTS) { emitLine(module, stage); } + for (const string& module : DEFAULT_VERSIONED_IMPORTS) + { + emitString(module, stage); + emitMdlVersionFilenameSuffix(context, stage); + emitString(IMPORT_ALL, stage); + emitLineEnd(stage, true); + } // Add global constants and type definitions emitTypeDefinitions(context, stage); @@ -697,6 +714,55 @@ void MdlShaderGenerator::emitShaderInputs(const VariableBlock& inputs, ShaderSta } } + +void MdlShaderGenerator::emitMdlVersionNumber(GenContext& context, ShaderStage& stage) const +{ + GenMdlOptionsPtr options = context.getUserData(GenMdlOptions::GEN_CONTEXT_USER_DATA_KEY); + GenMdlOptions::MdlVersion version = options ? options->targetVersion : GenMdlOptions::MdlVersion::MDL_LATEST; + + emitLineBegin(stage); + emitString("mdl ", stage); + switch (version) + { + case GenMdlOptions::MdlVersion::MDL_1_6: + emitString(MDL_VERSION_1_6, stage); + break; + case GenMdlOptions::MdlVersion::MDL_1_7: + emitString(MDL_VERSION_1_7, stage); + break; + default: + // GenMdlOptions::MdlVersion::MDL_1_8 + // GenMdlOptions::MdlVersion::MDL_LATEST + emitString(MDL_VERSION_1_8, 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; + + switch (version) + { + case GenMdlOptions::MdlVersion::MDL_1_6: + return MDL_VERSION_SUFFIX_1_6; + case GenMdlOptions::MdlVersion::MDL_1_7: + return MDL_VERSION_SUFFIX_1_7; + default: + // GenMdlOptions::MdlVersion::MDL_1_8 + // GenMdlOptions::MdlVersion::MDL_LATEST + return MDL_VERSION_SUFFIX_1_8; + } +} + + +void MdlShaderGenerator::emitMdlVersionFilenameSuffix(GenContext& context, ShaderStage& stage) const +{ + emitString(getMdlVersionFilenameSuffix(context), stage); +} + namespace MDL { // Identifiers for MDL variable blocks diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.h b/source/MaterialXGenMdl/MdlShaderGenerator.h index f1431b8916..5722c89e1d 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.h +++ b/source/MaterialXGenMdl/MdlShaderGenerator.h @@ -15,6 +15,35 @@ MATERIALX_NAMESPACE_BEGIN +/// Generator context data class to pass strings. +class MX_GENMDL_API GenMdlOptions : public GenUserData +{ + public: + /// MDL Versions supported by the Code Generator + enum class MdlVersion + { + MDL_1_6, + MDL_1_7, + MDL_1_8, + MDL_LATEST = MDL_1_8 + }; + + /// Create MDL code generator options with default values. + GenMdlOptions() : + targetVersion(MdlVersion::MDL_LATEST) { } + + /// Unique identifier for the MDL options on the GenContext object. + static const string GEN_CONTEXT_USER_DATA_KEY; + + /// The MDL version number the generated module will have. + /// Allows to generate MDL for older applications by limiting support according + /// to the corresponding specification. By default this option is MDL_LATEST. + MdlVersion targetVersion; +}; + +/// Shared pointer to GenMdlOptions +using GenMdlOptionsPtr = shared_ptr; + /// Shared pointer to an MdlShaderGenerator using MdlShaderGeneratorPtr = shared_ptr; @@ -47,6 +76,15 @@ 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.. + void emitMdlVersionNumber(GenContext& context, ShaderStage& stage) const; + + /// Add the version number suffix appended to MDL modules that use versions. + void emitMdlVersionFilenameSuffix(GenContext& context, ShaderStage& stage) const; + + /// Get the version number suffix appended to MDL modules that use versions. + const string& getMdlVersionFilenameSuffix(GenContext& context) const; + protected: // Create and initialize a new MDL shader for shader generation. ShaderPtr createShader(const string& name, ElementPtr element, GenContext& context) const; diff --git a/source/MaterialXGenMdl/Nodes/MaterialNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/MaterialNodeMdl.cpp index 936526d59d..d13aa2871f 100644 --- a/source/MaterialXGenMdl/Nodes/MaterialNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/MaterialNodeMdl.cpp @@ -4,6 +4,7 @@ // #include +#include #include #include #include @@ -30,6 +31,7 @@ void MaterialNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext& cont } const ShaderGenerator& shadergen = context.getShaderGenerator(); + const MdlShaderGenerator& shadergenMdl = static_cast(shadergen); // Emit the function call for upstream surface shader. const ShaderNode* surfaceshaderNode = surfaceshaderInput->getConnection()->getNode(); @@ -39,7 +41,9 @@ void MaterialNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext& cont // Emit the output and funtion name. shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = mx::stdlib::mx_surfacematerial(", stage); + shadergen.emitString(" = materialx::stdlib_", stage); + shadergenMdl.emitMdlVersionFilenameSuffix(context, stage); + shadergen.emitString("::mx_surfacematerial(", stage); // Emit all inputs on the node. string delim = ""; diff --git a/source/MaterialXGenMdl/Nodes/SourceCodeNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/SourceCodeNodeMdl.cpp index fde22bf1fc..8ce86263d4 100644 --- a/source/MaterialXGenMdl/Nodes/SourceCodeNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/SourceCodeNodeMdl.cpp @@ -4,6 +4,8 @@ // #include +#include +#include #include #include @@ -11,8 +13,43 @@ #include #include +#include + MATERIALX_NAMESPACE_BEGIN +namespace // anonymous +{ +const string MARKER_MDL_VERSION_SUFFIX = "MDL_VERSION_SUFFIX"; + +StringVec replaceSourceCodeMarkers(const string& nodeName, const string& soureCode, std::function lambda) +{ + // An inline function call + // Replace tokens of the format "{{}}" + static const string prefix("{{"); + static const string postfix("}}"); + + size_t pos = 0; + size_t i = soureCode.find_first_of(prefix); + StringVec code; + while (i != string::npos) + { + code.push_back(soureCode.substr(pos, i - pos)); + size_t j = soureCode.find_first_of(postfix, i + 2); + if (j == string::npos) + { + throw ExceptionShaderGenError("Malformed inline expression in implementation for node " + nodeName); + } + const string marker = soureCode.substr(i + 2, j - i - 2); + code.push_back(lambda(marker)); + pos = j + 2; + i = soureCode.find_first_of(prefix, pos); + } + code.push_back(soureCode.substr(pos)); + return code; +} + +} // anonymous namespace + ShaderNodeImplPtr SourceCodeNodeMdl::create() { return std::make_shared(); @@ -36,6 +73,15 @@ void SourceCodeNodeMdl::initialize(const InterfaceElement& element, GenContext& { size_t pos = _functionSource.find_first_of('('); string functionName = _functionSource.substr(0, pos); + + const ShaderGenerator& shadergen = context.getShaderGenerator(); + const MdlShaderGenerator& shadergenMdl = static_cast(shadergen); + const string versionSuffix = shadergenMdl.getMdlVersionFilenameSuffix(context); + StringVec code = replaceSourceCodeMarkers(getName(), functionName, [&versionSuffix](const string& marker) + { + return marker == MARKER_MDL_VERSION_SUFFIX ? versionSuffix : EMPTY_STRING; + }); + functionName = std::accumulate(code.begin(), code.end(), EMPTY_STRING); _returnStruct = functionName + "__result"; } else @@ -54,39 +100,31 @@ void SourceCodeNodeMdl::emitFunctionCall(const ShaderNode& node, GenContext& con DEFINE_SHADER_STAGE(stage, Stage::PIXEL) { const ShaderGenerator& shadergen = context.getShaderGenerator(); + const MdlShaderGenerator& shadergenMdl = static_cast(shadergen); if (_inlined) { - // An inline function call - - static const string prefix("{{"); - static const string postfix("}}"); - - size_t pos = 0; - size_t i = _functionSource.find_first_of(prefix); - StringVec code; - while (i != string::npos) - { - code.push_back(_functionSource.substr(pos, i - pos)); - size_t j = _functionSource.find_first_of(postfix, i + 2); - if (j == string::npos) + const string versionSuffix = shadergenMdl.getMdlVersionFilenameSuffix(context); + StringVec code = replaceSourceCodeMarkers(node.getName(), _functionSource, + [&shadergenMdl, &context, &node, &versionSuffix](const string& marker) { - throw ExceptionShaderGenError("Malformed inline expression in implementation for node " + node.getName()); - } - - const string variable = _functionSource.substr(i + 2, j - i - 2); - const ShaderInput* input = node.getInput(variable); - if (!input) - { - throw ExceptionShaderGenError("Could not find an input named '" + variable + - "' on node '" + node.getName() + "'"); - } - - code.push_back(shadergen.getUpstreamResult(input, context)); - - pos = j + 2; - i = _functionSource.find_first_of(prefix, pos); - } - code.push_back(_functionSource.substr(pos)); + // Special handling for the version suffix of MDL source code modules. + if (marker == MARKER_MDL_VERSION_SUFFIX) + { + return versionSuffix; + } + // Insert inputs based on parameter names. + else + { + const ShaderInput* input = node.getInput(marker); + if (!input) + { + throw ExceptionShaderGenError("Could not find an input named '" + marker + + "' on node '" + node.getName() + "'"); + } + + return shadergenMdl.getUpstreamResult(input, context); + } + }); if (!_returnStruct.empty()) { diff --git a/source/MaterialXGenMdl/Nodes/SurfaceNodeMdl.cpp b/source/MaterialXGenMdl/Nodes/SurfaceNodeMdl.cpp index 508bba43fc..305f2ad814 100644 --- a/source/MaterialXGenMdl/Nodes/SurfaceNodeMdl.cpp +++ b/source/MaterialXGenMdl/Nodes/SurfaceNodeMdl.cpp @@ -70,7 +70,9 @@ void SurfaceNodeMdl::emitFunctionCall(const ShaderNode& node, GenContext& contex // Emit the output and funtion name. shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = mx::pbrlib::mx_surface(", stage); + shadergen.emitString(" = materialx::pbrlib_", stage); + shadergen.emitMdlVersionFilenameSuffix(context, stage); + shadergen.emitString("::mx_surface(", stage); // Emit all inputs on the node. string delim = ""; diff --git a/source/MaterialXGenMdl/mdl/materialx/core.mdl b/source/MaterialXGenMdl/mdl/materialx/core.mdl index ddcea572e4..b0012f7dab 100644 --- a/source/MaterialXGenMdl/mdl/materialx/core.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/core.mdl @@ -27,11 +27,11 @@ // Document version 1.7.2, January 17, 2022 // www.nvidia.com/mdl -mdl 1.7; +mdl 1.6; import ::math::*; -import ::tex::*; import ::state::*; +import ::tex::*; // Epsilon value used in float calculations. export const float FLOAT_EPS = 0.000001; diff --git a/source/MaterialXGenMdl/mdl/materialx/hsv.mdl b/source/MaterialXGenMdl/mdl/materialx/hsv.mdl index 9adb1505cb..3c7753a96f 100644 --- a/source/MaterialXGenMdl/mdl/materialx/hsv.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/hsv.mdl @@ -16,10 +16,10 @@ // Support functions for HSV <--> RGB color conversions -mdl 1.0; +mdl 1.6; -import ::math::*; import ::limits::*; +import ::math::*; // Convert from the HSV color model to the RGB color model export float3 mx_hsvtorgb(float3 hsv) { diff --git a/source/MaterialXGenMdl/mdl/materialx/noise.mdl b/source/MaterialXGenMdl/mdl/materialx/noise.mdl index bcbc2fcd1b..a6c1658b74 100644 --- a/source/MaterialXGenMdl/mdl/materialx/noise.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/noise.mdl @@ -46,11 +46,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mdl 1.6; -using core import *; -import swizzle::*; +import ::anno::*; import ::math::*; import ::state::*; -import ::anno::*; + +import .::core::*; +import .::swizzle::*; float mx_bilerp_float(float v0, float v1, float v2, float v3, float s, float t) { diff --git a/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl b/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl index 61234c4037..0c11ce3744 100644 --- a/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/pbrlib.mdl @@ -14,997 +14,17 @@ * limitations under the License. */ -// Implementation of all types and nodes of +// MDL implementation of all types and nodes of // MaterialX Physically-Based Shading Nodes // Document v1.37 REV2, July 16, 2019 (Revised October 17, 2019) // see www.materialx.org // in -// NVIDIA Material Definition Language 1.7 +// NVIDIA Material Definition Language 1.8 // Language Specification -// Document version 1.7.2, January 17, 2022 +// Document version 1.8.2, May 24, 2023 // www.nvidia.com/mdl -mdl 1.7; +mdl 1.8; -using .::core import *; -import .::swizzle::*; - -import ::df::*; -import ::math::*; -import ::state::*; -import ::anno::*; - -// NOTE: We use the MDL material type to represent all PBS nodes of -// BSDF, EDF, VDF and other MaterialX material related types. -// To document, and possibly also support tool diagnostics, we -// use the ::anno::usage(string) annotation to document the -// true MaterialX type, only connections with equal usage -// annotations are correct MaterialX connections. - -// NOTE: Geometric parameters like surface normal are specified in MDL internal -// space, which is the efficient and natural way for MDL. -// TODO: Check that the generator emits proper space transform conversion -// calls where needed -// TODO: Check how MaterialX unit handling works with this -// TODO: Check if scene_units_per_meter() is applicable as well, like for displacement - -// NOTE: Some PBR nodes require multiple implementations with different -// parameter types. If those require a material type as result, we -// cannot use overlaods and must use different names. Examples are -// mix, add, multiply, and we include displacement for orthogonality. - -// NOTE: Because of the BTDFs and the VDF below them, we have to take care -// of volumetric properties in the BSDF components as well. Since IOR -// is uniform in MDL, some nodes have a limitation on how IOR works. - - -// Enum selecting scatter mode, instead of string -export enum mx_scatter_mode { - mx_scatter_mode_R, - mx_scatter_mode_T, - mx_scatter_mode_RT -}; - -// Helper function mapping MaterialX scatter mode to MDL scatter_mode enum -export df::scatter_mode mx_map_scatter_mode( mx_scatter_mode mode) { - switch (mode) { - case mx_scatter_mode_R: - return df::scatter_reflect; - case mx_scatter_mode_T: - return df::scatter_transmit; - default: - return df::scatter_reflect_transmit; - } -} - -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() -) [[ - anno::usage( "materialx:bsdf") -]] -= material( - surface: material_surface( - scattering: df::weighted_layer( - weight: mxp_weight, - layer: df::diffuse_reflection_bsdf( - tint: mxp_color, - roughness: mxp_roughness - ), - normal: mxp_normal - ) - ) -); - -// NOTE: Approximate Burley with df::diffuse_reflection_bsdf, the difference isn't big -export material mx_burley_diffuse_bsdf( - float mxp_weight = 1.0, - color mxp_color = color(0.18), - float mxp_roughness = 0.0, - float3 mxp_normal = state::normal() -) [[ - anno::usage( "materialx:bsdf") -]] -= material( - surface: material_surface( - scattering: df::weighted_layer( - weight: mxp_weight, - layer: df::diffuse_reflection_bsdf( - tint: mxp_color, - roughness: mxp_roughness - ), - normal: mxp_normal - ) - ) -); - -export material mx_translucent_bsdf( - float mxp_weight = 1.0, - color mxp_color = color(1.0), - float3 mxp_normal = state::normal() -) [[ - anno::usage( "materialx:bsdf") -]] -= material( - surface: material_surface( - scattering: df::weighted_layer( - weight: mxp_weight, - layer: df::diffuse_transmission_bsdf( - tint: mxp_color - ), - normal: mxp_normal - ) - ) -); - -// 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 mx_distribution_type mxp_distribution = 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") ]], - 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, - 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, - 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, - 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: mxp_base.ior, - volume: mxp_base.volume -); - -// TODO MDL 1.8 -// * thin_film(thickness: 0.0, ior: < 1.0) will be handled properly -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 mx_distribution_type mxp_distribution = 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, - 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 - ) - ) -); - -// 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_generalized_schlick_bsdf( - float mxp_weight = 1.0, - color mxp_color0 = color(1.0), - 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 mx_distribution_type mxp_distribution = 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") ]], - 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 avgF0 = math::average(float3(mxp_color0)); - bsdf ggx_model_R = df::microfacet_ggx_smith_bsdf( - roughness_u: mxp_roughness.x, - roughness_v: mxp_roughness.y, - tint: color(1.0), - 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), - tangent_u: mxp_tangent, - mode: df::scatter_transmit); -} in material( - surface: material_surface( - scattering: df::weighted_layer( - weight: mxp_weight, - layer: mxp_scatter_mode == mx_scatter_mode_T - ? df::color_custom_curve_layer( - normal_reflectivity: mxp_color0, - grazing_reflectivity: mxp_color90, - exponent: mxp_exponent, - layer: bsdf(), - base: ggx_model_T) - : df::thin_film( - thickness: mxp_thinfilm_thickness, - ior: color(coatIor), - base: df::color_custom_curve_layer( - normal_reflectivity: mxp_color0, - grazing_reflectivity: mxp_color90, - exponent: mxp_exponent, - layer: ggx_model_R, - base: mxp_scatter_mode == mx_scatter_mode_R - ? mxp_base.surface.scattering - : ggx_model_T)), - base: mxp_base.surface.scattering, - normal: mxp_normal - ) - ), - // we can't use the computed ior here because it's varying - // assuming that we have something glass like when transmission is used - ior: color(1.5), // color(mx_f0_to_ior(avgF0)) - - // we need to carry volume properties along for SSS - volume: mxp_base.volume -); - -export material mx_subsurface_bsdf( - float mxp_weight = 1.0 [[ anno::unused() ]], - color mxp_color = color(0.18), - float3 mxp_radius = float3(1.0), // TODO: should probably be a color in MTLX Spec - float mxp_anisotropy = 0.0, - float3 mxp_normal = state::normal() [[ anno::unused() ]] -) [[ - anno::usage( "materialx:bsdf") -]] -= let { - // https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf - // Phase function eccentricity 'g' has been omitted here since we pass that directly - // to anisotropic_vdf(directional_bias: g). - color albedo = color(4.09712) + - (4.20863f * mxp_color) - - math::sqrt( - 9.59217f + - 41.6808f * mxp_color + - 17.7126f * mxp_color * mxp_color); - - color albedo_sq = albedo * albedo; - - color white = color(1.0, 1.0, 1.0); - - color alpha = - (white - albedo_sq) / (white - mxp_anisotropy * albedo_sq); - - color radius_inv = white/color(mxp_radius); - - color sigma_s = alpha * radius_inv; - color sigma_a = radius_inv - sigma_s; - -} in material( - volume: material_volume( - scattering: df::anisotropic_vdf ( - directional_bias: mxp_anisotropy - ), - scattering_coefficient: sigma_s, - absorption_coefficient: sigma_a - ), - - surface: material_surface( - scattering: df::diffuse_transmission_bsdf(tint: white) - ) -); - -// To match with OSL, the sheen weight is scaled with average color as approximation of albedo. -// OSL uses the layer operator which mixes based on albedo. -export material mx_sheen_bsdf( - float mxp_weight = 1.0, - color mxp_color = color(1.0), - float mxp_roughness = 0.2, - float3 mxp_normal = state::normal(), - material mxp_base = material( - surface: material_surface( - scattering: df::diffuse_reflection_bsdf( - ))) [[ anno::usage( "materialx:bsdf") ]] -) [[ - anno::usage( "materialx:bsdf") -]] -= material( - surface: material_surface( - // using the mix seems to fit OSL best, at least in the test cases - scattering: df::weighted_layer( - weight: math::average(mxp_color) * mxp_weight, - layer: df::sheen_bsdf( - roughness: mxp_roughness, - tint: mxp_color, - multiscatter_tint: color(1.0), - multiscatter: mxp_base.surface.scattering - ), - base: mxp_base.surface.scattering, - normal: mxp_normal)), - // we need to carry volume properties along for SSS - ior: mxp_base.ior, - volume: mxp_base.volume -); - -export material mx_thin_film_bsdf( - float mxp_thickness = 1000.0, - float mxp_ior = 1.5, - material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]] -) [[ - anno::usage( "materialx:bsdf") -]] -= material( - surface: material_surface( - scattering: df::thin_film( - thickness: mxp_thickness, - ior: color(mxp_ior), - base: mxp_base.surface.scattering - ) - ), - // we need to carry volume properties along for SSS - ior: mxp_base.ior, - volume: mxp_base.volume -); - -// EDF Nodes - -export material mx_uniform_edf( - color mxp_color = color(1.0) -) [[ - anno::usage( "materialx:edf") -]] -= material( - surface: material_surface( - emission: material_emission( emission: df::diffuse_edf(), intensity: mxp_color * math::PI) - ) -); - -export material mx_conical_edf( - color mxp_color = color(1.0), - float3 mxp_normal = state::normal() - [[ - anno::unused() - ]], - uniform float mxp_inner_angle = 60.0, - uniform float mxp_outer_angle = 0.0 -) [[ - anno::usage( "materialx:edf") -]] -= material( - surface: material_surface( - emission: material_emission( - emission: df::spot_edf( // TODO: refine exact math of the mapping here - spread: math::radians( math::max(mxp_inner_angle, mxp_outer_angle)), - exponent: (mxp_outer_angle <= mxp_inner_angle) ? 0.0 : 1.0 - ), - intensity: mxp_color * math::PI - ) - ) -); - -export material mx_measured_edf( - color mxp_color = color(1.0), - float3 mxp_normal = state::normal() - [[ - anno::unused() - ]], - uniform light_profile mxp_file = light_profile() -) [[ - anno::usage( "materialx:edf") -]] -= material( - surface: material_surface( - emission: material_emission( - emission: df::measured_edf( profile: mxp_file), - intensity: mxp_color * math::PI - ) - ) -); - -export material mx_generalized_schlick_edf( - color mxp_color0 = color(1.0), - color mxp_color90 = color(1.0), - float mxp_exponent = 5.0, - material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]] -) [[ - anno::usage( "materialx:edf") -]] -= material( - thin_walled: mxp_base.thin_walled, - surface: material_surface( - scattering: mxp_base.surface.scattering, - emission: material_emission( - emission: df::directional_factor(mxp_color0, mxp_color90, mxp_exponent, mxp_base.surface.emission.emission), - intensity: mxp_base.surface.emission.intensity, - mode: mxp_base.surface.emission.mode) - ), - backface: mxp_base.backface, - ior: mxp_base.ior, - volume: mxp_base.volume, - geometry: mxp_base.geometry, - hair: mxp_base.hair -); - -// VDF Nodes - -export material mx_absorption_vdf( - // TODO: should probably become color3 in the MaterialX spec - float3 mxp_absorption = float3(0.0) -) [[ - anno::usage( "materialx:vdf") -]] -= material( - volume: material_volume( - absorption_coefficient: color( mxp_absorption) - ) -); - -export material mx_anisotropic_vdf( - // TODO: should probably become color3 in the MaterialX spec - float3 mxp_absorption = float3(0.0), - // TODO: should probably become color3 in the MaterialX spec - float3 mxp_scattering = float3(0.0), - float mxp_anisotropy = 0.0 -) [[ - anno::usage( "materialx:vdf") -]] -= material( - volume: material_volume( - scattering: df::anisotropic_vdf( directional_bias: mxp_anisotropy), - absorption_coefficient: color( mxp_absorption), - scattering_coefficient: color( mxp_scattering) - ) -); - -// 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 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: false, - 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 - ) -); - -export material mx_thin_surface( - material mxp_front_bsdf = material() [[ anno::usage( "materialx:bsdf") ]], - material mxp_front_edf = material() [[ anno::usage( "materialx:edf") ]], - material mxp_back_bsdf = material() [[ anno::usage( "materialx:bsdf") ]], - material mxp_back_edf = material() [[ anno::usage( "materialx:edf") ]], - float mxp_opacity = 1.0 -) [[ - anno::usage( "materialx:surfaceshader") -]] -= let { - bsdf front_bsdf_node = mxp_front_bsdf.surface.scattering; - material_emission front_edf_node = mxp_front_edf.surface.emission; - bsdf back_bsdf_node = mxp_back_bsdf.surface.scattering; - material_emission back_edf_node = mxp_back_edf.surface.emission; - // we need to carry volume properties along for SSS - // TODO: clarify SSS behavior in MaterialX for thin-walled surfaces, - // in MDL there is only one volume property - material_volume bsdf_volume = mxp_front_bsdf.volume; -} in material( - thin_walled: true, - surface: material_surface( - scattering: front_bsdf_node, - emission: front_edf_node - ), - backface: material_surface( - scattering: back_bsdf_node, - emission: back_edf_node - ), - ior: color(1.0), - volume: bsdf_volume, - geometry: material_geometry( - cutout_opacity: mxp_opacity - ) -); - -// MDL 1.7, Volumes do support emssion, but not as EDF, just emission intensity. -// A uniform emission DF is the only practical DF here. -export material mx_volume( - material mxp_vdf = material() [[ anno::usage( "materialx:vdf") ]], - material mxp_edf = material() [[ anno::usage( "materialx:edf") ]] -) [[ - anno::usage( "materialx:volumeshader") -]] -= material( - volume: material_volume( - absorption_coefficient: mxp_vdf.volume.absorption_coefficient, - scattering_coefficient: mxp_vdf.volume.scattering_coefficient, - emission_intensity: mxp_edf.surface.emission.intensity - ) -); - -export material mx_light( - material mxp_edf = material() [[ anno::usage( "materialx:edf") ]], - color mxp_intensity = color(1.0), - float mxp_exposure = 0.0 -) [[ - anno::usage( "materialx:lightshader") -]] -= let { - edf emission = mxp_edf.surface.emission.emission; - color intensity = mxp_edf.surface.emission.intensity; - color scale = (mxp_exposure == 0.0) - ? mxp_intensity - : mxp_intensity * math::pow(2, mxp_exposure); -} in material( - // TODO: check MTLX spec if we need emission on front- end backface - surface: material_surface( - emission: material_emission( - emission: emission, - intensity: intensity * scale - ) - ) -); - -// NOTE: MDL provides function overloading, but not material definition -// overlaoding. We thus try to use float3 as MDL type matching -// the MaterialX displacementshader and allow thus for an overloaded -// implementation of mxp_displacement. -// TODO: Check if this works in the translator and higher level nodes, like -// mxp_material, if not, we have to switch to the material type and -// use two different names for mxp_displacemnnt. -export material mx_displacement_float( - float mxp_displacement = 0.0, - float mxp_scale = 1.0 -) [[ - anno::usage( "materialx:displacementshader") -]] = material( - geometry: material_geometry( - displacement: mxp_displacement * mxp_scale * state::scene_units_per_meter() * state::normal() - ) -); - -export material mx_displacement_vector3( - float3 mxp_displacement = float3(0.0), - float mxp_scale = 1.0 -) [[ - anno::usage( "materialx:displacementshader") -]] = let -{ - float3 vec = (mxp_displacement.x * state::texture_tangent_u(0) - + mxp_displacement.y * state::texture_tangent_v(0) - + mxp_displacement.z * state::normal()); -} in material( - geometry: material_geometry( - displacement: vec * mxp_scale * state::scene_units_per_meter() - ) -); - - -// helper function to mix two scattering volumes: -// - combined scattering coefficient is just the sum of the two -// - VDF mixer weight is the relative probability of encountering the corresponding -// particle type -// NOTE: mixer weight should be a color, but due to a bug in current MDL compilers -// the color mixers don't accept non-uniform weights yet -struct volume_mix_return { - color scattering_coefficient; - float mix_weight1; // mix_weight2 = 1.0 - mix_weight1, can use any mixer -}; -volume_mix_return volume_mix( - color scattering_coefficient1, - float weight1, - color scattering_coefficient2, - float weight2) -{ - color s1 = weight1 * scattering_coefficient1; - color s = s1 + weight2 * scattering_coefficient2; - return volume_mix_return(scattering_coefficient: s, mix_weight1: math::average(s1 / s)); -} - -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 { - volume_mix_return v = volume_mix( - mxp_fg.volume.scattering_coefficient, mxp_mix, - mxp_bg.volume.scattering_coefficient, (1.0f - mxp_mix)); -} in material( - surface: material_surface( - scattering: df::weighted_layer( - weight: mxp_mix, - layer: mxp_fg.surface.scattering, - base: mxp_bg.surface.scattering - ) - ), - // we need to carry volume properties along for SSS - ior: mxp_fg.ior, // NOTE: IOR is uniform, cannot mix here - volume: material_volume( - scattering: df::unbounded_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: mxp_mix * mxp_fg.volume.absorption_coefficient + - (1.0 - mxp_mix) * mxp_bg.volume.absorption_coefficient, - scattering_coefficient: v.scattering_coefficient - ) -); - -export material mx_mix_edf( - material mxp_fg = material() [[ anno::usage( "materialx:edf") ]], - material mxp_bg = material() [[ anno::usage( "materialx:edf") ]], - float mxp_mix = 0.0 -) [[ - anno::usage( "materialx:edf") -]] -= material( - surface: material_surface( - emission: material_emission( - emission: df::unbounded_mix( // unbounded_mix is cheaper - 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 - ) - ) -); - -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 { - volume_mix_return v = volume_mix( - mxp_fg.volume.scattering_coefficient, mxp_mix, - mxp_bg.volume.scattering_coefficient, (1.0f - mxp_mix)); -} in material( - ior: mxp_fg.ior, // NOTE: IOR is uniform, cannot mix here - volume: material_volume( - scattering: df::unbounded_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: mxp_mix * mxp_fg.volume.absorption_coefficient + - (1.0 - mxp_mix) * mxp_bg.volume.absorption_coefficient, - scattering_coefficient: v.scattering_coefficient - ) -); - -// NOTE: Adding two BSDFs is not supported in MDL, the generator would best -// analyze the context for mixing weights and replace the add with a mix. -// The provided implementation just mixes the BSDFs with equal weight. -export material mx_add_bsdf( - material mxp_in1 = material() [[ anno::usage( "materialx:bsdf") ]], - material mxp_in2 = material() [[ anno::usage( "materialx:bsdf") ]] -) [[ - anno::usage( "materialx:bsdf") -]] -= let { - volume_mix_return v = volume_mix( - mxp_in1.volume.scattering_coefficient, 1.0f, - mxp_in2.volume.scattering_coefficient, 1.0f); -} in material( - surface: material_surface( - scattering: df::unbounded_mix( - df::bsdf_component[]( - df::bsdf_component( 1.0, mxp_in1.surface.scattering), - df::bsdf_component( 1.0, mxp_in2.surface.scattering) - ) - ) - ), - // we need to carry volume properties along for SSS - volume: material_volume( - scattering: df::unbounded_mix( - df::vdf_component[]( - df::vdf_component( v.mix_weight1, mxp_in1.volume.scattering), - df::vdf_component( 1.0 - v.mix_weight1, mxp_in2.volume.scattering)) - ), - absorption_coefficient: mxp_in1.volume.absorption_coefficient + - mxp_in2.volume.absorption_coefficient, - scattering_coefficient: v.scattering_coefficient - ) -); - -// NOTE: Adding two EDFs is not supported in MDL, the generator would best -// analyze the context for mixing weights and replace the add with a mix. -// The provided implementation just mixes the EDFs with equal weight -// and adds the intensities. -export material mx_add_edf( - material mxp_in1 = material() [[ anno::usage( "materialx:edf") ]], - material mxp_in2 = material() [[ anno::usage( "materialx:edf") ]] -) [[ - anno::usage( "materialx:edf") -]] -= material( - surface: material_surface( - emission: material_emission( - emission: df::unbounded_mix( - df::edf_component[]( - df::edf_component( 1.0, mxp_in1.surface.emission.emission), - df::edf_component( 1.0, mxp_in2.surface.emission.emission)) - ), - intensity: mxp_in1.surface.emission.intensity + mxp_in2.surface.emission.intensity - ) - ) -); - -// NOTE: Adding two VDFs is not supported in MDL, the generator would best -// analyze the context for mixing weights and replace the add with a mix. -// The provided implementation just mixes the VDFs with equal weight. -export material mx_add_vdf( - material mxp_in1 = material() [[ anno::usage( "materialx:vdf") ]], - material mxp_in2 = material() [[ anno::usage( "materialx:vdf") ]] -) [[ - anno::usage( "materialx:vdf") -]] -= let { - volume_mix_return v = volume_mix( - mxp_in1.volume.scattering_coefficient, 1.0f, - mxp_in2.volume.scattering_coefficient, 1.0f); -} in material( - // assuming mixing the IOR is the best we can do here - ior: 0.5 * mxp_in1.ior + 0.5 * mxp_in2.ior, - volume: material_volume( - scattering: df::unbounded_mix( - df::vdf_component[]( - df::vdf_component( v.mix_weight1, mxp_in1.volume.scattering), - df::vdf_component( 1.0 - v.mix_weight1, mxp_in2.volume.scattering)) - ), - absorption_coefficient: mxp_in1.volume.absorption_coefficient + - mxp_in2.volume.absorption_coefficient, - scattering_coefficient: v.scattering_coefficient - ) -); - -export material mx_multiply_bsdf_color3( - material mxp_in1 = material() [[ anno::usage( "materialx:bsdf") ]], - color mxp_in2 = color(1.0) -) [[ - anno::usage( "materialx:bsdf") -]] -= material( - surface: material_surface( - scattering: df::tint( - tint: mxp_in2, - base: mxp_in1.surface.scattering - ) - ), - // we need to carry volume properties along for SSS - ior: mxp_in1.ior, - volume: mxp_in1.volume -); - -export material mx_multiply_bsdf_float( - material mxp_in1 = material() [[ anno::usage( "materialx:bsdf") ]], - float mxp_in2 = 1.0 -) [[ - anno::usage( "materialx:bsdf") -]] -= material( - surface: material_surface( - scattering: df::tint( - tint: color(mxp_in2), - base: mxp_in1.surface.scattering - ) - ), - // we need to carry volume properties along for SSS - ior: mxp_in1.ior, - volume: mxp_in1.volume -); - -export material mx_multiply_edf_color3( - material mxp_in1 = material() [[ anno::usage( "materialx:edf") ]], - color mxp_in2 = color(1.0) -) [[ - anno::usage( "materialx:edf") -]] -= material( - surface: material_surface( - emission: material_emission( - emission: mxp_in1.surface.emission.emission, - intensity: mxp_in2 * mxp_in1.surface.emission.intensity - ) - ) -); - -export material mx_multiply_edf_float( - material mxp_in1 = material() [[ anno::usage( "materialx:edf") ]], - float mxp_in2 = 1.0 -) [[ - anno::usage( "materialx:edf") -]] -= material( - surface: material_surface( - emission: material_emission( - emission: mxp_in1.surface.emission.emission, - intensity: mxp_in2 * mxp_in1.surface.emission.intensity - ) - ) -); - -export material mx_multiply_vdf_color3( - material mxp_in1 = material() [[ anno::usage( "materialx:vdf") ]], - color mxp_in2 = color(1.0) -) [[ - anno::usage( "materialx:vdf") -]] -= material( - ior: mxp_in1.ior, - volume: material_volume( - scattering: mxp_in1.volume.scattering, - absorption_coefficient: color(1.0) - - mxp_in2 * (color(1.0) - mxp_in1.volume.absorption_coefficient), - scattering_coefficient: mxp_in2 * mxp_in1.volume.scattering_coefficient - ) -); - -export material mx_multiply_vdf_float( - material mxp_in1 = material() [[ anno::usage( "materialx:vdf") ]], - float mxp_in2 = 1.0 -) [[ - anno::usage( "materialx:vdf") -]] -= material( - ior: mxp_in1.ior, - volume: material_volume( - scattering: mxp_in1.volume.scattering, - absorption_coefficient: color(1.0) - - mxp_in2 * (color(1.0) - mxp_in1.volume.absorption_coefficient), - scattering_coefficient: mxp_in2 * mxp_in1.volume.scattering_coefficient - ) -); - -export float2 mx_roughness_anisotropy( - float mxp_roughness = 0.0, - float mxp_anisotropy = 0.0 -) { - float roughness_sqr = math::clamp(mxp_roughness*mxp_roughness, FLOAT_EPS, 1.0); - if (mxp_anisotropy > 0.0) - { - float aspect = math::sqrt(1.0 - math::clamp(mxp_anisotropy, 0.0, 0.98)); - return float2( - math::min(roughness_sqr / aspect, 1.0), - roughness_sqr * aspect); - } - return float2(roughness_sqr); -} - -export float2 mx_roughness_dual( - float2 mxp_roughness = float2(0.0) -) { - if (mxp_roughness.y < 0.0) - mxp_roughness.y = mxp_roughness.x; - return float2( - math::clamp(mxp_roughness.x * mxp_roughness.x, FLOAT_EPS, 1.0), - math::clamp(mxp_roughness.y * mxp_roughness.y, FLOAT_EPS, 1.0)); -} - -export color mx_blackbody( - float mxp_temperature = 5000 -) { - return math::blackbody( mxp_temperature); -} - -// Supportive struct type for the two outputs of mx_artistic_ior -export struct mx_artistic_ior__result { - color mxp_ior; - color mxp_extinction; -}; - -// Converts the artistic parameterization reflectivity and edgecolor -// to complex IOR values; this is the inverse of the ​complex_ior​ node. -export mx_artistic_ior__result mx_artistic_ior( - color mxp_reflectivity = color(0.947, 0.776, 0.371), - color mxp_edge_color = color(1.0, 0.982, 0.753) -) { - color r = math::clamp( mxp_reflectivity, color(0.0), color(0.99)); - color r_sqrt = math::sqrt(r); - color n_min = (1.0 - r) / (1.0 + r); - color n_max = (1.0 + r_sqrt) / (1.0 - r_sqrt); - color n = math::lerp(n_max, n_min, mxp_edge_color); - color np1 = n + 1.0; - color nm1 = n - 1.0; - color k2 = (np1*np1 * r - nm1*nm1) / (1.0 - r); - k2 = math::max(k2, 0.0); - color k = math::sqrt(k2); - return mx_artistic_ior__result(n,k); -} +// forward the latest version +export using .::pbrlib_1_8 import *; diff --git a/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl new file mode 100644 index 0000000000..fbd6b5c1dd --- /dev/null +++ b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_6.mdl @@ -0,0 +1,1009 @@ +/* + * 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 v1.37 REV2, July 16, 2019 (Revised October 17, 2019) +// see www.materialx.org +// in +// NVIDIA Material Definition Language 1.6 +// Language Specification +// Document version 1.6.1, December 16, 2019 +// www.nvidia.com/mdl + +mdl 1.6; + +import ::anno::*; +import ::df::*; +import ::math::*; +import ::state::*; + +import .::core::*; +import .::swizzle::*; + +// NOTE: We use the MDL material type to represent all PBS nodes of +// BSDF, EDF, VDF and other MaterialX material related types. +// To document, and possibly also support tool diagnostics, we +// use the ::anno::usage(string) annotation to document the +// true MaterialX type, only connections with equal usage +// annotations are correct MaterialX connections. + +// NOTE: Geometric parameters like surface normal are specified in MDL internal +// space, which is the efficient and natural way for MDL. +// TODO: Check that the generator emits proper space transform conversion +// calls where needed +// TODO: Check how MaterialX unit handling works with this +// TODO: Check if scene_units_per_meter() is applicable as well, like for displacement + +// NOTE: Some PBR nodes require multiple implementations with different +// parameter types. If those require a material type as result, we +// cannot use overlaods and must use different names. Examples are +// mix, add, multiply, and we include displacement for orthogonality. + +// NOTE: Because of the BTDFs and the VDF below them, we have to take care +// of volumetric properties in the BSDF components as well. Since IOR +// is uniform in MDL, some nodes have a limitation on how IOR works. + + +// Enum selecting scatter mode, instead of string +export enum mx_scatter_mode { + mx_scatter_mode_R, + mx_scatter_mode_T, + mx_scatter_mode_RT +}; + +// Helper function mapping MaterialX scatter mode to MDL scatter_mode enum +export df::scatter_mode mx_map_scatter_mode( + mx_scatter_mode mode +) { + switch (mode) { + case mx_scatter_mode_R: + return df::scatter_reflect; + case mx_scatter_mode_T: + return df::scatter_transmit; + default: + return df::scatter_reflect_transmit; + } +} + +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() +) [[ + anno::usage( "materialx:bsdf") +]] += material( + surface: material_surface( + scattering: df::weighted_layer( + weight: mxp_weight, + layer: df::diffuse_reflection_bsdf( + tint: mxp_color, + roughness: mxp_roughness + ), + normal: mxp_normal + ) + ) +); + +// NOTE: Approximate Burley with df::diffuse_reflection_bsdf, the difference isn't big +export material mx_burley_diffuse_bsdf( + float mxp_weight = 1.0, + color mxp_color = color(0.18), + float mxp_roughness = 0.0, + float3 mxp_normal = state::normal() +) [[ + anno::usage( "materialx:bsdf") +]] += material( + surface: material_surface( + scattering: df::weighted_layer( + weight: mxp_weight, + layer: df::diffuse_reflection_bsdf( + tint: mxp_color, + roughness: mxp_roughness + ), + normal: mxp_normal + ) + ) +); + +export material mx_translucent_bsdf( + float mxp_weight = 1.0, + color mxp_color = color(1.0), + float3 mxp_normal = state::normal() +) [[ + anno::usage( "materialx:bsdf") +]] += material( + surface: material_surface( + scattering: df::weighted_layer( + weight: mxp_weight, + layer: df::diffuse_transmission_bsdf( + tint: mxp_color + ), + normal: mxp_normal + ) + ) +); + +// 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") ]], + 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, + 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, + 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, + 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: mxp_base.ior, + volume: mxp_base.volume +); + +// TODO MDL 1.8 +// * thin_film(thickness: 0.0, ior: < 1.0) will be handled properly +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, + 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 + ) + ) +); + +// 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_generalized_schlick_bsdf( + float mxp_weight = 1.0, + color mxp_color0 = color(1.0), + 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") ]], + 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 avgF0 = math::average(float3(mxp_color0)); + bsdf ggx_model_R = df::microfacet_ggx_smith_bsdf( + roughness_u: mxp_roughness.x, + roughness_v: mxp_roughness.y, + tint: color(1.0), + 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), + tangent_u: mxp_tangent, + mode: df::scatter_transmit); +} in material( + surface: material_surface( + scattering: df::weighted_layer( + weight: mxp_weight, + layer: mxp_scatter_mode == mx_scatter_mode_T + ? df::color_custom_curve_layer( + normal_reflectivity: mxp_color0, + grazing_reflectivity: mxp_color90, + exponent: mxp_exponent, + layer: bsdf(), + base: ggx_model_T) + : df::thin_film( + thickness: mxp_thinfilm_thickness, + ior: color(coatIor), + base: df::color_custom_curve_layer( + normal_reflectivity: mxp_color0, + grazing_reflectivity: mxp_color90, + exponent: mxp_exponent, + layer: ggx_model_R, + base: mxp_scatter_mode == mx_scatter_mode_R + ? mxp_base.surface.scattering + : ggx_model_T)), + base: mxp_base.surface.scattering, + normal: mxp_normal + ) + ), + // we can't use the computed ior here because it's varying + // assuming that we have something glass like when transmission is used + ior: color(1.5), // color(mx_f0_to_ior(avgF0)) + + // we need to carry volume properties along for SSS + volume: mxp_base.volume +); + +export material mx_subsurface_bsdf( + float mxp_weight = 1.0 [[ anno::unused() ]], + color mxp_color = color(0.18), + float3 mxp_radius = float3(1.0), // TODO: should probably be a color in MTLX Spec + float mxp_anisotropy = 0.0, + float3 mxp_normal = state::normal() [[ anno::unused() ]] +) [[ + anno::usage( "materialx:bsdf") +]] += let { + // https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf + // Phase function eccentricity 'g' has been omitted here since we pass that directly + // to anisotropic_vdf(directional_bias: g). + color albedo = color(4.09712) + + (4.20863f * mxp_color) - + math::sqrt( + 9.59217f + + 41.6808f * mxp_color + + 17.7126f * mxp_color * mxp_color); + + color albedo_sq = albedo * albedo; + + color white = color(1.0, 1.0, 1.0); + + color alpha = + (white - albedo_sq) / (white - mxp_anisotropy * albedo_sq); + + color radius_inv = white/color(mxp_radius); + + color sigma_s = alpha * radius_inv; + color sigma_a = radius_inv - sigma_s; + +} in material( + volume: material_volume( + scattering: df::anisotropic_vdf ( + directional_bias: mxp_anisotropy + ), + scattering_coefficient: sigma_s, + absorption_coefficient: sigma_a + ), + + surface: material_surface( + scattering: df::diffuse_transmission_bsdf(tint: white) + ) +); + +// TODO: MDL's sheen BSDF has no possibility to configure the base BSDF, it is +// always a diffuse BSDF. Its color is configurable through the multiscatter +// tint and can be fed through the extra mxp_diffuse_tint input. A context +// analysis in the generator can map the color of the base to this input. +export material mx_sheen_bsdf( + float mxp_weight = 1.0, + color mxp_color = color(1.0), + float mxp_roughness = 0.2, + float3 mxp_normal = state::normal(), + material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]], + color mxp_diffuse_color = color(1.0) // color of the base layer, MDL supports only diffuse +) [[ + anno::usage( "materialx:bsdf") +]] += material( + surface: material_surface( + scattering: df::weighted_layer( + weight: mxp_weight, + layer: df::sheen_bsdf( + roughness: mxp_roughness, + tint: mxp_color, + multiscatter_tint: mxp_diffuse_color + ), + base: mxp_base.surface.scattering, + normal: mxp_normal + ) + ), + // we need to carry volume properties along for SSS + ior: mxp_base.ior, + volume: mxp_base.volume +); + +export material mx_thin_film_bsdf( + float mxp_thickness = 1000.0, + float mxp_ior = 1.5, + material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]] +) [[ + anno::usage( "materialx:bsdf") +]] += material( + surface: material_surface( + scattering: df::thin_film( + thickness: mxp_thickness, + ior: color(mxp_ior), + base: mxp_base.surface.scattering + ) + ), + // we need to carry volume properties along for SSS + ior: mxp_base.ior, + volume: mxp_base.volume +); + +// EDF Nodes + +export material mx_uniform_edf( + color mxp_color = color(1.0) +) [[ + anno::usage( "materialx:edf") +]] += material( + surface: material_surface( + emission: material_emission( emission: df::diffuse_edf(), intensity: mxp_color * math::PI) + ) +); + +export material mx_conical_edf( + color mxp_color = color(1.0), + float3 mxp_normal = state::normal() + [[ + anno::unused() + ]], + uniform float mxp_inner_angle = 60.0, + uniform float mxp_outer_angle = 0.0 +) [[ + anno::usage( "materialx:edf") +]] += material( + surface: material_surface( + emission: material_emission( + emission: df::spot_edf( // TODO: refine exact math of the mapping here + spread: math::radians( math::max(mxp_inner_angle, mxp_outer_angle)), + exponent: (mxp_outer_angle <= mxp_inner_angle) ? 0.0 : 1.0 + ), + intensity: mxp_color * math::PI + ) + ) +); + +export material mx_measured_edf( + color mxp_color = color(1.0), + float3 mxp_normal = state::normal() + [[ + anno::unused() + ]], + uniform light_profile mxp_file = light_profile() +) [[ + anno::usage( "materialx:edf") +]] += material( + surface: material_surface( + emission: material_emission( + emission: df::measured_edf( profile: mxp_file), + intensity: mxp_color * math::PI + ) + ) +); + +// no directional factor for EDFs in MDL 1.6 +export material mx_generalized_schlick_edf( + color mxp_color0 = color(1.0) [[anno::unused()]], + color mxp_color90 = color(1.0) [[anno::unused()]], + float mxp_exponent = 5.0 [[anno::unused()]], + material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]] +) [[ + anno::usage( "materialx:edf") +]] += material( + thin_walled: mxp_base.thin_walled, + surface: material_surface( + scattering: mxp_base.surface.scattering, + emission: mxp_base.surface.emission + ), + backface: mxp_base.backface, + ior: mxp_base.ior, + volume: mxp_base.volume, + geometry: mxp_base.geometry, + hair: mxp_base.hair +); + +// VDF Nodes + +export material mx_absorption_vdf( + // TODO: should probably become color3 in the MaterialX spec + float3 mxp_absorption = float3(0.0) +) [[ + anno::usage( "materialx:vdf") +]] += material( + volume: material_volume( + absorption_coefficient: color( mxp_absorption) + ) +); + +export material mx_anisotropic_vdf( + // TODO: should probably become color3 in the MaterialX spec + float3 mxp_absorption = float3(0.0), + // TODO: should probably become color3 in the MaterialX spec + float3 mxp_scattering = float3(0.0), + float mxp_anisotropy = 0.0 +) [[ + anno::usage( "materialx:vdf") +]] += material( + volume: material_volume( + scattering: df::anisotropic_vdf( directional_bias: mxp_anisotropy), + absorption_coefficient: color( mxp_absorption), + scattering_coefficient: color( mxp_scattering) + ) +); + +// 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 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: false, + 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 + ) +); + +export material mx_thin_surface( + material mxp_front_bsdf = material() [[ anno::usage( "materialx:bsdf") ]], + material mxp_front_edf = material() [[ anno::usage( "materialx:edf") ]], + material mxp_back_bsdf = material() [[ anno::usage( "materialx:bsdf") ]], + material mxp_back_edf = material() [[ anno::usage( "materialx:edf") ]], + float mxp_opacity = 1.0 +) [[ + anno::usage( "materialx:surfaceshader") +]] += let { + bsdf front_bsdf_node = mxp_front_bsdf.surface.scattering; + material_emission front_edf_node = mxp_front_edf.surface.emission; + bsdf back_bsdf_node = mxp_back_bsdf.surface.scattering; + material_emission back_edf_node = mxp_back_edf.surface.emission; + // we need to carry volume properties along for SSS + // TODO: clarify SSS behavior in MaterialX for thin-walled surfaces, + // in MDL there is only one volume property + material_volume bsdf_volume = mxp_front_bsdf.volume; +} in material( + thin_walled: true, + surface: material_surface( + scattering: front_bsdf_node, + emission: front_edf_node + ), + backface: material_surface( + scattering: back_bsdf_node, + emission: back_edf_node + ), + ior: color(1.0), + volume: bsdf_volume, + geometry: material_geometry( + cutout_opacity: mxp_opacity + ) +); + +// MDL 1.6, Volumes do not support emission. +export material mx_volume( + material mxp_vdf = material() [[ anno::usage( "materialx:vdf") ]], + material mxp_edf = material() [[ anno::usage( "materialx:edf"), anno::unused() ]] +) [[ + anno::usage( "materialx:volumeshader") +]] += material( + volume: material_volume( + absorption_coefficient: mxp_vdf.volume.absorption_coefficient, + scattering_coefficient: mxp_vdf.volume.scattering_coefficient + ) +); + +export material mx_light( + material mxp_edf = material() [[ anno::usage( "materialx:edf") ]], + color mxp_intensity = color(1.0), + float mxp_exposure = 0.0 +) [[ + anno::usage( "materialx:lightshader") +]] += let { + edf emission = mxp_edf.surface.emission.emission; + color intensity = mxp_edf.surface.emission.intensity; + color scale = (mxp_exposure == 0.0) + ? mxp_intensity + : mxp_intensity * math::pow(2, mxp_exposure); +} in material( + // TODO: check MTLX spec if we need emission on front- end backface + surface: material_surface( + emission: material_emission( + emission: emission, + intensity: intensity * scale + ) + ) +); + +// NOTE: MDL provides function overloading, but not material definition +// overlaoding. We thus try to use float3 as MDL type matching +// the MaterialX displacementshader and allow thus for an overloaded +// implementation of mxp_displacement. +// TODO: Check if this works in the translator and higher level nodes, like +// mxp_material, if not, we have to switch to the material type and +// use two different names for mxp_displacemnnt. +export material mx_displacement_float( + float mxp_displacement = 0.0, + float mxp_scale = 1.0 +) [[ + anno::usage( "materialx:displacementshader") +]] = material( + geometry: material_geometry( + displacement: mxp_displacement * mxp_scale * state::scene_units_per_meter() * state::normal() + ) +); + +export material mx_displacement_vector3( + float3 mxp_displacement = float3(0.0), + float mxp_scale = 1.0 +) [[ + anno::usage( "materialx:displacementshader") +]] = let +{ + float3 vec = (mxp_displacement.x * state::texture_tangent_u(0) + + mxp_displacement.y * state::texture_tangent_v(0) + + mxp_displacement.z * state::normal()); +} in material( + geometry: material_geometry( + displacement: vec * mxp_scale * state::scene_units_per_meter() + ) +); + + +// helper function to mix two scattering volumes: +// - combined scattering coefficient is just the sum of the two +// - VDF mixer weight is the relative probability of encountering the corresponding +// particle type +// NOTE: mixer weight should be a color, but due to a bug in current MDL compilers +// the color mixers don't accept non-uniform weights yet +export struct volume_mix_return { + color scattering_coefficient; + float mix_weight1; // mix_weight2 = 1.0 - mix_weight1, can use any mixer +}; +export volume_mix_return volume_mix( + color scattering_coefficient1, + float weight1, + color scattering_coefficient2, + float weight2) +{ + color s1 = weight1 * scattering_coefficient1; + color s = s1 + weight2 * scattering_coefficient2; + return volume_mix_return(scattering_coefficient: s, mix_weight1: math::average(s1 / s)); +} + +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: mxp_fg.ior, // NOTE: IOR is uniform, cannot mix here + 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 + ) +); + +// NOTE: mixing two EDFs fails with the df::clamped_mix since the weights are uniform in MDL 1.6 +export material mx_mix_edf( + material mxp_fg = material() [[ anno::usage( "materialx:edf") ]], + material mxp_bg = material() [[ anno::usage( "materialx:edf") ]], + float mxp_mix = 0.0 +) [[ + anno::usage( "materialx:edf") +]] += let { + float mix = math::saturate(mxp_mix); +} in material( + surface: material_surface( + emission: material_emission( + emission: mxp_fg.surface.emission.emission, + intensity: mix * mxp_fg.surface.emission.intensity + + (1.0 - mix) * mxp_bg.surface.emission.intensity + ) + ) +); + +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: mxp_fg.ior, // NOTE: IOR is uniform, cannot mix here + 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 + ) +); + +// NOTE: Adding two BSDFs is not supported in MDL, the generator would best +// analyze the context for mixing weights and replace the add with a mix. +// The provided implementation just mixes the BSDFs with equal weight. +export material mx_add_bsdf( + material mxp_in1 = material() [[ anno::usage( "materialx:bsdf") ]], + material mxp_in2 = material() [[ anno::usage( "materialx:bsdf") ]] +) [[ + anno::usage( "materialx:bsdf") +]] += let { + volume_mix_return v = volume_mix( + mxp_in1.volume.scattering_coefficient, 1.0f, + mxp_in2.volume.scattering_coefficient, 1.0f); +} in material( + surface: material_surface( + scattering: df::clamped_mix( + df::bsdf_component[]( + df::bsdf_component( 0.5, mxp_in1.surface.scattering), + df::bsdf_component( 0.5, mxp_in2.surface.scattering) + ) + ) + ), + // we need to carry volume properties along for SSS + volume: material_volume( + scattering: df::clamped_mix( + df::vdf_component[]( + df::vdf_component( v.mix_weight1, mxp_in1.volume.scattering), + df::vdf_component( 1.0 - v.mix_weight1, mxp_in2.volume.scattering)) + ), + absorption_coefficient: mxp_in1.volume.absorption_coefficient + + mxp_in2.volume.absorption_coefficient, + scattering_coefficient: v.scattering_coefficient + ) +); + +// NOTE: Adding two EDFs is not supported in MDL, the generator would best +// analyze the context for mixing weights and replace the add with a mix. +// The provided implementation just mixes the EDFs with equal weight +// and adds the intensities. +export material mx_add_edf( + material mxp_in1 = material() [[ anno::usage( "materialx:edf") ]], + material mxp_in2 = material() [[ anno::usage( "materialx:edf") ]] +) [[ + anno::usage( "materialx:edf") +]] += material( + surface: material_surface( + emission: material_emission( + emission: df::clamped_mix( + df::edf_component[]( + df::edf_component( 0.5, mxp_in1.surface.emission.emission), + df::edf_component( 0.5, mxp_in2.surface.emission.emission)) + ), + intensity: mxp_in1.surface.emission.intensity + mxp_in2.surface.emission.intensity + ) + ) +); + +// NOTE: Adding two VDFs is not supported in MDL, the generator would best +// analyze the context for mixing weights and replace the add with a mix. +// The provided implementation just mixes the VDFs with equal weight. +export material mx_add_vdf( + material mxp_in1 = material() [[ anno::usage( "materialx:vdf") ]], + material mxp_in2 = material() [[ anno::usage( "materialx:vdf") ]] +) [[ + anno::usage( "materialx:vdf") +]] += let { + volume_mix_return v = volume_mix( + mxp_in1.volume.scattering_coefficient, 1.0f, + mxp_in2.volume.scattering_coefficient, 1.0f); +} in material( + // assuming mixing the IOR is the best we can do here + ior: 0.5 * mxp_in1.ior + 0.5 * mxp_in2.ior, + volume: material_volume( + scattering: df::clamped_mix( + df::vdf_component[]( + df::vdf_component( v.mix_weight1, mxp_in1.volume.scattering), + df::vdf_component( 1.0 - v.mix_weight1, mxp_in2.volume.scattering)) + ), + absorption_coefficient: mxp_in1.volume.absorption_coefficient + + mxp_in2.volume.absorption_coefficient, + scattering_coefficient: v.scattering_coefficient + ) +); + +export material mx_multiply_bsdf_color3( + material mxp_in1 = material() [[ anno::usage( "materialx:bsdf") ]], + color mxp_in2 = color(1.0) +) [[ + anno::usage( "materialx:bsdf") +]] += material( + surface: material_surface( + scattering: df::tint( + tint: mxp_in2, + base: mxp_in1.surface.scattering + ) + ), + // we need to carry volume properties along for SSS + ior: mxp_in1.ior, + volume: mxp_in1.volume +); + +export material mx_multiply_bsdf_float( + material mxp_in1 = material() [[ anno::usage( "materialx:bsdf") ]], + float mxp_in2 = 1.0 +) [[ + anno::usage( "materialx:bsdf") +]] += material( + surface: material_surface( + scattering: df::tint( + tint: color(mxp_in2), + base: mxp_in1.surface.scattering + ) + ), + // we need to carry volume properties along for SSS + ior: mxp_in1.ior, + volume: mxp_in1.volume +); + +export material mx_multiply_edf_color3( + material mxp_in1 = material() [[ anno::usage( "materialx:edf") ]], + color mxp_in2 = color(1.0) +) [[ + anno::usage( "materialx:edf") +]] += material( + surface: material_surface( + emission: material_emission( + emission: mxp_in1.surface.emission.emission, + intensity: mxp_in2 * mxp_in1.surface.emission.intensity + ) + ) +); + +export material mx_multiply_edf_float( + material mxp_in1 = material() [[ anno::usage( "materialx:edf") ]], + float mxp_in2 = 1.0 +) [[ + anno::usage( "materialx:edf") +]] += material( + surface: material_surface( + emission: material_emission( + emission: mxp_in1.surface.emission.emission, + intensity: mxp_in2 * mxp_in1.surface.emission.intensity + ) + ) +); + +export material mx_multiply_vdf_color3( + material mxp_in1 = material() [[ anno::usage( "materialx:vdf") ]], + color mxp_in2 = color(1.0) +) [[ + anno::usage( "materialx:vdf") +]] += material( + ior: mxp_in1.ior, + volume: material_volume( + scattering: mxp_in1.volume.scattering, + absorption_coefficient: color(1.0) + - mxp_in2 * (color(1.0) - mxp_in1.volume.absorption_coefficient), + scattering_coefficient: mxp_in2 * mxp_in1.volume.scattering_coefficient + ) +); + +export material mx_multiply_vdf_float( + material mxp_in1 = material() [[ anno::usage( "materialx:vdf") ]], + float mxp_in2 = 1.0 +) [[ + anno::usage( "materialx:vdf") +]] += material( + ior: mxp_in1.ior, + volume: material_volume( + scattering: mxp_in1.volume.scattering, + absorption_coefficient: color(1.0) + - mxp_in2 * (color(1.0) - mxp_in1.volume.absorption_coefficient), + scattering_coefficient: mxp_in2 * mxp_in1.volume.scattering_coefficient + ) +); + +export float2 mx_roughness_anisotropy( + float mxp_roughness = 0.0, + float mxp_anisotropy = 0.0 +) { + float roughness_sqr = math::clamp(mxp_roughness*mxp_roughness, core::FLOAT_EPS, 1.0); + if (mxp_anisotropy > 0.0) + { + float aspect = math::sqrt(1.0 - math::clamp(mxp_anisotropy, 0.0, 0.98)); + return float2( + math::min(roughness_sqr / aspect, 1.0), + roughness_sqr * aspect); + } + return float2(roughness_sqr); +} + +export float2 mx_roughness_dual( + float2 mxp_roughness = float2(0.0) +) { + if (mxp_roughness.y < 0.0) + mxp_roughness.y = mxp_roughness.x; + return float2( + math::clamp(mxp_roughness.x * mxp_roughness.x, core::FLOAT_EPS, 1.0), + math::clamp(mxp_roughness.y * mxp_roughness.y, core::FLOAT_EPS, 1.0)); +} + +export color mx_blackbody( + float mxp_temperature = 5000 +) { + return math::blackbody( mxp_temperature); +} + +// Supportive struct type for the two outputs of mx_artistic_ior +export struct mx_artistic_ior__result { + color mxp_ior; + color mxp_extinction; +}; + +// Converts the artistic parameterization reflectivity and edgecolor +// to complex IOR values; this is the inverse of the ​complex_ior​ node. +export mx_artistic_ior__result mx_artistic_ior( + color mxp_reflectivity = color(0.947, 0.776, 0.371), + color mxp_edge_color = color(1.0, 0.982, 0.753) +) { + color r = math::clamp( mxp_reflectivity, color(0.0), color(0.99)); + color r_sqrt = math::sqrt(r); + color n_min = (1.0 - r) / (1.0 + r); + color n_max = (1.0 + r_sqrt) / (1.0 - r_sqrt); + color n = math::lerp(n_max, n_min, mxp_edge_color); + color np1 = n + 1.0; + color nm1 = n - 1.0; + color k2 = (np1*np1 * r - nm1*nm1) / (1.0 - r); + k2 = math::max(k2, 0.0); + color k = math::sqrt(k2); + return mx_artistic_ior__result(n,k); +} diff --git a/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_7.mdl b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_7.mdl new file mode 100644 index 0000000000..e7e5526c01 --- /dev/null +++ b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_7.mdl @@ -0,0 +1,259 @@ +/* + * 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 v1.37 REV2, July 16, 2019 (Revised October 17, 2019) +// see www.materialx.org +// in +// NVIDIA Material Definition Language 1.7 +// Language Specification +// Document version 1.7.2, January 17, 2022 +// www.nvidia.com/mdl + +mdl 1.7; + +// Changes since MDL 1.6 +// - Support for unbounded_mix to implement add_bsdf, add_edf, and add_vdf +// - Support for df::sheen_bsdf with a custom base BSDF +// - Support for df::directional_factor on EDFs to implement generalized_schlick_edf +// - Support for emission on VDFs + +import ::anno::*; +import ::df::*; +import ::math::*; +import ::state::*; + +// forward all unchanged definitions from the previous version +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_dielectric_bsdf; +export using .::pbrlib_1_6 import mx_conductor_bsdf; +export using .::pbrlib_1_6 import mx_generalized_schlick_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_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_surface; +export using .::pbrlib_1_6 import mx_thin_surface; +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_mix_bsdf; +export using .::pbrlib_1_6 import mx_mix_vdf; +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; + + + +// To match with OSL, the sheen weight is scaled with average color as approximation of albedo. +// OSL uses the layer operator which mixes based on albedo. +export material mx_sheen_bsdf( + float mxp_weight = 1.0, + color mxp_color = color(1.0), + float mxp_roughness = 0.2, + float3 mxp_normal = state::normal(), + material mxp_base = material( + surface: material_surface( + scattering: df::diffuse_reflection_bsdf( + ))) [[ anno::usage( "materialx:bsdf") ]] +) [[ + anno::usage( "materialx:bsdf") +]] += material( + surface: material_surface( + // using the mix seems to fit OSL best, at least in the test cases + scattering: df::weighted_layer( + weight: math::average(mxp_color) * mxp_weight, + layer: df::sheen_bsdf( + roughness: mxp_roughness, + tint: mxp_color, + multiscatter_tint: color(1.0), + multiscatter: mxp_base.surface.scattering + ), + base: mxp_base.surface.scattering, + normal: mxp_normal)), + // we need to carry volume properties along for SSS + ior: mxp_base.ior, + volume: mxp_base.volume +); + + +// NOTE: Adding two BSDFs is not supported in MDL, the generator would best +// analyze the context for mixing weights and replace the add with a mix. +// The provided implementation just mixes the BSDFs with equal weight. +export material mx_add_bsdf( + material mxp_in1 = material() [[ anno::usage( "materialx:bsdf") ]], + material mxp_in2 = material() [[ anno::usage( "materialx:bsdf") ]] +) [[ + anno::usage( "materialx:bsdf") +]] += let { + volume_mix_return v = volume_mix( + mxp_in1.volume.scattering_coefficient, 1.0f, + mxp_in2.volume.scattering_coefficient, 1.0f); +} in material( + surface: material_surface( + scattering: df::unbounded_mix( + df::bsdf_component[]( + df::bsdf_component( 1.0, mxp_in1.surface.scattering), + df::bsdf_component( 1.0, mxp_in2.surface.scattering) + ) + ) + ), + // we need to carry volume properties along for SSS + volume: material_volume( + scattering: df::unbounded_mix( + df::vdf_component[]( + df::vdf_component( v.mix_weight1, mxp_in1.volume.scattering), + df::vdf_component( 1.0 - v.mix_weight1, mxp_in2.volume.scattering)) + ), + absorption_coefficient: mxp_in1.volume.absorption_coefficient + + mxp_in2.volume.absorption_coefficient, + scattering_coefficient: v.scattering_coefficient + ) +); + +// NOTE: Adding two EDFs is not supported in MDL, the generator would best +// analyze the context for mixing weights and replace the add with a mix. +// The provided implementation just mixes the EDFs with equal weight +// and adds the intensities. +export material mx_add_edf( + material mxp_in1 = material() [[ anno::usage( "materialx:edf") ]], + material mxp_in2 = material() [[ anno::usage( "materialx:edf") ]] +) [[ + anno::usage( "materialx:edf") +]] += material( + surface: material_surface( + emission: material_emission( + emission: df::unbounded_mix( + df::edf_component[]( + df::edf_component( 1.0, mxp_in1.surface.emission.emission), + df::edf_component( 1.0, mxp_in2.surface.emission.emission)) + ), + intensity: mxp_in1.surface.emission.intensity + mxp_in2.surface.emission.intensity + ) + ) +); + +export material mx_mix_edf( + material mxp_fg = material() [[ anno::usage( "materialx:edf") ]], + material mxp_bg = material() [[ anno::usage( "materialx:edf") ]], + float mxp_mix = 0.0 +) [[ + anno::usage( "materialx:edf") +]] += let { + float mix = math::saturate(mxp_mix); +} in material( + surface: material_surface( + emission: material_emission( + emission: df::unbounded_mix( + df::edf_component[]( + df::edf_component( mix, mxp_fg.surface.emission.emission), + df::edf_component( 1.0 - mix, mxp_bg.surface.emission.emission)) + ), + intensity: mix * mxp_fg.surface.emission.intensity + + (1.0 - mix) * mxp_bg.surface.emission.intensity + ) + ) +); + +// NOTE: Adding two VDFs is not supported in MDL, the generator would best +// analyze the context for mixing weights and replace the add with a mix. +// The provided implementation just mixes the VDFs with equal weight. +export material mx_add_vdf( + material mxp_in1 = material() [[ anno::usage( "materialx:vdf") ]], + material mxp_in2 = material() [[ anno::usage( "materialx:vdf") ]] +) [[ + anno::usage( "materialx:vdf") +]] += let { + volume_mix_return v = volume_mix( + mxp_in1.volume.scattering_coefficient, 1.0f, + mxp_in2.volume.scattering_coefficient, 1.0f); +} in material( + // assuming mixing the IOR is the best we can do here + ior: 0.5 * mxp_in1.ior + 0.5 * mxp_in2.ior, + volume: material_volume( + scattering: df::unbounded_mix( + df::vdf_component[]( + df::vdf_component( v.mix_weight1, mxp_in1.volume.scattering), + df::vdf_component( 1.0 - v.mix_weight1, mxp_in2.volume.scattering)) + ), + absorption_coefficient: mxp_in1.volume.absorption_coefficient + + mxp_in2.volume.absorption_coefficient, + scattering_coefficient: v.scattering_coefficient + ) +); + +export material mx_generalized_schlick_edf( + color mxp_color0 = color(1.0), + color mxp_color90 = color(1.0), + float mxp_exponent = 5.0, + material mxp_base = material() [[ anno::usage( "materialx:bsdf") ]] +) [[ + anno::usage( "materialx:edf") +]] += material( + thin_walled: mxp_base.thin_walled, + surface: material_surface( + scattering: mxp_base.surface.scattering, + emission: material_emission( + emission: df::directional_factor(mxp_color0, mxp_color90, mxp_exponent, mxp_base.surface.emission.emission), + intensity: mxp_base.surface.emission.intensity, + mode: mxp_base.surface.emission.mode) + ), + backface: mxp_base.backface, + ior: mxp_base.ior, + volume: mxp_base.volume, + geometry: mxp_base.geometry, + hair: mxp_base.hair +); + +// MDL 1.7, Volumes do support emission, but not as EDF, just emission intensity. +// A uniform emission DF is the only practical DF here. +export material mx_volume( + material mxp_vdf = material() [[ anno::usage( "materialx:vdf") ]], + material mxp_edf = material() [[ anno::usage( "materialx:edf") ]] +) [[ + anno::usage( "materialx:volumeshader") +]] += material( + volume: material_volume( + absorption_coefficient: mxp_vdf.volume.absorption_coefficient, + scattering_coefficient: mxp_vdf.volume.scattering_coefficient, + emission_intensity: mxp_edf.surface.emission.intensity + ) +); diff --git a/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_8.mdl b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_8.mdl new file mode 100644 index 0000000000..fb77e4829b --- /dev/null +++ b/source/MaterialXGenMdl/mdl/materialx/pbrlib_1_8.mdl @@ -0,0 +1,36 @@ +/* + * 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 v1.37 REV2, July 16, 2019 (Revised October 17, 2019) +// see www.materialx.org +// in +// NVIDIA Material Definition Language 1.8 +// Language Specification +// Document version 1.8.2, May 24, 2023 +// www.nvidia.com/mdl + +mdl 1.8; + +// Changes since MDL 1.7 +// - Support thin-film on custom curve layer to improve generalized_schlick_bsdf, +// no new implementation required + +// forward all unchanged definitions from the previous version +export using .::pbrlib_1_7 import *; + +// without changing any source code diff --git a/source/MaterialXGenMdl/mdl/materialx/sampling.mdl b/source/MaterialXGenMdl/mdl/materialx/sampling.mdl index 89142f8c51..1809503653 100644 --- a/source/MaterialXGenMdl/mdl/materialx/sampling.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/sampling.mdl @@ -5,10 +5,9 @@ mdl 1.6; -import::math::*; +import ::math::*; -using mx = materialx; -using ::mx::core import *; +import .::core::*; // Restrict to 7x7 kernel size for performance reasons export const int MX_MAX_SAMPLE_COUNT = 49; @@ -171,12 +170,12 @@ export color mx_convolution_color(color[MX_MAX_SAMPLE_COUNT] S, float[MX_WEIGHT_ return result; } -export color4 mx_convolution_color4(color4[MX_MAX_SAMPLE_COUNT] S, float[MX_WEIGHT_ARRAY_SIZE] W, int offset, int sampleCount) +export core::color4 mx_convolution_color4(core::color4[MX_MAX_SAMPLE_COUNT] S, float[MX_WEIGHT_ARRAY_SIZE] W, int offset, int sampleCount) { - color4 result = mk_color4(0.0, 0.0, 0.0, 0.0); + core::color4 result = core::mk_color4(0.0, 0.0, 0.0, 0.0); for (int i=0; i 1.0)) - return mxp_default; - if ( mxp_vaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) - return mxp_default; - - float returnValue = ::tex::lookup_float(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, - wrap_u: map_addressmode(mxp_uaddressmode), - wrap_v: map_addressmode(mxp_vaddressmode)); - return returnValue; -} - -export color mx_image_color3( - uniform texture_2d mxp_file = texture_2d() - [[ - anno::display_name("Filename") - ]], - uniform string mxp_layer = string("") - [[ - anno::display_name("Layer"), anno::unused() - ]], - color mxp_default = color(0.0, 0.0, 0.0) - [[ - anno::display_name("Default Color") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) - [[ - anno::display_name("Texture Coordinates") - ]], - uniform mx_addressmode_type mxp_uaddressmode = mx_addressmode_type(mx_addressmode_type_periodic) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Address Mode U") - ]], - uniform mx_addressmode_type mxp_vaddressmode = mx_addressmode_type(mx_addressmode_type_periodic) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Address Mode V") - ]], - uniform mx_filterlookup_type mxp_filtertype = mx_filterlookup_type(mx_filterlookup_type_linear) - [[ - anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() - ]], - uniform string mxp_framerange = string("") - [[ - anno::display_name("Frame Range"), - anno::unused() - ]], - uniform int mxp_frameoffset = int(0) - [[ - anno::display_name("Frame Offset"), - anno::unused() - ]], - uniform mx_addressmode_type mxp_frameendaction = mx_addressmode_type(mx_addressmode_type_constant) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Frame End Action"), - anno::unused() - ]], - uniform bool mxp_flip_v = false - [[ - anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), - anno::hidden() - ]] -) - [[ - anno::description("Node Group: texture2d") - ]] -{ - if ( mxp_uaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) - return mxp_default; - if ( mxp_vaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) - return mxp_default; - - color returnValue = ::tex::lookup_color(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, - wrap_u: map_addressmode(mxp_uaddressmode), - wrap_v: map_addressmode(mxp_vaddressmode)); - return returnValue; -} - -export color4 mx_image_color4( - uniform texture_2d mxp_file = texture_2d() - [[ - anno::display_name("Filename") - ]], - uniform string mxp_layer = string("") - [[ - anno::display_name("Layer"), anno::unused() - ]], - color4 mxp_default = mk_color4(0.0, 0.0, 0.0, 0.0) - [[ - anno::display_name("Default Color") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) - [[ - anno::display_name("Texture Coordinates") - ]], - uniform mx_addressmode_type mxp_uaddressmode = mx_addressmode_type(mx_addressmode_type_periodic) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Address Mode U") - ]], - uniform mx_addressmode_type mxp_vaddressmode = mx_addressmode_type(mx_addressmode_type_periodic) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Address Mode V") - ]], - uniform mx_filterlookup_type mxp_filtertype = mx_filterlookup_type(mx_filterlookup_type_linear) - [[ - anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() - ]], - uniform string mxp_framerange = string("") - [[ - anno::display_name("Frame Range"), - anno::unused() - ]], - uniform int mxp_frameoffset = int(0) - [[ - anno::display_name("Frame Offset"), - anno::unused() - ]], - uniform mx_addressmode_type mxp_frameendaction = mx_addressmode_type(mx_addressmode_type_constant) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Frame End Action"), - anno::unused() - ]], - uniform bool mxp_flip_v = false - [[ - anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), - anno::hidden() - ]] -) - [[ - anno::description("Node Group: texture2d") - ]] -{ - if ( mxp_uaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) - return mxp_default; - if ( mxp_vaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) - return mxp_default; - - color4 returnValue = mk_color4( ::tex::lookup_float4(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, - wrap_u: map_addressmode(mxp_uaddressmode), - wrap_v: map_addressmode(mxp_vaddressmode))); - return returnValue; -} - -export float2 mx_image_vector2( - uniform texture_2d mxp_file = texture_2d() - [[ - anno::display_name("Filename") - ]], - uniform string mxp_layer = string("") - [[ - anno::display_name("Layer"), anno::unused() - ]], - float2 mxp_default = float2(0.0, 0.0) - [[ - anno::display_name("Default Color") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) - [[ - anno::display_name("Texture Coordinates") - ]], - uniform mx_addressmode_type mxp_uaddressmode = mx_addressmode_type(mx_addressmode_type_periodic) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Address Mode U") - ]], - uniform mx_addressmode_type mxp_vaddressmode = mx_addressmode_type(mx_addressmode_type_periodic) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Address Mode V") - ]], - uniform mx_filterlookup_type mxp_filtertype = mx_filterlookup_type(mx_filterlookup_type_linear) - [[ - anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() - ]], - uniform string mxp_framerange = string("") - [[ - anno::display_name("Frame Range"), - anno::unused() - ]], - uniform int mxp_frameoffset = int(0) - [[ - anno::display_name("Frame Offset"), - anno::unused() - ]], - uniform mx_addressmode_type mxp_frameendaction = mx_addressmode_type(mx_addressmode_type_constant) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Frame End Action"), - anno::unused() - ]], - uniform bool mxp_flip_v = false - [[ - anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), - anno::hidden() - ]] -) - [[ - anno::description("Node Group: texture2d") - ]] -{ - if ( mxp_uaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) - return mxp_default; - if ( mxp_vaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) - return mxp_default; - - float2 returnValue = ::tex::lookup_float2(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, - wrap_u: map_addressmode(mxp_uaddressmode), - wrap_v: map_addressmode(mxp_vaddressmode)); - return returnValue; -} - -export float3 mx_image_vector3( - uniform texture_2d mxp_file = texture_2d() - [[ - anno::display_name("Filename") - ]], - uniform string mxp_layer = string("") - [[ - anno::display_name("Layer"), anno::unused() - ]], - float3 mxp_default = float3(0.0, 0.0, 0.0) - [[ - anno::display_name("Default Color") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) - [[ - anno::display_name("Texture Coordinates") - ]], - uniform mx_addressmode_type mxp_uaddressmode = mx_addressmode_type(mx_addressmode_type_periodic) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Address Mode U") - ]], - uniform mx_addressmode_type mxp_vaddressmode = mx_addressmode_type(mx_addressmode_type_periodic) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Address Mode V") - ]], - uniform mx_filterlookup_type mxp_filtertype = mx_filterlookup_type(mx_filterlookup_type_linear) - [[ - anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() - ]], - uniform string mxp_framerange = string("") - [[ - anno::display_name("Frame Range"), - anno::unused() - ]], - uniform int mxp_frameoffset = int(0) - [[ - anno::display_name("Frame Offset"), - anno::unused() - ]], - uniform mx_addressmode_type mxp_frameendaction = mx_addressmode_type(mx_addressmode_type_constant) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Frame End Action"), - anno::unused() - ]], - uniform bool mxp_flip_v = false - [[ - anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), - anno::hidden() - ]] -) - [[ - anno::description("Node Group: texture2d") - ]] -{ - if ( mxp_uaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) - return mxp_default; - if ( mxp_vaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) - return mxp_default; - - float3 returnValue = ::tex::lookup_float3(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, - wrap_u: map_addressmode(mxp_uaddressmode), - wrap_v: map_addressmode(mxp_vaddressmode)); - return returnValue; -} - -export float4 mx_image_vector4( - uniform texture_2d mxp_file = texture_2d() - [[ - anno::display_name("Filename") - ]], - uniform string mxp_layer = string("") - [[ - anno::display_name("Layer"), anno::unused() - ]], - float4 mxp_default = float4(0.0, 0.0, 0.0, 0.0) - [[ - anno::display_name("Default Color") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) - [[ - anno::display_name("Texture Coordinates") - ]], - uniform mx_addressmode_type mxp_uaddressmode = mx_addressmode_type(mx_addressmode_type_periodic) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Address Mode U") - ]], - uniform mx_addressmode_type mxp_vaddressmode = mx_addressmode_type(mx_addressmode_type_periodic) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Address Mode V") - ]], - uniform mx_filterlookup_type mxp_filtertype = mx_filterlookup_type(mx_filterlookup_type_linear) - [[ - anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() - ]], - uniform string mxp_framerange = string("") - [[ - anno::display_name("Frame Range"), - anno::unused() - ]], - uniform int mxp_frameoffset = int(0) - [[ - anno::display_name("Frame Offset"), - anno::unused() - ]], - uniform mx_addressmode_type mxp_frameendaction = mx_addressmode_type(mx_addressmode_type_constant) - [[ - anno::description("Enumeration {constant,clamp,periodic,mirror}."), - anno::display_name("Frame End Action"), - anno::unused() - ]], - uniform bool mxp_flip_v = false - [[ - anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), - anno::hidden() - ]] -) - [[ - anno::description("Node Group: texture2d") - ]] -{ - if ( mxp_uaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) - return mxp_default; - if ( mxp_vaddressmode == mx_addressmode_type_constant - && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) - return mxp_default; - - float4 returnValue = ::tex::lookup_float4(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, - wrap_u: map_addressmode(mxp_uaddressmode), - wrap_v: map_addressmode(mxp_vaddressmode)); - return returnValue; -} - -// Nodedef: ND_tiledimage_float is represented by a nodegraph: NG_tiledimage_float -// Nodedef: ND_tiledimage_color3 is represented by a nodegraph: NG_tiledimage_color3 -// Nodedef: ND_tiledimage_color4 is represented by a nodegraph: NG_tiledimage_color4 -// Nodedef: ND_tiledimage_vector2 is represented by a nodegraph: NG_tiledimage_vector2 -// Nodedef: ND_tiledimage_vector3 is represented by a nodegraph: NG_tiledimage_vector3 -// Nodedef: ND_tiledimage_vector4 is represented by a nodegraph: NG_tiledimage_vector4 -// Nodedef: ND_triplanarprojection_float is represented by a nodegraph: NG_triplanarprojection_float -// Nodedef: ND_triplanarprojection_color3 is represented by a nodegraph: NG_triplanarprojection_color3 -// Nodedef: ND_triplanarprojection_color4 is represented by a nodegraph: NG_triplanarprojection_color4 -// Nodedef: ND_triplanarprojection_vector2 is represented by a nodegraph: NG_triplanarprojection_vector2 -// Nodedef: ND_triplanarprojection_vector3 is represented by a nodegraph: NG_triplanarprojection_vector3 -// Nodedef: ND_triplanarprojection_vector4 is represented by a nodegraph: NG_triplanarprojection_vector4 - -export float mx_constant_float( - float mxp_value = float(0.0) -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export color mx_constant_color3( - color mxp_value = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export color4 mx_constant_color4( - color4 mxp_value = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export float2 mx_constant_vector2( - float2 mxp_value = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export float3 mx_constant_vector3( - float3 mxp_value = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export float4 mx_constant_vector4( - float4 mxp_value = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export bool mx_constant_boolean( - bool mxp_value = bool(false) -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export int mx_constant_integer( - int mxp_value = int(0) -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export float3x3 mx_constant_matrix33( - float3x3 mxp_value = float3x3(1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0) -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export float4x4 mx_constant_matrix44( - float4x4 mxp_value = float4x4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export string mx_constant_string( - uniform string mxp_value = string("") -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export string mx_constant_filename( - uniform string mxp_value = string("") -) - [[ - anno::description("Node Group: procedural") - ]] -{ - return mxp_value; -} - -export float mx_ramplr_float( - float mxp_valuel = float(0.0), - float mxp_valuer = float(0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuel, mxp_valuer, math::clamp(mxp_texcoord.x, 0.0, 1.0)); -} - -export color mx_ramplr_color3( - color mxp_valuel = color(0.0, 0.0, 0.0), - color mxp_valuer = color(0.0, 0.0, 0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuel, mxp_valuer, math::clamp(mxp_texcoord.x, 0.0, 1.0)); -} - -export color4 mx_ramplr_color4( - color4 mxp_valuel = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_valuer = mk_color4(0.0, 0.0, 0.0, 0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - color rgb = math::lerp(mxp_valuel.rgb, mxp_valuer.rgb, math::clamp(mxp_texcoord.x, 0.0, 1.0)); - float a = math::lerp(mxp_valuel.a, mxp_valuer.a, math::clamp(mxp_texcoord.x, 0.0, 1.0)); - return color4(rgb, a);} - -export float2 mx_ramplr_vector2( - float2 mxp_valuel = float2(0.0, 0.0), - float2 mxp_valuer = float2(0.0, 0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuel, mxp_valuer, math::clamp(mxp_texcoord.x, 0.0, 1.0)); -} - -export float3 mx_ramplr_vector3( - float3 mxp_valuel = float3(0.0, 0.0, 0.0), - float3 mxp_valuer = float3(0.0, 0.0, 0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuel, mxp_valuer, math::clamp(mxp_texcoord.x, 0.0, 1.0)); -} - -export float4 mx_ramplr_vector4( - float4 mxp_valuel = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_valuer = float4(0.0, 0.0, 0.0, 0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuel, mxp_valuer, math::clamp(mxp_texcoord.x, 0.0, 1.0)); -} - -export float mx_ramptb_float( - float mxp_valuet = float(0.0), - float mxp_valueb = float(0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuet, mxp_valueb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); -} - -export color mx_ramptb_color3( - color mxp_valuet = color(0.0, 0.0, 0.0), - color mxp_valueb = color(0.0, 0.0, 0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuet, mxp_valueb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); -} - -export color4 mx_ramptb_color4( - color4 mxp_valuet = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_valueb = mk_color4(0.0, 0.0, 0.0, 0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - color rgb = math::lerp(mxp_valuet.rgb, mxp_valueb.rgb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); - float a = math::lerp(mxp_valuet.a, mxp_valueb.a, math::clamp(mxp_texcoord.y, 0.0, 1.0)); - return color4(rgb, a);} - -export float2 mx_ramptb_vector2( - float2 mxp_valuet = float2(0.0, 0.0), - float2 mxp_valueb = float2(0.0, 0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuet, mxp_valueb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); -} - -export float3 mx_ramptb_vector3( - float3 mxp_valuet = float3(0.0, 0.0, 0.0), - float3 mxp_valueb = float3(0.0, 0.0, 0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuet, mxp_valueb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); -} - -export float4 mx_ramptb_vector4( - float4 mxp_valuet = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_valueb = float4(0.0, 0.0, 0.0, 0.0), - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuet, mxp_valueb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); -} - -// Nodedef: ND_ramp4_float is represented by a nodegraph: NG_ramp4_float -// Nodedef: ND_ramp4_color3 is represented by a nodegraph: NG_ramp4_color3 -// Nodedef: ND_ramp4_color4 is represented by a nodegraph: NG_ramp4_color4 -// Nodedef: ND_ramp4_vector2 is represented by a nodegraph: NG_ramp4_vector2 -// Nodedef: ND_ramp4_vector3 is represented by a nodegraph: NG_ramp4_vector3 -// Nodedef: ND_ramp4_vector4 is represented by a nodegraph: NG_ramp4_vector4 - -export float mx_splitlr_float( - float mxp_valuel = float(0.0) - [[ - anno::display_name("Left") - ]], - float mxp_valuer = float(0.0) - [[ - anno::display_name("Right") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuel, mxp_valuer, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); -} - -export color mx_splitlr_color3( - color mxp_valuel = color(0.0, 0.0, 0.0) - [[ - anno::display_name("Left") - ]], - color mxp_valuer = color(0.0, 0.0, 0.0) - [[ - anno::display_name("Right") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuel, mxp_valuer, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); -} - -export color4 mx_splitlr_color4( - color4 mxp_valuel = mk_color4(0.0, 0.0, 0.0, 0.0) - [[ - anno::display_name("Left") - ]], - color4 mxp_valuer = mk_color4(0.0, 0.0, 0.0, 0.0) - [[ - anno::display_name("Right") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - color rgb = math::lerp(mxp_valuel.rgb, mxp_valuer.rgb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); - float a = math::lerp(mxp_valuel.a, mxp_valuer.a, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); - return color4(rgb, a); -} - -export float2 mx_splitlr_vector2( - float2 mxp_valuel = float2(0.0, 0.0) - [[ - anno::display_name("Left") - ]], - float2 mxp_valuer = float2(0.0, 0.0) - [[ - anno::display_name("Right") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuel, mxp_valuer, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); -} - -export float3 mx_splitlr_vector3( - float3 mxp_valuel = float3(0.0, 0.0, 0.0) - [[ - anno::display_name("Left") - ]], - float3 mxp_valuer = float3(0.0, 0.0, 0.0) - [[ - anno::display_name("Right") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuel, mxp_valuer, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); -} - -export float4 mx_splitlr_vector4( - float4 mxp_valuel = float4(0.0, 0.0, 0.0, 0.0) - [[ - anno::display_name("Left") - ]], - float4 mxp_valuer = float4(0.0, 0.0, 0.0, 0.0) - [[ - anno::display_name("Right") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuel, mxp_valuer, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); -} - -export float mx_splittb_float( - float mxp_valuet = float(0.0) - [[ - anno::display_name("Top") - ]], - float mxp_valueb = float(0.0) - [[ - anno::display_name("Bottom") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuet, mxp_valueb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); -} - -export color mx_splittb_color3( - color mxp_valuet = color(0.0, 0.0, 0.0) - [[ - anno::display_name("Top") - ]], - color mxp_valueb = color(0.0, 0.0, 0.0) - [[ - anno::display_name("Bottom") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuet, mxp_valueb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); -} - -export color4 mx_splittb_color4( - color4 mxp_valuet = mk_color4(0.0, 0.0, 0.0, 0.0) - [[ - anno::display_name("Top") - ]], - color4 mxp_valueb = mk_color4(0.0, 0.0, 0.0, 0.0) - [[ - anno::display_name("Bottom") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - color rgb = math::lerp(mxp_valuet.rgb, mxp_valueb.rgb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); float a = math::lerp(mxp_valuet.a, mxp_valueb.a, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); return color4(rgb, a); -} - -export float2 mx_splittb_vector2( - float2 mxp_valuet = float2(0.0, 0.0) - [[ - anno::display_name("Top") - ]], - float2 mxp_valueb = float2(0.0, 0.0) - [[ - anno::display_name("Bottom") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuet, mxp_valueb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); -} - -export float3 mx_splittb_vector3( - float3 mxp_valuet = float3(0.0, 0.0, 0.0) - [[ - anno::display_name("Top") - ]], - float3 mxp_valueb = float3(0.0, 0.0, 0.0) - [[ - anno::display_name("Bottom") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuet, mxp_valueb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); -} - -export float4 mx_splittb_vector4( - float4 mxp_valuet = float4(0.0, 0.0, 0.0, 0.0) - [[ - anno::display_name("Top") - ]], - float4 mxp_valueb = float4(0.0, 0.0, 0.0, 0.0) - [[ - anno::display_name("Bottom") - ]], - float mxp_center = float(0.5) - [[ - anno::display_name("Center") - ]], - float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) -) - [[ - anno::description("Node Group: procedural2d") - ]] -{ - return math::lerp(mxp_valuet, mxp_valueb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); -} - -export float3 mx_position_vector3( - uniform mx_coordinatespace_type mxp_space = mx_coordinatespace_type(mx_coordinatespace_type_object) - [[ - anno::description("Enumeration {model,object,world}.") - ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - state::coordinate_space fromSpace = ::mx_map_space(mx_coordinatespace_type_model); - state::coordinate_space toSpace = ::mx_map_space(mxp_space); - return state::transform_point(fromSpace, toSpace, state::position()); -} - -export float3 mx_normal_vector3( - uniform mx_coordinatespace_type mxp_space = mx_coordinatespace_type(mx_coordinatespace_type_object) - [[ - anno::description("Enumeration {model,object,world}.") - ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - state::coordinate_space fromSpace = ::mx_map_space(mx_coordinatespace_type_model); - state::coordinate_space toSpace = ::mx_map_space(mxp_space); - return state::transform_normal(fromSpace, toSpace, state::normal()); -} - -export float3 mx_tangent_vector3( - uniform mx_coordinatespace_type mxp_space = mx_coordinatespace_type(mx_coordinatespace_type_object) - [[ - anno::description("Enumeration {model,object,world}.") - ]], - uniform int mxp_index = int(0) -) - [[ - anno::description("Node Group: geometric") - ]] -{ - state::coordinate_space fromSpace = ::mx_map_space(mx_coordinatespace_type_model); - state::coordinate_space toSpace = ::mx_map_space(mxp_space); - return ::math::normalize(state::transform_vector(fromSpace, toSpace, state::texture_tangent_u(mxp_index))); -} - -export float3 mx_bitangent_vector3( - uniform mx_coordinatespace_type mxp_space = mx_coordinatespace_type(mx_coordinatespace_type_object) - [[ - anno::description("Enumeration {model,object,world}.") - ]], - uniform int mxp_index = int(0) -) - [[ - anno::description("Node Group: geometric") - ]] -{ - state::coordinate_space fromSpace = ::mx_map_space(mx_coordinatespace_type_model); - state::coordinate_space toSpace = ::mx_map_space(mxp_space); - return ::math::normalize(state::transform_vector(fromSpace, toSpace, state::texture_tangent_v(mxp_index))); -} - -export float2 mx_texcoord_vector2( - uniform int mxp_index = int(0) -) - [[ - anno::description("Node Group: geometric") - ]] -{ - return swizzle::xy((state::texture_coordinate(mxp_index))); -} - -export float3 mx_texcoord_vector3( - uniform int mxp_index = int(0) -) - [[ - anno::description("Node Group: geometric") - ]] -{ - return state::texture_coordinate(mxp_index); -} - -export float mx_geomcolor_float( - uniform int mxp_index = int(0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geomcolor_float - float defaultValue = float(0.0); - return defaultValue; -} - -export color mx_geomcolor_color3( - uniform int mxp_index = int(0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geomcolor_color3 - color defaultValue = color(0.0, 0.0, 0.0); - return defaultValue; -} - -export color4 mx_geomcolor_color4( - uniform int mxp_index = int(0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geomcolor_color4 - color4 defaultValue = mk_color4(0.0, 0.0, 0.0, 0.0); - return defaultValue; -} - -export int mx_geompropvalue_integer( - uniform string mxp_geomprop = string("") [[ anno::unused() ]], - int mxp_default = int(0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geompropvalue_integer - int defaultValue = int(0); - return defaultValue; -} - -export bool mx_geompropvalue_boolean( - uniform string mxp_geomprop = string("") [[ anno::unused() ]], - bool mxp_default = bool(false) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geompropvalue_boolean - bool defaultValue = bool(false); - return defaultValue; -} - -export string mx_geompropvalue_string( - uniform string mxp_geomprop = string("") [[ anno::unused() ]], - string mxp_default = string("") [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geompropvalue_string - string defaultValue; - return defaultValue; -} - -export float mx_geompropvalue_float( - uniform string mxp_geomprop = string("") [[ anno::unused() ]], - float mxp_default = float(0.0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geompropvalue_float - float defaultValue = float(0.0); - return defaultValue; -} - -export color mx_geompropvalue_color3( - uniform string mxp_geomprop = string("") [[ anno::unused() ]], - color mxp_default = color(0.0, 0.0, 0.0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geompropvalue_color3 - color defaultValue = color(0.0, 0.0, 0.0); - return defaultValue; -} - -export color4 mx_geompropvalue_color4( - uniform string mxp_geomprop = string("") [[ anno::unused() ]], - color4 mxp_default = mk_color4(0.0, 0.0, 0.0, 0.0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geompropvalue_color4 - color4 defaultValue = mk_color4(0.0, 0.0, 0.0, 0.0); - return defaultValue; -} - -export float2 mx_geompropvalue_vector2( - uniform string mxp_geomprop = string("") [[ anno::unused() ]], - float2 mxp_default = float2(0.0, 0.0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geompropvalue_vector2 - float2 defaultValue = float2(0.0, 0.0); - return defaultValue; -} - -export float3 mx_geompropvalue_vector3( - uniform string mxp_geomprop = string("") [[ anno::unused() ]], - float3 mxp_default = float3(0.0, 0.0, 0.0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geompropvalue_vector3 - float3 defaultValue = float3(0.0, 0.0, 0.0); - return defaultValue; -} - -export float4 mx_geompropvalue_vector4( - uniform string mxp_geomprop = string("") [[ anno::unused() ]], - float4 mxp_default = float4(0.0, 0.0, 0.0, 0.0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: geometric") - ]] -{ - // Not implemented: mx_geompropvalue_vector4 - float4 defaultValue = float4(0.0, 0.0, 0.0, 0.0); - return defaultValue; -} - -export float mx_ambientocclusion_float( - float mxp_coneangle = float(90.0) - [[ - anno::description("Unit Type:angle. Unit:degrees."), - anno::unused() - ]], - float mxp_maxdistance = float(1e38) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: global") - ]] -{ - // Not implemented: mx_ambientocclusion_float - float defaultValue = float(1.0); - return defaultValue; -} - -export float mx_frame_float( -) - [[ - anno::description("Node Group: application") - ]] -{ - // Not implemented: mx_frame_float - float defaultValue = float(1.0); - return defaultValue; -} - -export float mx_time_float( - uniform float mxp_fps = float(24.0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: application") - ]] -{ - return ::state::animation_time(); -} - -export float3 mx_viewdirection_vector3( - uniform mx_coordinatespace_type mxp_space = mx_coordinatespace_type(mx_coordinatespace_type_world) - [[ - anno::description("Enumeration {model,object,world}."), - anno::unused() - ]] -) - [[ - anno::description("Node Group: nprlib") - ]] -{ - // Not implemented: mx_viewdirection_vector3 - float3 defaultValue = float3(0.0, 0.0, 1.0); - return defaultValue; -} - -export color mx_modulo_color3( - color mxp_in1 = color(0.0, 0.0, 0.0), - color mxp_in2 = color(1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return color(mx_mod(float3(mxp_in1), float3(mxp_in2))); -} - -export color4 mx_modulo_color4( - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(1.0, 1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(mx_mod(mk_float4(mxp_in1), mk_float4(mxp_in2))); -} - -export color mx_modulo_color3FA( - color mxp_in1 = color(0.0, 0.0, 0.0), - float mxp_in2 = float(1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return color(mx_mod(float3(mxp_in1), float3(mxp_in2))); -} - -export color4 mx_modulo_color4FA( - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_in2 = float(1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(mx_mod(mk_float4(mxp_in1), float4(mxp_in2))); -} - -export color4 mx_invert_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_amount = mk_color4(1.0, 1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(mk_float4(mxp_amount) - mk_float4(mxp_in)); -} - -export color4 mx_invert_color4FA( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_amount = float(1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(float4(mxp_amount) - mk_float4(mxp_in)); -} - -export color4 mx_absval_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::abs(mk_float4(mxp_in))); -} - -export color mx_floor_color3( - color mxp_in = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return color(::math::floor(float3(mxp_in))); -} - -export color4 mx_floor_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::floor(mk_float4(mxp_in))); -} - -export color mx_ceil_color3( - color mxp_in = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return color(::math::ceil(float3(mxp_in))); -} - -export color4 mx_ceil_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::ceil(mk_float4(mxp_in))); -} - -export color4 mx_power_color4( - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(1.0, 1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::pow(mk_float4(mxp_in1), mk_float4(mxp_in2))); -} - -export color4 mx_power_color4FA( - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_in2 = float(1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::pow(mk_float4(mxp_in1), float4(mxp_in2))); -} - -export float mx_sin_float( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::sin(mxp_in); -} - -export float mx_cos_float( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::cos(mxp_in); -} - -export float mx_tan_float( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::tan(mxp_in); -} - -export float mx_asin_float( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::asin(mxp_in); -} - -export float mx_acos_float( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::acos(mxp_in); -} - -export float mx_atan2_float( - float mxp_in1 = float(1.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::atan2(mxp_in1, mxp_in2); -} - -export float2 mx_sin_vector2( - float2 mxp_in = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::sin(mxp_in); -} - -export float2 mx_cos_vector2( - float2 mxp_in = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::cos(mxp_in); -} - -export float2 mx_tan_vector2( - float2 mxp_in = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::tan(mxp_in); -} - -export float2 mx_asin_vector2( - float2 mxp_in = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::asin(mxp_in); -} - -export float2 mx_acos_vector2( - float2 mxp_in = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::acos(mxp_in); -} - -export float2 mx_atan2_vector2( - float2 mxp_in1 = float2(1.0, 1.0), - float2 mxp_in2 = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::atan2(mxp_in1, mxp_in2); -} - -export float3 mx_sin_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::sin(mxp_in); -} - -export float3 mx_cos_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::cos(mxp_in); -} - -export float3 mx_tan_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::tan(mxp_in); -} - -export float3 mx_asin_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::asin(mxp_in); -} - -export float3 mx_acos_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::acos(mxp_in); -} - -export float3 mx_atan2_vector3( - float3 mxp_in1 = float3(1.0, 1.0, 1.0), - float3 mxp_in2 = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::atan2(mxp_in1, mxp_in2); -} - -export float4 mx_sin_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::sin(mxp_in); -} - -export float4 mx_cos_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::cos(mxp_in); -} - -export float4 mx_tan_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::tan(mxp_in); -} - -export float4 mx_asin_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::asin(mxp_in); -} - -export float4 mx_acos_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::acos(mxp_in); -} - -export float4 mx_atan2_vector4( - float4 mxp_in1 = float4(1.0, 1.0, 1.0, 1.0), - float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::atan2(mxp_in1, mxp_in2); -} - -export float mx_sqrt_float( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::sqrt(mxp_in); -} - -export float mx_ln_float( - float mxp_in = float(1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::log(mxp_in); -} - -export float mx_exp_float( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::exp(mxp_in); -} - -export float2 mx_sqrt_vector2( - float2 mxp_in = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::sqrt(mxp_in); -} - -export float2 mx_ln_vector2( - float2 mxp_in = float2(1.0, 1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::log(mxp_in); -} - -export float2 mx_exp_vector2( - float2 mxp_in = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::exp(mxp_in); -} - -export float3 mx_sqrt_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::sqrt(mxp_in); -} - -export float3 mx_ln_vector3( - float3 mxp_in = float3(1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::log(mxp_in); -} - -export float3 mx_exp_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::exp(mxp_in); -} - -export float4 mx_sqrt_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::sqrt(mxp_in); -} - -export float4 mx_ln_vector4( - float4 mxp_in = float4(1.0, 1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::log(mxp_in); -} - -export float4 mx_exp_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::exp(mxp_in); -} - -export color mx_sign_color3( - color mxp_in = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return color(::math::sign(float3(mxp_in))); -} - -export color4 mx_sign_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::sign(mk_float4(mxp_in))); -} - -export color4 mx_clamp_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_low = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_high = mk_color4(1.0, 1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::clamp(mk_float4(mxp_in), mk_float4(mxp_low), mk_float4(mxp_high))); -} - -export color4 mx_clamp_color4FA( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_low = float(0.0), - float mxp_high = float(1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::clamp(mk_float4(mxp_in), float4(mxp_low), float4(mxp_high))); -} - -export color4 mx_min_color4( - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::min(mk_float4(mxp_in1), mk_float4(mxp_in2))); -} - -export color4 mx_min_color4( - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::min(mk_float4(mxp_in1), float4(mxp_in2))); -} - -export color4 mx_max_color4( - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::max(mk_float4(mxp_in1), mk_float4(mxp_in2))); -} - -export color4 mx_max_color4( - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mk_color4(::math::max(mk_float4(mxp_in1), float4(mxp_in2))); -} - -export float3 mx_transformpoint_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0), - uniform string mxp_fromspace = "object", - uniform string mxp_tospace = "world" -) - [[ - anno::description("Node Group: math") - ]] -{ - state::coordinate_space fromSpace = ::mx_map_space(mxp_fromspace); - state::coordinate_space toSpace = ::mx_map_space(mxp_tospace); - return state::transform_point(fromSpace, toSpace, mxp_in); -} - -export float3 mx_transformvector_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0), - uniform string mxp_fromspace = "object", - uniform string mxp_tospace = "world" -) - [[ - anno::description("Node Group: math") - ]] -{ - state::coordinate_space fromSpace = ::mx_map_space(mxp_fromspace); - state::coordinate_space toSpace = ::mx_map_space(mxp_tospace); - return state::transform_vector(fromSpace, toSpace, mxp_in); -} - -export float3 mx_transformnormal_vector3( - float3 mxp_in = float3(0.0, 0.0, 1.0), - uniform string mxp_fromspace = "object", - uniform string mxp_tospace = "world" -) - [[ - anno::description("Node Group: math") - ]] -{ - state::coordinate_space fromSpace = ::mx_map_space(mxp_fromspace); - state::coordinate_space toSpace = ::mx_map_space(mxp_tospace); - return state::transform_normal(fromSpace, toSpace, mxp_in); -} - -export float2 mx_transformmatrix_vector2M3( - float2 mxp_in = float2(0.0, 0.0), - float3x3 mxp_mat = float3x3(1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - float3 returnValue = mxp_mat * float3(mxp_in.x, mxp_in.y, 1.0); - return float2(returnValue.x, returnValue.y); -} - -export float3 mx_transformmatrix_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0), - float3x3 mxp_mat = float3x3(1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mxp_mat * mxp_in; -} - -export float3 mx_transformmatrix_vector3M4( - float3 mxp_in = float3(0.0, 0.0, 0.0), - float4x4 mxp_mat = float4x4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - float4 returnValue = mxp_mat * float4(mxp_in.x, mxp_in.y, mxp_in.z, 1.0); - return float3(returnValue.x, returnValue.y, returnValue.z); -} - -export float4 mx_transformmatrix_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), - float4x4 mxp_mat = float4x4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mxp_mat * mxp_in; -} - -export float3 mx_normalmap_vector2( - float3 mxp_in = float3(0.5, 0.5, 1.0), - uniform string mxp_space = string("tangent") - [[ - anno::description("Enumeration {tangent, object}.") - ]], - float2 mxp_scale = float2(1.0, 1.0), - float3 mxp_normal = float3(::state::transform_normal(::state::coordinate_internal,::state::coordinate_world,::state::normal())), - float3 mxp_tangent = float3(state::transform_vector(::state::coordinate_internal,::state::coordinate_world,::state::texture_tangent_u(0))) -) - [[ - anno::description("Node Group: math") - ]] -{ - if (mxp_space == "tangent") - { - float3 v = mxp_in * 2.0 - 1.0; - float3 binormal = ::math::normalize(::math::cross(mxp_normal, mxp_tangent)); - return ::math::normalize(mxp_tangent * v.x * mxp_scale.x + binormal * v.y * mxp_scale.y + mxp_normal * v.z); - } - else - { - float3 n = mxp_in * 2.0 - 1.0; - return ::math::normalize(n); - } -} - -export float3 mx_normalmap_float( - float3 mxp_in = float3(0.5, 0.5, 1.0), - uniform string mxp_space = string("tangent") - [[ - anno::description("Enumeration {tangent, object}.") - ]], - float mxp_scale = float(1.0), - float3 mxp_normal = float3(::state::transform_normal(::state::coordinate_internal,::state::coordinate_world,::state::normal())), - float3 mxp_tangent = float3(state::transform_vector(::state::coordinate_internal,::state::coordinate_world,::state::texture_tangent_u(0))) -) - [[ - anno::description("Node Group: math") - ]] -{ - return mx_normalmap_vector2(mxp_in, mxp_space, float2(mxp_scale, mxp_scale), mxp_normal, mxp_tangent); -} - -export float3x3 mx_transpose_matrix33( - float3x3 mxp_in = float3x3(1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::transpose(mxp_in); -} - -export float4x4 mx_transpose_matrix44( - float4x4 mxp_in = float4x4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return ::math::transpose(mxp_in); -} - -export float mx_determinant_matrix33(float3x3 mxp_in) -[[ - anno::description("Node Group: math") -]] -{ - return mxp_in[0][0] * (mxp_in[2][2]*mxp_in[1][1] - mxp_in[1][2]*mxp_in[2][1]) - + mxp_in[0][1] * (mxp_in[1][2]*mxp_in[2][0] - mxp_in[2][2]*mxp_in[1][0]) - + mxp_in[0][2] * (mxp_in[2][1]*mxp_in[1][0] - mxp_in[1][1]*mxp_in[2][0]); -} - -export float mx_determinant_matrix44(float4x4 mxp_in) -[[ - anno::description("Node Group: math") -]] -{ - float - b00 = mxp_in[0][0] * mxp_in[1][1] - mxp_in[0][1] * mxp_in[1][0], - b01 = mxp_in[0][0] * mxp_in[1][2] - mxp_in[0][2] * mxp_in[1][0], - b02 = mxp_in[0][0] * mxp_in[1][3] - mxp_in[0][3] * mxp_in[1][0], - b03 = mxp_in[0][1] * mxp_in[1][2] - mxp_in[0][2] * mxp_in[1][1], - b04 = mxp_in[0][1] * mxp_in[1][3] - mxp_in[0][3] * mxp_in[1][1], - b05 = mxp_in[0][2] * mxp_in[1][3] - mxp_in[0][3] * mxp_in[1][2], - b06 = mxp_in[2][0] * mxp_in[3][1] - mxp_in[2][1] * mxp_in[3][0], - b07 = mxp_in[2][0] * mxp_in[3][2] - mxp_in[2][2] * mxp_in[3][0], - b08 = mxp_in[2][0] * mxp_in[3][3] - mxp_in[2][3] * mxp_in[3][0], - b09 = mxp_in[2][1] * mxp_in[3][2] - mxp_in[2][2] * mxp_in[3][1], - b10 = mxp_in[2][1] * mxp_in[3][3] - mxp_in[2][3] * mxp_in[3][1], - b11 = mxp_in[2][2] * mxp_in[3][3] - mxp_in[2][3] * mxp_in[3][2]; - return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; -} - -export float3x3 mx_invertmatrix_matrix33( - float3x3 mxp_in = float3x3(1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - // Not implemented: mx_invertmatrix_matrix33 - float3x3 defaultValue = mxp_in; - return defaultValue; -} - -export float4x4 mx_invertmatrix_matrix44( - float4x4 mxp_in = float4x4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - // Not implemented: mx_invertmatrix_matrix44 - float4x4 defaultValue = mxp_in; - return defaultValue; -} - -export float2 mx_rotate2d_vector2( - float2 mxp_in = float2(0.0, 0.0), - float mxp_amount = float(0.0) - [[ - anno::description("Unit Type:angle. Unit:degrees.") - ]] -) -[[ - anno::description("Node Group: math") -]] -{ - float angleRadians = math::radians(mxp_amount); - float sinAngle = math::sin(angleRadians); - float cosAngle = math::cos(angleRadians); - return float2(cosAngle*mxp_in.x + sinAngle*mxp_in.y, -sinAngle*mxp_in.x + cosAngle*mxp_in.y); -} - -float4x4 mx_rotationMatrix(float3 mxp_axis, float mxp_amount) -{ - float sinAngle = math::sin(mxp_amount); - float cosAngle = math::cos(mxp_amount); - float oc = 1.0 - cosAngle; - - return float4x4( - oc * mxp_axis.x * mxp_axis.x + cosAngle, oc * mxp_axis.x * mxp_axis.y - mxp_axis.z * sinAngle, oc * mxp_axis.z * mxp_axis.x + mxp_axis.y * sinAngle, 0.0, - oc * mxp_axis.x * mxp_axis.y + mxp_axis.z * sinAngle, oc * mxp_axis.y * mxp_axis.y + cosAngle, oc * mxp_axis.y * mxp_axis.z - mxp_axis.x * sinAngle, 0.0, - oc * mxp_axis.z * mxp_axis.x - mxp_axis.y * sinAngle, oc * mxp_axis.y * mxp_axis.z + mxp_axis.x * sinAngle, oc * mxp_axis.z * mxp_axis.z + cosAngle, 0.0, - 0.0, 0.0, 0.0, 1.0); -} - -export float3 mx_rotate3d_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0), - float mxp_amount = float(0.0) - [[ - anno::description("Unit Type:angle. Unit:degrees.") - ]], - float3 mxp_axis = float3(0.0, 1.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - float angleRadians = math::radians(mxp_amount); - float4x4 m = mx_rotationMatrix(mxp_axis, angleRadians); - float4 v = m * float4(mxp_in.x, mxp_in.y, mxp_in.z, 1.0); - return float3(v.x, v.y, v.z); -} - -// Nodedef: ND_place2d_vector2 is represented by a nodegraph: NG_place2d_vector2 - -export float mx_remap_float( - float mxp_in = float(0.0), - float mxp_inlow = float(0.0), - float mxp_inhigh = float(1.0), - float mxp_outlow = float(0.0), - float mxp_outhigh = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); -} - -export color mx_remap_color3( - color mxp_in = color(0.0, 0.0, 0.0), - color mxp_inlow = color(0.0, 0.0, 0.0), - color mxp_inhigh = color(1.0, 1.0, 1.0), - color mxp_outlow = color(0.0, 0.0, 0.0), - color mxp_outhigh = color(1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); -} - -export color4 mx_remap_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_inlow = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_inhigh = mk_color4(1.0, 1.0, 1.0, 1.0), - color4 mxp_outlow = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_outhigh = mk_color4(1.0, 1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - color4 val = mxp_outlow; - color4 val2 = mx_add(val, mx_subtract(mxp_in, mxp_inlow)); - color4 val3 = mx_multiply(val2, mx_subtract(mxp_outhigh, mxp_outlow)); - return mx_divide(val3, mx_subtract(mxp_inhigh, mxp_inlow)); -} - -export float2 mx_remap_vector2( - float2 mxp_in = float2(0.0, 0.0), - float2 mxp_inlow = float2(0.0, 0.0), - float2 mxp_inhigh = float2(1.0, 1.0), - float2 mxp_outlow = float2(0.0, 0.0), - float2 mxp_outhigh = float2(1.0, 1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); -} - -export float3 mx_remap_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0), - float3 mxp_inlow = float3(0.0, 0.0, 0.0), - float3 mxp_inhigh = float3(1.0, 1.0, 1.0), - float3 mxp_outlow = float3(0.0, 0.0, 0.0), - float3 mxp_outhigh = float3(1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); -} - -export float4 mx_remap_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_inlow = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_inhigh = float4(1.0, 1.0, 1.0, 1.0), - float4 mxp_outlow = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_outhigh = float4(1.0, 1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); -} - -export color mx_remap_color3FA( - color mxp_in = color(0.0, 0.0, 0.0), - float mxp_inlow = float(0.0), - float mxp_inhigh = float(1.0), - float mxp_outlow = float(0.0), - float mxp_outhigh = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); -} - -export color4 mx_remap_color4FA( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_inlow = float(0.0), - float mxp_inhigh = float(1.0), - float mxp_outlow = float(0.0), - float mxp_outhigh = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - color4 val = mk_color4(mxp_outlow); - color4 val2 = mx_add(val, mx_subtract(mxp_in, mk_color4(mxp_inlow))); - color4 val3 = mx_multiply(val2, mx_subtract(mk_color4(mxp_outhigh), mk_color4(mxp_outlow))); - return mx_divide(val3, mx_subtract(mk_color4(mxp_inhigh), mk_color4(mxp_inlow))); -} - -export float2 mx_remap_vector2FA( - float2 mxp_in = float2(0.0, 0.0), - float mxp_inlow = float(0.0), - float mxp_inhigh = float(1.0), - float mxp_outlow = float(0.0), - float mxp_outhigh = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); -} - -export float3 mx_remap_vector3FA( - float3 mxp_in = float3(0.0, 0.0, 0.0), - float mxp_inlow = float(0.0), - float mxp_inhigh = float(1.0), - float mxp_outlow = float(0.0), - float mxp_outhigh = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); -} - -export float4 mx_remap_vector4FA( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), - float mxp_inlow = float(0.0), - float mxp_inhigh = float(1.0), - float mxp_outlow = float(0.0), - float mxp_outhigh = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); -} - -export float mx_smoothstep_float( - float mxp_in = float(0.0), - float mxp_low = float(0.0), - float mxp_high = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return ::math::smoothstep(float(mxp_low), float(mxp_high), float(mxp_in)); -} - -export color mx_smoothstep_color3( - color mxp_in = color(0.0, 0.0, 0.0), - color mxp_low = color(0.0, 0.0, 0.0), - color mxp_high = color(1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return color(::math::smoothstep(float3(mxp_low), float3(mxp_high), float3(mxp_in))); -} - -export color4 mx_smoothstep_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_low = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_high = mk_color4(1.0, 1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mk_color4(::math::smoothstep(mk_float4(mxp_low), mk_float4(mxp_high), mk_float4(mxp_in))); -} - -export float2 mx_smoothstep_vector2( - float2 mxp_in = float2(0.0, 0.0), - float2 mxp_low = float2(0.0, 0.0), - float2 mxp_high = float2(1.0, 1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return ::math::smoothstep(float2(mxp_low), float2(mxp_high), float2(mxp_in)); -} - -export float3 mx_smoothstep_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0), - float3 mxp_low = float3(0.0, 0.0, 0.0), - float3 mxp_high = float3(1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return ::math::smoothstep(float3(mxp_low), float3(mxp_high), float3(mxp_in)); -} - -export float4 mx_smoothstep_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_low = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_high = float4(1.0, 1.0, 1.0, 1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return ::math::smoothstep(float4(mxp_low), float4(mxp_high), float4(mxp_in)); -} - -export color mx_smoothstep_color3FA( - color mxp_in = color(0.0, 0.0, 0.0), - float mxp_low = float(0.0), - float mxp_high = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return color(::math::smoothstep(float3(mxp_in), float3(mxp_low), float3(mxp_high))); -} - -export color4 mx_smoothstep_color4FA( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_low = float(0.0), - float mxp_high = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return mk_color4(::math::smoothstep(mk_float4(mxp_in), float4(mxp_low), float4(mxp_high))); -} - -export float2 mx_smoothstep_vector2FA( - float2 mxp_in = float2(0.0, 0.0), - float mxp_low = float(0.0), - float mxp_high = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return ::math::smoothstep(float2(mxp_low), float2(mxp_high), float2(mxp_in)); -} - -export float3 mx_smoothstep_vector3FA( - float3 mxp_in = float3(0.0, 0.0, 0.0), - float mxp_low = float(0.0), - float mxp_high = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return ::math::smoothstep(float3(mxp_low), float3(mxp_high), float3(mxp_in)); -} - -export float4 mx_smoothstep_vector4FA( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), - float mxp_low = float(0.0), - float mxp_high = float(1.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return ::math::smoothstep(float4(mxp_low), float4(mxp_high), float4(mxp_in)); -} - -export float mx_curveadjust_float( - float mxp_in = float(0.0), - float2[] mxp_knots = float2[]() [[ anno::unused() ]] -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - // Not implemented: mx_curveadjust_float - float defaultValue = mxp_in; - return defaultValue; -} - -export color mx_curveadjust_color3( - color mxp_in = color(0.0, 0.0, 0.0), - float2[] mxp_knots = float2[]() [[ anno::unused() ]] -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - // Not implemented: mx_curveadjust_color3 - color defaultValue = mxp_in; - return defaultValue; -} - -export color4 mx_curveadjust_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - float2[] mxp_knots = float2[]() [[ anno::unused() ]] -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - // Not implemented: mx_curveadjust_color4 - color4 defaultValue = mxp_in; - return defaultValue; -} - -export float2 mx_curveadjust_vector2( - float2 mxp_in = float2(0.0, 0.0), - float2[] mxp_knots = float2[]() [[ anno::unused() ]] -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - // Not implemented: mx_curveadjust_vector2 - float2 defaultValue = mxp_in; - return defaultValue; -} - -export float3 mx_curveadjust_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0), - float2[] mxp_knots = float2[]() [[ anno::unused() ]] -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - // Not implemented: mx_curveadjust_vector3 - float3 defaultValue = mxp_in; - return defaultValue; -} - -export float4 mx_curveadjust_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), - float2[] mxp_knots = float2[]() [[ anno::unused() ]] -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - // Not implemented: mx_curveadjust_vector4 - float4 defaultValue = mxp_in; - return defaultValue; -} - -export color mx_luminance_color3( - color mxp_in = color(0.0, 0.0, 0.0), - uniform color mxp_lumacoeffs = color(0.2722287, 0.6740818, 0.0536895) - [[ - anno::description("Enumeration {acescg, rec709, rec2020, rec2100}."), - anno::unused() - ]] -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return color(::math::luminance(mxp_in)); -} - -export color4 mx_luminance_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - uniform color mxp_lumacoeffs = color(0.2722287, 0.6740818, 0.0536895) - [[ - anno::description("Enumeration {acescg, rec709, rec2020, rec2100}."), - anno::unused() - ]] -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - color rgb = color(mxp_in.rgb); - color4 returnValue = mk_color4(::math::luminance(rgb)); - returnValue.a = mxp_in.a; - return returnValue; -} - -export color mx_rgbtohsv_color3( - color mxp_in = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return color(::hsv::mx_rgbtohsv(float3(mxp_in))); -} - -export color4 mx_rgbtohsv_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - float3 rgb = hsv::mx_rgbtohsv(float3(mxp_in.rgb)); - return color4(color(rgb), mxp_in.a); -} - -export color mx_hsvtorgb_color3( - color mxp_in = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - return color(hsv::mx_hsvtorgb(float3(mxp_in))); -} - -export color4 mx_hsvtorgb_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: adjustment") - ]] -{ - float3 rgb = hsv::mx_hsvtorgb(float3(mxp_in.rgb)); - return color4(color(rgb), mxp_in.a); -} - -export color4 mx_premult_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - // Not implemented: mx_premult_color4 - color4 defaultValue = mxp_in; - return defaultValue; -} - -export color4 mx_unpremult_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - // Not implemented: mx_unpremult_color4 - color4 defaultValue = mxp_in; - return defaultValue; -} - -export color4 mx_plus_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color rgb = (mxp_mix*(mxp_bg.rgb + mxp_fg.rgb)) + ((1.0-mxp_mix)*mxp_bg.rgb); - float a = (mxp_mix*(mxp_bg.a + mxp_fg.a )) + ((1.0-mxp_mix)*mxp_bg.a ); - return color4(rgb,a); -} - -export color4 mx_minus_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color rgb = (mxp_mix*(mxp_bg.rgb - mxp_fg.rgb)) + ((1.0-mxp_mix)*mxp_bg.rgb); - float a = (mxp_mix*(mxp_bg.a - mxp_fg.a )) + ((1.0-mxp_mix)*mxp_bg.a ); - return color4(rgb,a); -} - -export color4 mx_difference_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color rgb = (mxp_mix*math::abs(mxp_bg.rgb - mxp_fg.rgb)) + ((1.0-mxp_mix)*mxp_bg.rgb); - float a = (mxp_mix*math::abs(mxp_bg.a - mxp_fg.a )) + ((1.0-mxp_mix)*mxp_bg.a ); - return color4(rgb,a); -} - -export float mx_burn_float( - float mxp_fg = 0.0, - float mxp_bg = 0.0, - float mxp_mix = 1.0 -) - [[ - anno::description("Node Group: compositing") - ]] -{ - if (math::abs(mxp_fg) < FLOAT_EPS) - { - return 0.0; - } - return mxp_mix*(1.0 - ((1.0 - mxp_bg) / mxp_fg)) + ((1.0 - mxp_mix)*mxp_bg); -} - -export color mx_burn_color3( - color mxp_fg = color(0.0), - color mxp_bg = color(0.0), - float mxp_mix = 1.0 -) - [[ - anno::description("Node Group: compositing") - ]] -{ - float3 fg(mxp_fg); - float3 bg(mxp_bg); - return color( - mx_burn_float(fg.x, bg.x, mxp_mix), - mx_burn_float(fg.y, bg.y, mxp_mix), - mx_burn_float(fg.z, bg.z, mxp_mix) - ); -} - -export color4 mx_burn_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = 1.0 -) - [[ - anno::description("Node Group: compositing") - ]] -{ - return color4( - mx_burn_color3(mxp_fg.rgb, mxp_bg.rgb, mxp_mix), - mx_burn_float(mxp_fg.a, mxp_bg.a, mxp_mix) - ); -} - -export float mx_dodge_float( - float mxp_fg = float(0.0), - float mxp_bg = float(0.0), - float mxp_mix = 1.0 -) - [[ - anno::description("Node Group: compositing") - ]] -{ - if (math::abs(1.0 - mxp_fg) < FLOAT_EPS) - { - return 0.0; - } - return mxp_mix*(mxp_bg / (1.0 - mxp_fg)) + ((1.0-mxp_mix)*mxp_bg); -} - -export color mx_dodge_color3( - color mxp_fg = color(0.0), - color mxp_bg = color(0.0), - float mxp_mix = 1.0 -) - [[ - anno::description("Node Group: compositing") - ]] -{ - float3 fg(mxp_fg); - float3 bg(mxp_bg); - return color( - mx_dodge_float(fg.x, bg.x, mxp_mix), - mx_dodge_float(fg.y, bg.y, mxp_mix), - mx_dodge_float(fg.z, bg.z, mxp_mix) - ); -} - -export color4 mx_dodge_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - return color4( - mx_dodge_color3(mxp_fg.rgb, mxp_bg.rgb, mxp_mix), - mx_dodge_float(mxp_fg.a, mxp_bg.a, mxp_mix) - ); -} - -export color4 mx_screen_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color rgb = (mxp_mix*((1.0 - (1.0 - mxp_fg.rgb) * (1 - mxp_bg.rgb)))) + ((1.0-mxp_mix)*mxp_bg.rgb); - float a = (mxp_mix*((1.0 - (1.0 - mxp_fg.a ) * (1 - mxp_bg.a )))) + ((1.0-mxp_mix)*mxp_bg.a ); - return color4(rgb,a); -} - -export color4 mx_disjointover_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color4 result; - float summedAlpha = mxp_fg.a + mxp_bg.a; - if (summedAlpha <= 1) - { - result.rgb = mxp_fg.rgb + mxp_bg.rgb; - } - else - { - if (math::abs(mxp_bg.a) < FLOAT_EPS) - { - result.rgb = color(0.0); - } - else - { - float x = (1 - mxp_fg.a) / mxp_bg.a; - result.rgb = mxp_fg.rgb + mxp_bg.rgb * x; - } - } - result.a = math::min(summedAlpha, 1.0); - result.rgb = result.rgb * mxp_mix + (1.0 - mxp_mix) * mxp_bg.rgb; - result.a = result.a * mxp_mix + (1.0 - mxp_mix) * mxp_bg.a; - return result; -} - -export color4 mx_in_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color rgb = mxp_fg.rgb*mxp_bg.a * mxp_mix + mxp_bg.rgb * (1.0-mxp_mix); - float a = mxp_fg.a *mxp_bg.a * mxp_mix + mxp_bg.a * (1.0-mxp_mix); - return color4(rgb,a); -} - -export color4 mx_mask_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color rgb = mxp_bg.rgb*mxp_fg.a * mxp_mix + mxp_bg.rgb * (1.0-mxp_mix); - float a = mxp_bg.a *mxp_fg.a * mxp_mix + mxp_bg.a * (1.0-mxp_mix); - return color4(rgb,a); -} - -export color4 mx_matte_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = 1.0 -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color rgb = (mxp_fg.rgb*mxp_fg.a + mxp_bg.rgb*(1.0-mxp_fg.a)) * mxp_mix + mxp_bg.rgb * (1.0-mxp_mix); - float a = (mxp_fg.a + mxp_bg.a*(1.0-mxp_fg.a)) * mxp_mix + mxp_bg.a * (1.0-mxp_mix); - return color4(rgb, a); -} - -export color4 mx_out_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color rgb = (mxp_fg.rgb*(1.0 - mxp_bg.a) * mxp_mix) + (mxp_bg.rgb * (1.0-mxp_mix)); - float a = (mxp_fg.a *(1.0 - mxp_bg.a) * mxp_mix) + (mxp_bg.a * (1.0-mxp_mix)); - return color4(rgb,a); -} - -export color4 mx_over_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(1.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - color rgb = (mxp_fg.rgb + (mxp_bg.rgb*(1.0-mxp_fg.a))) * mxp_mix + mxp_bg.rgb * (1.0-mxp_mix); - float a = (mxp_fg.a + (mxp_bg.a *(1.0-mxp_fg.a))) * mxp_mix + mxp_bg.a * (1.0-mxp_mix); - return color4(rgb,a); -} - -export color4 mx_mix_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_mix = float(0.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - return mk_color4(::math::lerp(mk_float4(mxp_bg), mk_float4(mxp_fg), float4(mxp_mix))); -} - -export color4 mx_mix_color4_color4( - color4 mxp_fg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_bg = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_mix = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: compositing") - ]] -{ - return mk_color4(::math::lerp(mk_float4(mxp_bg), mk_float4(mxp_fg), mk_float4(mxp_mix))); -} - -// 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::unbounded_mix( // unbounded_mix is cheaper - 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_fg.ior, // NOTE: IOR is uniform, cannot mix here - volume: material_volume( - scattering: df::unbounded_mix( // unbounded_mix is cheaper - 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 - ) -); - -export material mx_mix_volumeshader( - material mxp_fg = material() [[ anno::usage( "materialx:volumeshader") ]], - material mxp_bg = material() [[ anno::usage( "materialx:volumeshader") ]], - float mxp_mix = 0.0 -) [[ - anno::description("Node Group: compositing"), - anno::usage( "materialx:volumeshader") -]] -= mx_mix_surfaceshader( - mxp_fg: mxp_fg, - mxp_bg: mxp_bg, - mxp_mix: mxp_mix); - -export material mx_mix_displacementshader( - material mxp_fg = material() [[ anno::usage( "materialx:displacementshader") ]], - material mxp_bg = material() [[ anno::usage( "materialx:displacementshader") ]], - float mxp_mix = 0.0 -) [[ - anno::description("Node Group: compositing"), - anno::usage( "materialx:displacementshader") -]] -= mx_mix_surfaceshader( - mxp_fg: mxp_fg, - mxp_bg: mxp_bg, - mxp_mix: mxp_mix); - -export float mx_ifgreater_float( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color mx_ifgreater_color3( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - color mxp_in1 = color(0.0, 0.0, 0.0), - color mxp_in2 = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color4 mx_ifgreater_color4( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float2 mx_ifgreater_vector2( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float3 mx_ifgreater_vector3( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - float3 mxp_in1 = float3(0.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float4 mx_ifgreater_vector4( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float mx_ifgreater_floatI( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color mx_ifgreater_color3I( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - color mxp_in1 = color(0.0, 0.0, 0.0), - color mxp_in2 = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color4 mx_ifgreater_color4I( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float2 mx_ifgreater_vector2I( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float3 mx_ifgreater_vector3I( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - float3 mxp_in1 = float3(0.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float4 mx_ifgreater_vector4I( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float mx_ifgreatereq_float( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color mx_ifgreatereq_color3( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - color mxp_in1 = color(0.0, 0.0, 0.0), - color mxp_in2 = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color4 mx_ifgreatereq_color4( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float2 mx_ifgreatereq_vector2( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float3 mx_ifgreatereq_vector3( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - float3 mxp_in1 = float3(0.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float4 mx_ifgreatereq_vector4( - float mxp_value1 = float(1.0), - float mxp_value2 = float(0.0), - float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float mx_ifgreatereq_floatI( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color mx_ifgreatereq_color3I( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - color mxp_in1 = color(0.0, 0.0, 0.0), - color mxp_in2 = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color4 mx_ifgreatereq_color4I( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float2 mx_ifgreatereq_vector2I( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float3 mx_ifgreatereq_vector3I( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - float3 mxp_in1 = float3(0.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float4 mx_ifgreatereq_vector4I( - int mxp_value1 = int(1), - int mxp_value2 = int(0), - float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float mx_ifequal_float( - float mxp_value1 = float(0.0), - float mxp_value2 = float(0.0), - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color mx_ifequal_color3( - float mxp_value1 = float(0.0), - float mxp_value2 = float(0.0), - color mxp_in1 = color(0.0, 0.0, 0.0), - color mxp_in2 = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color4 mx_ifequal_color4( - float mxp_value1 = float(0.0), - float mxp_value2 = float(0.0), - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float2 mx_ifequal_vector2( - float mxp_value1 = float(0.0), - float mxp_value2 = float(0.0), - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float3 mx_ifequal_vector3( - float mxp_value1 = float(0.0), - float mxp_value2 = float(0.0), - float3 mxp_in1 = float3(0.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float4 mx_ifequal_vector4( - float mxp_value1 = float(0.0), - float mxp_value2 = float(0.0), - float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float mx_ifequal_floatI( - int mxp_value1 = int(0), - int mxp_value2 = int(0), - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color mx_ifequal_color3I( - int mxp_value1 = int(0), - int mxp_value2 = int(0), - color mxp_in1 = color(0.0, 0.0, 0.0), - color mxp_in2 = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color4 mx_ifequal_color4I( - int mxp_value1 = int(0), - int mxp_value2 = int(0), - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float2 mx_ifequal_vector2I( - int mxp_value1 = int(0), - int mxp_value2 = int(0), - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float3 mx_ifequal_vector3I( - int mxp_value1 = int(0), - int mxp_value2 = int(0), - float3 mxp_in1 = float3(0.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float4 mx_ifequal_vector4I( - int mxp_value1 = int(0), - int mxp_value2 = int(0), - float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float mx_ifequal_floatB( - bool mxp_value1 = bool(false), - bool mxp_value2 = bool(false), - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color mx_ifequal_color3B( - bool mxp_value1 = bool(false), - bool mxp_value2 = bool(false), - color mxp_in1 = color(0.0, 0.0, 0.0), - color mxp_in2 = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export color4 mx_ifequal_color4B( - bool mxp_value1 = bool(false), - bool mxp_value2 = bool(false), - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float2 mx_ifequal_vector2B( - bool mxp_value1 = bool(false), - bool mxp_value2 = bool(false), - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float3 mx_ifequal_vector3B( - bool mxp_value1 = bool(false), - bool mxp_value2 = bool(false), - float3 mxp_in1 = float3(0.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float4 mx_ifequal_vector4B( - bool mxp_value1 = bool(false), - bool mxp_value2 = bool(false), - float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; -} - -export float mx_switch_float( - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0), - float mxp_in3 = float(0.0), - float mxp_in4 = float(0.0), - float mxp_in5 = float(0.0), - float mxp_which = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - float returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export color mx_switch_color3( - color mxp_in1 = color(0.0, 0.0, 0.0), - color mxp_in2 = color(0.0, 0.0, 0.0), - color mxp_in3 = color(0.0, 0.0, 0.0), - color mxp_in4 = color(0.0, 0.0, 0.0), - color mxp_in5 = color(0.0, 0.0, 0.0), - float mxp_which = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - color returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export color4 mx_switch_color4( - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in3 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in4 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in5 = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_which = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - color4 returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export float2 mx_switch_vector2( - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0), - float2 mxp_in3 = float2(0.0, 0.0), - float2 mxp_in4 = float2(0.0, 0.0), - float2 mxp_in5 = float2(0.0, 0.0), - float mxp_which = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - float2 returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export float3 mx_switch_vector3( - float3 mxp_in1 = float3(0.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 0.0, 0.0), - float3 mxp_in3 = float3(0.0, 0.0, 0.0), - float3 mxp_in4 = float3(0.0, 0.0, 0.0), - float3 mxp_in5 = float3(0.0, 0.0, 0.0), - float mxp_which = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - float3 returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export float4 mx_switch_vector4( - float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in3 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in4 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in5 = float4(0.0, 0.0, 0.0, 0.0), - float mxp_which = float(0.0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - float4 returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export float mx_switch_floatI( - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0), - float mxp_in3 = float(0.0), - float mxp_in4 = float(0.0), - float mxp_in5 = float(0.0), - int mxp_which = int(0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - float returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export color mx_switch_color3I( - color mxp_in1 = color(0.0, 0.0, 0.0), - color mxp_in2 = color(0.0, 0.0, 0.0), - color mxp_in3 = color(0.0, 0.0, 0.0), - color mxp_in4 = color(0.0, 0.0, 0.0), - color mxp_in5 = color(0.0, 0.0, 0.0), - int mxp_which = int(0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - color returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export color4 mx_switch_color4I( - color4 mxp_in1 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in2 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in3 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in4 = mk_color4(0.0, 0.0, 0.0, 0.0), - color4 mxp_in5 = mk_color4(0.0, 0.0, 0.0, 0.0), - int mxp_which = int(0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - color4 returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export float2 mx_switch_vector2I( - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0), - float2 mxp_in3 = float2(0.0, 0.0), - float2 mxp_in4 = float2(0.0, 0.0), - float2 mxp_in5 = float2(0.0, 0.0), - int mxp_which = int(0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - float2 returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export float3 mx_switch_vector3I( - float3 mxp_in1 = float3(0.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 0.0, 0.0), - float3 mxp_in3 = float3(0.0, 0.0, 0.0), - float3 mxp_in4 = float3(0.0, 0.0, 0.0), - float3 mxp_in5 = float3(0.0, 0.0, 0.0), - int mxp_which = int(0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - float3 returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export float4 mx_switch_vector4I( - float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in3 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in4 = float4(0.0, 0.0, 0.0, 0.0), - float4 mxp_in5 = float4(0.0, 0.0, 0.0, 0.0), - int mxp_which = int(0) -) - [[ - anno::description("Node Group: conditional") - ]] -{ - float4 returnValue; - switch (int(mxp_which)) { - case 0: returnValue=mxp_in1; break; - case 1: returnValue=mxp_in2; break; - case 2: returnValue=mxp_in3; break; - case 3: returnValue=mxp_in4; break; - case 4: returnValue=mxp_in5; break; - default: returnValue=mxp_in1; break; - } - return returnValue; -} - -export color mx_convert_float_color3( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return color(mxp_in); -} - -export color4 mx_convert_float_color4( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return mk_color4(mxp_in); -} - -export float2 mx_convert_float_vector2( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float2(mxp_in); -} - -export float3 mx_convert_float_vector3( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float3(mxp_in); -} - -export float4 mx_convert_float_vector4( - float mxp_in = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float4(mxp_in); -} - -export float3 mx_convert_vector2_vector3( - float2 mxp_in = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float3(mxp_in.x, mxp_in.y, 0.0); -} - -export color mx_convert_vector3_color3( - float3 mxp_in = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return color(mxp_in); -} - -export float2 mx_convert_vector3_vector2( - float3 mxp_in = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float2(mxp_in.x, mxp_in.y); -} - -export float4 mx_convert_vector3_vector4( - float3 mxp_in = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float4(mxp_in.x, mxp_in.y, mxp_in.z, 0.0); -} - -export color4 mx_convert_vector4_color4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return mk_color4(mxp_in); -} - -export float3 mx_convert_vector4_vector3( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float3(mxp_in.x, mxp_in.y, mxp_in.z); -} - -export float3 mx_convert_color3_vector3( - color mxp_in = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float3(mxp_in); -} - -export float4 mx_convert_color4_vector4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return mk_float4(mxp_in); -} - -export color4 mx_convert_color3_color4( - color mxp_in = color(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return mk_color4(mxp_in); -} - -export color mx_convert_color4_color3( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return mxp_in.rgb; -} - -export float mx_convert_boolean_float( - bool mxp_in = bool(false) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float(mxp_in); -} - -export float mx_convert_integer_float( - int mxp_in = int(0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float(mxp_in); -} - -export float2 mx_combine2_vector2( - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float2(mxp_in1, mxp_in2); -} - -export color4 mx_combine2_color4CF( - color mxp_in1 = color(0.0, 0.0, 0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return color4(mxp_in1, mxp_in2); -} - -export float4 mx_combine2_vector4VF( - float3 mxp_in1 = float3(0.0, 0.0, 0.0), - float mxp_in2 = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float4(mxp_in1.x, mxp_in1.y, mxp_in1.z, mxp_in2); -} - -export color4 mx_combine2_color4CC( - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return color4(color(mxp_in1.x, mxp_in1.y, mxp_in2.x), mxp_in2.y); -} - -export float4 mx_combine2_vector4VV( - float2 mxp_in1 = float2(0.0, 0.0), - float2 mxp_in2 = float2(0.0, 0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float4(mxp_in1.x, mxp_in1.y, mxp_in2.x, mxp_in2.y); -} - -export color mx_combine3_color3( - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0), - float mxp_in3 = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return color(mxp_in1, mxp_in2, mxp_in3); -} - -export float3 mx_combine3_vector3( - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0), - float mxp_in3 = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float3(mxp_in1, mxp_in2, mxp_in3); -} - -export color4 mx_combine4_color4( - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0), - float mxp_in3 = float(0.0), - float mxp_in4 = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return mk_color4(mxp_in1, mxp_in2, mxp_in3, mxp_in4); -} - -export float4 mx_combine4_vector4( - float mxp_in1 = float(0.0), - float mxp_in2 = float(0.0), - float mxp_in3 = float(0.0), - float mxp_in4 = float(0.0) -) - [[ - anno::description("Node Group: channel") - ]] -{ - return float4(mxp_in1, mxp_in2, mxp_in3, mxp_in4); -} - -export float3x3 mx_creatematrix_vector3_matrix33( - float3 mxp_in1 = float3(1.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 1.0, 0.0), - float3 mxp_in3 = float3(0.0, 0.0, 1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return float3x3(mxp_in1[0],mxp_in1[1],mxp_in1[2],mxp_in2[0],mxp_in2[1],mxp_in2[2],mxp_in3[0],mxp_in3[1],mxp_in3[2]); -} - - -export float4x4 mx_creatematrix_vector3_matrix44( - float3 mxp_in1 = float3(1.0, 0.0, 0.0), - float3 mxp_in2 = float3(0.0, 1.0, 0.0), - float3 mxp_in3 = float3(0.0, 0.0, 1.0) - float3 mxp_in4 = float3(0.0, 0.0, 0.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return float4x4(mxp_in1[0],mxp_in1[1],mxp_in1[2],0.0, mxp_in2[0],mxp_in2[1],mxp_in2[2],0.0, mxp_in3[0],mxp_in3[1],mxp_in3[2]0.0, mxp_in4[0],mxp_in4[1],mxp_in4[2],1.0); -} - - -export float4x4 mx_creatematrix_vector4_matrix44( - float4 mxp_in1 = float4(1.0, 0.0, 0.0, 0.0), - float4 mxp_in2 = float4(0.0, 1.0, 0.0, 0.0), - float4 mxp_in3 = float4(0.0, 0.0, 1.0, 0.0) - float4 mxp_in4 = float4(0.0, 0.0, 0.0, 1.0) -) - [[ - anno::description("Node Group: math") - ]] -{ - return float4x4(mxp_in1[0],mxp_in1[1],mxp_in1[2],mxp_in1[3],mxp_in2[0],mxp_in2[1],mxp_in2[2],mxp_in2[3],mxp_in3[0],mxp_in3[1],mxp_in3[2],mxp_in3[3],mxp_in4[0],mxp_in4[1],mxp_in4[2],mxp_in4[3]); -} - -// Nodedef: ND_extract_color3 is represented by a nodegraph: NG_extract_color3 -// Nodedef: ND_extract_color4 is represented by a nodegraph: NG_extract_color4 -// Nodedef: ND_extract_vector2 is represented by a nodegraph: NG_extract_vector2 -// Nodedef: ND_extract_vector3 is represented by a nodegraph: NG_extract_vector3 -// Nodedef: ND_extract_vector4 is represented by a nodegraph: NG_extract_vector4 -// Nodedef: ND_separate2_vector2 is represented by a nodegraph: NG_separate2_vector2 -// Nodedef: ND_separate3_color3 is represented by a nodegraph: NG_separate3_color3 -// Nodedef: ND_separate3_vector3 is represented by a nodegraph: NG_separate3_vector3 -// Nodedef: ND_separate4_color4 is represented by a nodegraph: NG_separate4_color4 -// Nodedef: ND_separate4_vector4 is represented by a nodegraph: NG_separate4_vector4 - -export float mx_blur_float( - float mxp_in = float(0.0), - float mxp_size = float(0.0) - [[ - anno::unused() - ]], - uniform mx_filter_type mxp_filtertype = mx_filter_type(mx_filter_type_box) - [[ - anno::description("Enumeration {box,gaussian}."), - anno::unused() - ]] -) - [[ - anno::description("Node Group: convolution2d") - ]] -{ - // Not implemented: mx_blur_float - float defaultValue = mxp_in; - return defaultValue; -} - -export color mx_blur_color3( - color mxp_in = color(0.0, 0.0, 0.0), - float mxp_size = float(0.0) - [[ - anno::unused() - ]], - uniform mx_filter_type mxp_filtertype = mx_filter_type(mx_filter_type_box) - [[ - anno::description("Enumeration {box,gaussian}."), - anno::unused() - ]] -) - [[ - anno::description("Node Group: convolution2d") - ]] -{ - // Not implemented: mx_blur_color3 - color defaultValue = mxp_in; - return defaultValue; -} - -export color4 mx_blur_color4( - color4 mxp_in = mk_color4(0.0, 0.0, 0.0, 0.0), - float mxp_size = float(0.0) - [[ - anno::unused() - ]], - uniform mx_filter_type mxp_filtertype = mx_filter_type(mx_filter_type_box) - [[ - anno::description("Enumeration {box,gaussian}."), - anno::unused() - ]] -) - [[ - anno::description("Node Group: convolution2d") - ]] -{ - // Not implemented: mx_blur_color4 - color4 defaultValue = mxp_in; - return defaultValue; -} - -export float2 mx_blur_vector2( - float2 mxp_in = float2(0.0, 0.0), - float mxp_size = float(0.0) - [[ - anno::unused() - ]], - uniform mx_filter_type mxp_filtertype = mx_filter_type(mx_filter_type_box) - [[ - anno::description("Enumeration {box,gaussian}."), - anno::unused() - ]] -) - [[ - anno::description("Node Group: convolution2d") - ]] -{ - // Not implemented: mx_blur_vector2 - float2 defaultValue = mxp_in; - return defaultValue; -} - -export float3 mx_blur_vector3( - float3 mxp_in = float3(0.0, 0.0, 0.0), - float mxp_size = float(0.0) - [[ - anno::unused() - ]], - uniform mx_filter_type mxp_filtertype = mx_filter_type(mx_filter_type_box) - [[ - anno::description("Enumeration {box,gaussian}."), - anno::unused() - ]] -) - [[ - anno::description("Node Group: convolution2d") - ]] -{ - // Not implemented: mx_blur_vector3 - float3 defaultValue = mxp_in; - return defaultValue; -} - -export float4 mx_blur_vector4( - float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), - float mxp_size = float(0.0) - [[ - anno::unused() - ]], - uniform mx_filter_type mxp_filtertype = mx_filter_type(mx_filter_type_box) - [[ - anno::description("Enumeration {box,gaussian}."), - anno::unused() - ]] -) - [[ - anno::description("Node Group: convolution2d") - ]] -{ - // Not implemented: mx_blur_vector4 - float4 defaultValue = mxp_in; - return defaultValue; -} - -export float3 mx_heighttonormal_vector3( - float mxp_in = float(0.0) [[ anno::unused() ]], - float mxp_scale = float(1.0) [[ anno::unused() ]] -) - [[ - anno::description("Node Group: convolution2d") - ]] -{ - // Not implemented: mx_heighttonormal_vector3 - float3 defaultValue = float3(0.0, 1.0, 0.0); - return defaultValue; -} - -export float mx_noise2d_float( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - float value = noise::mx_perlin_noise_float(mxp_texcoord); - return value * mxp_amplitude + mxp_pivot; -} - -export float2 mx_noise2d_float2( - float2 mxp_amplitude = float2(1.0), - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - float3 value = noise::mx_perlin_noise_float3(mxp_texcoord); - return swizzle::xy(value) * mxp_amplitude + mxp_pivot; -} - -export float3 mx_noise2d_float3( - float3 mxp_amplitude = float3(1.0), - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - float3 value = noise::mx_perlin_noise_float3(mxp_texcoord); - return value * mxp_amplitude + mxp_pivot; -} - -export float4 mx_noise2d_float4( - float4 mxp_amplitude = float4(1.0), - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - float3 v = noise::mx_perlin_noise_float3(mxp_texcoord); - float w = noise::mx_perlin_noise_float(mxp_texcoord + float2(19, 73)); - return float4(v.x, v.y, v.z, w) * mxp_amplitude + mxp_pivot; -} - -export color mx_noise2d_color3( - float3 mxp_amplitude = float3(1.0), - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - return color(mx_noise2d_float3(mxp_amplitude, mxp_pivot, mxp_texcoord)); -} - -export color4 mx_noise2d_color4( - float4 mxp_amplitude = float4(1.0), - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - float3 v = noise::mx_perlin_noise_float3(mxp_texcoord); - float w = noise::mx_perlin_noise_float(mxp_texcoord + float2(19, 73)); - return mk_color4(float4(v.x, v.y, v.z, w) * mxp_amplitude + float4(mxp_pivot)); -} - -export float2 mx_noise2d_float2FA( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - return mx_noise2d_float2(float2(mxp_amplitude), mxp_pivot, mxp_texcoord); -} - -export float3 mx_noise2d_float3FA( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - return mx_noise2d_float3(float3(mxp_amplitude), mxp_pivot, mxp_texcoord); -} - -export float4 mx_noise2d_float4FA( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - return mx_noise2d_float4(float4(mxp_amplitude), mxp_pivot, mxp_texcoord); -} - -export color mx_noise2d_color3FA( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - return mx_noise2d_color3(float3(mxp_amplitude), mxp_pivot, mxp_texcoord); -} - -export color4 mx_noise2d_color4FA( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - return mx_noise2d_color4(float4(mxp_amplitude), mxp_pivot, mxp_texcoord); -} - -export float mx_noise3d_float( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - float value = noise::mx_perlin_noise_float(mxp_position); - return value * mxp_amplitude + mxp_pivot; -} - -export float2 mx_noise3d_float2( - float2 mxp_amplitude = float2(1.0), - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - float3 value = noise::mx_perlin_noise_float3(mxp_position); - return swizzle::xy(value) * mxp_amplitude + mxp_pivot; -} - -export float3 mx_noise3d_float3( - float3 mxp_amplitude = float3(1.0), - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - float3 value = noise::mx_perlin_noise_float3(mxp_position); - return value * mxp_amplitude + mxp_pivot; -} - -export float4 mx_noise3d_float4( - float4 mxp_amplitude = float4(1.0), - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - float3 v = noise::mx_perlin_noise_float3(mxp_position); - float w = noise::mx_perlin_noise_float(mxp_position + float3(19, 73, 29)); - return float4(v.x, v.y, v.z, w) * mxp_amplitude + mxp_pivot; -} - -export color mx_noise3d_color3( - float3 mxp_amplitude = float3(1.0), - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return color(mx_noise3d_float3(mxp_amplitude, mxp_pivot, mxp_position)); -} - -export color4 mx_noise3d_color4( - float4 mxp_amplitude = float4(1.0), - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mk_color4(mx_noise3d_float4(mxp_amplitude, mxp_pivot, mxp_position)); -} - -export float2 mx_noise3d_float2FA( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mx_noise3d_float2(float2(mxp_amplitude), mxp_pivot, mxp_position); -} - -export float3 mx_noise3d_float3FA( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mx_noise3d_float3(float3(mxp_amplitude), mxp_pivot, mxp_position); -} - -export float4 mx_noise3d_float4FA( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mx_noise3d_float4(float4(mxp_amplitude), mxp_pivot, mxp_position); -} - -export color mx_noise3d_color3FA( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return color(mx_noise3d_float3(float3(mxp_amplitude), mxp_pivot, mxp_position)); -} - -export color4 mx_noise3d_color4FA( - float mxp_amplitude = 1.0, - float mxp_pivot = 0.0, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mk_color4(mx_noise3d_float4FA(mxp_amplitude, mxp_pivot, mxp_position)); -} - -export float mx_fractal3d_float( - float mxp_amplitude = 1.0, - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - float v = noise::mx_fractal_noise_float(mxp_position, mxp_octaves, mxp_lacunarity, mxp_diminish); - return v * mxp_amplitude; -} - -export float2 mx_fractal3d_float2( - float2 mxp_amplitude = float2(1.0), - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - float2 v = noise::mx_fractal_noise_float2(mxp_position, mxp_octaves, mxp_lacunarity, mxp_diminish); - return v * mxp_amplitude; -} - -export float3 mx_fractal3d_float3( - float3 mxp_amplitude = float3(1.0), - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - float3 v = noise::mx_fractal_noise_float3(mxp_position, mxp_octaves, mxp_lacunarity, mxp_diminish); - return v * mxp_amplitude; -} - -export float4 mx_fractal3d_float4( - float4 mxp_amplitude = float4(1.0), - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - float4 v = noise::mx_fractal_noise_float4(mxp_position, mxp_octaves, mxp_lacunarity, mxp_diminish); - return v * mxp_amplitude; -} - -export color mx_fractal3d_color3( - float3 mxp_amplitude = float3(1.0), - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - float3 v = noise::mx_fractal_noise_float3(mxp_position, mxp_octaves, mxp_lacunarity, mxp_diminish); - return color(v * mxp_amplitude); -} - -export color4 mx_fractal3d_color4( - float4 mxp_amplitude = float4(1.0), - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mk_color4(mx_fractal3d_float4(mxp_amplitude, mxp_octaves, mxp_lacunarity, mxp_diminish, mxp_position)); -} - -export float2 mx_fractal3d_float2FA( - float mxp_amplitude = 1.0, - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mx_fractal3d_float2(float2(mxp_amplitude), mxp_octaves, mxp_lacunarity, mxp_diminish, mxp_position); -} - -export float3 mx_fractal3d_float3FA( - float mxp_amplitude = 1.0, - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mx_fractal3d_float3(float3(mxp_amplitude), mxp_octaves, mxp_lacunarity, mxp_diminish, mxp_position); -} - -export float4 mx_fractal3d_float4FA( - float mxp_amplitude = 1.0, - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mx_fractal3d_float4(float4(mxp_amplitude), mxp_octaves, mxp_lacunarity, mxp_diminish, mxp_position); -} - -export color mx_fractal3d_color3FA( - float mxp_amplitude = 1.0, - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mx_fractal3d_color3(float3(mxp_amplitude), mxp_octaves, mxp_lacunarity, mxp_diminish, mxp_position); -} - -export color4 mx_fractal3d_color4FA( - float mxp_amplitude = 1.0, - int mxp_octaves = 3, - float mxp_lacunarity = 2.0, - float mxp_diminish= 0.5, - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return mx_fractal3d_color4(float4(mxp_amplitude), mxp_octaves, mxp_lacunarity, mxp_diminish, mxp_position); -} - -export float mx_cellnoise2d_float( - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) -) -{ - return noise::mx_cell_noise_float(mxp_texcoord); -} - -export float mx_cellnoise3d_float( - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) -) -{ - return noise::mx_cell_noise_float(mxp_position); -} - -export float mx_worleynoise2d_float( - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)), - float mxp_jitter = 1.0 -) -{ - return noise::mx_worley_noise_float(mxp_texcoord, mxp_jitter, 0); -} - -export float2 mx_worleynoise2d_float2( - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)), - float mxp_jitter = 1.0 -) -{ - return noise::mx_worley_noise_float2(mxp_texcoord, mxp_jitter, 0); -} - -export float3 mx_worleynoise2d_float3( - float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)), - float mxp_jitter = 1.0 -) -{ - return noise::mx_worley_noise_float3(mxp_texcoord, mxp_jitter, 0); -} - -export float mx_worleynoise3d_float( - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()), - float mxp_jitter = 1.0 -) -{ - return noise::mx_worley_noise_float(mxp_position, mxp_jitter, 0); -} - -export float2 mx_worleynoise3d_float2( - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()), - float mxp_jitter = 1.0 -) -{ - return noise::mx_worley_noise_float2(mxp_position, mxp_jitter, 0); -} - -export float3 mx_worleynoise3d_float3( - float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()), - float mxp_jitter = 1.0 -) -{ - return noise::mx_worley_noise_float3(mxp_position, mxp_jitter, 0); -} +// forward the latest version +export using .::stdlib_1_8 import *; diff --git a/source/MaterialXGenMdl/mdl/materialx/stdlib_1_6.mdl b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_6.mdl new file mode 100644 index 0000000000..e3161989b2 --- /dev/null +++ b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_6.mdl @@ -0,0 +1,4558 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// +// MDL Implementation of all types and nodes of +// MaterialX Physically-Based Shading Nodes +// Document v1.37 REV2, July 16, 2019 (Revised October 17, 2019) +// see www.materialx.org +// in +// NVIDIA Material Definition Language 1.6 +// Language Specification +// Document version 1.6.1, December 16, 2019 +// www.nvidia.com/mdl + +mdl 1.6; + +import ::df::*; +import ::anno::*; +import ::math::*; +import ::state::*; +import ::tex::*; + +import .::core::*; +import .::noise::*; +import .::swizzle::*; +import .::hsv::*; + +// NOTE: To insulate MaterialX names from MDL names, in particular +// conflicts with MDL reserved names, all node names, type names +// and enumeration names are prefixed with 'mx_', while all +// node input parameter names are prefixed with 'mxp_' + +// NOTE: We use the ::anno::unused() annotation to mark unsupported parameters + + +// Shader Nodes + +export material mx_surfacematerial( + material mxp_surfaceshader = material() [[ anno::usage( "materialx:surfaceshader") ]], + material mxp_displacementshader = material() [[ anno::usage( "materialx:displacementshader") ]] +) += material( + thin_walled: false, + surface: mxp_surfaceshader.surface, + backface: mxp_surfaceshader.backface, + geometry: material_geometry( + cutout_opacity: mxp_surfaceshader.geometry.cutout_opacity, + displacement : mxp_displacementshader.geometry.displacement, + normal: mxp_surfaceshader.geometry.normal + ), + ior: mxp_surfaceshader.ior, + volume: mxp_surfaceshader.volume +); + +export material mx_surface_unlit( + float mxp_emission = 0.0, + color mxp_emission_color = color(1.0, 1.0, 1.0), + float mxp_transmission = 0.0, + color mxp_transmission_color = color(1.0, 1.0, 1.0), + float mxp_opacity = 1.0 +) += let { + float trans = math::clamp(mxp_transmission, 0.0, 1.0); + bsdf bsdf_node = df::specular_bsdf(trans * mxp_transmission_color, df::scatter_transmit); + material_emission edf_node = material_emission(df::diffuse_edf(), (1.0 - trans) * mxp_emission * mxp_emission_color * math::PI); +} in material( + thin_walled: true, + surface: material_surface( + scattering: bsdf_node, + emission: edf_node + ), + geometry: material_geometry( + cutout_opacity: mxp_opacity + ) +); + +// Texture Nodes + +// Helper function mapping texture node addressmodes to MDL wrap modes +::tex::wrap_mode map_addressmode( core::mx_addressmode_type value) { + switch (value) { + case core::mx_addressmode_type_clamp: + return ::tex::wrap_clamp; + case core::mx_addressmode_type_mirror: + return ::tex::wrap_mirrored_repeat; + default: + return ::tex::wrap_repeat; + } +} + +// NOTE: need to map MaterialX return type overloads to different function names +// or we require the mx_default to be always set explicitly + +export float mx_image_float( + uniform texture_2d mxp_file = texture_2d() + [[ + anno::display_name("Filename") + ]], + uniform string mxp_layer = string("") + [[ + anno::display_name("Layer"), anno::unused() + ]], + float mxp_default = float(0.0) + [[ + anno::display_name("Default Color") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) + [[ + anno::display_name("Texture Coordinates") + ]], + uniform core::mx_addressmode_type mxp_uaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode U") + ]], + uniform core::mx_addressmode_type mxp_vaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode V") + ]], + uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) + [[ + anno::description("Enumeration {closest,linear,cubic}."), + anno::display_name("Filter Type"), + anno::unused() + ]], + uniform string mxp_framerange = string("") + [[ + anno::display_name("Frame Range"), + anno::unused() + ]], + uniform int mxp_frameoffset = int(0) + [[ + anno::display_name("Frame Offset"), + anno::unused() + ]], + uniform core::mx_addressmode_type mxp_frameendaction = core::mx_addressmode_type(core::mx_addressmode_type_constant) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Frame End Action"), + anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() + ]] +) + [[ + anno::description("Node Group: texture2d") + ]] +{ + if ( mxp_uaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) + return mxp_default; + if ( mxp_vaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) + return mxp_default; + + float returnValue = ::tex::lookup_float(tex: mxp_file, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, + wrap_u: map_addressmode(mxp_uaddressmode), + wrap_v: map_addressmode(mxp_vaddressmode)); + return returnValue; +} + +export color mx_image_color3( + uniform texture_2d mxp_file = texture_2d() + [[ + anno::display_name("Filename") + ]], + uniform string mxp_layer = string("") + [[ + anno::display_name("Layer"), anno::unused() + ]], + color mxp_default = color(0.0, 0.0, 0.0) + [[ + anno::display_name("Default Color") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) + [[ + anno::display_name("Texture Coordinates") + ]], + uniform core::mx_addressmode_type mxp_uaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode U") + ]], + uniform core::mx_addressmode_type mxp_vaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode V") + ]], + uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) + [[ + anno::description("Enumeration {closest,linear,cubic}."), + anno::display_name("Filter Type"), + anno::unused() + ]], + uniform string mxp_framerange = string("") + [[ + anno::display_name("Frame Range"), + anno::unused() + ]], + uniform int mxp_frameoffset = int(0) + [[ + anno::display_name("Frame Offset"), + anno::unused() + ]], + uniform core::mx_addressmode_type mxp_frameendaction = core::mx_addressmode_type(core::mx_addressmode_type_constant) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Frame End Action"), + anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() + ]] +) + [[ + anno::description("Node Group: texture2d") + ]] +{ + if ( mxp_uaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) + return mxp_default; + if ( mxp_vaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) + return mxp_default; + + color returnValue = ::tex::lookup_color(tex: mxp_file, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, + wrap_u: map_addressmode(mxp_uaddressmode), + wrap_v: map_addressmode(mxp_vaddressmode)); + return returnValue; +} + +export core::color4 mx_image_color4( + uniform texture_2d mxp_file = texture_2d() + [[ + anno::display_name("Filename") + ]], + uniform string mxp_layer = string("") + [[ + anno::display_name("Layer"), anno::unused() + ]], + core::color4 mxp_default = core::mk_color4(0.0, 0.0, 0.0, 0.0) + [[ + anno::display_name("Default Color") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) + [[ + anno::display_name("Texture Coordinates") + ]], + uniform core::mx_addressmode_type mxp_uaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode U") + ]], + uniform core::mx_addressmode_type mxp_vaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode V") + ]], + uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) + [[ + anno::description("Enumeration {closest,linear,cubic}."), + anno::display_name("Filter Type"), + anno::unused() + ]], + uniform string mxp_framerange = string("") + [[ + anno::display_name("Frame Range"), + anno::unused() + ]], + uniform int mxp_frameoffset = int(0) + [[ + anno::display_name("Frame Offset"), + anno::unused() + ]], + uniform core::mx_addressmode_type mxp_frameendaction = core::mx_addressmode_type(core::mx_addressmode_type_constant) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Frame End Action"), + anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() + ]] +) + [[ + anno::description("Node Group: texture2d") + ]] +{ + if ( mxp_uaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) + return mxp_default; + if ( mxp_vaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) + return mxp_default; + + core::color4 returnValue = core::mk_color4(::tex::lookup_float4(tex: mxp_file, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, + wrap_u: map_addressmode(mxp_uaddressmode), + wrap_v: map_addressmode(mxp_vaddressmode))); + return returnValue; +} + +export float2 mx_image_vector2( + uniform texture_2d mxp_file = texture_2d() + [[ + anno::display_name("Filename") + ]], + uniform string mxp_layer = string("") + [[ + anno::display_name("Layer"), anno::unused() + ]], + float2 mxp_default = float2(0.0, 0.0) + [[ + anno::display_name("Default Color") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) + [[ + anno::display_name("Texture Coordinates") + ]], + uniform core::mx_addressmode_type mxp_uaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode U") + ]], + uniform core::mx_addressmode_type mxp_vaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode V") + ]], + uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) + [[ + anno::description("Enumeration {closest,linear,cubic}."), + anno::display_name("Filter Type"), + anno::unused() + ]], + uniform string mxp_framerange = string("") + [[ + anno::display_name("Frame Range"), + anno::unused() + ]], + uniform int mxp_frameoffset = int(0) + [[ + anno::display_name("Frame Offset"), + anno::unused() + ]], + uniform core::mx_addressmode_type mxp_frameendaction = core::mx_addressmode_type(core::mx_addressmode_type_constant) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Frame End Action"), + anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() + ]] +) + [[ + anno::description("Node Group: texture2d") + ]] +{ + if ( mxp_uaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) + return mxp_default; + if ( mxp_vaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) + return mxp_default; + + float2 returnValue = ::tex::lookup_float2(tex: mxp_file, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, + wrap_u: map_addressmode(mxp_uaddressmode), + wrap_v: map_addressmode(mxp_vaddressmode)); + return returnValue; +} + +export float3 mx_image_vector3( + uniform texture_2d mxp_file = texture_2d() + [[ + anno::display_name("Filename") + ]], + uniform string mxp_layer = string("") + [[ + anno::display_name("Layer"), anno::unused() + ]], + float3 mxp_default = float3(0.0, 0.0, 0.0) + [[ + anno::display_name("Default Color") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) + [[ + anno::display_name("Texture Coordinates") + ]], + uniform core::mx_addressmode_type mxp_uaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode U") + ]], + uniform core::mx_addressmode_type mxp_vaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode V") + ]], + uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) + [[ + anno::description("Enumeration {closest,linear,cubic}."), + anno::display_name("Filter Type"), + anno::unused() + ]], + uniform string mxp_framerange = string("") + [[ + anno::display_name("Frame Range"), + anno::unused() + ]], + uniform int mxp_frameoffset = int(0) + [[ + anno::display_name("Frame Offset"), + anno::unused() + ]], + uniform core::mx_addressmode_type mxp_frameendaction = core::mx_addressmode_type(core::mx_addressmode_type_constant) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Frame End Action"), + anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() + ]] +) + [[ + anno::description("Node Group: texture2d") + ]] +{ + if ( mxp_uaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) + return mxp_default; + if ( mxp_vaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) + return mxp_default; + + float3 returnValue = ::tex::lookup_float3(tex: mxp_file, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, + wrap_u: map_addressmode(mxp_uaddressmode), + wrap_v: map_addressmode(mxp_vaddressmode)); + return returnValue; +} + +export float4 mx_image_vector4( + uniform texture_2d mxp_file = texture_2d() + [[ + anno::display_name("Filename") + ]], + uniform string mxp_layer = string("") + [[ + anno::display_name("Layer"), anno::unused() + ]], + float4 mxp_default = float4(0.0, 0.0, 0.0, 0.0) + [[ + anno::display_name("Default Color") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) + [[ + anno::display_name("Texture Coordinates") + ]], + uniform core::mx_addressmode_type mxp_uaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode U") + ]], + uniform core::mx_addressmode_type mxp_vaddressmode = core::mx_addressmode_type(core::mx_addressmode_type_periodic) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Address Mode V") + ]], + uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) + [[ + anno::description("Enumeration {closest,linear,cubic}."), + anno::display_name("Filter Type"), + anno::unused() + ]], + uniform string mxp_framerange = string("") + [[ + anno::display_name("Frame Range"), + anno::unused() + ]], + uniform int mxp_frameoffset = int(0) + [[ + anno::display_name("Frame Offset"), + anno::unused() + ]], + uniform core::mx_addressmode_type mxp_frameendaction = core::mx_addressmode_type(core::mx_addressmode_type_constant) + [[ + anno::description("Enumeration {constant,clamp,periodic,mirror}."), + anno::display_name("Frame End Action"), + anno::unused() + ]], + uniform bool mxp_flip_v = false + [[ + anno::usage("for applying the 'fileTextureVerticalFlip' shader generator option."), + anno::hidden() + ]] +) + [[ + anno::description("Node Group: texture2d") + ]] +{ + if ( mxp_uaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.x < 0.0 || mxp_texcoord.x > 1.0)) + return mxp_default; + if ( mxp_vaddressmode == core::mx_addressmode_type_constant + && ( mxp_texcoord.y < 0.0 || mxp_texcoord.y > 1.0)) + return mxp_default; + + float4 returnValue = ::tex::lookup_float4(tex: mxp_file, + coord: mxp_flip_v + ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) + : mxp_texcoord, + wrap_u: map_addressmode(mxp_uaddressmode), + wrap_v: map_addressmode(mxp_vaddressmode)); + return returnValue; +} + +// Nodedef: ND_tiledimage_float is represented by a nodegraph: NG_tiledimage_float +// Nodedef: ND_tiledimage_color3 is represented by a nodegraph: NG_tiledimage_color3 +// Nodedef: ND_tiledimage_color4 is represented by a nodegraph: NG_tiledimage_color4 +// Nodedef: ND_tiledimage_vector2 is represented by a nodegraph: NG_tiledimage_vector2 +// Nodedef: ND_tiledimage_vector3 is represented by a nodegraph: NG_tiledimage_vector3 +// Nodedef: ND_tiledimage_vector4 is represented by a nodegraph: NG_tiledimage_vector4 +// Nodedef: ND_triplanarprojection_float is represented by a nodegraph: NG_triplanarprojection_float +// Nodedef: ND_triplanarprojection_color3 is represented by a nodegraph: NG_triplanarprojection_color3 +// Nodedef: ND_triplanarprojection_color4 is represented by a nodegraph: NG_triplanarprojection_color4 +// Nodedef: ND_triplanarprojection_vector2 is represented by a nodegraph: NG_triplanarprojection_vector2 +// Nodedef: ND_triplanarprojection_vector3 is represented by a nodegraph: NG_triplanarprojection_vector3 +// Nodedef: ND_triplanarprojection_vector4 is represented by a nodegraph: NG_triplanarprojection_vector4 + +export float mx_constant_float( + float mxp_value = float(0.0) +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export color mx_constant_color3( + color mxp_value = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export core::color4 mx_constant_color4( + core::color4 mxp_value = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export float2 mx_constant_vector2( + float2 mxp_value = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export float3 mx_constant_vector3( + float3 mxp_value = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export float4 mx_constant_vector4( + float4 mxp_value = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export bool mx_constant_boolean( + bool mxp_value = bool(false) +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export int mx_constant_integer( + int mxp_value = int(0) +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export float3x3 mx_constant_matrix33( + float3x3 mxp_value = float3x3(1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0) +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export float4x4 mx_constant_matrix44( + float4x4 mxp_value = float4x4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export string mx_constant_string( + uniform string mxp_value = string("") +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export string mx_constant_filename( + uniform string mxp_value = string("") +) + [[ + anno::description("Node Group: procedural") + ]] +{ + return mxp_value; +} + +export float mx_ramplr_float( + float mxp_valuel = float(0.0), + float mxp_valuer = float(0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuel, mxp_valuer, math::clamp(mxp_texcoord.x, 0.0, 1.0)); +} + +export color mx_ramplr_color3( + color mxp_valuel = color(0.0, 0.0, 0.0), + color mxp_valuer = color(0.0, 0.0, 0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuel, mxp_valuer, math::clamp(mxp_texcoord.x, 0.0, 1.0)); +} + +export core::color4 mx_ramplr_color4( + core::color4 mxp_valuel = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_valuer = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + color rgb = math::lerp(mxp_valuel.rgb, mxp_valuer.rgb, math::clamp(mxp_texcoord.x, 0.0, 1.0)); + float a = math::lerp(mxp_valuel.a, mxp_valuer.a, math::clamp(mxp_texcoord.x, 0.0, 1.0)); + return core::color4(rgb, a);} + +export float2 mx_ramplr_vector2( + float2 mxp_valuel = float2(0.0, 0.0), + float2 mxp_valuer = float2(0.0, 0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuel, mxp_valuer, math::clamp(mxp_texcoord.x, 0.0, 1.0)); +} + +export float3 mx_ramplr_vector3( + float3 mxp_valuel = float3(0.0, 0.0, 0.0), + float3 mxp_valuer = float3(0.0, 0.0, 0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuel, mxp_valuer, math::clamp(mxp_texcoord.x, 0.0, 1.0)); +} + +export float4 mx_ramplr_vector4( + float4 mxp_valuel = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_valuer = float4(0.0, 0.0, 0.0, 0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuel, mxp_valuer, math::clamp(mxp_texcoord.x, 0.0, 1.0)); +} + +export float mx_ramptb_float( + float mxp_valuet = float(0.0), + float mxp_valueb = float(0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuet, mxp_valueb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); +} + +export color mx_ramptb_color3( + color mxp_valuet = color(0.0, 0.0, 0.0), + color mxp_valueb = color(0.0, 0.0, 0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuet, mxp_valueb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); +} + +export core::color4 mx_ramptb_color4( + core::color4 mxp_valuet = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_valueb = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + color rgb = math::lerp(mxp_valuet.rgb, mxp_valueb.rgb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); + float a = math::lerp(mxp_valuet.a, mxp_valueb.a, math::clamp(mxp_texcoord.y, 0.0, 1.0)); + return core::color4(rgb, a);} + +export float2 mx_ramptb_vector2( + float2 mxp_valuet = float2(0.0, 0.0), + float2 mxp_valueb = float2(0.0, 0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuet, mxp_valueb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); +} + +export float3 mx_ramptb_vector3( + float3 mxp_valuet = float3(0.0, 0.0, 0.0), + float3 mxp_valueb = float3(0.0, 0.0, 0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuet, mxp_valueb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); +} + +export float4 mx_ramptb_vector4( + float4 mxp_valuet = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_valueb = float4(0.0, 0.0, 0.0, 0.0), + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuet, mxp_valueb, math::clamp(mxp_texcoord.y, 0.0, 1.0)); +} + +// Nodedef: ND_ramp4_float is represented by a nodegraph: NG_ramp4_float +// Nodedef: ND_ramp4_color3 is represented by a nodegraph: NG_ramp4_color3 +// Nodedef: ND_ramp4_color4 is represented by a nodegraph: NG_ramp4_color4 +// Nodedef: ND_ramp4_vector2 is represented by a nodegraph: NG_ramp4_vector2 +// Nodedef: ND_ramp4_vector3 is represented by a nodegraph: NG_ramp4_vector3 +// Nodedef: ND_ramp4_vector4 is represented by a nodegraph: NG_ramp4_vector4 + +export float mx_splitlr_float( + float mxp_valuel = float(0.0) + [[ + anno::display_name("Left") + ]], + float mxp_valuer = float(0.0) + [[ + anno::display_name("Right") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuel, mxp_valuer, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); +} + +export color mx_splitlr_color3( + color mxp_valuel = color(0.0, 0.0, 0.0) + [[ + anno::display_name("Left") + ]], + color mxp_valuer = color(0.0, 0.0, 0.0) + [[ + anno::display_name("Right") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuel, mxp_valuer, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); +} + +export core::color4 mx_splitlr_color4( + core::color4 mxp_valuel = core::mk_color4(0.0, 0.0, 0.0, 0.0) + [[ + anno::display_name("Left") + ]], + core::color4 mxp_valuer = core::mk_color4(0.0, 0.0, 0.0, 0.0) + [[ + anno::display_name("Right") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + color rgb = math::lerp(mxp_valuel.rgb, mxp_valuer.rgb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); + float a = math::lerp(mxp_valuel.a, mxp_valuer.a, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); + return core::color4(rgb, a); +} + +export float2 mx_splitlr_vector2( + float2 mxp_valuel = float2(0.0, 0.0) + [[ + anno::display_name("Left") + ]], + float2 mxp_valuer = float2(0.0, 0.0) + [[ + anno::display_name("Right") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuel, mxp_valuer, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); +} + +export float3 mx_splitlr_vector3( + float3 mxp_valuel = float3(0.0, 0.0, 0.0) + [[ + anno::display_name("Left") + ]], + float3 mxp_valuer = float3(0.0, 0.0, 0.0) + [[ + anno::display_name("Right") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuel, mxp_valuer, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); +} + +export float4 mx_splitlr_vector4( + float4 mxp_valuel = float4(0.0, 0.0, 0.0, 0.0) + [[ + anno::display_name("Left") + ]], + float4 mxp_valuer = float4(0.0, 0.0, 0.0, 0.0) + [[ + anno::display_name("Right") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuel, mxp_valuer, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); +} + +export float mx_splittb_float( + float mxp_valuet = float(0.0) + [[ + anno::display_name("Top") + ]], + float mxp_valueb = float(0.0) + [[ + anno::display_name("Bottom") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuet, mxp_valueb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); +} + +export color mx_splittb_color3( + color mxp_valuet = color(0.0, 0.0, 0.0) + [[ + anno::display_name("Top") + ]], + color mxp_valueb = color(0.0, 0.0, 0.0) + [[ + anno::display_name("Bottom") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuet, mxp_valueb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); +} + +export core::color4 mx_splittb_color4( + core::color4 mxp_valuet = core::mk_color4(0.0, 0.0, 0.0, 0.0) + [[ + anno::display_name("Top") + ]], + core::color4 mxp_valueb = core::mk_color4(0.0, 0.0, 0.0, 0.0) + [[ + anno::display_name("Bottom") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + color rgb = math::lerp(mxp_valuet.rgb, mxp_valueb.rgb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); float a = math::lerp(mxp_valuet.a, mxp_valueb.a, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); return core::color4(rgb, a); +} + +export float2 mx_splittb_vector2( + float2 mxp_valuet = float2(0.0, 0.0) + [[ + anno::display_name("Top") + ]], + float2 mxp_valueb = float2(0.0, 0.0) + [[ + anno::display_name("Bottom") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuet, mxp_valueb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); +} + +export float3 mx_splittb_vector3( + float3 mxp_valuet = float3(0.0, 0.0, 0.0) + [[ + anno::display_name("Top") + ]], + float3 mxp_valueb = float3(0.0, 0.0, 0.0) + [[ + anno::display_name("Bottom") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuet, mxp_valueb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); +} + +export float4 mx_splittb_vector4( + float4 mxp_valuet = float4(0.0, 0.0, 0.0, 0.0) + [[ + anno::display_name("Top") + ]], + float4 mxp_valueb = float4(0.0, 0.0, 0.0, 0.0) + [[ + anno::display_name("Bottom") + ]], + float mxp_center = float(0.5) + [[ + anno::display_name("Center") + ]], + float2 mxp_texcoord = float2(swizzle::xy(::state::texture_coordinate(0))) +) + [[ + anno::description("Node Group: procedural2d") + ]] +{ + return math::lerp(mxp_valuet, mxp_valueb, math::step(mxp_center, math::clamp(mxp_texcoord.x,0,1))); +} + +export float3 mx_position_vector3( + uniform core::mx_coordinatespace_type mxp_space = core::mx_coordinatespace_type(core::mx_coordinatespace_type_object) + [[ + anno::description("Enumeration {model,object,world}.") + ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + state::coordinate_space fromSpace = ::core::mx_map_space(core::mx_coordinatespace_type_model); + state::coordinate_space toSpace = ::core::mx_map_space(mxp_space); + return state::transform_point(fromSpace, toSpace, state::position()); +} + +export float3 mx_normal_vector3( + uniform core::mx_coordinatespace_type mxp_space = core::mx_coordinatespace_type(core::mx_coordinatespace_type_object) + [[ + anno::description("Enumeration {model,object,world}.") + ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + state::coordinate_space fromSpace = ::core::mx_map_space(core::mx_coordinatespace_type_model); + state::coordinate_space toSpace = ::core::mx_map_space(mxp_space); + return state::transform_normal(fromSpace, toSpace, state::normal()); +} + +export float3 mx_tangent_vector3( + uniform core::mx_coordinatespace_type mxp_space = core::mx_coordinatespace_type(core::mx_coordinatespace_type_object) + [[ + anno::description("Enumeration {model,object,world}.") + ]], + uniform int mxp_index = int(0) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + state::coordinate_space fromSpace = ::core::mx_map_space(core::mx_coordinatespace_type_model); + state::coordinate_space toSpace = ::core::mx_map_space(mxp_space); + return ::math::normalize(state::transform_vector(fromSpace, toSpace, state::texture_tangent_u(mxp_index))); +} + +export float3 mx_bitangent_vector3( + uniform core::mx_coordinatespace_type mxp_space = core::mx_coordinatespace_type(core::mx_coordinatespace_type_object) + [[ + anno::description("Enumeration {model,object,world}.") + ]], + uniform int mxp_index = int(0) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + state::coordinate_space fromSpace = ::core::mx_map_space(core::mx_coordinatespace_type_model); + state::coordinate_space toSpace = ::core::mx_map_space(mxp_space); + return ::math::normalize(state::transform_vector(fromSpace, toSpace, state::texture_tangent_v(mxp_index))); +} + +export float2 mx_texcoord_vector2( + uniform int mxp_index = int(0) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + return swizzle::xy((state::texture_coordinate(mxp_index))); +} + +export float3 mx_texcoord_vector3( + uniform int mxp_index = int(0) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + return state::texture_coordinate(mxp_index); +} + +export float mx_geomcolor_float( + uniform int mxp_index = int(0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geomcolor_float + float defaultValue = float(0.0); + return defaultValue; +} + +export color mx_geomcolor_color3( + uniform int mxp_index = int(0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geomcolor_color3 + color defaultValue = color(0.0, 0.0, 0.0); + return defaultValue; +} + +export core::color4 mx_geomcolor_color4( + uniform int mxp_index = int(0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geomcolor_color4 + core::color4 defaultValue = core::mk_color4(0.0, 0.0, 0.0, 0.0); + return defaultValue; +} + +export int mx_geompropvalue_integer( + uniform string mxp_geomprop = string("") [[ anno::unused() ]], + int mxp_default = int(0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geompropvalue_integer + int defaultValue = int(0); + return defaultValue; +} + +export bool mx_geompropvalue_boolean( + uniform string mxp_geomprop = string("") [[ anno::unused() ]], + bool mxp_default = bool(false) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geompropvalue_boolean + bool defaultValue = bool(false); + return defaultValue; +} + +export string mx_geompropvalue_string( + uniform string mxp_geomprop = string("") [[ anno::unused() ]], + string mxp_default = string("") [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geompropvalue_string + string defaultValue; + return defaultValue; +} + +export float mx_geompropvalue_float( + uniform string mxp_geomprop = string("") [[ anno::unused() ]], + float mxp_default = float(0.0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geompropvalue_float + float defaultValue = float(0.0); + return defaultValue; +} + +export color mx_geompropvalue_color3( + uniform string mxp_geomprop = string("") [[ anno::unused() ]], + color mxp_default = color(0.0, 0.0, 0.0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geompropvalue_color3 + color defaultValue = color(0.0, 0.0, 0.0); + return defaultValue; +} + +export core::color4 mx_geompropvalue_color4( + uniform string mxp_geomprop = string("") [[ anno::unused() ]], + core::color4 mxp_default = core::mk_color4(0.0, 0.0, 0.0, 0.0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geompropvalue_color4 + core::color4 defaultValue = core::mk_color4(0.0, 0.0, 0.0, 0.0); + return defaultValue; +} + +export float2 mx_geompropvalue_vector2( + uniform string mxp_geomprop = string("") [[ anno::unused() ]], + float2 mxp_default = float2(0.0, 0.0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geompropvalue_vector2 + float2 defaultValue = float2(0.0, 0.0); + return defaultValue; +} + +export float3 mx_geompropvalue_vector3( + uniform string mxp_geomprop = string("") [[ anno::unused() ]], + float3 mxp_default = float3(0.0, 0.0, 0.0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geompropvalue_vector3 + float3 defaultValue = float3(0.0, 0.0, 0.0); + return defaultValue; +} + +export float4 mx_geompropvalue_vector4( + uniform string mxp_geomprop = string("") [[ anno::unused() ]], + float4 mxp_default = float4(0.0, 0.0, 0.0, 0.0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: geometric") + ]] +{ + // Not implemented: mx_geompropvalue_vector4 + float4 defaultValue = float4(0.0, 0.0, 0.0, 0.0); + return defaultValue; +} + +export float mx_ambientocclusion_float( + float mxp_coneangle = float(90.0) + [[ + anno::description("Unit Type:angle. Unit:degrees."), + anno::unused() + ]], + float mxp_maxdistance = float(1e38) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: global") + ]] +{ + // Not implemented: mx_ambientocclusion_float + float defaultValue = float(1.0); + return defaultValue; +} + +export float mx_frame_float( +) + [[ + anno::description("Node Group: application") + ]] +{ + // Not implemented: mx_frame_float + float defaultValue = float(1.0); + return defaultValue; +} + +export float mx_time_float( + uniform float mxp_fps = float(24.0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: application") + ]] +{ + return ::state::animation_time(); +} + +export float3 mx_viewdirection_vector3( + uniform core::mx_coordinatespace_type mxp_space = core::mx_coordinatespace_type_world + [[ + anno::description("Enumeration {model,object,world}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: nprlib") + ]] +{ + // Not implemented: mx_viewdirection_vector3 + float3 defaultValue = float3(0.0, 0.0, 1.0); + return defaultValue; +} + +export color mx_modulo_color3( + color mxp_in1 = color(0.0, 0.0, 0.0), + color mxp_in2 = color(1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return color(core::mx_mod(float3(mxp_in1), float3(mxp_in2))); +} + +export core::color4 mx_modulo_color4( + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(1.0, 1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(core::mx_mod(core::mk_float4(mxp_in1), core::mk_float4(mxp_in2))); +} + +export color mx_modulo_color3FA( + color mxp_in1 = color(0.0, 0.0, 0.0), + float mxp_in2 = float(1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return color(core::mx_mod(float3(mxp_in1), float3(mxp_in2))); +} + +export core::color4 mx_modulo_color4FA( + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_in2 = float(1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(core::mx_mod(core::mk_float4(mxp_in1), float4(mxp_in2))); +} + +export core::color4 mx_invert_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_amount = core::mk_color4(1.0, 1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(core::mk_float4(mxp_amount) - core::mk_float4(mxp_in)); +} + +export core::color4 mx_invert_color4FA( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_amount = float(1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(float4(mxp_amount) - core::mk_float4(mxp_in)); +} + +export core::color4 mx_absval_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::abs(core::mk_float4(mxp_in))); +} + +export color mx_floor_color3( + color mxp_in = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return color(::math::floor(float3(mxp_in))); +} + +export core::color4 mx_floor_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::floor(core::mk_float4(mxp_in))); +} + +export color mx_ceil_color3( + color mxp_in = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return color(::math::ceil(float3(mxp_in))); +} + +export core::color4 mx_ceil_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::ceil(core::mk_float4(mxp_in))); +} + +export core::color4 mx_power_color4( + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(1.0, 1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::pow(core::mk_float4(mxp_in1), core::mk_float4(mxp_in2))); +} + +export core::color4 mx_power_color4FA( + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_in2 = float(1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::pow(core::mk_float4(mxp_in1), float4(mxp_in2))); +} + +export float mx_sin_float( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::sin(mxp_in); +} + +export float mx_cos_float( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::cos(mxp_in); +} + +export float mx_tan_float( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::tan(mxp_in); +} + +export float mx_asin_float( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::asin(mxp_in); +} + +export float mx_acos_float( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::acos(mxp_in); +} + +export float mx_atan2_float( + float mxp_in1 = float(1.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::atan2(mxp_in1, mxp_in2); +} + +export float2 mx_sin_vector2( + float2 mxp_in = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::sin(mxp_in); +} + +export float2 mx_cos_vector2( + float2 mxp_in = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::cos(mxp_in); +} + +export float2 mx_tan_vector2( + float2 mxp_in = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::tan(mxp_in); +} + +export float2 mx_asin_vector2( + float2 mxp_in = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::asin(mxp_in); +} + +export float2 mx_acos_vector2( + float2 mxp_in = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::acos(mxp_in); +} + +export float2 mx_atan2_vector2( + float2 mxp_in1 = float2(1.0, 1.0), + float2 mxp_in2 = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::atan2(mxp_in1, mxp_in2); +} + +export float3 mx_sin_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::sin(mxp_in); +} + +export float3 mx_cos_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::cos(mxp_in); +} + +export float3 mx_tan_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::tan(mxp_in); +} + +export float3 mx_asin_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::asin(mxp_in); +} + +export float3 mx_acos_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::acos(mxp_in); +} + +export float3 mx_atan2_vector3( + float3 mxp_in1 = float3(1.0, 1.0, 1.0), + float3 mxp_in2 = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::atan2(mxp_in1, mxp_in2); +} + +export float4 mx_sin_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::sin(mxp_in); +} + +export float4 mx_cos_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::cos(mxp_in); +} + +export float4 mx_tan_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::tan(mxp_in); +} + +export float4 mx_asin_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::asin(mxp_in); +} + +export float4 mx_acos_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::acos(mxp_in); +} + +export float4 mx_atan2_vector4( + float4 mxp_in1 = float4(1.0, 1.0, 1.0, 1.0), + float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::atan2(mxp_in1, mxp_in2); +} + +export float mx_sqrt_float( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::sqrt(mxp_in); +} + +export float mx_ln_float( + float mxp_in = float(1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::log(mxp_in); +} + +export float mx_exp_float( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::exp(mxp_in); +} + +export float2 mx_sqrt_vector2( + float2 mxp_in = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::sqrt(mxp_in); +} + +export float2 mx_ln_vector2( + float2 mxp_in = float2(1.0, 1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::log(mxp_in); +} + +export float2 mx_exp_vector2( + float2 mxp_in = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::exp(mxp_in); +} + +export float3 mx_sqrt_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::sqrt(mxp_in); +} + +export float3 mx_ln_vector3( + float3 mxp_in = float3(1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::log(mxp_in); +} + +export float3 mx_exp_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::exp(mxp_in); +} + +export float4 mx_sqrt_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::sqrt(mxp_in); +} + +export float4 mx_ln_vector4( + float4 mxp_in = float4(1.0, 1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::log(mxp_in); +} + +export float4 mx_exp_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::exp(mxp_in); +} + +export color mx_sign_color3( + color mxp_in = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return color(::math::sign(float3(mxp_in))); +} + +export core::color4 mx_sign_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::sign(core::mk_float4(mxp_in))); +} + +export core::color4 mx_clamp_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_low = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_high = core::mk_color4(1.0, 1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::clamp(core::mk_float4(mxp_in), core::mk_float4(mxp_low), core::mk_float4(mxp_high))); +} + +export core::color4 mx_clamp_color4FA( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_low = float(0.0), + float mxp_high = float(1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::clamp(core::mk_float4(mxp_in), float4(mxp_low), float4(mxp_high))); +} + +export core::color4 mx_min_color4( + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::min(core::mk_float4(mxp_in1), core::mk_float4(mxp_in2))); +} + +export core::color4 mx_min_color4( + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::min(core::mk_float4(mxp_in1), float4(mxp_in2))); +} + +export core::color4 mx_max_color4( + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::max(core::mk_float4(mxp_in1), core::mk_float4(mxp_in2))); +} + +export core::color4 mx_max_color4( + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return core::mk_color4(::math::max(core::mk_float4(mxp_in1), float4(mxp_in2))); +} + +export float3 mx_transformpoint_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0), + uniform string mxp_fromspace = "object", + uniform string mxp_tospace = "world" +) + [[ + anno::description("Node Group: math") + ]] +{ + state::coordinate_space fromSpace = ::core::mx_map_space(mxp_fromspace); + state::coordinate_space toSpace = ::core::mx_map_space(mxp_tospace); + return state::transform_point(fromSpace, toSpace, mxp_in); +} + +export float3 mx_transformvector_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0), + uniform string mxp_fromspace = "object", + uniform string mxp_tospace = "world" +) + [[ + anno::description("Node Group: math") + ]] +{ + state::coordinate_space fromSpace = ::core::mx_map_space(mxp_fromspace); + state::coordinate_space toSpace = ::core::mx_map_space(mxp_tospace); + return state::transform_vector(fromSpace, toSpace, mxp_in); +} + +export float3 mx_transformnormal_vector3( + float3 mxp_in = float3(0.0, 0.0, 1.0), + uniform string mxp_fromspace = "object", + uniform string mxp_tospace = "world" +) + [[ + anno::description("Node Group: math") + ]] +{ + state::coordinate_space fromSpace = ::core::mx_map_space(mxp_fromspace); + state::coordinate_space toSpace = ::core::mx_map_space(mxp_tospace); + return state::transform_normal(fromSpace, toSpace, mxp_in); +} + +export float2 mx_transformmatrix_vector2M3( + float2 mxp_in = float2(0.0, 0.0), + float3x3 mxp_mat = float3x3(1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + float3 returnValue = mxp_mat * float3(mxp_in.x, mxp_in.y, 1.0); + return float2(returnValue.x, returnValue.y); +} + +export float3 mx_transformmatrix_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0), + float3x3 mxp_mat = float3x3(1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return mxp_mat * mxp_in; +} + +export float3 mx_transformmatrix_vector3M4( + float3 mxp_in = float3(0.0, 0.0, 0.0), + float4x4 mxp_mat = float4x4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + float4 returnValue = mxp_mat * float4(mxp_in.x, mxp_in.y, mxp_in.z, 1.0); + return float3(returnValue.x, returnValue.y, returnValue.z); +} + +export float4 mx_transformmatrix_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), + float4x4 mxp_mat = float4x4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return mxp_mat * mxp_in; +} + +export float3 mx_normalmap_vector2( + float3 mxp_in = float3(0.5, 0.5, 1.0), + uniform string mxp_space = string("tangent") + [[ + anno::description("Enumeration {tangent, object}.") + ]], + float2 mxp_scale = float2(1.0, 1.0), + float3 mxp_normal = float3(::state::transform_normal(::state::coordinate_internal,::state::coordinate_world,::state::normal())), + float3 mxp_tangent = float3(state::transform_vector(::state::coordinate_internal,::state::coordinate_world,::state::texture_tangent_u(0))) +) + [[ + anno::description("Node Group: math") + ]] +{ + if (mxp_space == "tangent") + { + float3 v = mxp_in * 2.0 - 1.0; + float3 binormal = ::math::normalize(::math::cross(mxp_normal, mxp_tangent)); + return ::math::normalize(mxp_tangent * v.x * mxp_scale.x + binormal * v.y * mxp_scale.y + mxp_normal * v.z); + } + else + { + float3 n = mxp_in * 2.0 - 1.0; + return ::math::normalize(n); + } +} + +export float3 mx_normalmap_float( + float3 mxp_in = float3(0.5, 0.5, 1.0), + uniform string mxp_space = string("tangent") + [[ + anno::description("Enumeration {tangent, object}.") + ]], + float mxp_scale = float(1.0), + float3 mxp_normal = float3(::state::transform_normal(::state::coordinate_internal,::state::coordinate_world,::state::normal())), + float3 mxp_tangent = float3(state::transform_vector(::state::coordinate_internal,::state::coordinate_world,::state::texture_tangent_u(0))) +) + [[ + anno::description("Node Group: math") + ]] +{ + return mx_normalmap_vector2(mxp_in, mxp_space, float2(mxp_scale, mxp_scale), mxp_normal, mxp_tangent); +} + +export float3x3 mx_transpose_matrix33( + float3x3 mxp_in = float3x3(1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::transpose(mxp_in); +} + +export float4x4 mx_transpose_matrix44( + float4x4 mxp_in = float4x4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return ::math::transpose(mxp_in); +} + +export float mx_determinant_matrix33(float3x3 mxp_in) +[[ + anno::description("Node Group: math") +]] +{ + return mxp_in[0][0] * (mxp_in[2][2]*mxp_in[1][1] - mxp_in[1][2]*mxp_in[2][1]) + + mxp_in[0][1] * (mxp_in[1][2]*mxp_in[2][0] - mxp_in[2][2]*mxp_in[1][0]) + + mxp_in[0][2] * (mxp_in[2][1]*mxp_in[1][0] - mxp_in[1][1]*mxp_in[2][0]); +} + +export float mx_determinant_matrix44(float4x4 mxp_in) +[[ + anno::description("Node Group: math") +]] +{ + float + b00 = mxp_in[0][0] * mxp_in[1][1] - mxp_in[0][1] * mxp_in[1][0], + b01 = mxp_in[0][0] * mxp_in[1][2] - mxp_in[0][2] * mxp_in[1][0], + b02 = mxp_in[0][0] * mxp_in[1][3] - mxp_in[0][3] * mxp_in[1][0], + b03 = mxp_in[0][1] * mxp_in[1][2] - mxp_in[0][2] * mxp_in[1][1], + b04 = mxp_in[0][1] * mxp_in[1][3] - mxp_in[0][3] * mxp_in[1][1], + b05 = mxp_in[0][2] * mxp_in[1][3] - mxp_in[0][3] * mxp_in[1][2], + b06 = mxp_in[2][0] * mxp_in[3][1] - mxp_in[2][1] * mxp_in[3][0], + b07 = mxp_in[2][0] * mxp_in[3][2] - mxp_in[2][2] * mxp_in[3][0], + b08 = mxp_in[2][0] * mxp_in[3][3] - mxp_in[2][3] * mxp_in[3][0], + b09 = mxp_in[2][1] * mxp_in[3][2] - mxp_in[2][2] * mxp_in[3][1], + b10 = mxp_in[2][1] * mxp_in[3][3] - mxp_in[2][3] * mxp_in[3][1], + b11 = mxp_in[2][2] * mxp_in[3][3] - mxp_in[2][3] * mxp_in[3][2]; + return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; +} + +export float3x3 mx_invertmatrix_matrix33( + float3x3 mxp_in = float3x3(1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + // Not implemented: mx_invertmatrix_matrix33 + float3x3 defaultValue = mxp_in; + return defaultValue; +} + +export float4x4 mx_invertmatrix_matrix44( + float4x4 mxp_in = float4x4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + // Not implemented: mx_invertmatrix_matrix44 + float4x4 defaultValue = mxp_in; + return defaultValue; +} + +export float2 mx_rotate2d_vector2( + float2 mxp_in = float2(0.0, 0.0), + float mxp_amount = float(0.0) + [[ + anno::description("Unit Type:angle. Unit:degrees.") + ]] +) +[[ + anno::description("Node Group: math") +]] +{ + float angleRadians = math::radians(mxp_amount); + float sinAngle = math::sin(angleRadians); + float cosAngle = math::cos(angleRadians); + return float2(cosAngle*mxp_in.x + sinAngle*mxp_in.y, -sinAngle*mxp_in.x + cosAngle*mxp_in.y); +} + +float4x4 mx_rotationMatrix(float3 mxp_axis, float mxp_amount) +{ + float sinAngle = math::sin(mxp_amount); + float cosAngle = math::cos(mxp_amount); + float oc = 1.0 - cosAngle; + + return float4x4( + oc * mxp_axis.x * mxp_axis.x + cosAngle, oc * mxp_axis.x * mxp_axis.y - mxp_axis.z * sinAngle, oc * mxp_axis.z * mxp_axis.x + mxp_axis.y * sinAngle, 0.0, + oc * mxp_axis.x * mxp_axis.y + mxp_axis.z * sinAngle, oc * mxp_axis.y * mxp_axis.y + cosAngle, oc * mxp_axis.y * mxp_axis.z - mxp_axis.x * sinAngle, 0.0, + oc * mxp_axis.z * mxp_axis.x - mxp_axis.y * sinAngle, oc * mxp_axis.y * mxp_axis.z + mxp_axis.x * sinAngle, oc * mxp_axis.z * mxp_axis.z + cosAngle, 0.0, + 0.0, 0.0, 0.0, 1.0); +} + +export float3 mx_rotate3d_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0), + float mxp_amount = float(0.0) + [[ + anno::description("Unit Type:angle. Unit:degrees.") + ]], + float3 mxp_axis = float3(0.0, 1.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + float angleRadians = math::radians(mxp_amount); + float4x4 m = mx_rotationMatrix(mxp_axis, angleRadians); + float4 v = m * float4(mxp_in.x, mxp_in.y, mxp_in.z, 1.0); + return float3(v.x, v.y, v.z); +} + +// Nodedef: ND_place2d_vector2 is represented by a nodegraph: NG_place2d_vector2 + +export float mx_remap_float( + float mxp_in = float(0.0), + float mxp_inlow = float(0.0), + float mxp_inhigh = float(1.0), + float mxp_outlow = float(0.0), + float mxp_outhigh = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); +} + +export color mx_remap_color3( + color mxp_in = color(0.0, 0.0, 0.0), + color mxp_inlow = color(0.0, 0.0, 0.0), + color mxp_inhigh = color(1.0, 1.0, 1.0), + color mxp_outlow = color(0.0, 0.0, 0.0), + color mxp_outhigh = color(1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); +} + +export core::color4 mx_remap_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_inlow = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_inhigh = core::mk_color4(1.0, 1.0, 1.0, 1.0), + core::color4 mxp_outlow = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_outhigh = core::mk_color4(1.0, 1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + core::color4 val = mxp_outlow; + core::color4 val2 = core::mx_add(val, core::mx_subtract(mxp_in, mxp_inlow)); + core::color4 val3 = core::mx_multiply(val2, core::mx_subtract(mxp_outhigh, mxp_outlow)); + return core::mx_divide(val3, core::mx_subtract(mxp_inhigh, mxp_inlow)); +} + +export float2 mx_remap_vector2( + float2 mxp_in = float2(0.0, 0.0), + float2 mxp_inlow = float2(0.0, 0.0), + float2 mxp_inhigh = float2(1.0, 1.0), + float2 mxp_outlow = float2(0.0, 0.0), + float2 mxp_outhigh = float2(1.0, 1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); +} + +export float3 mx_remap_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0), + float3 mxp_inlow = float3(0.0, 0.0, 0.0), + float3 mxp_inhigh = float3(1.0, 1.0, 1.0), + float3 mxp_outlow = float3(0.0, 0.0, 0.0), + float3 mxp_outhigh = float3(1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); +} + +export float4 mx_remap_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_inlow = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_inhigh = float4(1.0, 1.0, 1.0, 1.0), + float4 mxp_outlow = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_outhigh = float4(1.0, 1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); +} + +export color mx_remap_color3FA( + color mxp_in = color(0.0, 0.0, 0.0), + float mxp_inlow = float(0.0), + float mxp_inhigh = float(1.0), + float mxp_outlow = float(0.0), + float mxp_outhigh = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); +} + +export core::color4 mx_remap_color4FA( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_inlow = float(0.0), + float mxp_inhigh = float(1.0), + float mxp_outlow = float(0.0), + float mxp_outhigh = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + core::color4 val = core::mk_color4(mxp_outlow); + core::color4 val2 = core::mx_add(val, core::mx_subtract(mxp_in, core::mk_color4(mxp_inlow))); + core::color4 val3 = core::mx_multiply(val2, core::mx_subtract(core::mk_color4(mxp_outhigh), core::mk_color4(mxp_outlow))); + return core::mx_divide(val3, core::mx_subtract(core::mk_color4(mxp_inhigh), core::mk_color4(mxp_inlow))); +} + +export float2 mx_remap_vector2FA( + float2 mxp_in = float2(0.0, 0.0), + float mxp_inlow = float(0.0), + float mxp_inhigh = float(1.0), + float mxp_outlow = float(0.0), + float mxp_outhigh = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); +} + +export float3 mx_remap_vector3FA( + float3 mxp_in = float3(0.0, 0.0, 0.0), + float mxp_inlow = float(0.0), + float mxp_inhigh = float(1.0), + float mxp_outlow = float(0.0), + float mxp_outhigh = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); +} + +export float4 mx_remap_vector4FA( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), + float mxp_inlow = float(0.0), + float mxp_inhigh = float(1.0), + float mxp_outlow = float(0.0), + float mxp_outhigh = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return mxp_outlow + (mxp_in - mxp_inlow) * (mxp_outhigh - mxp_outlow) / (mxp_inhigh - mxp_inlow); +} + +export float mx_smoothstep_float( + float mxp_in = float(0.0), + float mxp_low = float(0.0), + float mxp_high = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return ::math::smoothstep(float(mxp_low), float(mxp_high), float(mxp_in)); +} + +export color mx_smoothstep_color3( + color mxp_in = color(0.0, 0.0, 0.0), + color mxp_low = color(0.0, 0.0, 0.0), + color mxp_high = color(1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return color(::math::smoothstep(float3(mxp_low), float3(mxp_high), float3(mxp_in))); +} + +export core::color4 mx_smoothstep_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_low = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_high = core::mk_color4(1.0, 1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return core::mk_color4(::math::smoothstep(core::mk_float4(mxp_low), core::mk_float4(mxp_high), core::mk_float4(mxp_in))); +} + +export float2 mx_smoothstep_vector2( + float2 mxp_in = float2(0.0, 0.0), + float2 mxp_low = float2(0.0, 0.0), + float2 mxp_high = float2(1.0, 1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return ::math::smoothstep(float2(mxp_low), float2(mxp_high), float2(mxp_in)); +} + +export float3 mx_smoothstep_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0), + float3 mxp_low = float3(0.0, 0.0, 0.0), + float3 mxp_high = float3(1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return ::math::smoothstep(float3(mxp_low), float3(mxp_high), float3(mxp_in)); +} + +export float4 mx_smoothstep_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_low = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_high = float4(1.0, 1.0, 1.0, 1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return ::math::smoothstep(float4(mxp_low), float4(mxp_high), float4(mxp_in)); +} + +export color mx_smoothstep_color3FA( + color mxp_in = color(0.0, 0.0, 0.0), + float mxp_low = float(0.0), + float mxp_high = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return color(::math::smoothstep(float3(mxp_in), float3(mxp_low), float3(mxp_high))); +} + +export core::color4 mx_smoothstep_color4FA( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_low = float(0.0), + float mxp_high = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return core::mk_color4(::math::smoothstep(core::mk_float4(mxp_in), float4(mxp_low), float4(mxp_high))); +} + +export float2 mx_smoothstep_vector2FA( + float2 mxp_in = float2(0.0, 0.0), + float mxp_low = float(0.0), + float mxp_high = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return ::math::smoothstep(float2(mxp_low), float2(mxp_high), float2(mxp_in)); +} + +export float3 mx_smoothstep_vector3FA( + float3 mxp_in = float3(0.0, 0.0, 0.0), + float mxp_low = float(0.0), + float mxp_high = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return ::math::smoothstep(float3(mxp_low), float3(mxp_high), float3(mxp_in)); +} + +export float4 mx_smoothstep_vector4FA( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), + float mxp_low = float(0.0), + float mxp_high = float(1.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return ::math::smoothstep(float4(mxp_low), float4(mxp_high), float4(mxp_in)); +} + +export float mx_curveadjust_float( + float mxp_in = float(0.0), + float2[] mxp_knots = float2[]() [[ anno::unused() ]] +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + // Not implemented: mx_curveadjust_float + float defaultValue = mxp_in; + return defaultValue; +} + +export color mx_curveadjust_color3( + color mxp_in = color(0.0, 0.0, 0.0), + float2[] mxp_knots = float2[]() [[ anno::unused() ]] +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + // Not implemented: mx_curveadjust_color3 + color defaultValue = mxp_in; + return defaultValue; +} + +export core::color4 mx_curveadjust_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float2[] mxp_knots = float2[]() [[ anno::unused() ]] +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + // Not implemented: mx_curveadjust_color4 + core::color4 defaultValue = mxp_in; + return defaultValue; +} + +export float2 mx_curveadjust_vector2( + float2 mxp_in = float2(0.0, 0.0), + float2[] mxp_knots = float2[]() [[ anno::unused() ]] +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + // Not implemented: mx_curveadjust_vector2 + float2 defaultValue = mxp_in; + return defaultValue; +} + +export float3 mx_curveadjust_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0), + float2[] mxp_knots = float2[]() [[ anno::unused() ]] +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + // Not implemented: mx_curveadjust_vector3 + float3 defaultValue = mxp_in; + return defaultValue; +} + +export float4 mx_curveadjust_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), + float2[] mxp_knots = float2[]() [[ anno::unused() ]] +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + // Not implemented: mx_curveadjust_vector4 + float4 defaultValue = mxp_in; + return defaultValue; +} + +export color mx_luminance_color3( + color mxp_in = color(0.0, 0.0, 0.0), + uniform color mxp_lumacoeffs = color(0.2722287, 0.6740818, 0.0536895) + [[ + anno::description("Enumeration {acescg, rec709, rec2020, rec2100}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return color(::math::luminance(mxp_in)); +} + +export core::color4 mx_luminance_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + uniform color mxp_lumacoeffs = color(0.2722287, 0.6740818, 0.0536895) + [[ + anno::description("Enumeration {acescg, rec709, rec2020, rec2100}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + color rgb = color(mxp_in.rgb); + core::color4 returnValue = core::mk_color4(::math::luminance(rgb)); + returnValue.a = mxp_in.a; + return returnValue; +} + +export color mx_rgbtohsv_color3( + color mxp_in = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return color(::hsv::mx_rgbtohsv(float3(mxp_in))); +} + +export core::color4 mx_rgbtohsv_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + float3 rgb = hsv::mx_rgbtohsv(float3(mxp_in.rgb)); + return core::color4(color(rgb), mxp_in.a); +} + +export color mx_hsvtorgb_color3( + color mxp_in = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + return color(hsv::mx_hsvtorgb(float3(mxp_in))); +} + +export core::color4 mx_hsvtorgb_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: adjustment") + ]] +{ + float3 rgb = hsv::mx_hsvtorgb(float3(mxp_in.rgb)); + return core::color4(color(rgb), mxp_in.a); +} + +export core::color4 mx_premult_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + // Not implemented: mx_premult_color4 + core::color4 defaultValue = mxp_in; + return defaultValue; +} + +export core::color4 mx_unpremult_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + // Not implemented: mx_unpremult_color4 + core::color4 defaultValue = mxp_in; + return defaultValue; +} + +export core::color4 mx_plus_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + color rgb = (mxp_mix*(mxp_bg.rgb + mxp_fg.rgb)) + ((1.0-mxp_mix)*mxp_bg.rgb); + float a = (mxp_mix*(mxp_bg.a + mxp_fg.a )) + ((1.0-mxp_mix)*mxp_bg.a ); + return core::color4(rgb,a); +} + +export core::color4 mx_minus_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + color rgb = (mxp_mix*(mxp_bg.rgb - mxp_fg.rgb)) + ((1.0-mxp_mix)*mxp_bg.rgb); + float a = (mxp_mix*(mxp_bg.a - mxp_fg.a )) + ((1.0-mxp_mix)*mxp_bg.a ); + return core::color4(rgb,a); +} + +export core::color4 mx_difference_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + color rgb = (mxp_mix*math::abs(mxp_bg.rgb - mxp_fg.rgb)) + ((1.0-mxp_mix)*mxp_bg.rgb); + float a = (mxp_mix*math::abs(mxp_bg.a - mxp_fg.a )) + ((1.0-mxp_mix)*mxp_bg.a ); + return core::color4(rgb,a); +} + +export float mx_burn_float( + float mxp_fg = 0.0, + float mxp_bg = 0.0, + float mxp_mix = 1.0 +) + [[ + anno::description("Node Group: compositing") + ]] +{ + if (math::abs(mxp_fg) < core::FLOAT_EPS) + { + return 0.0; + } + return mxp_mix*(1.0 - ((1.0 - mxp_bg) / mxp_fg)) + ((1.0 - mxp_mix)*mxp_bg); +} + +export color mx_burn_color3( + color mxp_fg = color(0.0), + color mxp_bg = color(0.0), + float mxp_mix = 1.0 +) + [[ + anno::description("Node Group: compositing") + ]] +{ + float3 fg(mxp_fg); + float3 bg(mxp_bg); + return color( + mx_burn_float(fg.x, bg.x, mxp_mix), + mx_burn_float(fg.y, bg.y, mxp_mix), + mx_burn_float(fg.z, bg.z, mxp_mix) + ); +} + +export core::color4 mx_burn_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = 1.0 +) + [[ + anno::description("Node Group: compositing") + ]] +{ + return core::color4( + mx_burn_color3(mxp_fg.rgb, mxp_bg.rgb, mxp_mix), + mx_burn_float(mxp_fg.a, mxp_bg.a, mxp_mix) + ); +} + +export float mx_dodge_float( + float mxp_fg = float(0.0), + float mxp_bg = float(0.0), + float mxp_mix = 1.0 +) + [[ + anno::description("Node Group: compositing") + ]] +{ + if (math::abs(1.0 - mxp_fg) < core::FLOAT_EPS) + { + return 0.0; + } + return mxp_mix*(mxp_bg / (1.0 - mxp_fg)) + ((1.0-mxp_mix)*mxp_bg); +} + +export color mx_dodge_color3( + color mxp_fg = color(0.0), + color mxp_bg = color(0.0), + float mxp_mix = 1.0 +) + [[ + anno::description("Node Group: compositing") + ]] +{ + float3 fg(mxp_fg); + float3 bg(mxp_bg); + return color( + mx_dodge_float(fg.x, bg.x, mxp_mix), + mx_dodge_float(fg.y, bg.y, mxp_mix), + mx_dodge_float(fg.z, bg.z, mxp_mix) + ); +} + +export core::color4 mx_dodge_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + return core::color4( + mx_dodge_color3(mxp_fg.rgb, mxp_bg.rgb, mxp_mix), + mx_dodge_float(mxp_fg.a, mxp_bg.a, mxp_mix) + ); +} + +export core::color4 mx_screen_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + color rgb = (mxp_mix*((1.0 - (1.0 - mxp_fg.rgb) * (1 - mxp_bg.rgb)))) + ((1.0-mxp_mix)*mxp_bg.rgb); + float a = (mxp_mix*((1.0 - (1.0 - mxp_fg.a ) * (1 - mxp_bg.a )))) + ((1.0-mxp_mix)*mxp_bg.a ); + return core::color4(rgb,a); +} + +export core::color4 mx_disjointover_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + core::color4 result; + float summedAlpha = mxp_fg.a + mxp_bg.a; + if (summedAlpha <= 1) + { + result.rgb = mxp_fg.rgb + mxp_bg.rgb; + } + else + { + if (math::abs(mxp_bg.a) < core::FLOAT_EPS) + { + result.rgb = color(0.0); + } + else + { + float x = (1 - mxp_fg.a) / mxp_bg.a; + result.rgb = mxp_fg.rgb + mxp_bg.rgb * x; + } + } + result.a = math::min(summedAlpha, 1.0); + result.rgb = result.rgb * mxp_mix + (1.0 - mxp_mix) * mxp_bg.rgb; + result.a = result.a * mxp_mix + (1.0 - mxp_mix) * mxp_bg.a; + return result; +} + +export core::color4 mx_in_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + color rgb = mxp_fg.rgb*mxp_bg.a * mxp_mix + mxp_bg.rgb * (1.0-mxp_mix); + float a = mxp_fg.a *mxp_bg.a * mxp_mix + mxp_bg.a * (1.0-mxp_mix); + return core::color4(rgb,a); +} + +export core::color4 mx_mask_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + color rgb = mxp_bg.rgb*mxp_fg.a * mxp_mix + mxp_bg.rgb * (1.0-mxp_mix); + float a = mxp_bg.a *mxp_fg.a * mxp_mix + mxp_bg.a * (1.0-mxp_mix); + return core::color4(rgb,a); +} + +export core::color4 mx_matte_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = 1.0 +) + [[ + anno::description("Node Group: compositing") + ]] +{ + color rgb = (mxp_fg.rgb*mxp_fg.a + mxp_bg.rgb*(1.0-mxp_fg.a)) * mxp_mix + mxp_bg.rgb * (1.0-mxp_mix); + float a = (mxp_fg.a + mxp_bg.a*(1.0-mxp_fg.a)) * mxp_mix + mxp_bg.a * (1.0-mxp_mix); + return core::color4(rgb, a); +} + +export core::color4 mx_out_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + color rgb = (mxp_fg.rgb*(1.0 - mxp_bg.a) * mxp_mix) + (mxp_bg.rgb * (1.0-mxp_mix)); + float a = (mxp_fg.a *(1.0 - mxp_bg.a) * mxp_mix) + (mxp_bg.a * (1.0-mxp_mix)); + return core::color4(rgb,a); +} + +export core::color4 mx_over_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(1.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + color rgb = (mxp_fg.rgb + (mxp_bg.rgb*(1.0-mxp_fg.a))) * mxp_mix + mxp_bg.rgb * (1.0-mxp_mix); + float a = (mxp_fg.a + (mxp_bg.a *(1.0-mxp_fg.a))) * mxp_mix + mxp_bg.a * (1.0-mxp_mix); + return core::color4(rgb,a); +} + +export core::color4 mx_mix_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_mix = float(0.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + return core::mk_color4(::math::lerp(core::mk_float4(mxp_bg), core::mk_float4(mxp_fg), float4(mxp_mix))); +} + +export core::color4 mx_mix_color4_color4( + core::color4 mxp_fg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_bg = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_mix = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: compositing") + ]] +{ + return core::mk_color4(::math::lerp(core::mk_float4(mxp_bg), core::mk_float4(mxp_fg), core::mk_float4(mxp_mix))); +} + +// 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_fg.ior, // NOTE: IOR is uniform, cannot mix here + 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 + ) +); + +export material mx_mix_volumeshader( + material mxp_fg = material() [[ anno::usage( "materialx:volumeshader") ]], + material mxp_bg = material() [[ anno::usage( "materialx:volumeshader") ]], + float mxp_mix = 0.0 +) [[ + anno::description("Node Group: compositing"), + anno::usage( "materialx:volumeshader") +]] += mx_mix_surfaceshader( + mxp_fg: mxp_fg, + mxp_bg: mxp_bg, + mxp_mix: mxp_mix); + +export material mx_mix_displacementshader( + material mxp_fg = material() [[ anno::usage( "materialx:displacementshader") ]], + material mxp_bg = material() [[ anno::usage( "materialx:displacementshader") ]], + float mxp_mix = 0.0 +) [[ + anno::description("Node Group: compositing"), + anno::usage( "materialx:displacementshader") +]] += mx_mix_surfaceshader( + mxp_fg: mxp_fg, + mxp_bg: mxp_bg, + mxp_mix: mxp_mix); + +export float mx_ifgreater_float( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export color mx_ifgreater_color3( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + color mxp_in1 = color(0.0, 0.0, 0.0), + color mxp_in2 = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export core::color4 mx_ifgreater_color4( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float2 mx_ifgreater_vector2( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float3 mx_ifgreater_vector3( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + float3 mxp_in1 = float3(0.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float4 mx_ifgreater_vector4( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float mx_ifgreater_floatI( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export color mx_ifgreater_color3I( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + color mxp_in1 = color(0.0, 0.0, 0.0), + color mxp_in2 = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export core::color4 mx_ifgreater_color4I( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float2 mx_ifgreater_vector2I( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float3 mx_ifgreater_vector3I( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + float3 mxp_in1 = float3(0.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float4 mx_ifgreater_vector4I( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 > mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float mx_ifgreatereq_float( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export color mx_ifgreatereq_color3( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + color mxp_in1 = color(0.0, 0.0, 0.0), + color mxp_in2 = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export core::color4 mx_ifgreatereq_color4( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float2 mx_ifgreatereq_vector2( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float3 mx_ifgreatereq_vector3( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + float3 mxp_in1 = float3(0.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float4 mx_ifgreatereq_vector4( + float mxp_value1 = float(1.0), + float mxp_value2 = float(0.0), + float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float mx_ifgreatereq_floatI( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export color mx_ifgreatereq_color3I( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + color mxp_in1 = color(0.0, 0.0, 0.0), + color mxp_in2 = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export core::color4 mx_ifgreatereq_color4I( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float2 mx_ifgreatereq_vector2I( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float3 mx_ifgreatereq_vector3I( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + float3 mxp_in1 = float3(0.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float4 mx_ifgreatereq_vector4I( + int mxp_value1 = int(1), + int mxp_value2 = int(0), + float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 >= mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float mx_ifequal_float( + float mxp_value1 = float(0.0), + float mxp_value2 = float(0.0), + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export color mx_ifequal_color3( + float mxp_value1 = float(0.0), + float mxp_value2 = float(0.0), + color mxp_in1 = color(0.0, 0.0, 0.0), + color mxp_in2 = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export core::color4 mx_ifequal_color4( + float mxp_value1 = float(0.0), + float mxp_value2 = float(0.0), + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float2 mx_ifequal_vector2( + float mxp_value1 = float(0.0), + float mxp_value2 = float(0.0), + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float3 mx_ifequal_vector3( + float mxp_value1 = float(0.0), + float mxp_value2 = float(0.0), + float3 mxp_in1 = float3(0.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float4 mx_ifequal_vector4( + float mxp_value1 = float(0.0), + float mxp_value2 = float(0.0), + float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float mx_ifequal_floatI( + int mxp_value1 = int(0), + int mxp_value2 = int(0), + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export color mx_ifequal_color3I( + int mxp_value1 = int(0), + int mxp_value2 = int(0), + color mxp_in1 = color(0.0, 0.0, 0.0), + color mxp_in2 = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export core::color4 mx_ifequal_color4I( + int mxp_value1 = int(0), + int mxp_value2 = int(0), + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float2 mx_ifequal_vector2I( + int mxp_value1 = int(0), + int mxp_value2 = int(0), + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float3 mx_ifequal_vector3I( + int mxp_value1 = int(0), + int mxp_value2 = int(0), + float3 mxp_in1 = float3(0.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float4 mx_ifequal_vector4I( + int mxp_value1 = int(0), + int mxp_value2 = int(0), + float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float mx_ifequal_floatB( + bool mxp_value1 = bool(false), + bool mxp_value2 = bool(false), + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export color mx_ifequal_color3B( + bool mxp_value1 = bool(false), + bool mxp_value2 = bool(false), + color mxp_in1 = color(0.0, 0.0, 0.0), + color mxp_in2 = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export core::color4 mx_ifequal_color4B( + bool mxp_value1 = bool(false), + bool mxp_value2 = bool(false), + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float2 mx_ifequal_vector2B( + bool mxp_value1 = bool(false), + bool mxp_value2 = bool(false), + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float3 mx_ifequal_vector3B( + bool mxp_value1 = bool(false), + bool mxp_value2 = bool(false), + float3 mxp_in1 = float3(0.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float4 mx_ifequal_vector4B( + bool mxp_value1 = bool(false), + bool mxp_value2 = bool(false), + float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + if (mxp_value1 == mxp_value2) { return mxp_in1; } return mxp_in2; +} + +export float mx_switch_float( + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0), + float mxp_in3 = float(0.0), + float mxp_in4 = float(0.0), + float mxp_in5 = float(0.0), + float mxp_which = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + float returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export color mx_switch_color3( + color mxp_in1 = color(0.0, 0.0, 0.0), + color mxp_in2 = color(0.0, 0.0, 0.0), + color mxp_in3 = color(0.0, 0.0, 0.0), + color mxp_in4 = color(0.0, 0.0, 0.0), + color mxp_in5 = color(0.0, 0.0, 0.0), + float mxp_which = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + color returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export core::color4 mx_switch_color4( + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in3 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in4 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in5 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_which = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + core::color4 returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export float2 mx_switch_vector2( + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0), + float2 mxp_in3 = float2(0.0, 0.0), + float2 mxp_in4 = float2(0.0, 0.0), + float2 mxp_in5 = float2(0.0, 0.0), + float mxp_which = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + float2 returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export float3 mx_switch_vector3( + float3 mxp_in1 = float3(0.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 0.0, 0.0), + float3 mxp_in3 = float3(0.0, 0.0, 0.0), + float3 mxp_in4 = float3(0.0, 0.0, 0.0), + float3 mxp_in5 = float3(0.0, 0.0, 0.0), + float mxp_which = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + float3 returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export float4 mx_switch_vector4( + float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in3 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in4 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in5 = float4(0.0, 0.0, 0.0, 0.0), + float mxp_which = float(0.0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + float4 returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export float mx_switch_floatI( + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0), + float mxp_in3 = float(0.0), + float mxp_in4 = float(0.0), + float mxp_in5 = float(0.0), + int mxp_which = int(0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + float returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export color mx_switch_color3I( + color mxp_in1 = color(0.0, 0.0, 0.0), + color mxp_in2 = color(0.0, 0.0, 0.0), + color mxp_in3 = color(0.0, 0.0, 0.0), + color mxp_in4 = color(0.0, 0.0, 0.0), + color mxp_in5 = color(0.0, 0.0, 0.0), + int mxp_which = int(0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + color returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export core::color4 mx_switch_color4I( + core::color4 mxp_in1 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in2 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in3 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in4 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + core::color4 mxp_in5 = core::mk_color4(0.0, 0.0, 0.0, 0.0), + int mxp_which = int(0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + core::color4 returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export float2 mx_switch_vector2I( + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0), + float2 mxp_in3 = float2(0.0, 0.0), + float2 mxp_in4 = float2(0.0, 0.0), + float2 mxp_in5 = float2(0.0, 0.0), + int mxp_which = int(0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + float2 returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export float3 mx_switch_vector3I( + float3 mxp_in1 = float3(0.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 0.0, 0.0), + float3 mxp_in3 = float3(0.0, 0.0, 0.0), + float3 mxp_in4 = float3(0.0, 0.0, 0.0), + float3 mxp_in5 = float3(0.0, 0.0, 0.0), + int mxp_which = int(0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + float3 returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export float4 mx_switch_vector4I( + float4 mxp_in1 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in2 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in3 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in4 = float4(0.0, 0.0, 0.0, 0.0), + float4 mxp_in5 = float4(0.0, 0.0, 0.0, 0.0), + int mxp_which = int(0) +) + [[ + anno::description("Node Group: conditional") + ]] +{ + float4 returnValue; + switch (int(mxp_which)) { + case 0: returnValue=mxp_in1; break; + case 1: returnValue=mxp_in2; break; + case 2: returnValue=mxp_in3; break; + case 3: returnValue=mxp_in4; break; + case 4: returnValue=mxp_in5; break; + default: returnValue=mxp_in1; break; + } + return returnValue; +} + +export color mx_convert_float_color3( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return color(mxp_in); +} + +export core::color4 mx_convert_float_color4( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return core::mk_color4(mxp_in); +} + +export float2 mx_convert_float_vector2( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float2(mxp_in); +} + +export float3 mx_convert_float_vector3( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float3(mxp_in); +} + +export float4 mx_convert_float_vector4( + float mxp_in = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float4(mxp_in); +} + +export float3 mx_convert_vector2_vector3( + float2 mxp_in = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float3(mxp_in.x, mxp_in.y, 0.0); +} + +export color mx_convert_vector3_color3( + float3 mxp_in = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return color(mxp_in); +} + +export float2 mx_convert_vector3_vector2( + float3 mxp_in = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float2(mxp_in.x, mxp_in.y); +} + +export float4 mx_convert_vector3_vector4( + float3 mxp_in = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float4(mxp_in.x, mxp_in.y, mxp_in.z, 0.0); +} + +export core::color4 mx_convert_vector4_color4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return core::mk_color4(mxp_in); +} + +export float3 mx_convert_vector4_vector3( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float3(mxp_in.x, mxp_in.y, mxp_in.z); +} + +export float3 mx_convert_color3_vector3( + color mxp_in = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float3(mxp_in); +} + +export float4 mx_convert_color4_vector4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return core::mk_float4(mxp_in); +} + +export core::color4 mx_convert_color3_color4( + color mxp_in = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return core::mk_color4(mxp_in); +} + +export color mx_convert_color4_color3( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return mxp_in.rgb; +} + +export float mx_convert_boolean_float( + bool mxp_in = bool(false) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float(mxp_in); +} + +export float mx_convert_integer_float( + int mxp_in = int(0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float(mxp_in); +} + +export float2 mx_combine2_vector2( + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float2(mxp_in1, mxp_in2); +} + +export core::color4 mx_combine2_color4CF( + color mxp_in1 = color(0.0, 0.0, 0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return core::color4(mxp_in1, mxp_in2); +} + +export float4 mx_combine2_vector4VF( + float3 mxp_in1 = float3(0.0, 0.0, 0.0), + float mxp_in2 = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float4(mxp_in1.x, mxp_in1.y, mxp_in1.z, mxp_in2); +} + +export core::color4 mx_combine2_color4CC( + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return core::color4(color(mxp_in1.x, mxp_in1.y, mxp_in2.x), mxp_in2.y); +} + +export float4 mx_combine2_vector4VV( + float2 mxp_in1 = float2(0.0, 0.0), + float2 mxp_in2 = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float4(mxp_in1.x, mxp_in1.y, mxp_in2.x, mxp_in2.y); +} + +export color mx_combine3_color3( + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0), + float mxp_in3 = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return color(mxp_in1, mxp_in2, mxp_in3); +} + +export float3 mx_combine3_vector3( + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0), + float mxp_in3 = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float3(mxp_in1, mxp_in2, mxp_in3); +} + +export core::color4 mx_combine4_color4( + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0), + float mxp_in3 = float(0.0), + float mxp_in4 = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return core::mk_color4(mxp_in1, mxp_in2, mxp_in3, mxp_in4); +} + +export float4 mx_combine4_vector4( + float mxp_in1 = float(0.0), + float mxp_in2 = float(0.0), + float mxp_in3 = float(0.0), + float mxp_in4 = float(0.0) +) + [[ + anno::description("Node Group: channel") + ]] +{ + return float4(mxp_in1, mxp_in2, mxp_in3, mxp_in4); +} + +export float3x3 mx_creatematrix_vector3_matrix33( + float3 mxp_in1 = float3(1.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 1.0, 0.0), + float3 mxp_in3 = float3(0.0, 0.0, 1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return float3x3( + mxp_in1[0], mxp_in1[1], mxp_in1[2], + mxp_in2[0], mxp_in2[1], mxp_in2[2], + mxp_in3[0], mxp_in3[1], mxp_in3[2]); +} + + +export float4x4 mx_creatematrix_vector3_matrix44( + float3 mxp_in1 = float3(1.0, 0.0, 0.0), + float3 mxp_in2 = float3(0.0, 1.0, 0.0), + float3 mxp_in3 = float3(0.0, 0.0, 1.0), + float3 mxp_in4 = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return float4x4( + mxp_in1[0], mxp_in1[1], mxp_in1[2], 0.0, + mxp_in2[0], mxp_in2[1], mxp_in2[2], 0.0, + mxp_in3[0], mxp_in3[1], mxp_in3[2], 0.0, + mxp_in4[0], mxp_in4[1], mxp_in4[2], 1.0); +} + + +export float4x4 mx_creatematrix_vector4_matrix44( + float4 mxp_in1 = float4(1.0, 0.0, 0.0, 0.0), + float4 mxp_in2 = float4(0.0, 1.0, 0.0, 0.0), + float4 mxp_in3 = float4(0.0, 0.0, 1.0, 0.0), + float4 mxp_in4 = float4(0.0, 0.0, 0.0, 1.0) +) + [[ + anno::description("Node Group: math") + ]] +{ + return float4x4( + mxp_in1[0], mxp_in1[1], mxp_in1[2], mxp_in1[3], + mxp_in2[0], mxp_in2[1], mxp_in2[2], mxp_in2[3], + mxp_in3[0], mxp_in3[1], mxp_in3[2], mxp_in3[3], + mxp_in4[0], mxp_in4[1], mxp_in4[2], mxp_in4[3]); +} + +// Nodedef: ND_extract_color3 is represented by a nodegraph: NG_extract_color3 +// Nodedef: ND_extract_color4 is represented by a nodegraph: NG_extract_color4 +// Nodedef: ND_extract_vector2 is represented by a nodegraph: NG_extract_vector2 +// Nodedef: ND_extract_vector3 is represented by a nodegraph: NG_extract_vector3 +// Nodedef: ND_extract_vector4 is represented by a nodegraph: NG_extract_vector4 +// Nodedef: ND_separate2_vector2 is represented by a nodegraph: NG_separate2_vector2 +// Nodedef: ND_separate3_color3 is represented by a nodegraph: NG_separate3_color3 +// Nodedef: ND_separate3_vector3 is represented by a nodegraph: NG_separate3_vector3 +// Nodedef: ND_separate4_color4 is represented by a nodegraph: NG_separate4_color4 +// Nodedef: ND_separate4_vector4 is represented by a nodegraph: NG_separate4_vector4 + +export float mx_blur_float( + float mxp_in = float(0.0), + float mxp_size = float(0.0) + [[ + anno::unused() + ]], + uniform core::mx_filter_type mxp_filtertype = core::mx_filter_type(core::mx_filter_type_box) + [[ + anno::description("Enumeration {box,gaussian}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: convolution2d") + ]] +{ + // Not implemented: mx_blur_float + float defaultValue = mxp_in; + return defaultValue; +} + +export color mx_blur_color3( + color mxp_in = color(0.0, 0.0, 0.0), + float mxp_size = float(0.0) + [[ + anno::unused() + ]], + uniform core::mx_filter_type mxp_filtertype = core::mx_filter_type(core::mx_filter_type_box) + [[ + anno::description("Enumeration {box,gaussian}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: convolution2d") + ]] +{ + // Not implemented: mx_blur_color3 + color defaultValue = mxp_in; + return defaultValue; +} + +export core::color4 mx_blur_color4( + core::color4 mxp_in = core::mk_color4(0.0, 0.0, 0.0, 0.0), + float mxp_size = float(0.0) + [[ + anno::unused() + ]], + uniform core::mx_filter_type mxp_filtertype = core::mx_filter_type(core::mx_filter_type_box) + [[ + anno::description("Enumeration {box,gaussian}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: convolution2d") + ]] +{ + // Not implemented: mx_blur_color4 + core::color4 defaultValue = mxp_in; + return defaultValue; +} + +export float2 mx_blur_vector2( + float2 mxp_in = float2(0.0, 0.0), + float mxp_size = float(0.0) + [[ + anno::unused() + ]], + uniform core::mx_filter_type mxp_filtertype = core::mx_filter_type(core::mx_filter_type_box) + [[ + anno::description("Enumeration {box,gaussian}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: convolution2d") + ]] +{ + // Not implemented: mx_blur_vector2 + float2 defaultValue = mxp_in; + return defaultValue; +} + +export float3 mx_blur_vector3( + float3 mxp_in = float3(0.0, 0.0, 0.0), + float mxp_size = float(0.0) + [[ + anno::unused() + ]], + uniform core::mx_filter_type mxp_filtertype = core::mx_filter_type(core::mx_filter_type_box) + [[ + anno::description("Enumeration {box,gaussian}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: convolution2d") + ]] +{ + // Not implemented: mx_blur_vector3 + float3 defaultValue = mxp_in; + return defaultValue; +} + +export float4 mx_blur_vector4( + float4 mxp_in = float4(0.0, 0.0, 0.0, 0.0), + float mxp_size = float(0.0) + [[ + anno::unused() + ]], + uniform core::mx_filter_type mxp_filtertype = core::mx_filter_type(core::mx_filter_type_box) + [[ + anno::description("Enumeration {box,gaussian}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: convolution2d") + ]] +{ + // Not implemented: mx_blur_vector4 + float4 defaultValue = mxp_in; + return defaultValue; +} + +export float3 mx_heighttonormal_vector3( + float mxp_in = float(0.0) [[ anno::unused() ]], + float mxp_scale = float(1.0) [[ anno::unused() ]] +) + [[ + anno::description("Node Group: convolution2d") + ]] +{ + // Not implemented: mx_heighttonormal_vector3 + float3 defaultValue = float3(0.0, 1.0, 0.0); + return defaultValue; +} + +export float mx_noise2d_float( + float mxp_amplitude = 1.0, + float mxp_pivot = 0.0, + float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) +) +{ + float value = noise::mx_perlin_noise_float(mxp_texcoord); + return value * mxp_amplitude + mxp_pivot; +} + +export float2 mx_noise2d_float2( + float2 mxp_amplitude = float2(1.0), + float mxp_pivot = 0.0, + float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) +) +{ + float3 value = noise::mx_perlin_noise_float3(mxp_texcoord); + return swizzle::xy(value) * mxp_amplitude + mxp_pivot; +} + +export float3 mx_noise2d_float3( + float3 mxp_amplitude = float3(1.0), + float mxp_pivot = 0.0, + float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) +) +{ + float3 value = noise::mx_perlin_noise_float3(mxp_texcoord); + return value * mxp_amplitude + mxp_pivot; +} + +export float4 mx_noise2d_float4( + float4 mxp_amplitude = float4(1.0), + float mxp_pivot = 0.0, + float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) +) +{ + float3 v = noise::mx_perlin_noise_float3(mxp_texcoord); + float w = noise::mx_perlin_noise_float(mxp_texcoord + float2(19, 73)); + return float4(v.x, v.y, v.z, w) * mxp_amplitude + mxp_pivot; +} + +export float mx_noise3d_float( + float mxp_amplitude = 1.0, + float mxp_pivot = 0.0, + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) +) +{ + float value = noise::mx_perlin_noise_float(mxp_position); + return value * mxp_amplitude + mxp_pivot; +} + +export float2 mx_noise3d_float2( + float2 mxp_amplitude = float2(1.0), + float mxp_pivot = 0.0, + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) +) +{ + float3 value = noise::mx_perlin_noise_float3(mxp_position); + return swizzle::xy(value) * mxp_amplitude + mxp_pivot; +} + +export float3 mx_noise3d_float3( + float3 mxp_amplitude = float3(1.0), + float mxp_pivot = 0.0, + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) +) +{ + float3 value = noise::mx_perlin_noise_float3(mxp_position); + return value * mxp_amplitude + mxp_pivot; +} + +export float4 mx_noise3d_float4( + float4 mxp_amplitude = float4(1.0), + float mxp_pivot = 0.0, + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) +) +{ + float3 v = noise::mx_perlin_noise_float3(mxp_position); + float w = noise::mx_perlin_noise_float(mxp_position + float3(19, 73, 29)); + return float4(v.x, v.y, v.z, w) * mxp_amplitude + mxp_pivot; +} + +export float mx_fractal3d_float( + float mxp_amplitude = 1.0, + int mxp_octaves = 3, + float mxp_lacunarity = 2.0, + float mxp_diminish= 0.5, + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) +) +{ + float v = noise::mx_fractal_noise_float(mxp_position, mxp_octaves, mxp_lacunarity, mxp_diminish); + return v * mxp_amplitude; +} + +export float2 mx_fractal3d_float2( + float2 mxp_amplitude = float2(1.0), + int mxp_octaves = 3, + float mxp_lacunarity = 2.0, + float mxp_diminish= 0.5, + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) +) +{ + float2 v = noise::mx_fractal_noise_float2(mxp_position, mxp_octaves, mxp_lacunarity, mxp_diminish); + return v * mxp_amplitude; +} + +export float3 mx_fractal3d_float3( + float3 mxp_amplitude = float3(1.0), + int mxp_octaves = 3, + float mxp_lacunarity = 2.0, + float mxp_diminish= 0.5, + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) +) +{ + float3 v = noise::mx_fractal_noise_float3(mxp_position, mxp_octaves, mxp_lacunarity, mxp_diminish); + return v * mxp_amplitude; +} + +export float4 mx_fractal3d_float4( + float4 mxp_amplitude = float4(1.0), + int mxp_octaves = 3, + float mxp_lacunarity = 2.0, + float mxp_diminish= 0.5, + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) +) +{ + float4 v = noise::mx_fractal_noise_float4(mxp_position, mxp_octaves, mxp_lacunarity, mxp_diminish); + return v * mxp_amplitude; +} + +export float mx_cellnoise2d_float( + float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)) +) +{ + return noise::mx_cell_noise_float(mxp_texcoord); +} + +export float mx_cellnoise3d_float( + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()) +) +{ + return noise::mx_cell_noise_float(mxp_position); +} + +export float mx_worleynoise2d_float( + float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)), + float mxp_jitter = 1.0 +) +{ + return noise::mx_worley_noise_float(mxp_texcoord, mxp_jitter, 0); +} + +export float2 mx_worleynoise2d_float2( + float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)), + float mxp_jitter = 1.0 +) +{ + return noise::mx_worley_noise_float2(mxp_texcoord, mxp_jitter, 0); +} + +export float3 mx_worleynoise2d_float3( + float2 mxp_texcoord = swizzle::xy( ::state::texture_coordinate(0)), + float mxp_jitter = 1.0 +) +{ + return noise::mx_worley_noise_float3(mxp_texcoord, mxp_jitter, 0); +} + +export float mx_worleynoise3d_float( + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()), + float mxp_jitter = 1.0 +) +{ + return noise::mx_worley_noise_float(mxp_position, mxp_jitter, 0); +} + +export float2 mx_worleynoise3d_float2( + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()), + float mxp_jitter = 1.0 +) +{ + return noise::mx_worley_noise_float2(mxp_position, mxp_jitter, 0); +} + +export float3 mx_worleynoise3d_float3( + float3 mxp_position = state::transform_point(state::coordinate_internal, state::coordinate_object, state::position()), + float mxp_jitter = 1.0 +) +{ + return noise::mx_worley_noise_float3(mxp_position, mxp_jitter, 0); +} diff --git a/source/MaterialXGenMdl/mdl/materialx/stdlib_1_7.mdl b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_7.mdl new file mode 100644 index 0000000000..019bbb1548 --- /dev/null +++ b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_7.mdl @@ -0,0 +1,18 @@ +// +// 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 v1.37 REV2, January 19, 2020 +// www.materialx.org +// in +// NVIDIA Material Definition Language 1.7 +// Language Specification +// Document version 1.7.2, January 17, 2022 +// www.nvidia.com/mdl + +mdl 1.7; + +// forward all unchanged definitions from the previous version +export using .::stdlib_1_6 import *; diff --git a/source/MaterialXGenMdl/mdl/materialx/stdlib_1_8.mdl b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_8.mdl new file mode 100644 index 0000000000..9b86317596 --- /dev/null +++ b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_8.mdl @@ -0,0 +1,421 @@ +// +// 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 v1.37 REV2, January 19, 2020 +// www.materialx.org +// in +// NVIDIA Material Definition Language 1.8 +// Language Specification +// Document version 1.8.2, May 24, 2023 +// www.nvidia.com/mdl + +mdl 1.8; + +import ::anno::*; +import ::math::*; +import ::scene::*; +import ::state::*; + +import .::core::*; +import .::noise::*; +import .::swizzle::*; +import .::hsv::*; + +// Changes since MDL 1.7 +// - Scene data lookups used for PrimVar readers allow non-literal string names + +// forward all 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_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_surfaceshader; +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_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_floatI; +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_ifgreatereq_float; +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_floatI; +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_ifequal_float; +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_floatI; +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_floatB; +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_switch_float; +export using .::stdlib_1_7 import mx_switch_color3; +export using .::stdlib_1_7 import mx_switch_color4; +export using .::stdlib_1_7 import mx_switch_vector2; +export using .::stdlib_1_7 import mx_switch_vector3; +export using .::stdlib_1_7 import mx_switch_vector4; +export using .::stdlib_1_7 import mx_switch_floatI; +export using .::stdlib_1_7 import mx_switch_color3I; +export using .::stdlib_1_7 import mx_switch_color4I; +export using .::stdlib_1_7 import mx_switch_vector2I; +export using .::stdlib_1_7 import mx_switch_vector3I; +export using .::stdlib_1_7 import mx_switch_vector4I; +export using .::stdlib_1_7 import mx_convert_float_color3; +export using .::stdlib_1_7 import mx_convert_float_color4; +export using .::stdlib_1_7 import mx_convert_float_vector2; +export using .::stdlib_1_7 import mx_convert_float_vector3; +export using .::stdlib_1_7 import mx_convert_float_vector4; +export using .::stdlib_1_7 import mx_convert_vector2_vector3; +export using .::stdlib_1_7 import mx_convert_vector3_color3; +export using .::stdlib_1_7 import mx_convert_vector3_vector2; +export using .::stdlib_1_7 import mx_convert_vector3_vector4; +export using .::stdlib_1_7 import mx_convert_vector4_color4; +export using .::stdlib_1_7 import mx_convert_vector4_vector3; +export using .::stdlib_1_7 import mx_convert_color3_vector3; +export using .::stdlib_1_7 import mx_convert_color4_vector4; +export using .::stdlib_1_7 import mx_convert_color3_color4; +export using .::stdlib_1_7 import mx_convert_color4_color3; +export using .::stdlib_1_7 import mx_convert_boolean_float; +export using .::stdlib_1_7 import mx_convert_integer_float; +export using .::stdlib_1_7 import mx_combine2_vector2; +export using .::stdlib_1_7 import mx_combine2_color4CF; +export using .::stdlib_1_7 import mx_combine2_vector4VF; +export using .::stdlib_1_7 import mx_combine2_color4CC; +export using .::stdlib_1_7 import mx_combine2_vector4VV; +export using .::stdlib_1_7 import mx_combine3_color3; +export using .::stdlib_1_7 import mx_combine3_vector3; +export using .::stdlib_1_7 import mx_combine4_color4; +export using .::stdlib_1_7 import mx_combine4_vector4; +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_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; + +// NOTE: Not planned to be implemented. +export using .::stdlib_1_7 import mx_geompropvalue_string; + +// NOTE: No boolean scene data in MDL so it's mapped to integer. +// Returns false if the scene data is zero, true otherwise. +export bool mx_geompropvalue_boolean( + uniform string mxp_geomprop = string(""), + bool mxp_default = bool(false) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + int defaultValue = mxp_default ? 1 : 0; + return scene::data_lookup_int(mxp_geomprop, defaultValue) == 0 ? false : true; +} + +export int mx_geompropvalue_integer( + uniform string mxp_geomprop = string(""), + int mxp_default = int(0) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + return scene::data_lookup_int(mxp_geomprop, mxp_default); +} + +export float mx_geompropvalue_float( + uniform string mxp_geomprop = string(""), + float mxp_default = float(0.0) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + return scene::data_lookup_float(mxp_geomprop, mxp_default); +} + +export color mx_geompropvalue_color3( + uniform string mxp_geomprop = string(""), + color mxp_default = color(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + return scene::data_lookup_color(mxp_geomprop, mxp_default); +} + +export core::color4 mx_geompropvalue_color4( + uniform string mxp_geomprop = string(""), + core::color4 mxp_default = core::mk_color4(0.0, 0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + float3 rgbValue = float3(mxp_default.rgb); + float4 defaultValue = float4(rgbValue.x, rgbValue.y, rgbValue.z, mxp_default.a); + float4 value = scene::data_lookup_float4(mxp_geomprop, defaultValue); + return core::mk_color4(value.x, value.y, value.z, value.w); +} + +export float2 mx_geompropvalue_vector2( + uniform string mxp_geomprop = string(""), + float2 mxp_default = float2(0.0, 0.0) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + return scene::data_lookup_float2(mxp_geomprop, mxp_default); +} + +export float3 mx_geompropvalue_vector3( + uniform string mxp_geomprop = string(""), + float3 mxp_default = float3(0.0, 0.0, 0.0) +) + [[ + anno::description("Node Group: geometric") + ]] +{ + return scene::data_lookup_float3(mxp_geomprop, mxp_default); +} + +export float4 mx_geompropvalue_vector4( + uniform string mxp_geomprop = string(""), + float4 mxp_default = float4(0.0, 0.0, 0.0, 0.0) +) +{ + return scene::data_lookup_float4(mxp_geomprop, mxp_default); +} diff --git a/source/MaterialXGenMdl/mdl/materialx/swizzle.mdl b/source/MaterialXGenMdl/mdl/materialx/swizzle.mdl index 414f8dac77..fb87022adb 100644 --- a/source/MaterialXGenMdl/mdl/materialx/swizzle.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/swizzle.mdl @@ -16,12 +16,12 @@ // Support functions to simplify conversions between vector types with swizzles // Supported argument types: float (with implied field name x), float2, float3, -// float4, color, color4 (as RGB and RGBA) +// float4, color, core::color4 (as RGB and RGBA) // Supported return types: float, float2, float3, float4 mdl 1.6; -using .::core import color4; +import .::core::*; // Swizzles with float return type export float x( float a) { return a; } @@ -42,10 +42,10 @@ export float x( color a) { return x( float3(a)); } export float y( color a) { return y( float3(a)); } export float z( color a) { return z( float3(a)); } -export float x( color4 a) { return float3( a.rgb).x; } -export float y( color4 a) { return float3( a.rgb).y; } -export float z( color4 a) { return float3( a.rgb).z; } -export float w( color4 a) { return a.a; } +export float x( core::color4 a) { return float3( a.rgb).x; } +export float y( core::color4 a) { return float3( a.rgb).y; } +export float z( core::color4 a) { return float3( a.rgb).z; } +export float w( core::color4 a) { return a.a; } // Swizzles with float2 return type export float2 xx( float a) { return float2( a, a); } @@ -92,22 +92,22 @@ export float2 zx( color a) { return zx( float3(a)); } export float2 zy( color a) { return zy( float3(a)); } export float2 zz( color a) { return zz( float3(a)); } -export float2 xx( color4 a) { return xx( float3( a.rgb)); } -export float2 xy( color4 a) { return xy( float3( a.rgb)); } -export float2 xz( color4 a) { return xz( float3( a.rgb)); } -export float2 xw( color4 a) { return float2( float3( a.rgb).x, a.a); } -export float2 yx( color4 a) { return yx( float3( a.rgb)); } -export float2 yy( color4 a) { return yy( float3( a.rgb)); } -export float2 yz( color4 a) { return yz( float3( a.rgb)); } -export float2 yw( color4 a) { return float2( float3( a.rgb).y, a.a); } -export float2 zx( color4 a) { return zx( float3( a.rgb)); } -export float2 zy( color4 a) { return zy( float3( a.rgb)); } -export float2 zz( color4 a) { return zz( float3( a.rgb)); } -export float2 zw( color4 a) { return float2( float3( a.rgb).z, a.a); } -export float2 wx( color4 a) { return float2( a.a, float3( a.rgb).x); } -export float2 wy( color4 a) { return float2( a.a, float3( a.rgb).y); } -export float2 wz( color4 a) { return float2( a.a, float3( a.rgb).z); } -export float2 ww( color4 a) { return float2( a.a, a.a); } +export float2 xx( core::color4 a) { return xx( float3( a.rgb)); } +export float2 xy( core::color4 a) { return xy( float3( a.rgb)); } +export float2 xz( core::color4 a) { return xz( float3( a.rgb)); } +export float2 xw( core::color4 a) { return float2( float3( a.rgb).x, a.a); } +export float2 yx( core::color4 a) { return yx( float3( a.rgb)); } +export float2 yy( core::color4 a) { return yy( float3( a.rgb)); } +export float2 yz( core::color4 a) { return yz( float3( a.rgb)); } +export float2 yw( core::color4 a) { return float2( float3( a.rgb).y, a.a); } +export float2 zx( core::color4 a) { return zx( float3( a.rgb)); } +export float2 zy( core::color4 a) { return zy( float3( a.rgb)); } +export float2 zz( core::color4 a) { return zz( float3( a.rgb)); } +export float2 zw( core::color4 a) { return float2( float3( a.rgb).z, a.a); } +export float2 wx( core::color4 a) { return float2( a.a, float3( a.rgb).x); } +export float2 wy( core::color4 a) { return float2( a.a, float3( a.rgb).y); } +export float2 wz( core::color4 a) { return float2( a.a, float3( a.rgb).z); } +export float2 ww( core::color4 a) { return float2( a.a, a.a); } // Swizzles with float3 return type export float3 xxx( float a) { return float3( a, a, a); } @@ -242,70 +242,70 @@ export float3 zzx( color a) { return zzx( float3(a)); } export float3 zzy( color a) { return zzy( float3(a)); } export float3 zzz( color a) { return zzz( float3(a)); } -export float3 xxx( color4 a) { return xxx( float3( a.rgb)); } -export float3 xxy( color4 a) { return xxy( float3( a.rgb)); } -export float3 xxz( color4 a) { return xxz( float3( a.rgb)); } -export float3 xxw( color4 a) { return float3( float3( a.rgb).x, float3( a.rgb).x, a.a); } -export float3 xyx( color4 a) { return xyx( float3( a.rgb)); } -export float3 xyy( color4 a) { return xyy( float3( a.rgb)); } -export float3 xyz( color4 a) { return xyz( float3( a.rgb)); } -export float3 xyw( color4 a) { return float3( float3( a.rgb).x, float3( a.rgb).y, a.a); } -export float3 xzx( color4 a) { return xzx( float3( a.rgb)); } -export float3 xzy( color4 a) { return xzy( float3( a.rgb)); } -export float3 xzz( color4 a) { return xzz( float3( a.rgb)); } -export float3 xzw( color4 a) { return float3( float3( a.rgb).x, float3( a.rgb).z, a.a); } -export float3 xwx( color4 a) { return float3( float3( a.rgb).x, a.a, float3( a.rgb).x); } -export float3 xwy( color4 a) { return float3( float3( a.rgb).x, a.a, float3( a.rgb).y); } -export float3 xwz( color4 a) { return float3( float3( a.rgb).x, a.a, float3( a.rgb).z); } -export float3 xww( color4 a) { return float3( float3( a.rgb).x, a.a, a.a); } -export float3 yxx( color4 a) { return yxx( float3( a.rgb)); } -export float3 yxy( color4 a) { return yxy( float3( a.rgb)); } -export float3 yxz( color4 a) { return yxz( float3( a.rgb)); } -export float3 yxw( color4 a) { return float3( float3( a.rgb).y, float3( a.rgb).x, a.a); } -export float3 yyx( color4 a) { return yyx( float3( a.rgb)); } -export float3 yyy( color4 a) { return yyy( float3( a.rgb)); } -export float3 yyz( color4 a) { return yyz( float3( a.rgb)); } -export float3 yyw( color4 a) { return float3( float3( a.rgb).y, float3( a.rgb).y, a.a); } -export float3 yzx( color4 a) { return yzx( float3( a.rgb)); } -export float3 yzy( color4 a) { return yzy( float3( a.rgb)); } -export float3 yzz( color4 a) { return yzz( float3( a.rgb)); } -export float3 yzw( color4 a) { return float3( float3( a.rgb).y, float3( a.rgb).z, a.a); } -export float3 ywx( color4 a) { return float3( float3( a.rgb).y, a.a, float3( a.rgb).x); } -export float3 ywy( color4 a) { return float3( float3( a.rgb).y, a.a, float3( a.rgb).y); } -export float3 ywz( color4 a) { return float3( float3( a.rgb).y, a.a, float3( a.rgb).z); } -export float3 yww( color4 a) { return float3( float3( a.rgb).y, a.a, a.a); } -export float3 zxx( color4 a) { return zxx( float3( a.rgb)); } -export float3 zxy( color4 a) { return zxy( float3( a.rgb)); } -export float3 zxz( color4 a) { return zxz( float3( a.rgb)); } -export float3 zxw( color4 a) { return float3( float3( a.rgb).z, float3( a.rgb).x, a.a); } -export float3 zyx( color4 a) { return zyx( float3( a.rgb)); } -export float3 zyy( color4 a) { return zyy( float3( a.rgb)); } -export float3 zyz( color4 a) { return zyz( float3( a.rgb)); } -export float3 zyw( color4 a) { return float3( float3( a.rgb).z, float3( a.rgb).y, a.a); } -export float3 zzx( color4 a) { return zzx( float3( a.rgb)); } -export float3 zzy( color4 a) { return zzy( float3( a.rgb)); } -export float3 zzz( color4 a) { return zzz( float3( a.rgb)); } -export float3 zzw( color4 a) { return float3( float3( a.rgb).z, float3( a.rgb).z, a.a); } -export float3 zwx( color4 a) { return float3( float3( a.rgb).z, a.a, float3( a.rgb).x); } -export float3 zwy( color4 a) { return float3( float3( a.rgb).z, a.a, float3( a.rgb).y); } -export float3 zwz( color4 a) { return float3( float3( a.rgb).z, a.a, float3( a.rgb).z); } -export float3 zww( color4 a) { return float3( float3( a.rgb).z, a.a, a.a); } -export float3 wxx( color4 a) { return float3( a.a, float3( a.rgb).x, float3( a.rgb).x); } -export float3 wxy( color4 a) { return float3( a.a, float3( a.rgb).x, float3( a.rgb).y); } -export float3 wxz( color4 a) { return float3( a.a, float3( a.rgb).x, float3( a.rgb).z); } -export float3 wxw( color4 a) { return float3( a.a, float3( a.rgb).x, a.a); } -export float3 wyx( color4 a) { return float3( a.a, float3( a.rgb).y, float3( a.rgb).x); } -export float3 wyy( color4 a) { return float3( a.a, float3( a.rgb).y, float3( a.rgb).y); } -export float3 wyz( color4 a) { return float3( a.a, float3( a.rgb).y, float3( a.rgb).z); } -export float3 wyw( color4 a) { return float3( a.a, float3( a.rgb).y, a.a); } -export float3 wzx( color4 a) { return float3( a.a, float3( a.rgb).z, float3( a.rgb).x); } -export float3 wzy( color4 a) { return float3( a.a, float3( a.rgb).z, float3( a.rgb).y); } -export float3 wzz( color4 a) { return float3( a.a, float3( a.rgb).z, float3( a.rgb).z); } -export float3 wzw( color4 a) { return float3( a.a, float3( a.rgb).z, a.a); } -export float3 wwx( color4 a) { return float3( a.a, a.a, float3( a.rgb).x); } -export float3 wwy( color4 a) { return float3( a.a, a.a, float3( a.rgb).y); } -export float3 wwz( color4 a) { return float3( a.a, a.a, float3( a.rgb).z); } -export float3 www( color4 a) { return float3( a.a, a.a, a.a); } +export float3 xxx( core::color4 a) { return xxx( float3( a.rgb)); } +export float3 xxy( core::color4 a) { return xxy( float3( a.rgb)); } +export float3 xxz( core::color4 a) { return xxz( float3( a.rgb)); } +export float3 xxw( core::color4 a) { return float3( float3( a.rgb).x, float3( a.rgb).x, a.a); } +export float3 xyx( core::color4 a) { return xyx( float3( a.rgb)); } +export float3 xyy( core::color4 a) { return xyy( float3( a.rgb)); } +export float3 xyz( core::color4 a) { return xyz( float3( a.rgb)); } +export float3 xyw( core::color4 a) { return float3( float3( a.rgb).x, float3( a.rgb).y, a.a); } +export float3 xzx( core::color4 a) { return xzx( float3( a.rgb)); } +export float3 xzy( core::color4 a) { return xzy( float3( a.rgb)); } +export float3 xzz( core::color4 a) { return xzz( float3( a.rgb)); } +export float3 xzw( core::color4 a) { return float3( float3( a.rgb).x, float3( a.rgb).z, a.a); } +export float3 xwx( core::color4 a) { return float3( float3( a.rgb).x, a.a, float3( a.rgb).x); } +export float3 xwy( core::color4 a) { return float3( float3( a.rgb).x, a.a, float3( a.rgb).y); } +export float3 xwz( core::color4 a) { return float3( float3( a.rgb).x, a.a, float3( a.rgb).z); } +export float3 xww( core::color4 a) { return float3( float3( a.rgb).x, a.a, a.a); } +export float3 yxx( core::color4 a) { return yxx( float3( a.rgb)); } +export float3 yxy( core::color4 a) { return yxy( float3( a.rgb)); } +export float3 yxz( core::color4 a) { return yxz( float3( a.rgb)); } +export float3 yxw( core::color4 a) { return float3( float3( a.rgb).y, float3( a.rgb).x, a.a); } +export float3 yyx( core::color4 a) { return yyx( float3( a.rgb)); } +export float3 yyy( core::color4 a) { return yyy( float3( a.rgb)); } +export float3 yyz( core::color4 a) { return yyz( float3( a.rgb)); } +export float3 yyw( core::color4 a) { return float3( float3( a.rgb).y, float3( a.rgb).y, a.a); } +export float3 yzx( core::color4 a) { return yzx( float3( a.rgb)); } +export float3 yzy( core::color4 a) { return yzy( float3( a.rgb)); } +export float3 yzz( core::color4 a) { return yzz( float3( a.rgb)); } +export float3 yzw( core::color4 a) { return float3( float3( a.rgb).y, float3( a.rgb).z, a.a); } +export float3 ywx( core::color4 a) { return float3( float3( a.rgb).y, a.a, float3( a.rgb).x); } +export float3 ywy( core::color4 a) { return float3( float3( a.rgb).y, a.a, float3( a.rgb).y); } +export float3 ywz( core::color4 a) { return float3( float3( a.rgb).y, a.a, float3( a.rgb).z); } +export float3 yww( core::color4 a) { return float3( float3( a.rgb).y, a.a, a.a); } +export float3 zxx( core::color4 a) { return zxx( float3( a.rgb)); } +export float3 zxy( core::color4 a) { return zxy( float3( a.rgb)); } +export float3 zxz( core::color4 a) { return zxz( float3( a.rgb)); } +export float3 zxw( core::color4 a) { return float3( float3( a.rgb).z, float3( a.rgb).x, a.a); } +export float3 zyx( core::color4 a) { return zyx( float3( a.rgb)); } +export float3 zyy( core::color4 a) { return zyy( float3( a.rgb)); } +export float3 zyz( core::color4 a) { return zyz( float3( a.rgb)); } +export float3 zyw( core::color4 a) { return float3( float3( a.rgb).z, float3( a.rgb).y, a.a); } +export float3 zzx( core::color4 a) { return zzx( float3( a.rgb)); } +export float3 zzy( core::color4 a) { return zzy( float3( a.rgb)); } +export float3 zzz( core::color4 a) { return zzz( float3( a.rgb)); } +export float3 zzw( core::color4 a) { return float3( float3( a.rgb).z, float3( a.rgb).z, a.a); } +export float3 zwx( core::color4 a) { return float3( float3( a.rgb).z, a.a, float3( a.rgb).x); } +export float3 zwy( core::color4 a) { return float3( float3( a.rgb).z, a.a, float3( a.rgb).y); } +export float3 zwz( core::color4 a) { return float3( float3( a.rgb).z, a.a, float3( a.rgb).z); } +export float3 zww( core::color4 a) { return float3( float3( a.rgb).z, a.a, a.a); } +export float3 wxx( core::color4 a) { return float3( a.a, float3( a.rgb).x, float3( a.rgb).x); } +export float3 wxy( core::color4 a) { return float3( a.a, float3( a.rgb).x, float3( a.rgb).y); } +export float3 wxz( core::color4 a) { return float3( a.a, float3( a.rgb).x, float3( a.rgb).z); } +export float3 wxw( core::color4 a) { return float3( a.a, float3( a.rgb).x, a.a); } +export float3 wyx( core::color4 a) { return float3( a.a, float3( a.rgb).y, float3( a.rgb).x); } +export float3 wyy( core::color4 a) { return float3( a.a, float3( a.rgb).y, float3( a.rgb).y); } +export float3 wyz( core::color4 a) { return float3( a.a, float3( a.rgb).y, float3( a.rgb).z); } +export float3 wyw( core::color4 a) { return float3( a.a, float3( a.rgb).y, a.a); } +export float3 wzx( core::color4 a) { return float3( a.a, float3( a.rgb).z, float3( a.rgb).x); } +export float3 wzy( core::color4 a) { return float3( a.a, float3( a.rgb).z, float3( a.rgb).y); } +export float3 wzz( core::color4 a) { return float3( a.a, float3( a.rgb).z, float3( a.rgb).z); } +export float3 wzw( core::color4 a) { return float3( a.a, float3( a.rgb).z, a.a); } +export float3 wwx( core::color4 a) { return float3( a.a, a.a, float3( a.rgb).x); } +export float3 wwy( core::color4 a) { return float3( a.a, a.a, float3( a.rgb).y); } +export float3 wwz( core::color4 a) { return float3( a.a, a.a, float3( a.rgb).z); } +export float3 www( core::color4 a) { return float3( a.a, a.a, a.a); } // Swizzles with float4 return type export float4 xxxx( float a) { return float4( a, a, a, a); } @@ -748,260 +748,260 @@ export float4 zzzx( color a) { return zzzx( float3(a)); } export float4 zzzy( color a) { return zzzy( float3(a)); } export float4 zzzz( color a) { return zzzz( float3(a)); } -export float4 xxxx( color4 a) { return xxxx( float3( a.rgb)); } -export float4 xxxy( color4 a) { return xxxy( float3( a.rgb)); } -export float4 xxxz( color4 a) { return xxxz( float3( a.rgb)); } -export float4 xxxw( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).x, a.a); } -export float4 xxyx( color4 a) { return xxyx( float3( a.rgb)); } -export float4 xxyy( color4 a) { return xxyy( float3( a.rgb)); } -export float4 xxyz( color4 a) { return xxyz( float3( a.rgb)); } -export float4 xxyw( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).y, a.a); } -export float4 xxzx( color4 a) { return xxzx( float3( a.rgb)); } -export float4 xxzy( color4 a) { return xxzy( float3( a.rgb)); } -export float4 xxzz( color4 a) { return xxzz( float3( a.rgb)); } -export float4 xxzw( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).z, a.a); } -export float4 xxwx( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, a.a, float3( a.rgb).x); } -export float4 xxwy( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, a.a, float3( a.rgb).y); } -export float4 xxwz( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, a.a, float3( a.rgb).z); } -export float4 xxww( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, a.a, a.a); } -export float4 xyxx( color4 a) { return xyxx( float3( a.rgb)); } -export float4 xyxy( color4 a) { return xyxy( float3( a.rgb)); } -export float4 xyxz( color4 a) { return xyxz( float3( a.rgb)); } -export float4 xyxw( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).x, a.a); } -export float4 xyyx( color4 a) { return xyyx( float3( a.rgb)); } -export float4 xyyy( color4 a) { return xyyy( float3( a.rgb)); } -export float4 xyyz( color4 a) { return xyyz( float3( a.rgb)); } -export float4 xyyw( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).y, a.a); } -export float4 xyzx( color4 a) { return xyzx( float3( a.rgb)); } -export float4 xyzy( color4 a) { return xyzy( float3( a.rgb)); } -export float4 xyzz( color4 a) { return xyzz( float3( a.rgb)); } -export float4 xyzw( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).z, a.a); } -export float4 xywx( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, a.a, float3( a.rgb).x); } -export float4 xywy( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, a.a, float3( a.rgb).y); } -export float4 xywz( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, a.a, float3( a.rgb).z); } -export float4 xyww( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, a.a, a.a); } -export float4 xzxx( color4 a) { return xzxx( float3( a.rgb)); } -export float4 xzxy( color4 a) { return xzxy( float3( a.rgb)); } -export float4 xzxz( color4 a) { return xzxz( float3( a.rgb)); } -export float4 xzxw( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).x, a.a); } -export float4 xzyx( color4 a) { return xzyx( float3( a.rgb)); } -export float4 xzyy( color4 a) { return xzyy( float3( a.rgb)); } -export float4 xzyz( color4 a) { return xzyz( float3( a.rgb)); } -export float4 xzyw( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).y, a.a); } -export float4 xzzx( color4 a) { return xzzx( float3( a.rgb)); } -export float4 xzzy( color4 a) { return xzzy( float3( a.rgb)); } -export float4 xzzz( color4 a) { return xzzz( float3( a.rgb)); } -export float4 xzzw( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).z, a.a); } -export float4 xzwx( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, a.a, float3( a.rgb).x); } -export float4 xzwy( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, a.a, float3( a.rgb).y); } -export float4 xzwz( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, a.a, float3( a.rgb).z); } -export float4 xzww( color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, a.a, a.a); } -export float4 xwxx( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).x, float3( a.rgb).x); } -export float4 xwxy( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).x, float3( a.rgb).y); } -export float4 xwxz( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).x, float3( a.rgb).z); } -export float4 xwxw( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).x, a.a); } -export float4 xwyx( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).y, float3( a.rgb).x); } -export float4 xwyy( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).y, float3( a.rgb).y); } -export float4 xwyz( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).y, float3( a.rgb).z); } -export float4 xwyw( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).y, a.a); } -export float4 xwzx( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).z, float3( a.rgb).x); } -export float4 xwzy( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).z, float3( a.rgb).y); } -export float4 xwzz( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).z, float3( a.rgb).z); } -export float4 xwzw( color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).z, a.a); } -export float4 xwwx( color4 a) { return float4( float3( a.rgb).x, a.a, a.a, float3( a.rgb).x); } -export float4 xwwy( color4 a) { return float4( float3( a.rgb).x, a.a, a.a, float3( a.rgb).y); } -export float4 xwwz( color4 a) { return float4( float3( a.rgb).x, a.a, a.a, float3( a.rgb).z); } -export float4 xwww( color4 a) { return float4( float3( a.rgb).x, a.a, a.a, a.a); } -export float4 yxxx( color4 a) { return yxxx( float3( a.rgb)); } -export float4 yxxy( color4 a) { return yxxy( float3( a.rgb)); } -export float4 yxxz( color4 a) { return yxxz( float3( a.rgb)); } -export float4 yxxw( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).x, a.a); } -export float4 yxyx( color4 a) { return yxyx( float3( a.rgb)); } -export float4 yxyy( color4 a) { return yxyy( float3( a.rgb)); } -export float4 yxyz( color4 a) { return yxyz( float3( a.rgb)); } -export float4 yxyw( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).y, a.a); } -export float4 yxzx( color4 a) { return yxzx( float3( a.rgb)); } -export float4 yxzy( color4 a) { return yxzy( float3( a.rgb)); } -export float4 yxzz( color4 a) { return yxzz( float3( a.rgb)); } -export float4 yxzw( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).z, a.a); } -export float4 yxwx( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, a.a, float3( a.rgb).x); } -export float4 yxwy( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, a.a, float3( a.rgb).y); } -export float4 yxwz( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, a.a, float3( a.rgb).z); } -export float4 yxww( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, a.a, a.a); } -export float4 yyxx( color4 a) { return yyxx( float3( a.rgb)); } -export float4 yyxy( color4 a) { return yyxy( float3( a.rgb)); } -export float4 yyxz( color4 a) { return yyxz( float3( a.rgb)); } -export float4 yyxw( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).x, a.a); } -export float4 yyyx( color4 a) { return yyyx( float3( a.rgb)); } -export float4 yyyy( color4 a) { return yyyy( float3( a.rgb)); } -export float4 yyyz( color4 a) { return yyyz( float3( a.rgb)); } -export float4 yyyw( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).y, a.a); } -export float4 yyzx( color4 a) { return yyzx( float3( a.rgb)); } -export float4 yyzy( color4 a) { return yyzy( float3( a.rgb)); } -export float4 yyzz( color4 a) { return yyzz( float3( a.rgb)); } -export float4 yyzw( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).z, a.a); } -export float4 yywx( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, a.a, float3( a.rgb).x); } -export float4 yywy( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, a.a, float3( a.rgb).y); } -export float4 yywz( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, a.a, float3( a.rgb).z); } -export float4 yyww( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, a.a, a.a); } -export float4 yzxx( color4 a) { return yzxx( float3( a.rgb)); } -export float4 yzxy( color4 a) { return yzxy( float3( a.rgb)); } -export float4 yzxz( color4 a) { return yzxz( float3( a.rgb)); } -export float4 yzxw( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).x, a.a); } -export float4 yzyx( color4 a) { return yzyx( float3( a.rgb)); } -export float4 yzyy( color4 a) { return yzyy( float3( a.rgb)); } -export float4 yzyz( color4 a) { return yzyz( float3( a.rgb)); } -export float4 yzyw( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).y, a.a); } -export float4 yzzx( color4 a) { return yzzx( float3( a.rgb)); } -export float4 yzzy( color4 a) { return yzzy( float3( a.rgb)); } -export float4 yzzz( color4 a) { return yzzz( float3( a.rgb)); } -export float4 yzzw( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).z, a.a); } -export float4 yzwx( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, a.a, float3( a.rgb).x); } -export float4 yzwy( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, a.a, float3( a.rgb).y); } -export float4 yzwz( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, a.a, float3( a.rgb).z); } -export float4 yzww( color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, a.a, a.a); } -export float4 ywxx( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).x, float3( a.rgb).x); } -export float4 ywxy( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).x, float3( a.rgb).y); } -export float4 ywxz( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).x, float3( a.rgb).z); } -export float4 ywxw( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).x, a.a); } -export float4 ywyx( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).y, float3( a.rgb).x); } -export float4 ywyy( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).y, float3( a.rgb).y); } -export float4 ywyz( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).y, float3( a.rgb).z); } -export float4 ywyw( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).y, a.a); } -export float4 ywzx( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).z, float3( a.rgb).x); } -export float4 ywzy( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).z, float3( a.rgb).y); } -export float4 ywzz( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).z, float3( a.rgb).z); } -export float4 ywzw( color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).z, a.a); } -export float4 ywwx( color4 a) { return float4( float3( a.rgb).y, a.a, a.a, float3( a.rgb).x); } -export float4 ywwy( color4 a) { return float4( float3( a.rgb).y, a.a, a.a, float3( a.rgb).y); } -export float4 ywwz( color4 a) { return float4( float3( a.rgb).y, a.a, a.a, float3( a.rgb).z); } -export float4 ywww( color4 a) { return float4( float3( a.rgb).y, a.a, a.a, a.a); } -export float4 zxxx( color4 a) { return zxxx( float3( a.rgb)); } -export float4 zxxy( color4 a) { return zxxy( float3( a.rgb)); } -export float4 zxxz( color4 a) { return zxxz( float3( a.rgb)); } -export float4 zxxw( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).x, a.a); } -export float4 zxyx( color4 a) { return zxyx( float3( a.rgb)); } -export float4 zxyy( color4 a) { return zxyy( float3( a.rgb)); } -export float4 zxyz( color4 a) { return zxyz( float3( a.rgb)); } -export float4 zxyw( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).y, a.a); } -export float4 zxzx( color4 a) { return zxzx( float3( a.rgb)); } -export float4 zxzy( color4 a) { return zxzy( float3( a.rgb)); } -export float4 zxzz( color4 a) { return zxzz( float3( a.rgb)); } -export float4 zxzw( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).z, a.a); } -export float4 zxwx( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, a.a, float3( a.rgb).x); } -export float4 zxwy( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, a.a, float3( a.rgb).y); } -export float4 zxwz( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, a.a, float3( a.rgb).z); } -export float4 zxww( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, a.a, a.a); } -export float4 zyxx( color4 a) { return zyxx( float3( a.rgb)); } -export float4 zyxy( color4 a) { return zyxy( float3( a.rgb)); } -export float4 zyxz( color4 a) { return zyxz( float3( a.rgb)); } -export float4 zyxw( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).x, a.a); } -export float4 zyyx( color4 a) { return zyyx( float3( a.rgb)); } -export float4 zyyy( color4 a) { return zyyy( float3( a.rgb)); } -export float4 zyyz( color4 a) { return zyyz( float3( a.rgb)); } -export float4 zyyw( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).y, a.a); } -export float4 zyzx( color4 a) { return zyzx( float3( a.rgb)); } -export float4 zyzy( color4 a) { return zyzy( float3( a.rgb)); } -export float4 zyzz( color4 a) { return zyzz( float3( a.rgb)); } -export float4 zyzw( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).z, a.a); } -export float4 zywx( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, a.a, float3( a.rgb).x); } -export float4 zywy( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, a.a, float3( a.rgb).y); } -export float4 zywz( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, a.a, float3( a.rgb).z); } -export float4 zyww( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, a.a, a.a); } -export float4 zzxx( color4 a) { return zzxx( float3( a.rgb)); } -export float4 zzxy( color4 a) { return zzxy( float3( a.rgb)); } -export float4 zzxz( color4 a) { return zzxz( float3( a.rgb)); } -export float4 zzxw( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).x, a.a); } -export float4 zzyx( color4 a) { return zzyx( float3( a.rgb)); } -export float4 zzyy( color4 a) { return zzyy( float3( a.rgb)); } -export float4 zzyz( color4 a) { return zzyz( float3( a.rgb)); } -export float4 zzyw( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).y, a.a); } -export float4 zzzx( color4 a) { return zzzx( float3( a.rgb)); } -export float4 zzzy( color4 a) { return zzzy( float3( a.rgb)); } -export float4 zzzz( color4 a) { return zzzz( float3( a.rgb)); } -export float4 zzzw( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).z, a.a); } -export float4 zzwx( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, a.a, float3( a.rgb).x); } -export float4 zzwy( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, a.a, float3( a.rgb).y); } -export float4 zzwz( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, a.a, float3( a.rgb).z); } -export float4 zzww( color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, a.a, a.a); } -export float4 zwxx( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).x, float3( a.rgb).x); } -export float4 zwxy( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).x, float3( a.rgb).y); } -export float4 zwxz( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).x, float3( a.rgb).z); } -export float4 zwxw( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).x, a.a); } -export float4 zwyx( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).y, float3( a.rgb).x); } -export float4 zwyy( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).y, float3( a.rgb).y); } -export float4 zwyz( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).y, float3( a.rgb).z); } -export float4 zwyw( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).y, a.a); } -export float4 zwzx( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).z, float3( a.rgb).x); } -export float4 zwzy( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).z, float3( a.rgb).y); } -export float4 zwzz( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).z, float3( a.rgb).z); } -export float4 zwzw( color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).z, a.a); } -export float4 zwwx( color4 a) { return float4( float3( a.rgb).z, a.a, a.a, float3( a.rgb).x); } -export float4 zwwy( color4 a) { return float4( float3( a.rgb).z, a.a, a.a, float3( a.rgb).y); } -export float4 zwwz( color4 a) { return float4( float3( a.rgb).z, a.a, a.a, float3( a.rgb).z); } -export float4 zwww( color4 a) { return float4( float3( a.rgb).z, a.a, a.a, a.a); } -export float4 wxxx( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).x); } -export float4 wxxy( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).y); } -export float4 wxxz( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).z); } -export float4 wxxw( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).x, a.a); } -export float4 wxyx( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).x); } -export float4 wxyy( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).y); } -export float4 wxyz( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).z); } -export float4 wxyw( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).y, a.a); } -export float4 wxzx( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).x); } -export float4 wxzy( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).y); } -export float4 wxzz( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).z); } -export float4 wxzw( color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).z, a.a); } -export float4 wxwx( color4 a) { return float4( a.a, float3( a.rgb).x, a.a, float3( a.rgb).x); } -export float4 wxwy( color4 a) { return float4( a.a, float3( a.rgb).x, a.a, float3( a.rgb).y); } -export float4 wxwz( color4 a) { return float4( a.a, float3( a.rgb).x, a.a, float3( a.rgb).z); } -export float4 wxww( color4 a) { return float4( a.a, float3( a.rgb).x, a.a, a.a); } -export float4 wyxx( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).x); } -export float4 wyxy( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).y); } -export float4 wyxz( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).z); } -export float4 wyxw( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).x, a.a); } -export float4 wyyx( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).x); } -export float4 wyyy( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).y); } -export float4 wyyz( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).z); } -export float4 wyyw( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).y, a.a); } -export float4 wyzx( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).x); } -export float4 wyzy( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).y); } -export float4 wyzz( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).z); } -export float4 wyzw( color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).z, a.a); } -export float4 wywx( color4 a) { return float4( a.a, float3( a.rgb).y, a.a, float3( a.rgb).x); } -export float4 wywy( color4 a) { return float4( a.a, float3( a.rgb).y, a.a, float3( a.rgb).y); } -export float4 wywz( color4 a) { return float4( a.a, float3( a.rgb).y, a.a, float3( a.rgb).z); } -export float4 wyww( color4 a) { return float4( a.a, float3( a.rgb).y, a.a, a.a); } -export float4 wzxx( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).x); } -export float4 wzxy( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).y); } -export float4 wzxz( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).z); } -export float4 wzxw( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).x, a.a); } -export float4 wzyx( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).x); } -export float4 wzyy( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).y); } -export float4 wzyz( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).z); } -export float4 wzyw( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).y, a.a); } -export float4 wzzx( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).x); } -export float4 wzzy( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).y); } -export float4 wzzz( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).z); } -export float4 wzzw( color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).z, a.a); } -export float4 wzwx( color4 a) { return float4( a.a, float3( a.rgb).z, a.a, float3( a.rgb).x); } -export float4 wzwy( color4 a) { return float4( a.a, float3( a.rgb).z, a.a, float3( a.rgb).y); } -export float4 wzwz( color4 a) { return float4( a.a, float3( a.rgb).z, a.a, float3( a.rgb).z); } -export float4 wzww( color4 a) { return float4( a.a, float3( a.rgb).z, a.a, a.a); } -export float4 wwxx( color4 a) { return float4( a.a, a.a, float3( a.rgb).x, float3( a.rgb).x); } -export float4 wwxy( color4 a) { return float4( a.a, a.a, float3( a.rgb).x, float3( a.rgb).y); } -export float4 wwxz( color4 a) { return float4( a.a, a.a, float3( a.rgb).x, float3( a.rgb).z); } -export float4 wwxw( color4 a) { return float4( a.a, a.a, float3( a.rgb).x, a.a); } -export float4 wwyx( color4 a) { return float4( a.a, a.a, float3( a.rgb).y, float3( a.rgb).x); } -export float4 wwyy( color4 a) { return float4( a.a, a.a, float3( a.rgb).y, float3( a.rgb).y); } -export float4 wwyz( color4 a) { return float4( a.a, a.a, float3( a.rgb).y, float3( a.rgb).z); } -export float4 wwyw( color4 a) { return float4( a.a, a.a, float3( a.rgb).y, a.a); } -export float4 wwzx( color4 a) { return float4( a.a, a.a, float3( a.rgb).z, float3( a.rgb).x); } -export float4 wwzy( color4 a) { return float4( a.a, a.a, float3( a.rgb).z, float3( a.rgb).y); } -export float4 wwzz( color4 a) { return float4( a.a, a.a, float3( a.rgb).z, float3( a.rgb).z); } -export float4 wwzw( color4 a) { return float4( a.a, a.a, float3( a.rgb).z, a.a); } -export float4 wwwx( color4 a) { return float4( a.a, a.a, a.a, float3( a.rgb).x); } -export float4 wwwy( color4 a) { return float4( a.a, a.a, a.a, float3( a.rgb).y); } -export float4 wwwz( color4 a) { return float4( a.a, a.a, a.a, float3( a.rgb).z); } -export float4 wwww( color4 a) { return float4( a.a, a.a, a.a, a.a); } +export float4 xxxx( core::color4 a) { return xxxx( float3( a.rgb)); } +export float4 xxxy( core::color4 a) { return xxxy( float3( a.rgb)); } +export float4 xxxz( core::color4 a) { return xxxz( float3( a.rgb)); } +export float4 xxxw( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).x, a.a); } +export float4 xxyx( core::color4 a) { return xxyx( float3( a.rgb)); } +export float4 xxyy( core::color4 a) { return xxyy( float3( a.rgb)); } +export float4 xxyz( core::color4 a) { return xxyz( float3( a.rgb)); } +export float4 xxyw( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).y, a.a); } +export float4 xxzx( core::color4 a) { return xxzx( float3( a.rgb)); } +export float4 xxzy( core::color4 a) { return xxzy( float3( a.rgb)); } +export float4 xxzz( core::color4 a) { return xxzz( float3( a.rgb)); } +export float4 xxzw( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).z, a.a); } +export float4 xxwx( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, a.a, float3( a.rgb).x); } +export float4 xxwy( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, a.a, float3( a.rgb).y); } +export float4 xxwz( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, a.a, float3( a.rgb).z); } +export float4 xxww( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).x, a.a, a.a); } +export float4 xyxx( core::color4 a) { return xyxx( float3( a.rgb)); } +export float4 xyxy( core::color4 a) { return xyxy( float3( a.rgb)); } +export float4 xyxz( core::color4 a) { return xyxz( float3( a.rgb)); } +export float4 xyxw( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).x, a.a); } +export float4 xyyx( core::color4 a) { return xyyx( float3( a.rgb)); } +export float4 xyyy( core::color4 a) { return xyyy( float3( a.rgb)); } +export float4 xyyz( core::color4 a) { return xyyz( float3( a.rgb)); } +export float4 xyyw( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).y, a.a); } +export float4 xyzx( core::color4 a) { return xyzx( float3( a.rgb)); } +export float4 xyzy( core::color4 a) { return xyzy( float3( a.rgb)); } +export float4 xyzz( core::color4 a) { return xyzz( float3( a.rgb)); } +export float4 xyzw( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).z, a.a); } +export float4 xywx( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, a.a, float3( a.rgb).x); } +export float4 xywy( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, a.a, float3( a.rgb).y); } +export float4 xywz( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, a.a, float3( a.rgb).z); } +export float4 xyww( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).y, a.a, a.a); } +export float4 xzxx( core::color4 a) { return xzxx( float3( a.rgb)); } +export float4 xzxy( core::color4 a) { return xzxy( float3( a.rgb)); } +export float4 xzxz( core::color4 a) { return xzxz( float3( a.rgb)); } +export float4 xzxw( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).x, a.a); } +export float4 xzyx( core::color4 a) { return xzyx( float3( a.rgb)); } +export float4 xzyy( core::color4 a) { return xzyy( float3( a.rgb)); } +export float4 xzyz( core::color4 a) { return xzyz( float3( a.rgb)); } +export float4 xzyw( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).y, a.a); } +export float4 xzzx( core::color4 a) { return xzzx( float3( a.rgb)); } +export float4 xzzy( core::color4 a) { return xzzy( float3( a.rgb)); } +export float4 xzzz( core::color4 a) { return xzzz( float3( a.rgb)); } +export float4 xzzw( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).z, a.a); } +export float4 xzwx( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, a.a, float3( a.rgb).x); } +export float4 xzwy( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, a.a, float3( a.rgb).y); } +export float4 xzwz( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, a.a, float3( a.rgb).z); } +export float4 xzww( core::color4 a) { return float4( float3( a.rgb).x, float3( a.rgb).z, a.a, a.a); } +export float4 xwxx( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).x, float3( a.rgb).x); } +export float4 xwxy( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).x, float3( a.rgb).y); } +export float4 xwxz( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).x, float3( a.rgb).z); } +export float4 xwxw( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).x, a.a); } +export float4 xwyx( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).y, float3( a.rgb).x); } +export float4 xwyy( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).y, float3( a.rgb).y); } +export float4 xwyz( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).y, float3( a.rgb).z); } +export float4 xwyw( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).y, a.a); } +export float4 xwzx( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).z, float3( a.rgb).x); } +export float4 xwzy( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).z, float3( a.rgb).y); } +export float4 xwzz( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).z, float3( a.rgb).z); } +export float4 xwzw( core::color4 a) { return float4( float3( a.rgb).x, a.a, float3( a.rgb).z, a.a); } +export float4 xwwx( core::color4 a) { return float4( float3( a.rgb).x, a.a, a.a, float3( a.rgb).x); } +export float4 xwwy( core::color4 a) { return float4( float3( a.rgb).x, a.a, a.a, float3( a.rgb).y); } +export float4 xwwz( core::color4 a) { return float4( float3( a.rgb).x, a.a, a.a, float3( a.rgb).z); } +export float4 xwww( core::color4 a) { return float4( float3( a.rgb).x, a.a, a.a, a.a); } +export float4 yxxx( core::color4 a) { return yxxx( float3( a.rgb)); } +export float4 yxxy( core::color4 a) { return yxxy( float3( a.rgb)); } +export float4 yxxz( core::color4 a) { return yxxz( float3( a.rgb)); } +export float4 yxxw( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).x, a.a); } +export float4 yxyx( core::color4 a) { return yxyx( float3( a.rgb)); } +export float4 yxyy( core::color4 a) { return yxyy( float3( a.rgb)); } +export float4 yxyz( core::color4 a) { return yxyz( float3( a.rgb)); } +export float4 yxyw( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).y, a.a); } +export float4 yxzx( core::color4 a) { return yxzx( float3( a.rgb)); } +export float4 yxzy( core::color4 a) { return yxzy( float3( a.rgb)); } +export float4 yxzz( core::color4 a) { return yxzz( float3( a.rgb)); } +export float4 yxzw( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).z, a.a); } +export float4 yxwx( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, a.a, float3( a.rgb).x); } +export float4 yxwy( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, a.a, float3( a.rgb).y); } +export float4 yxwz( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, a.a, float3( a.rgb).z); } +export float4 yxww( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).x, a.a, a.a); } +export float4 yyxx( core::color4 a) { return yyxx( float3( a.rgb)); } +export float4 yyxy( core::color4 a) { return yyxy( float3( a.rgb)); } +export float4 yyxz( core::color4 a) { return yyxz( float3( a.rgb)); } +export float4 yyxw( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).x, a.a); } +export float4 yyyx( core::color4 a) { return yyyx( float3( a.rgb)); } +export float4 yyyy( core::color4 a) { return yyyy( float3( a.rgb)); } +export float4 yyyz( core::color4 a) { return yyyz( float3( a.rgb)); } +export float4 yyyw( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).y, a.a); } +export float4 yyzx( core::color4 a) { return yyzx( float3( a.rgb)); } +export float4 yyzy( core::color4 a) { return yyzy( float3( a.rgb)); } +export float4 yyzz( core::color4 a) { return yyzz( float3( a.rgb)); } +export float4 yyzw( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).z, a.a); } +export float4 yywx( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, a.a, float3( a.rgb).x); } +export float4 yywy( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, a.a, float3( a.rgb).y); } +export float4 yywz( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, a.a, float3( a.rgb).z); } +export float4 yyww( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).y, a.a, a.a); } +export float4 yzxx( core::color4 a) { return yzxx( float3( a.rgb)); } +export float4 yzxy( core::color4 a) { return yzxy( float3( a.rgb)); } +export float4 yzxz( core::color4 a) { return yzxz( float3( a.rgb)); } +export float4 yzxw( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).x, a.a); } +export float4 yzyx( core::color4 a) { return yzyx( float3( a.rgb)); } +export float4 yzyy( core::color4 a) { return yzyy( float3( a.rgb)); } +export float4 yzyz( core::color4 a) { return yzyz( float3( a.rgb)); } +export float4 yzyw( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).y, a.a); } +export float4 yzzx( core::color4 a) { return yzzx( float3( a.rgb)); } +export float4 yzzy( core::color4 a) { return yzzy( float3( a.rgb)); } +export float4 yzzz( core::color4 a) { return yzzz( float3( a.rgb)); } +export float4 yzzw( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).z, a.a); } +export float4 yzwx( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, a.a, float3( a.rgb).x); } +export float4 yzwy( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, a.a, float3( a.rgb).y); } +export float4 yzwz( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, a.a, float3( a.rgb).z); } +export float4 yzww( core::color4 a) { return float4( float3( a.rgb).y, float3( a.rgb).z, a.a, a.a); } +export float4 ywxx( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).x, float3( a.rgb).x); } +export float4 ywxy( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).x, float3( a.rgb).y); } +export float4 ywxz( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).x, float3( a.rgb).z); } +export float4 ywxw( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).x, a.a); } +export float4 ywyx( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).y, float3( a.rgb).x); } +export float4 ywyy( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).y, float3( a.rgb).y); } +export float4 ywyz( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).y, float3( a.rgb).z); } +export float4 ywyw( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).y, a.a); } +export float4 ywzx( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).z, float3( a.rgb).x); } +export float4 ywzy( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).z, float3( a.rgb).y); } +export float4 ywzz( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).z, float3( a.rgb).z); } +export float4 ywzw( core::color4 a) { return float4( float3( a.rgb).y, a.a, float3( a.rgb).z, a.a); } +export float4 ywwx( core::color4 a) { return float4( float3( a.rgb).y, a.a, a.a, float3( a.rgb).x); } +export float4 ywwy( core::color4 a) { return float4( float3( a.rgb).y, a.a, a.a, float3( a.rgb).y); } +export float4 ywwz( core::color4 a) { return float4( float3( a.rgb).y, a.a, a.a, float3( a.rgb).z); } +export float4 ywww( core::color4 a) { return float4( float3( a.rgb).y, a.a, a.a, a.a); } +export float4 zxxx( core::color4 a) { return zxxx( float3( a.rgb)); } +export float4 zxxy( core::color4 a) { return zxxy( float3( a.rgb)); } +export float4 zxxz( core::color4 a) { return zxxz( float3( a.rgb)); } +export float4 zxxw( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).x, a.a); } +export float4 zxyx( core::color4 a) { return zxyx( float3( a.rgb)); } +export float4 zxyy( core::color4 a) { return zxyy( float3( a.rgb)); } +export float4 zxyz( core::color4 a) { return zxyz( float3( a.rgb)); } +export float4 zxyw( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).y, a.a); } +export float4 zxzx( core::color4 a) { return zxzx( float3( a.rgb)); } +export float4 zxzy( core::color4 a) { return zxzy( float3( a.rgb)); } +export float4 zxzz( core::color4 a) { return zxzz( float3( a.rgb)); } +export float4 zxzw( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).z, a.a); } +export float4 zxwx( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, a.a, float3( a.rgb).x); } +export float4 zxwy( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, a.a, float3( a.rgb).y); } +export float4 zxwz( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, a.a, float3( a.rgb).z); } +export float4 zxww( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).x, a.a, a.a); } +export float4 zyxx( core::color4 a) { return zyxx( float3( a.rgb)); } +export float4 zyxy( core::color4 a) { return zyxy( float3( a.rgb)); } +export float4 zyxz( core::color4 a) { return zyxz( float3( a.rgb)); } +export float4 zyxw( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).x, a.a); } +export float4 zyyx( core::color4 a) { return zyyx( float3( a.rgb)); } +export float4 zyyy( core::color4 a) { return zyyy( float3( a.rgb)); } +export float4 zyyz( core::color4 a) { return zyyz( float3( a.rgb)); } +export float4 zyyw( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).y, a.a); } +export float4 zyzx( core::color4 a) { return zyzx( float3( a.rgb)); } +export float4 zyzy( core::color4 a) { return zyzy( float3( a.rgb)); } +export float4 zyzz( core::color4 a) { return zyzz( float3( a.rgb)); } +export float4 zyzw( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).z, a.a); } +export float4 zywx( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, a.a, float3( a.rgb).x); } +export float4 zywy( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, a.a, float3( a.rgb).y); } +export float4 zywz( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, a.a, float3( a.rgb).z); } +export float4 zyww( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).y, a.a, a.a); } +export float4 zzxx( core::color4 a) { return zzxx( float3( a.rgb)); } +export float4 zzxy( core::color4 a) { return zzxy( float3( a.rgb)); } +export float4 zzxz( core::color4 a) { return zzxz( float3( a.rgb)); } +export float4 zzxw( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).x, a.a); } +export float4 zzyx( core::color4 a) { return zzyx( float3( a.rgb)); } +export float4 zzyy( core::color4 a) { return zzyy( float3( a.rgb)); } +export float4 zzyz( core::color4 a) { return zzyz( float3( a.rgb)); } +export float4 zzyw( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).y, a.a); } +export float4 zzzx( core::color4 a) { return zzzx( float3( a.rgb)); } +export float4 zzzy( core::color4 a) { return zzzy( float3( a.rgb)); } +export float4 zzzz( core::color4 a) { return zzzz( float3( a.rgb)); } +export float4 zzzw( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).z, a.a); } +export float4 zzwx( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, a.a, float3( a.rgb).x); } +export float4 zzwy( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, a.a, float3( a.rgb).y); } +export float4 zzwz( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, a.a, float3( a.rgb).z); } +export float4 zzww( core::color4 a) { return float4( float3( a.rgb).z, float3( a.rgb).z, a.a, a.a); } +export float4 zwxx( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).x, float3( a.rgb).x); } +export float4 zwxy( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).x, float3( a.rgb).y); } +export float4 zwxz( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).x, float3( a.rgb).z); } +export float4 zwxw( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).x, a.a); } +export float4 zwyx( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).y, float3( a.rgb).x); } +export float4 zwyy( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).y, float3( a.rgb).y); } +export float4 zwyz( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).y, float3( a.rgb).z); } +export float4 zwyw( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).y, a.a); } +export float4 zwzx( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).z, float3( a.rgb).x); } +export float4 zwzy( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).z, float3( a.rgb).y); } +export float4 zwzz( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).z, float3( a.rgb).z); } +export float4 zwzw( core::color4 a) { return float4( float3( a.rgb).z, a.a, float3( a.rgb).z, a.a); } +export float4 zwwx( core::color4 a) { return float4( float3( a.rgb).z, a.a, a.a, float3( a.rgb).x); } +export float4 zwwy( core::color4 a) { return float4( float3( a.rgb).z, a.a, a.a, float3( a.rgb).y); } +export float4 zwwz( core::color4 a) { return float4( float3( a.rgb).z, a.a, a.a, float3( a.rgb).z); } +export float4 zwww( core::color4 a) { return float4( float3( a.rgb).z, a.a, a.a, a.a); } +export float4 wxxx( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).x); } +export float4 wxxy( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).y); } +export float4 wxxz( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).x, float3( a.rgb).z); } +export float4 wxxw( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).x, a.a); } +export float4 wxyx( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).x); } +export float4 wxyy( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).y); } +export float4 wxyz( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).y, float3( a.rgb).z); } +export float4 wxyw( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).y, a.a); } +export float4 wxzx( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).x); } +export float4 wxzy( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).y); } +export float4 wxzz( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).z, float3( a.rgb).z); } +export float4 wxzw( core::color4 a) { return float4( a.a, float3( a.rgb).x, float3( a.rgb).z, a.a); } +export float4 wxwx( core::color4 a) { return float4( a.a, float3( a.rgb).x, a.a, float3( a.rgb).x); } +export float4 wxwy( core::color4 a) { return float4( a.a, float3( a.rgb).x, a.a, float3( a.rgb).y); } +export float4 wxwz( core::color4 a) { return float4( a.a, float3( a.rgb).x, a.a, float3( a.rgb).z); } +export float4 wxww( core::color4 a) { return float4( a.a, float3( a.rgb).x, a.a, a.a); } +export float4 wyxx( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).x); } +export float4 wyxy( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).y); } +export float4 wyxz( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).x, float3( a.rgb).z); } +export float4 wyxw( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).x, a.a); } +export float4 wyyx( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).x); } +export float4 wyyy( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).y); } +export float4 wyyz( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).y, float3( a.rgb).z); } +export float4 wyyw( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).y, a.a); } +export float4 wyzx( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).x); } +export float4 wyzy( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).y); } +export float4 wyzz( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).z, float3( a.rgb).z); } +export float4 wyzw( core::color4 a) { return float4( a.a, float3( a.rgb).y, float3( a.rgb).z, a.a); } +export float4 wywx( core::color4 a) { return float4( a.a, float3( a.rgb).y, a.a, float3( a.rgb).x); } +export float4 wywy( core::color4 a) { return float4( a.a, float3( a.rgb).y, a.a, float3( a.rgb).y); } +export float4 wywz( core::color4 a) { return float4( a.a, float3( a.rgb).y, a.a, float3( a.rgb).z); } +export float4 wyww( core::color4 a) { return float4( a.a, float3( a.rgb).y, a.a, a.a); } +export float4 wzxx( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).x); } +export float4 wzxy( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).y); } +export float4 wzxz( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).x, float3( a.rgb).z); } +export float4 wzxw( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).x, a.a); } +export float4 wzyx( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).x); } +export float4 wzyy( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).y); } +export float4 wzyz( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).y, float3( a.rgb).z); } +export float4 wzyw( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).y, a.a); } +export float4 wzzx( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).x); } +export float4 wzzy( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).y); } +export float4 wzzz( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).z, float3( a.rgb).z); } +export float4 wzzw( core::color4 a) { return float4( a.a, float3( a.rgb).z, float3( a.rgb).z, a.a); } +export float4 wzwx( core::color4 a) { return float4( a.a, float3( a.rgb).z, a.a, float3( a.rgb).x); } +export float4 wzwy( core::color4 a) { return float4( a.a, float3( a.rgb).z, a.a, float3( a.rgb).y); } +export float4 wzwz( core::color4 a) { return float4( a.a, float3( a.rgb).z, a.a, float3( a.rgb).z); } +export float4 wzww( core::color4 a) { return float4( a.a, float3( a.rgb).z, a.a, a.a); } +export float4 wwxx( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).x, float3( a.rgb).x); } +export float4 wwxy( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).x, float3( a.rgb).y); } +export float4 wwxz( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).x, float3( a.rgb).z); } +export float4 wwxw( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).x, a.a); } +export float4 wwyx( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).y, float3( a.rgb).x); } +export float4 wwyy( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).y, float3( a.rgb).y); } +export float4 wwyz( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).y, float3( a.rgb).z); } +export float4 wwyw( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).y, a.a); } +export float4 wwzx( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).z, float3( a.rgb).x); } +export float4 wwzy( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).z, float3( a.rgb).y); } +export float4 wwzz( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).z, float3( a.rgb).z); } +export float4 wwzw( core::color4 a) { return float4( a.a, a.a, float3( a.rgb).z, a.a); } +export float4 wwwx( core::color4 a) { return float4( a.a, a.a, a.a, float3( a.rgb).x); } +export float4 wwwy( core::color4 a) { return float4( a.a, a.a, a.a, float3( a.rgb).y); } +export float4 wwwz( core::color4 a) { return float4( a.a, a.a, a.a, float3( a.rgb).z); } +export float4 wwww( core::color4 a) { return float4( a.a, a.a, a.a, a.a); } diff --git a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp index 22ad0d456e..8da7e22fe5 100644 --- a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp +++ b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp @@ -327,11 +327,11 @@ void MdlShaderGeneratorTester::compileSource(const std::vector& so mx::FilePath outputImageName = moduleToTestPath / (imageFilename + extension); renderCommand += " -o " + outputImageName.asString(); - mx::FilePath logFile = moduleToTestPath / (moduleToTest + ".mdl_render_errors.txt"); - renderCommand += " > " + logFile.asString() + " 2>&1"; - + mx::FilePath logFile = moduleToTestPath / (moduleToTest + ".mdl_render_log.txt"); + renderCommand += " --log_file " + logFile.asString(); + mx::FilePath errorLogFile = moduleToTestPath / (moduleToTest + ".mdl_render_errors.txt"); int returnValue = std::system(renderCommand.c_str()); - std::ifstream logStream(logFile); + std::ifstream logStream(errorLogFile); mx::StringVec result; std::string line; bool writeLogCode = false; @@ -382,5 +382,11 @@ TEST_CASE("GenShader: MDL Shader Generation", "[genmdl]") genOptions.fileTextureVerticalFlip = true; mx::FilePath optionsFilePath = searchPath.find("resources/Materials/TestSuite/_options.mtlx"); + + // Specify the MDL target version to be the latest which is also the default. + mx::GenMdlOptionsPtr genMdlOptions = std::make_shared(); + genMdlOptions->targetVersion = mx::GenMdlOptions::MdlVersion::MDL_LATEST; + tester.addUserData(mx::GenMdlOptions::GEN_CONTEXT_USER_DATA_KEY, genMdlOptions); + tester.validate(genOptions, optionsFilePath); } From cff9a7c27572291c23f8daa65d34a8f229dbd93e Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Mon, 5 Feb 2024 15:26:09 -0500 Subject: [PATCH 095/128] Add reflect node and toon shading example (#1690) - Add in new `reflect` node to compute reflection against a planes normal. - Add in new "toon" shading example which uses the `reflect` node. --- libraries/nprlib/nprlib_defs.mtlx | 2 +- libraries/nprlib/nprlib_ng.mtlx | 22 +-- libraries/stdlib/stdlib_defs.mtlx | 11 ++ libraries/stdlib/stdlib_ng.mtlx | 25 +++ .../TestSuite/nprlib/toon_shade.mtlx | 147 ++++++++++++++++++ 5 files changed, 189 insertions(+), 18 deletions(-) create mode 100644 resources/Materials/TestSuite/nprlib/toon_shade.mtlx diff --git a/libraries/nprlib/nprlib_defs.mtlx b/libraries/nprlib/nprlib_defs.mtlx index 384ebec140..57d889c896 100644 --- a/libraries/nprlib/nprlib_defs.mtlx +++ b/libraries/nprlib/nprlib_defs.mtlx @@ -48,7 +48,7 @@ - + diff --git a/libraries/nprlib/nprlib_ng.mtlx b/libraries/nprlib/nprlib_ng.mtlx index 580432ac77..38fc4c97d7 100644 --- a/libraries/nprlib/nprlib_ng.mtlx +++ b/libraries/nprlib/nprlib_ng.mtlx @@ -75,23 +75,11 @@ - - - - - - - - - - - - - - - - - + + + + + diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index 0c24fac77e..fefbf70713 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -2749,6 +2749,17 @@ + + + + + + + diff --git a/libraries/stdlib/stdlib_ng.mtlx b/libraries/stdlib/stdlib_ng.mtlx index 8ea8a74f1a..4cc7721191 100644 --- a/libraries/stdlib/stdlib_ng.mtlx +++ b/libraries/stdlib/stdlib_ng.mtlx @@ -2703,6 +2703,31 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Materials/TestSuite/nprlib/toon_shade.mtlx b/resources/Materials/TestSuite/nprlib/toon_shade.mtlx new file mode 100644 index 0000000000..dae24c4706 --- /dev/null +++ b/resources/Materials/TestSuite/nprlib/toon_shade.mtlx @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a81ed0c650d8df640c9760982d440338c6fbf2cc Mon Sep 17 00:00:00 2001 From: ld-kerley <154285602+ld-kerley@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:23:34 -0800 Subject: [PATCH 096/128] Add refract node (#1698) Adding refract node to partner with the reflect node, with a similar named interface, and implementation as a nodegraph taken from the OSL spec. --- libraries/stdlib/stdlib_defs.mtlx | 11 ++++++ libraries/stdlib/stdlib_ng.mtlx | 61 +++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index fefbf70713..a8d8d1e81a 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -2761,6 +2761,17 @@ + + + + + + + + diff --git a/libraries/stdlib/stdlib_ng.mtlx b/libraries/stdlib/stdlib_ng.mtlx index 4cc7721191..fc6d1c20a2 100644 --- a/libraries/stdlib/stdlib_ng.mtlx +++ b/libraries/stdlib/stdlib_ng.mtlx @@ -2728,6 +2728,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 4fe6acc754e387472b7f30eb274f5e58a7552c2e Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 7 Feb 2024 15:41:53 -0800 Subject: [PATCH 097/128] Update TSC stakeholders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update names and accents for Fran González García, the MaterialX TSC representative from Pixar RenderMan. - Swap Eric Bourque with Henrik Edstrom as the representative from Autodesk. - Swap Lee Kerley with Ole Gulbrandsen as the representative from Sony Pictures Imageworks. - Remove Brian Savery as the representative from AMD. --- GOVERNANCE.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 2ec3d7b867..3cfcab6cd8 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -62,17 +62,16 @@ MaterialX project, though they are encouraged to do so. The current Stakeholders of the MaterialX TSC are: -- Eric Bourque - Autodesk -- Fran Gonzalez - Pixar RenderMan +- Henrik Edstrom - Autodesk +- Fran González García - Pixar RenderMan - Dhruv Govil - Apple - Rafal Jaroszkiewicz - SideFX -- Lee Kerley - Sony Pictures Imageworks +- Ole Gulbrandsen - Sony Pictures Imageworks - Lutz Kettner - NVIDIA - Chris Kulla - Epic Games - Bernard Kwok - Khronos Group - André Mazzone - ILM - Magnus Pettersson - IKEA -- Brian Savery - AMD ### TSC Nomination and Succession From 799646085575aaf7e8ce5c96cc178e5d4960f13f Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Thu, 8 Feb 2024 10:36:16 -0500 Subject: [PATCH 098/128] Support hosting of JsMaterialXCore library (#1693) - Expose JsMaterialXCore as part of published github pages. - This allows users to load in the core package only for Web usage without pulling in the much larger shader gen package (JsMaterialXGenShader) -- which is often undesired. --- javascript/MaterialXView/webpack.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/javascript/MaterialXView/webpack.config.js b/javascript/MaterialXView/webpack.config.js index cd33a443f2..354ba29ce6 100644 --- a/javascript/MaterialXView/webpack.config.js +++ b/javascript/MaterialXView/webpack.config.js @@ -71,6 +71,8 @@ module.exports = { { from: stdSurfaceMaterials, to: stdSurfaceMaterialsBaseURL }, { from: usdSurfaceMaterials, to: usdSurfaceMaterialsBaseURL }, { from: gltfSurfaceMaterials, to: gltfSurfaceMaterialsBaseURL }, + { from: "../build/bin/JsMaterialXCore.wasm" }, + { from: "../build/bin/JsMaterialXCore.js" }, { from: "../build/bin/JsMaterialXGenShader.wasm" }, { from: "../build/bin/JsMaterialXGenShader.js" }, { from: "../build/bin/JsMaterialXGenShader.data" }, From ffbc5189a1f0968c65802f0714fd04b3f9b1f6c6 Mon Sep 17 00:00:00 2001 From: krohmerNV <42233792+krohmerNV@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:41:25 +0100 Subject: [PATCH 099/128] MDL parameter annotations (#1682) Add a first annotation to relate between MDL and the original graph --- source/MaterialXGenMdl/MdlShaderGenerator.cpp | 24 +++++++++++++++++-- source/MaterialXGenMdl/MdlShaderGenerator.h | 2 +- source/MaterialXGenMdl/mdl/materialx/core.mdl | 5 +++- .../MaterialXGenShader/GenShaderUtil.cpp | 1 + 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.cpp b/source/MaterialXGenMdl/MdlShaderGenerator.cpp index 039b82ec6a..5a1f39f48d 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.cpp +++ b/source/MaterialXGenMdl/MdlShaderGenerator.cpp @@ -26,6 +26,7 @@ #include #include #include +#include MATERIALX_NAMESPACE_BEGIN @@ -261,7 +262,7 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G emitScopeBegin(stage, Syntax::PARENTHESES); // Emit shader inputs - emitShaderInputs(stage.getInputBlock(MDL::INPUTS), stage); + emitShaderInputs(element->getDocument(), stage.getInputBlock(MDL::INPUTS), stage); // End shader signature emitScopeEnd(stage); @@ -677,7 +678,25 @@ ShaderPtr MdlShaderGenerator::createShader(const string& name, ElementPtr elemen return shader; } -void MdlShaderGenerator::emitShaderInputs(const VariableBlock& inputs, ShaderStage& stage) const +namespace +{ + +void emitInputAnnotations(const MdlShaderGenerator& _this, const DocumentPtr doc, const ShaderPort* variable, ShaderStage& stage) +{ + // allows to relate between MaterialX and MDL parameters when looking at the MDL code. + const std::string mtlxParameterPathAnno = "materialx::core::origin(\"" + variable->getPath() + "\")"; + + _this.emitLineEnd(stage, false); + _this.emitLine("[[", stage, false); + _this.emitLine("\t" + mtlxParameterPathAnno, stage, false); + _this.emitLineBegin(stage); + _this.emitString("]]", stage); // line ending follows by caller +} + +} // anonymous namespace + + +void MdlShaderGenerator::emitShaderInputs(const DocumentPtr doc, const VariableBlock& inputs, ShaderStage& stage) const { const string uniformPrefix = _syntax->getUniformQualifier() + " "; for (size_t i = 0; i < inputs.size(); ++i) @@ -704,6 +723,7 @@ void MdlShaderGenerator::emitShaderInputs(const VariableBlock& inputs, ShaderSta emitLineBegin(stage); emitString(qualifier + type + " " + input->getVariable() + " = " + value, stage); + emitInputAnnotations(*this, doc, input, stage); if (i < inputs.size() - 1) { diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.h b/source/MaterialXGenMdl/MdlShaderGenerator.h index 5722c89e1d..3a24bcf87d 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.h +++ b/source/MaterialXGenMdl/MdlShaderGenerator.h @@ -90,7 +90,7 @@ class MX_GENMDL_API MdlShaderGenerator : public ShaderGenerator ShaderPtr createShader(const string& name, ElementPtr element, GenContext& context) const; // Emit a block of shader inputs. - void emitShaderInputs(const VariableBlock& inputs, ShaderStage& stage) const; + void emitShaderInputs(const DocumentPtr doc, const VariableBlock& inputs, ShaderStage& stage) const; }; namespace MDL diff --git a/source/MaterialXGenMdl/mdl/materialx/core.mdl b/source/MaterialXGenMdl/mdl/materialx/core.mdl index b0012f7dab..f9fe427b3e 100644 --- a/source/MaterialXGenMdl/mdl/materialx/core.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/core.mdl @@ -193,4 +193,7 @@ export enum mx_distribution_type { mx_distribution_type_ggx }; - +// Custom annotation for MDL function parameters to map between MDL and the original MaterialX graph. +// * When added to a paramater, the "name" will contain the path in the MaterialX graph starting +// from the root up to the input using `/` as separator. +export annotation origin(string name); diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp index 1280ff390d..aa6d084347 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp @@ -705,6 +705,7 @@ void ShaderGeneratorTester::validate(const mx::GenOptions& generateOptions, cons { // Apply optional preprocessing. preprocessDocument(doc); + _shaderGenerator->registerShaderMetadata(doc, context); // For each new file clear the implementation cache. // Since the new file might contain implementations with names From 42d08008d8dbfe174f254450d5ee0ff1c1c1c020 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 7 Feb 2024 16:18:32 -0800 Subject: [PATCH 100/128] Enable new OSL closures by default This changelist enables the OSL 1.12+ closures by default in MaterialX shader generation, with the MATERIALX_OSL_LEGACY_CLOSURES flag used to request legacy closures. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c29565a7ed..9cd5c859e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ option(MATERIALX_TEST_RENDER "Run rendering tests for MaterialX Render module. G option(MATERIALX_WARNINGS_AS_ERRORS "Interpret all compiler warnings as errors." OFF) option(MATERIALX_COVERAGE_ANALYSIS "Build MaterialX libraries with coverage analysis on supporting platforms." OFF) option(MATERIALX_DYNAMIC_ANALYSIS "Build MaterialX libraries with dynamic analysis on supporting platforms." OFF) -option(MATERIALX_OSL_LEGACY_CLOSURES "Build OSL shader generation supporting the legacy OSL closures." ON) +option(MATERIALX_OSL_LEGACY_CLOSURES "Build OSL shader generation supporting the legacy OSL closures." OFF) option(MATERIALX_BUILD_IOS "Build MaterialX for iOS." OFF) if (MATERIALX_BUILD_IOS) From da242e504b13458c82555ce153175ded13235c9b Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Thu, 8 Feb 2024 08:37:29 -0800 Subject: [PATCH 101/128] Update changelog for recent work --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8232e75596..956027feeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,9 @@ ### Added - Added an initial NPR (non-photorealistic rendering) data library to MaterialX, supporting the [View Direction](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1631), [Facing Ratio](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1671), and [Gooch Shading](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1674) nodes. +- Added new nodes to the standard data library, including [Reflect](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1690), [Refract](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1698), [Safe Power](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1689) and [Create Matrix](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1553). - Added support for the generation of [pre-filtered environment maps](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1420) in MaterialX GLSL and MSL. -- Added support for [geometry drag & drop](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1663), [frame capture](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1636), [UI attributes](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1623) and [enumerated values](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1632) in the MaterialX Web Viewer. -- Added support for the [safepower](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1689) and [creatematrix](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1553) nodes in shader generation. +- Added support for [geometry drag & drop](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1663), [frame capture](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1636), [UI ranges](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1623) and [enumerated values](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1632) in the MaterialX Web Viewer. - Added [floating popups](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1565) for hovered pins in the MaterialX Graph Editor. - Added [UI ranges](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1646) to the 'useSpecularWorkflow' and 'normal' inputs of the UsdPreviewSurface shading model. - Added [versioning rules](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1664) for the MaterialX API and data libraries to the developer guide. From 4eadb478babc8ac9d388fb3cd3310fa59688ff88 Mon Sep 17 00:00:00 2001 From: ld-kerley <154285602+ld-kerley@users.noreply.github.com> Date: Fri, 9 Feb 2024 10:06:50 -0800 Subject: [PATCH 102/128] Add round node to data libraries (#1678) Mirror the existing ceil node definition. --- .../stdlib/genglsl/stdlib_genglsl_impl.mtlx | 9 +++ .../stdlib/genmdl/stdlib_genmdl_impl.mtlx | 9 +++ .../stdlib/genmsl/stdlib_genmsl_impl.mtlx | 9 +++ libraries/stdlib/genosl/include/color4.h | 5 ++ libraries/stdlib/genosl/include/vector2.h | 5 ++ libraries/stdlib/genosl/include/vector4.h | 8 +++ .../stdlib/genosl/stdlib_genosl_impl.mtlx | 9 +++ libraries/stdlib/stdlib_defs.mtlx | 33 ++++++++++ python/Scripts/genmdl.py | 3 + .../Materials/TestSuite/stdlib/math/math.mtlx | 63 +++++++++++++++++++ .../mdl/materialx/stdlib_1_6.mdl | 20 ++++++ .../mdl/materialx/stdlib_1_8.mdl | 2 + 12 files changed, 175 insertions(+) diff --git a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx index 70d7674981..243a264763 100644 --- a/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx +++ b/libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx @@ -302,6 +302,15 @@ + + + + + + + + + diff --git a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx index 24e6070071..7d80ecb429 100644 --- a/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx +++ b/libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx @@ -304,6 +304,15 @@ + + + + + + + + + diff --git a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx index 2a17cc06fd..e8b6110813 100644 --- a/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx +++ b/libraries/stdlib/genmsl/stdlib_genmsl_impl.mtlx @@ -302,6 +302,15 @@ + + + + + + + + + diff --git a/libraries/stdlib/genosl/include/color4.h b/libraries/stdlib/genosl/include/color4.h index 78b06b24ec..dcee101258 100644 --- a/libraries/stdlib/genosl/include/color4.h +++ b/libraries/stdlib/genosl/include/color4.h @@ -151,6 +151,11 @@ color4 ceil(color4 a) return color4(ceil(a.rgb), ceil(a.a)); } +color4 round(color4 a) +{ + return color4(round(a.rgb), round(a.a)); +} + color4 floor(color4 a) { return color4(floor(a.rgb), floor(a.a)); diff --git a/libraries/stdlib/genosl/include/vector2.h b/libraries/stdlib/genosl/include/vector2.h index f819dd142f..83fad03456 100644 --- a/libraries/stdlib/genosl/include/vector2.h +++ b/libraries/stdlib/genosl/include/vector2.h @@ -151,6 +151,11 @@ vector2 ceil(vector2 a) return vector2 (ceil(a.x), ceil(a.y)); } +vector2 round(vector2 a) +{ + return vector2 (round(a.x), round(a.y)); +} + vector2 floor(vector2 a) { return vector2 (floor(a.x), floor(a.y)); diff --git a/libraries/stdlib/genosl/include/vector4.h b/libraries/stdlib/genosl/include/vector4.h index 56b64b0c6a..6c8b3996dc 100644 --- a/libraries/stdlib/genosl/include/vector4.h +++ b/libraries/stdlib/genosl/include/vector4.h @@ -160,6 +160,14 @@ vector4 ceil(vector4 in) ceil(in.w)); } +vector4 round(vector4 in) +{ + return vector4 (round(in.x), + round(in.y), + round(in.z), + round(in.w)); +} + vector4 floor(vector4 in) { return vector4 (floor(in.x), diff --git a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx index 177b28cfab..c916eb3052 100644 --- a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx +++ b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx @@ -304,6 +304,15 @@ + + + + + + + + + diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index a8d8d1e81a..6034f109f3 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -1914,6 +1914,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + diff --git a/libraries/stdlib/stdlib_ng.mtlx b/libraries/stdlib/stdlib_ng.mtlx index fc6d1c20a2..046d704bb2 100644 --- a/libraries/stdlib/stdlib_ng.mtlx +++ b/libraries/stdlib/stdlib_ng.mtlx @@ -2705,8 +2705,7 @@ @@ -2727,66 +2726,67 @@ - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - - - + + + + - + @@ -2862,190 +2862,190 @@ --> - + - + - - + + - - + + - + - + - + - - + + - - + + - + - + - + - - + + - - + + - + - + - + - - + + - - + + - + - + - + - - + + - - + + - + - + - + - - + + - - + + - + - + - + - - + + - - + + - + - + - + - - + + - - + + - + - + - + - - + + - - + + - + - + - + - - + + - - + + - + - + - + - - + + - - + + - + - + diff --git a/source/MaterialXGenMdl/mdl/materialx/stdlib_1_8.mdl b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_8.mdl index ffb4f2cd91..0173cfcf7d 100644 --- a/source/MaterialXGenMdl/mdl/materialx/stdlib_1_8.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_8.mdl @@ -421,3 +421,29 @@ export float4 mx_geompropvalue_vector4( { return scene::data_lookup_float4(mxp_geomprop, mxp_default); } + +export float3 mx_viewdirection_vector3( + uniform core::mx_coordinatespace_type mxp_space = core::mx_coordinatespace_type_world + [[ + anno::description("Enumeration {model,object,world}."), + anno::unused() + ]] +) + [[ + anno::description("Node Group: nprlib") + ]] +{ + float3 internal_space_direction = + state::position() - scene::data_lookup_float3("CAMERA_POSITION", float3(0.0, 0.0, 0.0)); + + if (mxp_space == core::mx_coordinatespace_type_world) + return math::normalize(state::transform_vector( + ::state::coordinate_internal, + ::state::coordinate_world, + internal_space_direction)); + else + return math::normalize(state::transform_vector( + ::state::coordinate_internal, + ::state::coordinate_object, + internal_space_direction)); +} From 7a15aa1f35164ecc4947c7b0f699e99f8158a303 Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Fri, 9 Feb 2024 16:37:59 -0500 Subject: [PATCH 105/128] Fix handling of unrecognized types in Web Viewer (#1705) Remove recursive call which appears to be unfinished code, and even has the wrong number of args to the call. --- javascript/MaterialXView/source/helper.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/javascript/MaterialXView/source/helper.js b/javascript/MaterialXView/source/helper.js index 2b7f0f7d5b..cd3f144f06 100644 --- a/javascript/MaterialXView/source/helper.js +++ b/javascript/MaterialXView/source/helper.js @@ -127,10 +127,8 @@ function toThreeUniform(type, value, name, uniforms, textureLoader, searchPath, break; case 'samplerCube': case 'string': - break; default: - // struct - outValue = toThreeUniform(value); + break; } return outValue; From d178310d0376c377db86da72797d5c4881448e01 Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Sat, 10 Feb 2024 23:00:56 -0500 Subject: [PATCH 106/128] Improve input filtering in Web Viewer (#1697) Add UI filtering for interior inputs, non-inputs, and repeated inputs. --- javascript/MaterialXView/source/viewer.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/javascript/MaterialXView/source/viewer.js b/javascript/MaterialXView/source/viewer.js index 06236fdac9..4e42013a25 100644 --- a/javascript/MaterialXView/source/viewer.js +++ b/javascript/MaterialXView/source/viewer.js @@ -1082,6 +1082,12 @@ export class Material { continue; } + + // Skip non-input types and anything > 2 levels deep + if (!currentElem.asAInput() || currentElem.getNamePath().split('/').length > 2) + { + continue; + } let currentNode = null; if (currentElem.getParent() && currentElem.getParent().getNamePath() != "") @@ -1171,6 +1177,21 @@ export class Material } } + // Skip if already added to current folder + let found = false; + for (let i = 0; i < currentFolder.children.length; ++i) + { + if (currentFolder.children[i]._name == path) + { + found = true; + break; + } + } + if (found) + { + continue; + } + switch (variable.getType().getName()) { case 'float': @@ -1390,7 +1411,6 @@ export class Material case 'filename': break; case 'string': - console.log('String: ', name); if (value != null) { var dummy = From ece229234931bd52274da353e650e6ffaf468b8f Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sun, 11 Feb 2024 16:20:19 -0800 Subject: [PATCH 107/128] Update action versions in GitHub CI (#1708) This changelist updates the versions of several actions in GitHub CI, including checkout, setup-python, setup-node, and upload-artifact. --- .github/workflows/main.yml | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a9d6675d3c..ef23a446a0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -120,7 +120,7 @@ jobs: steps: - name: Sync Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive @@ -168,7 +168,7 @@ jobs: - name: Install Python ${{ matrix.python }} if: matrix.python != 'None' - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} architecture: ${{ matrix.architecture }} @@ -189,7 +189,7 @@ jobs: - name: Install Node if: matrix.build_javascript == 'ON' - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '16' @@ -274,34 +274,34 @@ jobs: - name: Upload Installed Package if: matrix.python != 'None' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: MaterialX_${{ matrix.name }} path: build/installed/ - name: Upload Formatted Source if: matrix.clang_format == 'ON' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: MaterialX_ClangFormat path: source - name: Upload Reference Shaders - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: matrix.upload_shaders == 'ON' with: name: Reference_Shaders_${{ matrix.name }} path: build/bin/reference/ - name: Upload Renders - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: matrix.test_render == 'ON' with: name: Renders_${{ matrix.name }} path: build/render/*.png - name: Upload Coverage Report - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: matrix.coverage_analysis == 'ON' with: name: MaterialX_Coverage @@ -340,7 +340,7 @@ jobs: - name: Upload JavaScript Package if: matrix.build_javascript == 'ON' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: MaterialX_JavaScript path: javascript/build/installed/JavaScript/MaterialX @@ -355,10 +355,10 @@ jobs: steps: - name: Sync Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.11 @@ -370,7 +370,7 @@ jobs: echo "filename=$(ls dist)" >> "$GITHUB_OUTPUT" - name: Upload SDist - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: MaterialX_Python_SDist path: dist/*.tar.gz @@ -388,15 +388,15 @@ jobs: steps: - name: Sync Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Python 3.${{ matrix.python-minor }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.${{ matrix.python-minor }} - name: Download Sdist - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: MaterialX_Python_SDist path: sdist @@ -429,7 +429,7 @@ jobs: working-directory: python - name: Upload Wheel - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: MaterialX_Python_Wheels + name: MaterialX_Python_Wheel_${{ runner.os }}_3_${{ matrix.python-minor }} path: wheelhouse/*.whl From a147a1656b5192fd9821c5af1177acaa67f8d1ef Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Tue, 13 Feb 2024 11:53:00 -0500 Subject: [PATCH 108/128] Align vector spaces for npr nodes (#1710) - Gooch was using `` in "object" space and `` in "world" space. This causes incorrect rendering when the geometric transform is not identity. - The toon example was also doing this. --- libraries/nprlib/nprlib_ng.mtlx | 8 ++++++-- resources/Materials/TestSuite/nprlib/toon_shade.mtlx | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/libraries/nprlib/nprlib_ng.mtlx b/libraries/nprlib/nprlib_ng.mtlx index 3870b852e9..f3db3f51ff 100644 --- a/libraries/nprlib/nprlib_ng.mtlx +++ b/libraries/nprlib/nprlib_ng.mtlx @@ -48,8 +48,12 @@ Node: --> - - + + + + + + diff --git a/resources/Materials/TestSuite/nprlib/toon_shade.mtlx b/resources/Materials/TestSuite/nprlib/toon_shade.mtlx index dae24c4706..1c93cad62d 100644 --- a/resources/Materials/TestSuite/nprlib/toon_shade.mtlx +++ b/resources/Materials/TestSuite/nprlib/toon_shade.mtlx @@ -27,7 +27,9 @@ - + + + @@ -47,7 +49,9 @@ - + + + From 52fdca7c3fd9d0154c91f725b503588086e341dd Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 13 Feb 2024 20:51:40 -0800 Subject: [PATCH 109/128] MacOS updates in GitHub CI - Update from MacOS 11 to 12, as the former environment is now deprecated. - Update from MacOS 13 to 14, taking advantage of new beta environments. --- .github/workflows/main.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ef23a446a0..0c42bf93ad 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -71,10 +71,10 @@ jobs: cmake_config: -DMATERIALX_DYNAMIC_ANALYSIS=ON dynamic_analysis: ON - - name: MacOS_Xcode_11_Python37 - os: macos-11 + - name: MacOS_Xcode_13_Python37 + os: macos-12 compiler: xcode - compiler_version: "11.7" + compiler_version: "13.1" cmake_config: -DMATERIALX_BUILD_SHARED_LIBS=ON python: 3.7 @@ -85,14 +85,14 @@ jobs: python: 3.11 - name: MacOS_Xcode_15_Python312 - os: macos-13 + os: macos-14 compiler: xcode compiler_version: "15.0" python: 3.12 test_shaders: ON - name: iOS_Xcode_15 - os: macos-13 + os: macos-14 compiler: xcode compiler_version: "15.0" python: None From bbaeabaf56cb924930ee20c7fda863da0759db02 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Wed, 14 Feb 2024 10:27:15 -0800 Subject: [PATCH 110/128] Update changelog for recent work --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 956027feeb..66a79d724a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ ### Added - Added an initial NPR (non-photorealistic rendering) data library to MaterialX, supporting the [View Direction](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1631), [Facing Ratio](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1671), and [Gooch Shading](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1674) nodes. -- Added new nodes to the standard data library, including [Reflect](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1690), [Refract](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1698), [Safe Power](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1689) and [Create Matrix](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1553). +- Added new nodes to the standard data library, including [Reflect](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1690), [Refract](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1698), [Safe Power](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1689), [Create Matrix](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1553), and [Round](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1678). - Added support for the generation of [pre-filtered environment maps](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1420) in MaterialX GLSL and MSL. - Added support for [geometry drag & drop](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1663), [frame capture](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1636), [UI ranges](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1623) and [enumerated values](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1632) in the MaterialX Web Viewer. - Added [floating popups](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1565) for hovered pins in the MaterialX Graph Editor. @@ -16,12 +16,12 @@ ### Changed +- Enabled the [new OSL closures](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1702) by default in shader generation, with the MATERIALX_OSL_LEGACY_CLOSURES flag used to request legacy closures. +- Updated the MaterialX Web Viewer to [three.js r152](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1615). +- Switched to a more efficient representation of [HDR images](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1616) in the MaterialX Web Viewer. - Improved the logic for [connecting pins](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1569) in the MaterialX Graph Editor. -- Improved the robustness of [type pointer comparisons](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1665) in shader generation. - Improved the handling of [filename inputs](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1547) in OSL shader generation. - Reduced the size of the MaterialX data libraries, improving the use of [graph definitions](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1653) and merging [duplicate implementations](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1642). -- Updated the MaterialX Web Viewer to [three.js r152](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1615). -- Switched to a more efficient representation of [HDR images](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1616) in the MaterialX Web Viewer. - Raised the minimum CMake version to [CMake 3.16](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1607). - Updated the C++ unit test library to [Catch 2.13.10](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1566). @@ -29,6 +29,7 @@ - Fixed the attenuation of [coated emission](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1534) in the Standard Surface shading model. - Fixed the implementation of the [overlay node](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1539) in shader generation. +- Fixed an edge case for [type pointer comparisons](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1665) in shader generation. - Fixed an edge case for [transform nodes](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1560) in GLSL and MSL shader generation. - Fixed the implementation of [mx_hsvtorgb](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1584) in MDL shader generation. - Fixed [orphaned links](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1667) when deleting nodes in the MaterialX Graph Editor. From 1d5ac95ec6007c6a7f39bbd8ec326d6aa243ccaa Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sat, 17 Feb 2024 15:14:43 -0800 Subject: [PATCH 111/128] Simplify render test suite (#1717) --- resources/Materials/TestSuite/_options.mtlx | 49 ------- .../pbrlib/bsdf/generalized_schlick.mtlx | 2 +- .../pbrlib/bsdf/wedge_conductor.mtlx | 25 ---- .../pbrlib/displacement/displacement.mtlx | 4 +- .../pbrlib/multioutput/multishaderoutput.mtlx | 4 +- .../surfacematerial_with_graph.mtlx | 52 +++---- .../MaterialXGenShader/GenShaderUtil.cpp | 66 --------- .../MaterialXGenShader/GenShaderUtil.h | 10 -- .../MaterialXRender/RenderUtil.cpp | 128 +----------------- .../MaterialXRender/RenderUtil.h | 4 - .../MaterialXRenderGlsl/RenderGlsl.cpp | 38 ------ .../MaterialXRenderMsl/RenderMsl.mm | 38 ------ 12 files changed, 33 insertions(+), 387 deletions(-) delete mode 100644 resources/Materials/TestSuite/pbrlib/bsdf/wedge_conductor.mtlx diff --git a/resources/Materials/TestSuite/_options.mtlx b/resources/Materials/TestSuite/_options.mtlx index 74bfe1eb35..99db2a9f50 100644 --- a/resources/Materials/TestSuite/_options.mtlx +++ b/resources/Materials/TestSuite/_options.mtlx @@ -11,23 +11,6 @@ can also be performed depending on the options enabled. --> - - - - - - - - - - - - - - - - - @@ -95,37 +78,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx b/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx index cb36a8957d..a320dcda9a 100644 --- a/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx +++ b/resources/Materials/TestSuite/pbrlib/bsdf/generalized_schlick.mtlx @@ -1,6 +1,6 @@ - + diff --git a/resources/Materials/TestSuite/pbrlib/bsdf/wedge_conductor.mtlx b/resources/Materials/TestSuite/pbrlib/bsdf/wedge_conductor.mtlx deleted file mode 100644 index 4e34fdc4a1..0000000000 --- a/resources/Materials/TestSuite/pbrlib/bsdf/wedge_conductor.mtlx +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/Materials/TestSuite/pbrlib/displacement/displacement.mtlx b/resources/Materials/TestSuite/pbrlib/displacement/displacement.mtlx index 6ea8b7e90d..d0ef073583 100644 --- a/resources/Materials/TestSuite/pbrlib/displacement/displacement.mtlx +++ b/resources/Materials/TestSuite/pbrlib/displacement/displacement.mtlx @@ -1,6 +1,6 @@ - + @@ -21,7 +21,7 @@ - + diff --git a/resources/Materials/TestSuite/pbrlib/multioutput/multishaderoutput.mtlx b/resources/Materials/TestSuite/pbrlib/multioutput/multishaderoutput.mtlx index 7456b088d9..f6dacf6ed5 100644 --- a/resources/Materials/TestSuite/pbrlib/multioutput/multishaderoutput.mtlx +++ b/resources/Materials/TestSuite/pbrlib/multioutput/multishaderoutput.mtlx @@ -1,6 +1,6 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/resources/Materials/TestSuite/pbrlib/surfaceshader/surfacematerial_with_graph.mtlx b/resources/Materials/TestSuite/pbrlib/surfaceshader/surfacematerial_with_graph.mtlx index 203aae6be4..1ea487a503 100644 --- a/resources/Materials/TestSuite/pbrlib/surfaceshader/surfacematerial_with_graph.mtlx +++ b/resources/Materials/TestSuite/pbrlib/surfaceshader/surfacematerial_with_graph.mtlx @@ -1,10 +1,6 @@ - - - - - + @@ -12,42 +8,46 @@ - - - + + + - + + - - - - - - + + + + + + + + + + + + - + + + + + - - - - - - - - + + - - + diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp index aa6d084347..5aa1d7aa2d 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp @@ -965,8 +965,6 @@ bool TestSuiteOptions::readOptions(const std::string& optionFile) const std::string EXTRA_LIBRARY_PATHS("extraLibraryPaths"); const std::string RENDER_TEST_PATHS("renderTestPaths"); const std::string ENABLE_REFERENCE_QUALITY("enableReferenceQuality"); - const std::string WEDGE_SETTING("wedgerender"); - const std::string BAKER_SETTINGS("baker"); overrideFiles.clear(); dumpGeneratedCode = false; @@ -983,70 +981,6 @@ bool TestSuiteOptions::readOptions(const std::string& optionFile) mx::NodeDefPtr optionDefs = doc->getNodeDef(RENDER_TEST_OPTIONS_STRING); if (optionDefs) { - // Read Wedge Render Settings - for (mx::ElementPtr p : optionDefs->getChildrenOfType(WEDGE_SETTING)) - { - WedgeSetting setting; - for (auto child : p->getChildren()) - { - mx::InputPtr input = child->asA(); - const std::string& name = input->getName(); - mx::ValuePtr val = input->getValue(); - - if (name == "file") - { - setting.wedgeFile = val->asA(); - } - else if (name == "parameter") - { - setting.parameter = val->asA(); - } - else if (name == "range") - { - setting.range = val->asA(); - } - else if (name == "steps") - { - setting.steps = val->asA(); - } - } - wedgeSettings.push_back(setting); - } - - // Read Baker Settings - for (mx::ElementPtr p : optionDefs->getChildrenOfType(BAKER_SETTINGS)) - { - BakeSetting setting; - for (auto child : p->getChildren()) - { - mx::InputPtr input = child->asA(); - const std::string& name = input->getName(); - mx::ValuePtr val = input->getValue(); - - if (name == "file") - { - setting.bakeFile = val->asA(); - } - else if (name == "resolution") - { - setting.resolution = val->asA(); - } - else if (name == "hdr") - { - setting.hdr = val->asA(); - } - else if (name == "uvmin") - { - setting.uvmin = val->asA(); - } - else if (name == "uvmax") - { - setting.uvmax = val->asA(); - } - } - bakeSettings.push_back(setting); - } - for (auto p : optionDefs->getInputs()) { const std::string& name = p->getName(); diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h index 9c471466aa..2bac14e435 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h @@ -131,16 +131,6 @@ class TestSuiteOptions // Enable reference quality rendering. Default is false. bool enableReferenceQuality; - // Wedge parameters - struct WedgeSetting - { - std::string wedgeFile; - std::string parameter; - mx::Vector2 range; - int steps; - }; - std::vector wedgeSettings; - // Bake parameters struct BakeSetting { diff --git a/source/MaterialXTest/MaterialXRender/RenderUtil.cpp b/source/MaterialXTest/MaterialXRender/RenderUtil.cpp index 0460f9282a..cabcaca9a4 100644 --- a/source/MaterialXTest/MaterialXRender/RenderUtil.cpp +++ b/source/MaterialXTest/MaterialXRender/RenderUtil.cpp @@ -256,22 +256,6 @@ bool ShaderRenderTester::validate(const mx::FilePath optionsFilePath) mx::FilePath outputPath = mx::FilePath(dir) / file; outputPath.removeExtension(); - // Perform bake and use that file for rendering - if (canBake()) - { - for (auto& doctoBake : options.bakeSettings) - { - mx::FilePath outputBakeFile = file; - if (doctoBake.bakeFile == outputBakeFile.asString()) - { - outputBakeFile.removeExtension(); - outputBakeFile = outputPath / (outputBakeFile.asString() + "_baked.mtlx"); - runBake(doc, imageSearchPath, outputBakeFile, doctoBake, log); - break; - } - } - } - renderableSearchTimer.startTimer(); std::vector elements; try @@ -287,116 +271,8 @@ bool ShaderRenderTester::validate(const mx::FilePath optionsFilePath) for (const auto& element : elements) { - const mx::string elementName = mx::createValidName(mx::replaceSubstrings(element->getNamePath(), pathMap)); - - auto it = std::find_if(options.wedgeSettings.begin(), options.wedgeSettings.end(), - [&file] (const GenShaderUtil::TestSuiteOptions::WedgeSetting& setting) { - return (file.asString() == setting.wedgeFile); - }); - - const bool performWedge = (it != options.wedgeSettings.end()) ? true : false; - if (!performWedge) - { - runRenderer(elementName, element, context, doc, log, options, profileTimes, imageSearchPath, outputPath, nullptr); - } - else - { - for (auto &wedgesetting: options.wedgeSettings) - { - mx::ImageVec imageVec; - - const std::string& wedgeFile = wedgesetting.wedgeFile; - if (wedgeFile != file.asString()) - { - continue; - } - - // Make this a utility - std::string parameterPath = wedgesetting.parameter; - mx::ElementPtr uniformElement = doc->getDescendant(parameterPath); - if (!uniformElement) - { - std::string nodePath = mx::parentNamePath(parameterPath); - mx::ElementPtr uniformParent = doc->getDescendant(nodePath); - if (uniformParent) - { - mx::NodePtr uniformNode = uniformParent->asA(); - if (uniformNode) - { - mx::StringVec pathVec = mx::splitNamePath(parameterPath); - uniformNode->addInputFromNodeDef(pathVec[pathVec.size() - 1]); - } - } - } - uniformElement = doc->getDescendant(parameterPath); - mx::ValueElementPtr valueElement = uniformElement ? uniformElement->asA() : nullptr; - if (!valueElement) - { - continue; - } - - mx::ValuePtr origPropertyValue(valueElement ? valueElement->getValue() : nullptr); - mx::ValuePtr newValue = valueElement->getValue(); - - float wedgePropertyMin = wedgesetting.range[0]; - float wedgePropertyMax = wedgesetting.range[1]; - int wedgeImageCount = std::max(wedgesetting.steps, 2); - - float wedgePropertyStep = (wedgePropertyMax - wedgePropertyMin) / (wedgeImageCount - 1); - for (int w = 0; w < wedgeImageCount; w++) - { - bool setValue = false; - float propertyValue = (w == wedgeImageCount - 1) ? wedgePropertyMax : wedgePropertyMin + wedgePropertyStep * w; - if (origPropertyValue->isA()) - { - valueElement->setValue(static_cast(propertyValue)); - setValue = true; - } - else if (origPropertyValue->isA()) - { - valueElement->setValue(propertyValue); - setValue = true; - } - else if (origPropertyValue->isA()) - { - mx::Vector2 val(propertyValue, propertyValue); - valueElement->setValue(val); - setValue = true; - } - else if (origPropertyValue->isA() || - origPropertyValue->isA()) - { - mx::Vector3 val(propertyValue, propertyValue, propertyValue); - valueElement->setValue(val); - setValue = true; - } - else if (origPropertyValue->isA() || - origPropertyValue->isA()) - { - mx::Vector4 val(propertyValue, propertyValue, propertyValue, origPropertyValue->isA() ? 1.0f : propertyValue); - valueElement->setValue(val); - setValue = true; - } - - if (setValue) - { - runRenderer(elementName, element, context, doc, log, options, profileTimes, imageSearchPath, outputPath, &imageVec); - } - } - - if (!imageVec.empty()) - { - mx::ImagePtr wedgeImage = mx::createImageStrip(imageVec); - if (wedgeImage) - { - std::string wedgeFileName = mx::createValidName(mx::replaceSubstrings(parameterPath, pathMap)); - wedgeFileName += "_" + _shaderGenerator->getTarget() + ".bmp"; - mx::FilePath wedgePath = outputPath / wedgeFileName; - saveImage(wedgePath, wedgeImage, true); - } - } - } - } + mx::string elementName = mx::createValidName(mx::replaceSubstrings(element->getNamePath(), pathMap)); + runRenderer(elementName, element, context, doc, log, options, profileTimes, imageSearchPath, outputPath, nullptr); } } } diff --git a/source/MaterialXTest/MaterialXRender/RenderUtil.h b/source/MaterialXTest/MaterialXRender/RenderUtil.h index b29145dcb1..15eb5778f6 100644 --- a/source/MaterialXTest/MaterialXRender/RenderUtil.h +++ b/source/MaterialXTest/MaterialXRender/RenderUtil.h @@ -165,10 +165,6 @@ class ShaderRenderTester std::ostream& stream, mx::DocumentPtr dependLib); - virtual bool canBake() const { return false; } - virtual void runBake(mx::DocumentPtr /*doc*/, const mx::FileSearchPath& /*codeSearchPath*/, const mx::FilePath& /*outputFilename*/, - const GenShaderUtil::TestSuiteOptions::BakeSetting& /*bakeOptions*/, std::ostream& /*log*/) {}; - // If these streams don't exist add them for testing purposes void addAdditionalTestStreams(mx::MeshPtr mesh); diff --git a/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp b/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp index 719914a62e..01e0875727 100644 --- a/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp +++ b/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -54,14 +53,6 @@ class GlslShaderRenderTester : public RenderUtil::ShaderRenderTester bool saveImage(const mx::FilePath& filePath, mx::ConstImagePtr image, bool verticalFlip) const override; - bool canBake() const override - { - return true; - } - - void runBake(mx::DocumentPtr doc, const mx::FileSearchPath& imageSearchPath, const mx::FilePath& outputFilename, - const GenShaderUtil::TestSuiteOptions::BakeSetting& bakeOptions, std::ostream& log) override; - mx::GlslRendererPtr _renderer; mx::LightHandlerPtr _lightHandler; }; @@ -421,35 +412,6 @@ bool GlslShaderRenderTester::runRenderer(const std::string& shaderName, return true; } -void GlslShaderRenderTester::runBake(mx::DocumentPtr doc, const mx::FileSearchPath& imageSearchPath, const mx::FilePath& outputFileName, - const GenShaderUtil::TestSuiteOptions::BakeSetting& bakeOptions, std::ostream& log) -{ - mx::ImageVec imageVec = _renderer->getImageHandler()->getReferencedImages(doc); - auto maxImageSize = mx::getMaxDimensions(imageVec); - const unsigned bakeWidth = std::max(bakeOptions.resolution, maxImageSize.first); - const unsigned bakeHeight = std::max(bakeOptions.resolution, maxImageSize.second); - - mx::Image::BaseType baseType = bakeOptions.hdr ? mx::Image::BaseType::FLOAT : mx::Image::BaseType::UINT8; - mx::TextureBakerPtr baker = mx::TextureBakerGlsl::create(bakeWidth, bakeHeight, baseType); - baker->setupUnitSystem(doc); - baker->setImageHandler(_renderer->getImageHandler()); - baker->setOptimizeConstants(true); - baker->setHashImageNames(true); - baker->setTextureSpaceMin(bakeOptions.uvmin); - baker->setTextureSpaceMax(bakeOptions.uvmax); - - try - { - baker->setOutputStream(&log); - baker->bakeAllMaterials(doc, imageSearchPath, outputFileName); - } - catch (mx::Exception& e) - { - const mx::FilePath& sourceUri = doc->getSourceUri(); - log << sourceUri.asString() + " failed baking process: " + e.what() << std::endl; - } -} - TEST_CASE("Render: GLSL TestSuite", "[renderglsl]") { mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); diff --git a/source/MaterialXTest/MaterialXRenderMsl/RenderMsl.mm b/source/MaterialXTest/MaterialXRenderMsl/RenderMsl.mm index 248d458542..be5b8aa616 100644 --- a/source/MaterialXTest/MaterialXRenderMsl/RenderMsl.mm +++ b/source/MaterialXTest/MaterialXRenderMsl/RenderMsl.mm @@ -17,7 +17,6 @@ #endif #include -#include #include @@ -58,14 +57,6 @@ bool runRenderer(const std::string& shaderName, bool saveImage(const mx::FilePath& filePath, mx::ConstImagePtr image, bool verticalFlip) const override; - bool canBake() const override - { - return true; - } - - void runBake(mx::DocumentPtr doc, const mx::FileSearchPath& imageSearchPath, const mx::FilePath& outputFilename, - const GenShaderUtil::TestSuiteOptions::BakeSetting& bakeOptions, std::ostream& log) override; - mx::MslRendererPtr _renderer; mx::LightHandlerPtr _lightHandler; id _device; @@ -427,35 +418,6 @@ void runBake(mx::DocumentPtr doc, const mx::FileSearchPath& imageSearchPath, con return true; } -void MslShaderRenderTester::runBake(mx::DocumentPtr doc, const mx::FileSearchPath& imageSearchPath, const mx::FilePath& outputFileName, - const GenShaderUtil::TestSuiteOptions::BakeSetting& bakeOptions, std::ostream& log) -{ - mx::ImageVec imageVec = _renderer->getImageHandler()->getReferencedImages(doc); - auto maxImageSize = mx::getMaxDimensions(imageVec); - const unsigned bakeWidth = std::max(bakeOptions.resolution, maxImageSize.first); - const unsigned bakeHeight = std::max(bakeOptions.resolution, maxImageSize.second); - - mx::Image::BaseType baseType = bakeOptions.hdr ? mx::Image::BaseType::FLOAT : mx::Image::BaseType::UINT8; - mx::TextureBakerPtr baker = mx::TextureBakerMsl::create(bakeWidth, bakeHeight, baseType); - baker->setupUnitSystem(doc); - baker->setImageHandler(_renderer->getImageHandler()); - baker->setOptimizeConstants(true); - baker->setHashImageNames(true); - baker->setTextureSpaceMin(bakeOptions.uvmin); - baker->setTextureSpaceMax(bakeOptions.uvmax); - - try - { - baker->setOutputStream(&log); - baker->bakeAllMaterials(doc, imageSearchPath, outputFileName); - } - catch (mx::Exception& e) - { - const mx::FilePath& sourceUri = doc->getSourceUri(); - log << sourceUri.asString() + " failed baking process: " + e.what() << std::endl; - } -} - TEST_CASE("Render: MSL TestSuite", "[rendermsl]") { mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); From 4cd0dcfcccd4384a39690c8ca3e072355462f15b Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 20 Feb 2024 17:45:20 -0800 Subject: [PATCH 112/128] Add TypedElement::isColorType method This changelist adds a TypedElement::isColorType helper method, allowing color logic to be written more clearly through the MaterialX API. --- source/MaterialXCore/Element.h | 6 ++++++ source/MaterialXRender/TextureBaker.inl | 5 ++--- source/MaterialXTest/MaterialXCore/Document.cpp | 1 + source/PyMaterialX/PyMaterialXCore/PyElement.cpp | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/source/MaterialXCore/Element.h b/source/MaterialXCore/Element.h index 0e00bf596a..2db357e173 100644 --- a/source/MaterialXCore/Element.h +++ b/source/MaterialXCore/Element.h @@ -869,6 +869,12 @@ class MX_CORE_API TypedElement : public Element return getAttribute(TYPE_ATTRIBUTE); } + /// Return true if the element is of color type. + bool isColorType() const + { + return getType() == "color3" || getType() == "color4"; + } + /// Return true if the element is of multi-output type. bool isMultiOutputType() const { diff --git a/source/MaterialXRender/TextureBaker.inl b/source/MaterialXRender/TextureBaker.inl index 65759ed998..c1df7858ff 100644 --- a/source/MaterialXRender/TextureBaker.inl +++ b/source/MaterialXRender/TextureBaker.inl @@ -223,8 +223,7 @@ void TextureBaker::bakeGraphOutput(OutputPtr output, GenCon return; } - bool encodeSrgb = _colorSpace == SRGB_TEXTURE && - (output->getType() == "color3" || output->getType() == "color4"); + bool encodeSrgb = _colorSpace == SRGB_TEXTURE && output->isColorType(); Renderer::getFramebuffer()->setEncodeSrgb(encodeSrgb); ShaderPtr shader = _generator->generate("BakingShader", output, context); @@ -412,7 +411,7 @@ DocumentPtr TextureBaker::generateNewDocumentFromShader(Nod Color4 uniformColor = _bakedConstantMap[output].color; string uniformColorString = getValueStringFromColor(uniformColor, bakedInput->getType()); bakedInput->setValueString(uniformColorString); - if (bakedInput->getType() == "color3" || bakedInput->getType() == "color4") + if (bakedInput->isColorType()) { bakedInput->setColorSpace(_colorSpace); } diff --git a/source/MaterialXTest/MaterialXCore/Document.cpp b/source/MaterialXTest/MaterialXCore/Document.cpp index af39035dbe..9670c54283 100644 --- a/source/MaterialXTest/MaterialXCore/Document.cpp +++ b/source/MaterialXTest/MaterialXCore/Document.cpp @@ -23,6 +23,7 @@ TEST_CASE("Document", "[document]") constant->setInputValue("value", mx::Color3(0.5f)); mx::OutputPtr output = nodeGraph->addOutput(); output->setConnectedNode(constant); + REQUIRE(output->isColorType()); REQUIRE(doc->validate()); // Create and test a type mismatch in a connection. diff --git a/source/PyMaterialX/PyMaterialXCore/PyElement.cpp b/source/PyMaterialX/PyMaterialXCore/PyElement.cpp index d89cbc81a4..6e846c120e 100644 --- a/source/PyMaterialX/PyMaterialXCore/PyElement.cpp +++ b/source/PyMaterialX/PyMaterialXCore/PyElement.cpp @@ -124,6 +124,7 @@ void bindPyElement(py::module& mod) .def("setType", &mx::TypedElement::setType) .def("hasType", &mx::TypedElement::hasType) .def("getType", &mx::TypedElement::getType) + .def("isColorType", &mx::TypedElement::isColorType) .def("isMultiOutputType", &mx::TypedElement::isMultiOutputType) .def("getTypeDef", &mx::TypedElement::getTypeDef) .def_readonly_static("TYPE_ATTRIBUTE", &mx::TypedElement::TYPE_ATTRIBUTE); From d63431144a01eae129cd720222e530aff36b3459 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Fri, 23 Feb 2024 10:55:23 -0800 Subject: [PATCH 113/128] Improvements to color transform handling - Add support for a wider set of use cases for color space bindings, including surface shader nodes with filename-type inputs. - Add support for scoped color space bindings in shader translation. - Add a test suite example that covers newly-supported use cases. Supporting changes include: - Merge the protected method ShaderGraph::createSurfaceShader into ShaderGraph::create, allowing surface shader nodes to be handled in the same fashion as other nodes. - Update the interface of ShaderGraph::createNode, allowing greater flexibility in accessing parent nodes during shader generation. We've omitted a deprecated wrapper for this API update, as it would not be straightforward to write one in a memory-safe fashion, but fortunately this method only appears to be used within the ShaderGraph class. --- .../surfaceshader/network_surfaceshader.mtlx | 22 + source/MaterialXGenShader/GenContext.h | 19 + source/MaterialXGenShader/ShaderGraph.cpp | 435 ++++++------------ source/MaterialXGenShader/ShaderGraph.h | 16 +- .../MaterialXGenShader/ShaderTranslator.cpp | 5 +- 5 files changed, 184 insertions(+), 313 deletions(-) create mode 100644 resources/Materials/TestSuite/pbrlib/surfaceshader/network_surfaceshader.mtlx diff --git a/resources/Materials/TestSuite/pbrlib/surfaceshader/network_surfaceshader.mtlx b/resources/Materials/TestSuite/pbrlib/surfaceshader/network_surfaceshader.mtlx new file mode 100644 index 0000000000..fb5202b37c --- /dev/null +++ b/resources/Materials/TestSuite/pbrlib/surfaceshader/network_surfaceshader.mtlx @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/MaterialXGenShader/GenContext.h b/source/MaterialXGenShader/GenContext.h index f1de04ace6..1a936ac0dd 100644 --- a/source/MaterialXGenShader/GenContext.h +++ b/source/MaterialXGenShader/GenContext.h @@ -125,6 +125,24 @@ class MX_GENSHADER_API GenContext return _closureContexts.size() ? _closureContexts.back() : nullptr; } + /// Push a parent node onto the stack + void pushParentNode(ConstNodePtr node) + { + _parentNodes.push_back(node); + } + + /// Pop the current parent node from the stack. + void popParentNode() + { + _parentNodes.pop_back(); + } + + /// Return the current stack of parent nodes. + const vector& getParentNodes() + { + return _parentNodes; + } + /// Add user data to the context to make it /// available during shader generator. void pushUserData(const string& name, GenUserDataPtr data) @@ -216,6 +234,7 @@ class MX_GENSHADER_API GenContext std::unordered_map _outputSuffix; vector _closureContexts; + vector _parentNodes; ApplicationVariableHandler _applicationVariableHandler; }; diff --git a/source/MaterialXGenShader/ShaderGraph.cpp b/source/MaterialXGenShader/ShaderGraph.cpp index 41ac0da8e7..bcfe1ae441 100644 --- a/source/MaterialXGenShader/ShaderGraph.cpp +++ b/source/MaterialXGenShader/ShaderGraph.cpp @@ -93,7 +93,7 @@ void ShaderGraph::createConnectedNodes(const ElementPtr& downstreamElement, ShaderNode* newNode = getNode(newNodeName); if (!newNode) { - newNode = createNode(*upstreamNode, context); + newNode = createNode(upstreamNode, context); } // @@ -443,171 +443,6 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const NodeGraph& n return graph; } -ShaderGraphPtr ShaderGraph::createSurfaceShader( - const string& name, - const ShaderGraph* parent, - NodePtr node, - GenContext& context, - ElementPtr& root) -{ - NodeDefPtr nodeDef = node->getNodeDef(EMPTY_STRING, true); - if (!nodeDef) - { - throw ExceptionShaderGenError("Could not find a nodedef for shader node '" + node->getName() + - "' with category '" + node->getCategory() + "'"); - } - - ShaderGraphPtr graph = std::make_shared(parent, name, node->getDocument(), context.getReservedWords()); - - // Create input sockets - graph->addInputSockets(*nodeDef, context); - - // Create output sockets - graph->addOutputSockets(*nodeDef); - - // Create this shader node in the graph. - const string& newNodeName = node->getName(); - ShaderNodePtr newNode = ShaderNode::create(graph.get(), newNodeName, *nodeDef, context); - newNode->initialize(*node, *nodeDef, context); - graph->addNode(newNode); - - // Share metadata. - graph->setMetadata(newNode->getMetadata()); - - // Connect it to the graph output - ShaderGraphOutputSocket* outputSocket = graph->getOutputSocket(); - outputSocket->makeConnection(newNode->getOutput()); - outputSocket->setPath(node->getNamePath()); - - ColorManagementSystemPtr colorManagementSystem = context.getShaderGenerator().getColorManagementSystem(); - string targetColorSpace = context.getOptions().targetColorSpaceOverride.empty() ? - node->getDocument()->getColorSpace() : - context.getOptions().targetColorSpaceOverride; - - const string& targetDistanceUnit = context.getOptions().targetDistanceUnit; - UnitSystemPtr unitSystem = context.getShaderGenerator().getUnitSystem(); - - // Set node input values onto graph input sockets - for (const InputPtr& nodeDefInput : nodeDef->getActiveInputs()) - { - ShaderGraphInputSocket* inputSocket = graph->getInputSocket(nodeDefInput->getName()); - ShaderInput* input = newNode->getInput(nodeDefInput->getName()); - if (!inputSocket || !input) - { - throw ExceptionShaderGenError("Shader input '" + nodeDefInput->getName() + "' doesn't match an existing input on graph '" + graph->getName() + "'"); - } - - InputPtr nodeInput = node->getInput(nodeDefInput->getName()); - if (nodeInput) - { - // Copy value from binding - ValuePtr nodeInputValue = nodeInput->getResolvedValue(); - if (nodeInputValue) - { - inputSocket->setValue(nodeInputValue); - input->setBindInput(); - graph->populateColorTransformMap(colorManagementSystem, input, nodeInput, targetColorSpace, true); - graph->populateUnitTransformMap(unitSystem, input, nodeInput, targetDistanceUnit, true); - } - inputSocket->setPath(nodeInput->getNamePath()); - input->setPath(inputSocket->getPath()); - const string& nodeInputUnit = nodeInput->getUnit(); - if (!nodeInputUnit.empty()) - { - inputSocket->setUnit(nodeInputUnit); - input->setUnit(nodeInputUnit); - } - const string& nodeColorspace = nodeInput->getColorSpace(); - if (!nodeColorspace.empty()) - { - inputSocket->setColorSpace(nodeColorspace); - input->setColorSpace(nodeColorspace); - } - } - - // Check if the input is a uniform - bool isUniform = nodeDefInput->getIsUniform(); - if (isUniform) - { - inputSocket->makeConnection(input); - } - else - { - GeomPropDefPtr geomprop = nodeDefInput->getDefaultGeomProp(); - if (geomprop) - { - inputSocket->setGeomProp(geomprop->getName()); - input->setGeomProp(geomprop->getName()); - } - - // If no explicit connection, connect to geometric node if a geomprop is used - // or otherwise to the graph interface. - const string& connection = nodeInput ? nodeInput->getOutputString() : EMPTY_STRING; - if (connection.empty()) - { - if (geomprop) - { - graph->addDefaultGeomNode(input, *geomprop, context); - } - else - { - inputSocket->makeConnection(input); - } - } - } - - // Share metadata. - inputSocket->setMetadata(input->getMetadata()); - } - - // Add shader node paths and unit value - const string& nodePath = node->getNamePath(); - for (auto nodeInput : nodeDef->getActiveInputs()) - { - const string& inputName = nodeInput->getName(); - const string path = nodePath + NAME_PATH_SEPARATOR + inputName; - const string& unit = nodeInput->getUnit(); - const string& colorSpace = nodeInput->getColorSpace(); - ShaderInput* input = newNode->getInput(inputName); - if (input) - { - if (input->getPath().empty()) - { - input->setPath(path); - } - if (input->getUnit().empty() && !unit.empty()) - { - input->setUnit(unit); - } - if (input->getColorSpace().empty() && !colorSpace.empty()) - { - input->setColorSpace(colorSpace); - } - } - ShaderGraphInputSocket* inputSocket = graph->getInputSocket(inputName); - if (inputSocket) - { - if (inputSocket->getPath().empty()) - { - inputSocket->setPath(path); - } - if (inputSocket->getUnit().empty() && !unit.empty()) - { - inputSocket->setUnit(unit); - } - if (inputSocket->getColorSpace().empty() && !colorSpace.empty()) - { - inputSocket->setColorSpace(colorSpace); - } - } - } - - // Start traversal from this shader node - root = node; - - return graph; -} - ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name, ElementPtr element, GenContext& context) { ShaderGraphPtr graph; @@ -674,104 +509,95 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name else if (element->isA()) { NodePtr node = element->asA(); - - // Handle shader nodes different from other nodes - if (node->getType() == SURFACE_SHADER_TYPE_STRING) + NodeDefPtr nodeDef = node->getNodeDef(); + if (!nodeDef) { - graph = createSurfaceShader(name, parent, node, context, root); + throw ExceptionShaderGenError("Could not find a nodedef for node '" + node->getName() + "'"); } - else - { - NodeDefPtr nodeDef = node->getNodeDef(); - if (!nodeDef) - { - throw ExceptionShaderGenError("Could not find a nodedef for node '" + node->getName() + "'"); - } - graph = std::make_shared(parent, name, element->getDocument(), context.getReservedWords()); + graph = std::make_shared(parent, name, element->getDocument(), context.getReservedWords()); - // Create input sockets - graph->addInputSockets(*nodeDef, context); + // Create input sockets + graph->addInputSockets(*nodeDef, context); - // Create output sockets - graph->addOutputSockets(*nodeDef); + // Create output sockets + graph->addOutputSockets(*nodeDef); - // Create this shader node in the graph. - ShaderNodePtr newNode = ShaderNode::create(graph.get(), node->getName(), *nodeDef, context); - graph->addNode(newNode); + // Create this shader node in the graph. + ShaderNodePtr newNode = ShaderNode::create(graph.get(), node->getName(), *nodeDef, context); + graph->addNode(newNode); - // Share metadata. - graph->setMetadata(newNode->getMetadata()); + // Share metadata. + graph->setMetadata(newNode->getMetadata()); - // Connect it to the graph outputs - for (size_t i = 0; i < newNode->numOutputs(); ++i) + // Connect it to the graph outputs + for (size_t i = 0; i < newNode->numOutputs(); ++i) + { + ShaderGraphOutputSocket* outputSocket = graph->getOutputSocket(i); + outputSocket->makeConnection(newNode->getOutput(i)); + outputSocket->setPath(node->getNamePath()); + } + + // Handle node input ports + for (const InputPtr& nodedefInput : nodeDef->getActiveInputs()) + { + ShaderGraphInputSocket* inputSocket = graph->getInputSocket(nodedefInput->getName()); + ShaderInput* input = newNode->getInput(nodedefInput->getName()); + if (!inputSocket || !input) { - ShaderGraphOutputSocket* outputSocket = graph->getOutputSocket(i); - outputSocket->makeConnection(newNode->getOutput(i)); - outputSocket->setPath(node->getNamePath()); + throw ExceptionShaderGenError("Node input '" + nodedefInput->getName() + "' doesn't match an existing input on graph '" + graph->getName() + "'"); } - // Handle node input ports - for (const InputPtr& nodedefInput : nodeDef->getActiveInputs()) + // Copy data from node element to shadergen representation + InputPtr nodeInput = node->getInput(nodedefInput->getName()); + if (nodeInput) { - ShaderGraphInputSocket* inputSocket = graph->getInputSocket(nodedefInput->getName()); - ShaderInput* input = newNode->getInput(nodedefInput->getName()); - if (!inputSocket || !input) + ValuePtr value = nodeInput->getResolvedValue(); + if (value) { - throw ExceptionShaderGenError("Node input '" + nodedefInput->getName() + "' doesn't match an existing input on graph '" + graph->getName() + "'"); - } - - // Copy data from node element to shadergen representation - InputPtr nodeInput = node->getInput(nodedefInput->getName()); - if (nodeInput) - { - ValuePtr value = nodeInput->getResolvedValue(); - if (value) - { - const string& valueString = value->getValueString(); - std::pair enumResult; - const TypeDesc* type = TypeDesc::get(nodedefInput->getType()); - const string& enumNames = nodedefInput->getAttribute(ValueElement::ENUM_ATTRIBUTE); - if (context.getShaderGenerator().getSyntax().remapEnumeration(valueString, type, enumNames, enumResult)) - { - inputSocket->setValue(enumResult.second); - } - else - { - inputSocket->setValue(value); - } - } - - const string path = nodeInput->getNamePath(); - if (!path.empty()) - { - inputSocket->setPath(path); - input->setPath(path); - } - const string& unit = nodeInput->getUnit(); - if (!unit.empty()) + const string& valueString = value->getValueString(); + std::pair enumResult; + const TypeDesc* type = TypeDesc::get(nodedefInput->getType()); + const string& enumNames = nodedefInput->getAttribute(ValueElement::ENUM_ATTRIBUTE); + if (context.getShaderGenerator().getSyntax().remapEnumeration(valueString, type, enumNames, enumResult)) { - inputSocket->setUnit(unit); - input->setUnit(unit); + inputSocket->setValue(enumResult.second); } - const string& colorSpace = nodeInput->getColorSpace(); - if (!colorSpace.empty()) + else { - inputSocket->setColorSpace(colorSpace); - input->setColorSpace(colorSpace); + inputSocket->setValue(value); } } - // Connect graph socket to the node input - inputSocket->makeConnection(input); - - // Share metadata. - inputSocket->setMetadata(input->getMetadata()); + const string path = nodeInput->getNamePath(); + if (!path.empty()) + { + inputSocket->setPath(path); + input->setPath(path); + } + const string& unit = nodeInput->getUnit(); + if (!unit.empty()) + { + inputSocket->setUnit(unit); + input->setUnit(unit); + } + const string& colorSpace = nodeInput->getColorSpace(); + if (!colorSpace.empty()) + { + inputSocket->setColorSpace(colorSpace); + input->setColorSpace(colorSpace); + } } - // Set root for upstream dependency traversal - root = node; + // Connect graph socket to the node input + inputSocket->makeConnection(input); + + // Share metadata. + inputSocket->setMetadata(input->getMetadata()); } + + // Set root for upstream dependency traversal + root = node; } if (!graph) @@ -790,23 +616,24 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name return graph; } -ShaderNode* ShaderGraph::createNode(const Node& node, GenContext& context) +ShaderNode* ShaderGraph::createNode(ConstNodePtr node, GenContext& context) { - NodeDefPtr nodeDef = node.getNodeDef(); + NodeDefPtr nodeDef = node->getNodeDef(); if (!nodeDef) { - throw ExceptionShaderGenError("Could not find a nodedef for node '" + node.getName() + "'"); + throw ExceptionShaderGenError("Could not find a nodedef for node '" + node->getName() + "'"); } // Create this node in the graph. - const string& name = node.getName(); - ShaderNodePtr newNode = ShaderNode::create(this, name, *nodeDef, context); - newNode->initialize(node, *nodeDef, context); - _nodeMap[name] = newNode; + context.pushParentNode(node); + ShaderNodePtr newNode = ShaderNode::create(this, node->getName(), *nodeDef, context); + newNode->initialize(*node, *nodeDef, context); + _nodeMap[node->getName()] = newNode; _nodeOrder.push_back(newNode.get()); + context.popParentNode(); // Check if any of the node inputs should be connected to the graph interface - for (ValueElementPtr elem : node.getChildrenOfType()) + for (ValueElementPtr elem : node->getChildrenOfType()) { const string& interfaceName = elem->getInterfaceName(); if (!interfaceName.empty()) @@ -829,7 +656,7 @@ ShaderNode* ShaderGraph::createNode(const Node& node, GenContext& context) for (const InputPtr& nodeDefInput : nodeDef->getActiveInputs()) { ShaderInput* input = newNode->getInput(nodeDefInput->getName()); - InputPtr nodeInput = node.getInput(nodeDefInput->getName()); + InputPtr nodeInput = node->getInput(nodeDefInput->getName()); const string& connection = nodeInput ? nodeInput->getNodeName() : EMPTY_STRING; if (connection.empty() && !input->getConnection()) @@ -843,35 +670,47 @@ ShaderNode* ShaderGraph::createNode(const Node& node, GenContext& context) } // Handle colorspace and unit conversion if needed. + ColorManagementSystemPtr colorManagementSystem = context.getShaderGenerator().getColorManagementSystem(); UnitSystemPtr unitSystem = context.getShaderGenerator().getUnitSystem(); + const string& targetColorSpace = context.getOptions().targetColorSpaceOverride.empty() ? + _document->getActiveColorSpace() : + context.getOptions().targetColorSpaceOverride; const string& targetDistanceUnit = context.getOptions().targetDistanceUnit; - ColorManagementSystemPtr colorManagementSystem = context.getShaderGenerator().getColorManagementSystem(); - string targetColorSpace = context.getOptions().targetColorSpaceOverride.empty() ? - _document->getActiveColorSpace() : - context.getOptions().targetColorSpaceOverride; - - for (InputPtr input : node.getInputs()) + for (InputPtr input : node->getInputs()) { - if (input->getType() == FILENAME_TYPE_STRING) + if (input->hasValue() || input->hasInterfaceName()) { - ShaderOutput* shaderOutput = newNode->getOutput(); - if (shaderOutput) + string sourceColorSpace = input->getActiveColorSpace(); + if (input->getType() == FILENAME_TYPE_STRING && node->isColorType()) { - string colorSpace = populateColorTransformMap(colorManagementSystem, shaderOutput, input, targetColorSpace, false); - ShaderInput* shaderInput = newNode->getInput(input->getName()); - if (shaderInput && !colorSpace.empty()) + // Adjust the source color space for filename interface names. + if (input->hasInterfaceName()) { - shaderInput->setColorSpace(colorSpace); + for (ConstNodePtr parentNode : context.getParentNodes()) + { + if (!parentNode->isColorType()) + { + InputPtr interfaceInput = parentNode->getInput(input->getInterfaceName()); + string interfaceColorSpace = interfaceInput ? interfaceInput->getActiveColorSpace() : EMPTY_STRING; + if (!interfaceColorSpace.empty()) + { + sourceColorSpace = interfaceColorSpace; + } + } + } } + + ShaderOutput* shaderOutput = newNode->getOutput(); + populateColorTransformMap(colorManagementSystem, shaderOutput, sourceColorSpace, targetColorSpace, false); populateUnitTransformMap(unitSystem, shaderOutput, input, targetDistanceUnit, false); } - } - else - { - ShaderInput* shaderInput = newNode->getInput(input->getName()); - populateColorTransformMap(colorManagementSystem, shaderInput, input, targetColorSpace, true); - populateUnitTransformMap(unitSystem, shaderInput, input, targetDistanceUnit, true); + else + { + ShaderInput* shaderInput = newNode->getInput(input->getName()); + populateColorTransformMap(colorManagementSystem, shaderInput, sourceColorSpace, targetColorSpace, true); + populateUnitTransformMap(unitSystem, shaderInput, input, targetDistanceUnit, true); + } } } @@ -1229,48 +1068,44 @@ void ShaderGraph::setVariableNames(GenContext& context) } } -string ShaderGraph::populateColorTransformMap(ColorManagementSystemPtr colorManagementSystem, ShaderPort* shaderPort, - ValueElementPtr input, const string& targetColorSpace, bool asInput) +void ShaderGraph::populateColorTransformMap(ColorManagementSystemPtr colorManagementSystem, ShaderPort* shaderPort, + const string& sourceColorSpace, const string& targetColorSpace, bool asInput) { - if (targetColorSpace.empty()) + if (!shaderPort || + sourceColorSpace.empty() || + targetColorSpace.empty() || + sourceColorSpace == targetColorSpace) { - return EMPTY_STRING; + return; } - const string& sourceColorSpace = input->getActiveColorSpace(); - if (shaderPort && !sourceColorSpace.empty()) + if (*(shaderPort->getType()) == *Type::COLOR3 || *(shaderPort->getType()) == *Type::COLOR4) { - if (*(shaderPort->getType()) == *Type::COLOR3 || *(shaderPort->getType()) == *Type::COLOR4) + // Store the source color space on the shader port. + shaderPort->setColorSpace(sourceColorSpace); + + // Update the color transform map, if a color management system is provided. + if (colorManagementSystem) { - // If we're converting between two identical color spaces than we have no work to do. - if (sourceColorSpace != targetColorSpace) + ColorSpaceTransform transform(sourceColorSpace, targetColorSpace, shaderPort->getType()); + if (colorManagementSystem->supportsTransform(transform)) { - // Cache colorspace on shader port - shaderPort->setColorSpace(sourceColorSpace); - if (colorManagementSystem) + if (asInput) { - ColorSpaceTransform transform(sourceColorSpace, targetColorSpace, shaderPort->getType()); - if (colorManagementSystem->supportsTransform(transform)) - { - if (asInput) - { - _inputColorTransformMap.emplace(static_cast(shaderPort), transform); - } - else - { - _outputColorTransformMap.emplace(static_cast(shaderPort), transform); - } - } - else - { - std::cerr << "Unsupported color space transform from " << - sourceColorSpace << " to " << targetColorSpace << std::endl; - } + _inputColorTransformMap.emplace(static_cast(shaderPort), transform); } + else + { + _outputColorTransformMap.emplace(static_cast(shaderPort), transform); + } + } + else + { + std::cerr << "Unsupported color space transform from " << + sourceColorSpace << " to " << targetColorSpace << std::endl; } } } - return sourceColorSpace; } void ShaderGraph::populateUnitTransformMap(UnitSystemPtr unitSystem, ShaderPort* shaderPort, ValueElementPtr input, const string& globalTargetUnitSpace, bool asInput) diff --git a/source/MaterialXGenShader/ShaderGraph.h b/source/MaterialXGenShader/ShaderGraph.h index 4117599c27..b8ac15fc46 100644 --- a/source/MaterialXGenShader/ShaderGraph.h +++ b/source/MaterialXGenShader/ShaderGraph.h @@ -93,7 +93,7 @@ class MX_GENSHADER_API ShaderGraph : public ShaderNode const vector& getOutputSockets() const { return _inputOrder; } /// Create a new node in the graph - ShaderNode* createNode(const Node& node, GenContext& context); + ShaderNode* createNode(ConstNodePtr node, GenContext& context); /// Add input/output sockets ShaderGraphInputSocket* addInputSocket(const string& name, const TypeDesc* type); @@ -112,13 +112,6 @@ class MX_GENSHADER_API ShaderGraph : public ShaderNode IdentifierMap& getIdentifierMap() { return _identifiers; } protected: - static ShaderGraphPtr createSurfaceShader( - const string& name, - const ShaderGraph* parent, - NodePtr node, - GenContext& context, - ElementPtr& root); - /// Create node connections corresponding to the connection between a pair of elements. /// @param downstreamElement Element representing the node to connect to. /// @param upstreamElement Element representing the node to connect from @@ -171,9 +164,10 @@ class MX_GENSHADER_API ShaderGraph : public ShaderNode /// to avoid name conflicts during shader generation. void setVariableNames(GenContext& context); - /// Populates the input or output color transform map if the provided input/parameter - /// has a color space attribute and has a type of color3 or color4. - string populateColorTransformMap(ColorManagementSystemPtr colorManagementSystem, ShaderPort* shaderPort, ValueElementPtr element, const string& targetColorSpace, bool asInput); + /// Populate the color transform map for the given shader port, if the provided combination of + /// source and target color spaces are supported for its data type. + void populateColorTransformMap(ColorManagementSystemPtr colorManagementSystem, ShaderPort* shaderPort, + const string& sourceColorSpace, const string& targetColorSpace, bool asInput); /// Populates the appropriate unit transform map if the provided input/parameter or output /// has a unit attribute and is of the supported type diff --git a/source/MaterialXGenShader/ShaderTranslator.cpp b/source/MaterialXGenShader/ShaderTranslator.cpp index 2d53d14925..8a03c106cb 100644 --- a/source/MaterialXGenShader/ShaderTranslator.cpp +++ b/source/MaterialXGenShader/ShaderTranslator.cpp @@ -52,9 +52,10 @@ void ShaderTranslator::connectTranslationInputs(NodePtr shader, NodeDefPtr trans throw Exception("Shader input has no associated output or value " + shaderInput->getName()); } - if (shaderInput->hasColorSpace()) + string colorSpace = shaderInput->getActiveColorSpace(); + if (!colorSpace.empty()) { - input->setColorSpace(shaderInput->getColorSpace()); + input->setColorSpace(colorSpace); } if (shaderInput->hasUnit()) { From 5f9fee7ef4a29bb2e2bfbb353fb7427b8072b6dc Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Mon, 26 Feb 2024 08:22:47 -0800 Subject: [PATCH 114/128] Finalize changelog for 1.38.9 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66a79d724a..a27d750456 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## [1.38.9] - Development +## [1.38.9] - 2024-02-26 ### Added From 49b5b38c2849d14391a92834c56d7069dbcd6dc1 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sun, 24 Mar 2024 14:11:58 -0700 Subject: [PATCH 115/128] Update development build to 1.38.10 --- CHANGELOG.md | 2 ++ CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a27d750456..2067ac2626 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Change Log +## [1.38.10] - Development + ## [1.38.9] - 2024-02-26 ### Added diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cd5c859e6..1465bfe403 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # MaterialX Version set(MATERIALX_MAJOR_VERSION 1) set(MATERIALX_MINOR_VERSION 38) -set(MATERIALX_BUILD_VERSION 9) +set(MATERIALX_BUILD_VERSION 10) set(MATERIALX_LIBRARY_VERSION ${MATERIALX_MAJOR_VERSION}.${MATERIALX_MINOR_VERSION}.${MATERIALX_BUILD_VERSION}) # Cmake setup From afd31ca67ddcd1d9c3badf3c3d5a6e7aa6015d9c Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sun, 24 Mar 2024 16:28:51 -0700 Subject: [PATCH 116/128] Move prefilter functions to referencing GLSL files This changelist moves environment prefilter functions into the GLSL files that reference them, addressing shader compilation errors when GenOptions::hwDirectionalAlbedoMethod is set to DIRECTIONAL_ALBEDO_TABLE or DIRECTIONAL_ALBEDO_MONTE_CARLO by the client. --- .../genglsl/lib/mx_environment_prefilter.glsl | 7 +++++++ .../genglsl/lib/mx_generate_prefilter_env.glsl | 7 +++++++ .../pbrlib/genglsl/lib/mx_microfacet_specular.glsl | 14 -------------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl b/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl index e448ae247e..ad3f86cc90 100644 --- a/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl @@ -1,5 +1,12 @@ #include "mx_microfacet_specular.glsl" +// Return the mip level associated with the given alpha in a prefiltered environment. +float mx_latlong_alpha_to_lod(float alpha) +{ + float lodBias = (alpha < 0.25) ? sqrt(alpha) : 0.5 * alpha + 0.375; + return lodBias * float($envRadianceMips - 1); +} + vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd) { N = mx_forward_facing_normal(N, V); diff --git a/libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl b/libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl index e437e886af..41bf33aae3 100644 --- a/libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_generate_prefilter_env.glsl @@ -12,6 +12,13 @@ mat3 mx_orthonormal_basis(vec3 N) return mat3(X, Y, N); } +// Return the alpha associated with the given mip level in a prefiltered environment. +float mx_latlong_lod_to_alpha(float lod) +{ + float lodBias = lod / float($envRadianceMips - 1); + return (lodBias < 0.5) ? mx_square(lodBias) : 2.0 * (lodBias - 0.375); +} + // The inverse of mx_latlong_projection. vec3 mx_latlong_map_projection_inverse(vec2 uv) { diff --git a/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl b/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl index a27f717a24..ddbc3f6f95 100644 --- a/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl @@ -604,17 +604,3 @@ float mx_latlong_compute_lod(vec3 dir, float pdf, float maxMipLevel, int envSamp float distortion = sqrt(1.0 - mx_square(dir.y)); return max(effectiveMaxMipLevel - 0.5 * log2(float(envSamples) * pdf * distortion), 0.0); } - -// Return the mip level associated with the given alpha in a prefiltered environment. -float mx_latlong_alpha_to_lod(float alpha) -{ - float lodBias = (alpha < 0.25) ? sqrt(alpha) : 0.5 * alpha + 0.375; - return lodBias * float($envRadianceMips - 1); -} - -// Return the alpha associated with the given mip level in a prefiltered environment. -float mx_latlong_lod_to_alpha(float lod) -{ - float lodBias = lod / float($envRadianceMips - 1); - return (lodBias < 0.5) ? mx_square(lodBias) : 2.0 * (lodBias - 0.375); -} From 84154c19583004b124a79fe0e5a25afb5eae23b6 Mon Sep 17 00:00:00 2001 From: Dhruv Govil Date: Tue, 26 Mar 2024 11:15:51 -0700 Subject: [PATCH 117/128] Use framework linkage for OpenGL on macOS (#1752) Backporting #1741 to Main for 1.38.10 --- source/MaterialXRenderGlsl/CMakeLists.txt | 2 +- source/MaterialXRenderMsl/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/MaterialXRenderGlsl/CMakeLists.txt b/source/MaterialXRenderGlsl/CMakeLists.txt index 067cc5d016..27934bf5db 100644 --- a/source/MaterialXRenderGlsl/CMakeLists.txt +++ b/source/MaterialXRenderGlsl/CMakeLists.txt @@ -70,7 +70,7 @@ if(WIN32) elseif(APPLE) target_link_libraries( ${MATERIALX_MODULE_NAME} - OpenGL::GL + "-framework OpenGL" "-framework Foundation" "-framework Cocoa" "-framework Metal") diff --git a/source/MaterialXRenderMsl/CMakeLists.txt b/source/MaterialXRenderMsl/CMakeLists.txt index 41e00d4b9f..3d980fa44b 100644 --- a/source/MaterialXRenderMsl/CMakeLists.txt +++ b/source/MaterialXRenderMsl/CMakeLists.txt @@ -57,7 +57,7 @@ elseif(APPLE) target_link_libraries( ${MATERIALX_MODULE_NAME} "-framework Cocoa" - OpenGL::GL) + "-framework OpenGL") endif() target_link_libraries( ${MATERIALX_MODULE_NAME} From 281320c99b7b92c6078cf2fcec7e18de60787e93 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Tue, 26 Mar 2024 11:33:20 -0700 Subject: [PATCH 118/128] Store Document caches in declaration order (#1753) This changelist updates Document caches to store elements in the order they were declared, rather than allowing this order to be compiler-dependent. This addresses issues where requesting a NodeDef for a given Node could generate different results across compilers. --- source/MaterialXCore/Document.cpp | 63 +++++++++++++++---------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/source/MaterialXCore/Document.cpp b/source/MaterialXCore/Document.cpp index 80143bb9c8..b6ff1041a1 100644 --- a/source/MaterialXCore/Document.cpp +++ b/source/MaterialXCore/Document.cpp @@ -95,7 +95,7 @@ class Document::Cache PortElementPtr portElem = elem->asA(); if (portElem) { - portElementMap.emplace(portElem->getQualifiedName(nodeName), portElem); + portElementMap[portElem->getQualifiedName(nodeName)].push_back(portElem); } } else @@ -105,7 +105,7 @@ class Document::Cache PortElementPtr portElem = elem->asA(); if (portElem) { - portElementMap.emplace(portElem->getQualifiedName(nodeGraphName), portElem); + portElementMap[portElem->getQualifiedName(nodeGraphName)].push_back(portElem); } } } @@ -114,7 +114,7 @@ class Document::Cache NodeDefPtr nodeDef = elem->asA(); if (nodeDef) { - nodeDefMap.emplace(nodeDef->getQualifiedName(nodeString), nodeDef); + nodeDefMap[nodeDef->getQualifiedName(nodeString)].push_back(nodeDef); } } if (!nodeDefString.empty()) @@ -124,7 +124,7 @@ class Document::Cache { if (interface->isA()) { - implementationMap.emplace(interface->getQualifiedName(nodeDefString), interface); + implementationMap[interface->getQualifiedName(nodeDefString)].push_back(interface); } ImplementationPtr impl = interface->asA(); if (impl) @@ -135,11 +135,11 @@ class Document::Cache { NodeGraphPtr nodeGraph = impl->getDocument()->getNodeGraph(nodeGraphString); if (nodeGraph) - implementationMap.emplace(interface->getQualifiedName(nodeDefString), nodeGraph); + implementationMap[interface->getQualifiedName(nodeDefString)].push_back(nodeGraph); } else { - implementationMap.emplace(interface->getQualifiedName(nodeDefString), interface); + implementationMap[interface->getQualifiedName(nodeDefString)].push_back(interface); } } } @@ -154,9 +154,9 @@ class Document::Cache weak_ptr doc; std::mutex mutex; bool valid; - std::unordered_multimap portElementMap; - std::unordered_multimap nodeDefMap; - std::unordered_multimap implementationMap; + std::unordered_map> portElementMap; + std::unordered_map> nodeDefMap; + std::unordered_map> implementationMap; }; // @@ -304,16 +304,15 @@ vector Document::getMatchingPorts(const string& nodeName) const // Refresh the cache. _cache->refresh(); - // Find all port elements matching the given node name. - vector ports; - auto keyRange = _cache->portElementMap.equal_range(nodeName); - for (auto it = keyRange.first; it != keyRange.second; ++it) + // Return all port elements matching the given node name. + if (_cache->portElementMap.count(nodeName)) { - ports.push_back(it->second); + return _cache->portElementMap.at(nodeName); + } + else + { + return vector(); } - - // Return the matches. - return ports; } ValuePtr Document::getGeomPropValue(const string& geomPropName, const string& geom) const @@ -362,16 +361,15 @@ vector Document::getMatchingNodeDefs(const string& nodeName) const // Refresh the cache. _cache->refresh(); - // Find all nodedefs matching the given node name. - vector nodeDefs; - auto keyRange = _cache->nodeDefMap.equal_range(nodeName); - for (auto it = keyRange.first; it != keyRange.second; ++it) + // Return all nodedefs matching the given node name. + if (_cache->nodeDefMap.count(nodeName)) { - nodeDefs.push_back(it->second); + return _cache->nodeDefMap.at(nodeName); + } + else + { + return vector(); } - - // Return the matches. - return nodeDefs; } vector Document::getMatchingImplementations(const string& nodeDef) const @@ -379,16 +377,15 @@ vector Document::getMatchingImplementations(const string& n // Refresh the cache. _cache->refresh(); - // Find all implementations matching the given nodedef string. - vector implementations; - auto keyRange = _cache->implementationMap.equal_range(nodeDef); - for (auto it = keyRange.first; it != keyRange.second; ++it) + // Return all implementations matching the given nodedef string. + if (_cache->implementationMap.count(nodeDef)) { - implementations.push_back(it->second); + return _cache->implementationMap.at(nodeDef); + } + else + { + return vector(); } - - // Return the matches. - return implementations; } bool Document::validate(string* message) const From 710f272db2b2fe5c09a871bc7d753851b7390c6a Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Mon, 1 Apr 2024 16:08:17 -0700 Subject: [PATCH 119/128] Enable color and unit transforms on root nodes (#1757) This changelist adds support for color and unit transforms on the root nodes that are passed into shader generation, where previously they were only supported on non-root nodes in the material graph. In MaterialX 1.38.9, a special-case pathway for root surface shader nodes was merged into the main logic, causing color transforms in some USD/MaterialX contexts to be omitted, and this changelist restores and generalizes the original approach to handle all root nodes. --- source/MaterialXGenShader/ShaderGraph.cpp | 98 +++++++++++++---------- source/MaterialXGenShader/ShaderGraph.h | 3 + 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/source/MaterialXGenShader/ShaderGraph.cpp b/source/MaterialXGenShader/ShaderGraph.cpp index bcfe1ae441..d5c8bea521 100644 --- a/source/MaterialXGenShader/ShaderGraph.cpp +++ b/source/MaterialXGenShader/ShaderGraph.cpp @@ -569,6 +569,7 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name } } + input->setBindInput(); const string path = nodeInput->getNamePath(); if (!path.empty()) { @@ -596,6 +597,9 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name inputSocket->setMetadata(input->getMetadata()); } + // Apply color and unit transforms to each input. + graph->applyInputTransforms(node, newNode, context); + // Set root for upstream dependency traversal root = node; } @@ -616,6 +620,54 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name return graph; } +void ShaderGraph::applyInputTransforms(ConstNodePtr node, ShaderNodePtr shaderNode, GenContext& context) +{ + ColorManagementSystemPtr colorManagementSystem = context.getShaderGenerator().getColorManagementSystem(); + UnitSystemPtr unitSystem = context.getShaderGenerator().getUnitSystem(); + + const string& targetColorSpace = context.getOptions().targetColorSpaceOverride.empty() ? + _document->getActiveColorSpace() : + context.getOptions().targetColorSpaceOverride; + const string& targetDistanceUnit = context.getOptions().targetDistanceUnit; + + for (InputPtr input : node->getInputs()) + { + if (input->hasValue() || input->hasInterfaceName()) + { + string sourceColorSpace = input->getActiveColorSpace(); + if (input->getType() == FILENAME_TYPE_STRING && node->isColorType()) + { + // Adjust the source color space for filename interface names. + if (input->hasInterfaceName()) + { + for (ConstNodePtr parentNode : context.getParentNodes()) + { + if (!parentNode->isColorType()) + { + InputPtr interfaceInput = parentNode->getInput(input->getInterfaceName()); + string interfaceColorSpace = interfaceInput ? interfaceInput->getActiveColorSpace() : EMPTY_STRING; + if (!interfaceColorSpace.empty()) + { + sourceColorSpace = interfaceColorSpace; + } + } + } + } + + ShaderOutput* shaderOutput = shaderNode->getOutput(); + populateColorTransformMap(colorManagementSystem, shaderOutput, sourceColorSpace, targetColorSpace, false); + populateUnitTransformMap(unitSystem, shaderOutput, input, targetDistanceUnit, false); + } + else + { + ShaderInput* shaderInput = shaderNode->getInput(input->getName()); + populateColorTransformMap(colorManagementSystem, shaderInput, sourceColorSpace, targetColorSpace, true); + populateUnitTransformMap(unitSystem, shaderInput, input, targetDistanceUnit, true); + } + } + } +} + ShaderNode* ShaderGraph::createNode(ConstNodePtr node, GenContext& context) { NodeDefPtr nodeDef = node->getNodeDef(); @@ -669,50 +721,8 @@ ShaderNode* ShaderGraph::createNode(ConstNodePtr node, GenContext& context) } } - // Handle colorspace and unit conversion if needed. - ColorManagementSystemPtr colorManagementSystem = context.getShaderGenerator().getColorManagementSystem(); - UnitSystemPtr unitSystem = context.getShaderGenerator().getUnitSystem(); - const string& targetColorSpace = context.getOptions().targetColorSpaceOverride.empty() ? - _document->getActiveColorSpace() : - context.getOptions().targetColorSpaceOverride; - const string& targetDistanceUnit = context.getOptions().targetDistanceUnit; - - for (InputPtr input : node->getInputs()) - { - if (input->hasValue() || input->hasInterfaceName()) - { - string sourceColorSpace = input->getActiveColorSpace(); - if (input->getType() == FILENAME_TYPE_STRING && node->isColorType()) - { - // Adjust the source color space for filename interface names. - if (input->hasInterfaceName()) - { - for (ConstNodePtr parentNode : context.getParentNodes()) - { - if (!parentNode->isColorType()) - { - InputPtr interfaceInput = parentNode->getInput(input->getInterfaceName()); - string interfaceColorSpace = interfaceInput ? interfaceInput->getActiveColorSpace() : EMPTY_STRING; - if (!interfaceColorSpace.empty()) - { - sourceColorSpace = interfaceColorSpace; - } - } - } - } - - ShaderOutput* shaderOutput = newNode->getOutput(); - populateColorTransformMap(colorManagementSystem, shaderOutput, sourceColorSpace, targetColorSpace, false); - populateUnitTransformMap(unitSystem, shaderOutput, input, targetDistanceUnit, false); - } - else - { - ShaderInput* shaderInput = newNode->getInput(input->getName()); - populateColorTransformMap(colorManagementSystem, shaderInput, sourceColorSpace, targetColorSpace, true); - populateUnitTransformMap(unitSystem, shaderInput, input, targetDistanceUnit, true); - } - } - } + // Apply color and unit transforms to each input. + applyInputTransforms(node, newNode, context); return newNode.get(); } diff --git a/source/MaterialXGenShader/ShaderGraph.h b/source/MaterialXGenShader/ShaderGraph.h index b8ac15fc46..a96f59edce 100644 --- a/source/MaterialXGenShader/ShaderGraph.h +++ b/source/MaterialXGenShader/ShaderGraph.h @@ -92,6 +92,9 @@ class MX_GENSHADER_API ShaderGraph : public ShaderNode const vector& getInputSockets() const { return _outputOrder; } const vector& getOutputSockets() const { return _inputOrder; } + /// Apply color and unit transforms to each input of a node. + void applyInputTransforms(ConstNodePtr node, ShaderNodePtr shaderNode, GenContext& context); + /// Create a new node in the graph ShaderNode* createNode(ConstNodePtr node, GenContext& context); From e2ef60adc30af0bc0248096c11b495b650cc891b Mon Sep 17 00:00:00 2001 From: Ashwin Bhat <1727158+ashwinbhat@users.noreply.github.com> Date: Thu, 4 Apr 2024 09:55:19 -0700 Subject: [PATCH 120/128] Merge minor lighting improvements from 1.39 (#1763) - Add environment light intensity in GLSL (#1737) - Remove 'baked' suffix from TextureBaker names (#1744) - Move light uniforms into referencing GLSL files (#1750) --- .../genglsl/lib/mx_environment_fis.glsl | 5 +++-- .../genglsl/lib/mx_environment_prefilter.glsl | 5 +++-- resources/Lights/environment_map.mtlx | 7 ++++++- .../MaterialXGenShader/HwShaderGenerator.cpp | 5 +++++ source/MaterialXGenShader/HwShaderGenerator.h | 3 +++ source/MaterialXRender/LightHandler.h | 14 ++++++++++++++ source/MaterialXRender/TextureBaker.inl | 9 ++++----- source/MaterialXRenderGlsl/GlslProgram.cpp | 1 + .../MslPipelineStateObject.mm | 1 + source/MaterialXView/Main.cpp | 7 +++++++ source/MaterialXView/RenderPipelineGL.cpp | 3 +++ source/MaterialXView/RenderPipelineMetal.mm | 3 +++ source/MaterialXView/Viewer.cpp | 19 ++++++++++++++++++- source/MaterialXView/Viewer.h | 6 ++++++ 14 files changed, 77 insertions(+), 11 deletions(-) diff --git a/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl b/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl index 85c88c3280..0b28f3645f 100644 --- a/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl @@ -59,10 +59,11 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio radiance /= G1V * float(envRadianceSamples); // Return the final radiance. - return radiance; + return radiance * $envLightIntensity; } vec3 mx_environment_irradiance(vec3 N) { - return mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance); + vec3 Li = mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance); + return Li * $envLightIntensity; } diff --git a/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl b/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl index ad3f86cc90..778742c449 100644 --- a/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl @@ -20,10 +20,11 @@ vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio vec3 FG = fd.refraction ? vec3(1.0) - (F * G) : F * G; vec3 Li = mx_latlong_map_lookup(L, $envMatrix, mx_latlong_alpha_to_lod(avgAlpha), $envRadiance); - return Li * FG; + return Li * FG * $envLightIntensity; } vec3 mx_environment_irradiance(vec3 N) { - return mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance); + vec3 Li = mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance); + return Li * $envLightIntensity; } diff --git a/resources/Lights/environment_map.mtlx b/resources/Lights/environment_map.mtlx index abd14d546b..8aef3c11a5 100644 --- a/resources/Lights/environment_map.mtlx +++ b/resources/Lights/environment_map.mtlx @@ -46,7 +46,12 @@ + + + + + - + diff --git a/source/MaterialXGenShader/HwShaderGenerator.cpp b/source/MaterialXGenShader/HwShaderGenerator.cpp index 693e95da7c..0f13e95736 100644 --- a/source/MaterialXGenShader/HwShaderGenerator.cpp +++ b/source/MaterialXGenShader/HwShaderGenerator.cpp @@ -77,6 +77,7 @@ const string T_ENV_RADIANCE = "$envRadiance"; const string T_ENV_RADIANCE_MIPS = "$envRadianceMips"; const string T_ENV_RADIANCE_SAMPLES = "$envRadianceSamples"; const string T_ENV_IRRADIANCE = "$envIrradiance"; +const string T_ENV_LIGHT_INTENSITY = "$envLightIntensity"; const string T_ENV_PREFILTER_MIP = "$envPrefilterMip"; const string T_REFRACTION_TWO_SIDED = "$refractionTwoSided"; const string T_ALBEDO_TABLE = "$albedoTable"; @@ -132,6 +133,7 @@ const string ENV_RADIANCE = "u_envRadiance"; const string ENV_RADIANCE_MIPS = "u_envRadianceMips"; const string ENV_RADIANCE_SAMPLES = "u_envRadianceSamples"; const string ENV_IRRADIANCE = "u_envIrradiance"; +const string ENV_LIGHT_INTENSITY = "u_envLightIntensity"; const string ENV_PREFILTER_MIP = "u_envPrefilterMip"; const string REFRACTION_TWO_SIDED = "u_refractionTwoSided"; const string ALBEDO_TABLE = "u_albedoTable"; @@ -233,6 +235,7 @@ HwShaderGenerator::HwShaderGenerator(SyntaxPtr syntax) : _tokenSubstitutions[HW::T_ENV_RADIANCE_MIPS] = HW::ENV_RADIANCE_MIPS; _tokenSubstitutions[HW::T_ENV_RADIANCE_SAMPLES] = HW::ENV_RADIANCE_SAMPLES; _tokenSubstitutions[HW::T_ENV_IRRADIANCE] = HW::ENV_IRRADIANCE; + _tokenSubstitutions[HW::T_ENV_LIGHT_INTENSITY] = HW::ENV_LIGHT_INTENSITY; _tokenSubstitutions[HW::T_REFRACTION_TWO_SIDED] = HW::REFRACTION_TWO_SIDED; _tokenSubstitutions[HW::T_ALBEDO_TABLE] = HW::ALBEDO_TABLE; _tokenSubstitutions[HW::T_ALBEDO_TABLE_SIZE] = HW::ALBEDO_TABLE_SIZE; @@ -366,6 +369,7 @@ ShaderPtr HwShaderGenerator::createShader(const string& name, ElementPtr element const Matrix44 yRotationPI = Matrix44::createScale(Vector3(-1, 1, -1)); psPrivateUniforms->add(Type::MATRIX44, HW::T_ENV_MATRIX, Value::createValue(yRotationPI)); psPrivateUniforms->add(Type::FILENAME, HW::T_ENV_RADIANCE); + psPrivateUniforms->add(Type::FLOAT, HW::T_ENV_LIGHT_INTENSITY, Value::createValue(1.0f)); psPrivateUniforms->add(Type::INTEGER, HW::T_ENV_RADIANCE_MIPS, Value::createValue(1)); psPrivateUniforms->add(Type::INTEGER, HW::T_ENV_RADIANCE_SAMPLES, Value::createValue(16)); psPrivateUniforms->add(Type::FILENAME, HW::T_ENV_IRRADIANCE); @@ -384,6 +388,7 @@ ShaderPtr HwShaderGenerator::createShader(const string& name, ElementPtr element if (context.getOptions().hwWriteEnvPrefilter) { psPrivateUniforms->add(Type::FILENAME, HW::T_ENV_RADIANCE); + psPrivateUniforms->add(Type::FLOAT, HW::T_ENV_LIGHT_INTENSITY, Value::createValue(1.0f)); psPrivateUniforms->add(Type::INTEGER, HW::T_ENV_PREFILTER_MIP, Value::createValue(1)); const Matrix44 yRotationPI = Matrix44::createScale(Vector3(-1, 1, -1)); psPrivateUniforms->add(Type::MATRIX44, HW::T_ENV_MATRIX, Value::createValue(yRotationPI)); diff --git a/source/MaterialXGenShader/HwShaderGenerator.h b/source/MaterialXGenShader/HwShaderGenerator.h index f93a8983ca..bdd1e33a5c 100644 --- a/source/MaterialXGenShader/HwShaderGenerator.h +++ b/source/MaterialXGenShader/HwShaderGenerator.h @@ -71,6 +71,7 @@ Uniform variables : $envMatrix u_envMatrix mat4 Rotation matrix for the environment. $envIrradiance u_envIrradiance sampler2D Sampler for the texture used for diffuse environment lighting. $envRadiance u_envRadiance sampler2D Sampler for the texture used for specular environment lighting. + $envLightIntensity u_envLightIntensity float Linear multiplier for environment lighting $envRadianceMips u_envRadianceMips int Number of mipmaps used on the specular environment texture. $envRadianceSamples u_envRadianceSamples int Samples to use if Filtered Importance Sampling is used for specular environment lighting. @@ -126,6 +127,7 @@ extern MX_GENSHADER_API const string T_ENV_RADIANCE; extern MX_GENSHADER_API const string T_ENV_RADIANCE_MIPS; extern MX_GENSHADER_API const string T_ENV_RADIANCE_SAMPLES; extern MX_GENSHADER_API const string T_ENV_IRRADIANCE; +extern MX_GENSHADER_API const string T_ENV_LIGHT_INTENSITY; extern MX_GENSHADER_API const string T_ENV_PREFILTER_MIP; extern MX_GENSHADER_API const string T_REFRACTION_TWO_SIDED; extern MX_GENSHADER_API const string T_ALBEDO_TABLE; @@ -183,6 +185,7 @@ extern MX_GENSHADER_API const string ENV_RADIANCE; extern MX_GENSHADER_API const string ENV_RADIANCE_MIPS; extern MX_GENSHADER_API const string ENV_RADIANCE_SAMPLES; extern MX_GENSHADER_API const string ENV_IRRADIANCE; +extern MX_GENSHADER_API const string ENV_LIGHT_INTENSITY; extern MX_GENSHADER_API const string ENV_PREFILTER_MIP; extern MX_GENSHADER_API const string REFRACTION_TWO_SIDED; extern MX_GENSHADER_API const string ALBEDO_TABLE; diff --git a/source/MaterialXRender/LightHandler.h b/source/MaterialXRender/LightHandler.h index a080c72081..056b0c5cbb 100644 --- a/source/MaterialXRender/LightHandler.h +++ b/source/MaterialXRender/LightHandler.h @@ -38,6 +38,7 @@ class MX_RENDER_API LightHandler _directLighting(true), _indirectLighting(true), _usePrefilteredMap(false), + _envLightIntensity(1.0f), _envSampleCount(DEFAULT_ENV_SAMPLE_COUNT), _refractionTwoSided(false) { @@ -150,6 +151,18 @@ class MX_RENDER_API LightHandler return _envSampleCount; } + /// Set the environment light intensity. + void setEnvLightIntensity(const float intensity) + { + _envLightIntensity = intensity; + } + + /// Return the environment light intensity. + float getEnvLightIntensity() + { + return _envLightIntensity; + } + /// Set the two-sided refraction property. void setRefractionTwoSided(bool enable) { @@ -246,6 +259,7 @@ class MX_RENDER_API LightHandler ImagePtr _envRadianceMap; ImagePtr _envPrefilteredMap; ImagePtr _envIrradianceMap; + float _envLightIntensity; int _envSampleCount; bool _refractionTwoSided; diff --git a/source/MaterialXRender/TextureBaker.inl b/source/MaterialXRender/TextureBaker.inl index c1df7858ff..ff05cb49e7 100644 --- a/source/MaterialXRender/TextureBaker.inl +++ b/source/MaterialXRender/TextureBaker.inl @@ -18,7 +18,6 @@ namespace const string SRGB_TEXTURE = "srgb_texture"; const string LIN_REC709 = "lin_rec709"; -const string BAKED_POSTFIX = "_baked"; const string SHADER_PREFIX = "SR_"; const string DEFAULT_UDIM_PREFIX = "_"; @@ -352,13 +351,13 @@ DocumentPtr TextureBaker::generateNewDocumentFromShader(Nod } // Create a shader node. - NodePtr bakedShader = _bakedTextureDoc->addNode(shader->getCategory(), shader->getName() + BAKED_POSTFIX, shader->getType()); + NodePtr bakedShader = _bakedTextureDoc->addNode(shader->getCategory(), shader->getName(), shader->getType()); // Optionally create a material node, connecting it to the new shader node. if (_material) { string materialName = (_texTemplateOverrides.count("$MATERIAL")) ? _texTemplateOverrides["$MATERIAL"] : _material->getName(); - NodePtr bakedMaterial = _bakedTextureDoc->addNode(_material->getCategory(), materialName + BAKED_POSTFIX, _material->getType()); + NodePtr bakedMaterial = _bakedTextureDoc->addNode(_material->getCategory(), materialName, _material->getType()); for (auto sourceMaterialInput : _material->getInputs()) { const string& sourceMaterialInputName = sourceMaterialInput->getName(); @@ -421,7 +420,7 @@ DocumentPtr TextureBaker::generateNewDocumentFromShader(Nod if (!_bakedImageMap.empty()) { // Add the image node. - NodePtr bakedImage = bakedNodeGraph->addNode("image", sourceName + BAKED_POSTFIX, sourceType); + NodePtr bakedImage = bakedNodeGraph->addNode("image", sourceName, sourceType); InputPtr input = bakedImage->addInput("file", "filename"); StringMap filenameTemplateMap = initializeFileTemplateMap(bakedInput, shader, udimSet.empty() ? EMPTY_STRING : UDIM_TOKEN); input->setValueString(generateTextureFilename(filenameTemplateMap)); @@ -433,7 +432,7 @@ DocumentPtr TextureBaker::generateNewDocumentFromShader(Nod NodePtr origWorldSpaceNode = worldSpacePair->second; if (origWorldSpaceNode) { - NodePtr newWorldSpaceNode = bakedNodeGraph->addNode(origWorldSpaceNode->getCategory(), sourceName + BAKED_POSTFIX + "_map", sourceType); + NodePtr newWorldSpaceNode = bakedNodeGraph->addNode(origWorldSpaceNode->getCategory(), sourceName + "_map", sourceType); newWorldSpaceNode->copyContentFrom(origWorldSpaceNode); InputPtr mapInput = newWorldSpaceNode->getInput("in"); if (mapInput) diff --git a/source/MaterialXRenderGlsl/GlslProgram.cpp b/source/MaterialXRenderGlsl/GlslProgram.cpp index c9d0467b01..54f2ba1ca3 100644 --- a/source/MaterialXRenderGlsl/GlslProgram.cpp +++ b/source/MaterialXRenderGlsl/GlslProgram.cpp @@ -578,6 +578,7 @@ void GlslProgram::bindLighting(LightHandlerPtr lightHandler, ImageHandlerPtr ima Matrix44 envRotation = Matrix44::createRotationY(PI) * lightHandler->getLightTransform().getTranspose(); bindUniform(HW::ENV_MATRIX, Value::createValue(envRotation), false); bindUniform(HW::ENV_RADIANCE_SAMPLES, Value::createValue(lightHandler->getEnvSampleCount()), false); + bindUniform(HW::ENV_LIGHT_INTENSITY, Value::createValue(lightHandler->getEnvLightIntensity()), false); ImagePtr envRadiance = nullptr; if (lightHandler->getIndirectLighting()) { diff --git a/source/MaterialXRenderMsl/MslPipelineStateObject.mm b/source/MaterialXRenderMsl/MslPipelineStateObject.mm index f0cc8e47bb..6e5c2764e1 100644 --- a/source/MaterialXRenderMsl/MslPipelineStateObject.mm +++ b/source/MaterialXRenderMsl/MslPipelineStateObject.mm @@ -706,6 +706,7 @@ int GetStrideOfMetalType(MTLDataType type) Matrix44 envRotation = Matrix44::createRotationY(PI) * lightHandler->getLightTransform().getTranspose(); bindUniform(HW::ENV_MATRIX, Value::createValue(envRotation), false); bindUniform(HW::ENV_RADIANCE_SAMPLES, Value::createValue(lightHandler->getEnvSampleCount()), false); + bindUniform(HW::ENV_LIGHT_INTENSITY, Value::createValue(lightHandler->getEnvLightIntensity()), false); ImageMap envLights = { { HW::ENV_RADIANCE, lightHandler->getEnvRadianceMap() }, diff --git a/source/MaterialXView/Main.cpp b/source/MaterialXView/Main.cpp index c703e48883..904466c065 100644 --- a/source/MaterialXView/Main.cpp +++ b/source/MaterialXView/Main.cpp @@ -28,6 +28,7 @@ const std::string options = " --envRad [FILENAME] Specify the filename of the environment light to display, stored as HDR environment radiance in the latitude-longitude format\n" " --envMethod [INTEGER] Specify the environment lighting method (0 = filtered importance sampling, 1 = prefiltered environment maps, defaults to 0)\n" " --envSampleCount [INTEGER] Specify the environment sample count (defaults to 16)\n" + " --envLightIntensity [FLOAT] Specify the environment light intensity (defaults to 1)\n" " --lightRotation [FLOAT] Specify the rotation in degrees of the lighting environment about the Y axis (defaults to 0)\n" " --shadowMap [BOOLEAN] Specify whether shadow mapping is enabled (defaults to true)\n" " --path [FILEPATH] Specify an additional data search path location (e.g. '/projects/MaterialX'). This absolute path will be queried when locating data libraries, XInclude references, and referenced images.\n" @@ -87,6 +88,7 @@ int main(int argc, char* const argv[]) float cameraZoom(DEFAULT_CAMERA_ZOOM); mx::HwSpecularEnvironmentMethod specularEnvironmentMethod = mx::SPECULAR_ENVIRONMENT_FIS; int envSampleCount = mx::DEFAULT_ENV_SAMPLE_COUNT; + float envLightIntensity = 1.0f; float lightRotation = 0.0f; bool shadowMap = true; DocumentModifiers modifiers; @@ -160,6 +162,10 @@ int main(int argc, char* const argv[]) { parseToken(nextToken, "integer", envSampleCount); } + else if (token == "--envLightIntensity") + { + parseToken(nextToken, "float", envLightIntensity); + } else if (token == "--lightRotation") { parseToken(nextToken, "float", lightRotation); @@ -278,6 +284,7 @@ int main(int argc, char* const argv[]) viewer->setCameraZoom(cameraZoom); viewer->setSpecularEnvironmentMethod(specularEnvironmentMethod); viewer->setEnvSampleCount(envSampleCount); + viewer->setEnvLightIntensity(envLightIntensity); viewer->setLightRotation(lightRotation); viewer->setShadowMapEnable(shadowMap); viewer->setDrawEnvironment(drawEnvironment); diff --git a/source/MaterialXView/RenderPipelineGL.cpp b/source/MaterialXView/RenderPipelineGL.cpp index 68ac0be040..a41a4c1c4e 100644 --- a/source/MaterialXView/RenderPipelineGL.cpp +++ b/source/MaterialXView/RenderPipelineGL.cpp @@ -367,6 +367,9 @@ void GLRenderPipeline::renderFrame(void*, int shadowMapSize, const char* dirLigh float longitudeOffset = (lightRotation / 360.0f) + 0.5f; envMaterial->modifyUniform("longitude/in2", mx::Value::createValue(longitudeOffset)); + // Apply light intensity to the environment shader. + envMaterial->modifyUniform("envImageAdjusted/in2", mx::Value::createValue(lightHandler->getEnvLightIntensity())); + // Render the environment mesh. glDepthMask(GL_FALSE); envMaterial->bindShader(); diff --git a/source/MaterialXView/RenderPipelineMetal.mm b/source/MaterialXView/RenderPipelineMetal.mm index 0dc85b8aa4..9ced3b1669 100644 --- a/source/MaterialXView/RenderPipelineMetal.mm +++ b/source/MaterialXView/RenderPipelineMetal.mm @@ -490,6 +490,9 @@ float longitudeOffset = (lightRotation / 360.0f) + 0.5f; envMaterial->modifyUniform("longitude/in2", mx::Value::createValue(longitudeOffset)); + // Apply light intensity to the environment shader. + envMaterial->modifyUniform("envImageAdjusted/in2", mx::Value::createValue(lightHandler->getEnvLightIntensity())); + // Render the environment mesh. [MTL(renderCmdEncoder) setCullMode:MTLCullModeNone]; envMaterial->bindShader(); diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp index c6a810c2d4..7cd70d6c7f 100644 --- a/source/MaterialXView/Viewer.cpp +++ b/source/MaterialXView/Viewer.cpp @@ -745,7 +745,24 @@ void Viewer::createAdvancedSettings(Widget* parent) { _genContext.getOptions().hwDirectionalAlbedoMethod = (mx::HwDirectionalAlbedoMethod) index; reloadShaders(); - _renderPipeline->updateAlbedoTable(ALBEDO_TABLE_SIZE); + try + { + _renderPipeline->updateAlbedoTable(ALBEDO_TABLE_SIZE); + } + catch (mx::ExceptionRenderError& e) + { + for (const std::string& error : e.errorLog()) + { + std::cerr << error << std::endl; + } + new ng::MessageDialog(this, ng::MessageDialog::Type::Warning, "Shader generation error", e.what()); + _materialAssignments.clear(); + } + catch (std::exception& e) + { + new ng::MessageDialog(this, ng::MessageDialog::Type::Warning, "Failed to update albedo table", e.what()); + _materialAssignments.clear(); + } }); Widget* sampleGroup = new Widget(advancedPopup); diff --git a/source/MaterialXView/Viewer.h b/source/MaterialXView/Viewer.h index ff0827d12a..cab8efb95b 100644 --- a/source/MaterialXView/Viewer.h +++ b/source/MaterialXView/Viewer.h @@ -109,6 +109,12 @@ class Viewer : public ng::Screen _lightHandler->setEnvSampleCount(count); } + // Set the environment light intensity. + void setEnvLightIntensity(float intensity) + { + _lightHandler->setEnvLightIntensity(intensity); + } + // Set the rotation of the lighting environment about the Y axis. void setLightRotation(float rotation) { From b77576ced9609982eba2ebacee7dd751889e4bb4 Mon Sep 17 00:00:00 2001 From: Karen Lucknavalai <34335343+klucknav@users.noreply.github.com> Date: Thu, 4 Apr 2024 09:57:20 -0700 Subject: [PATCH 121/128] Add missing vertex data prefix to Vulkan ShaderGen (#1762) @clach found that the VkShaderGenerator::getVertexDataPrefix() is returning the empty string when it seems like it should be returning vertexData.GetInstance() + "." similar to the glsl and metal shader gens do. --- source/MaterialXGenGlsl/VkShaderGenerator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/MaterialXGenGlsl/VkShaderGenerator.cpp b/source/MaterialXGenGlsl/VkShaderGenerator.cpp index b57a4d2e94..5a91d96ff5 100644 --- a/source/MaterialXGenGlsl/VkShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/VkShaderGenerator.cpp @@ -69,9 +69,9 @@ void VkShaderGenerator::emitInputs(GenContext& context, ShaderStage& stage) cons } } -string VkShaderGenerator::getVertexDataPrefix(const VariableBlock&) const +string VkShaderGenerator::getVertexDataPrefix(const VariableBlock& vertexData) const { - return EMPTY_STRING; + return vertexData.getInstance() + "."; } void VkShaderGenerator::emitOutputs(GenContext& context, ShaderStage& stage) const From 64b85a5a8393645106eb6f7713b0d7e2701e782a Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Thu, 4 Apr 2024 16:55:14 -0700 Subject: [PATCH 122/128] Update changelog for recent work --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2067ac2626..fe571c1693 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ ## [1.38.10] - Development +### Added + +- Added support for [environment light intensity](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1737) in generated GLSL shaders. + +### Changed + +- Removed an [extra suffix](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1744) from element names in texture baking. + +### Fixed + +- Move environment prefilter functions to their [referencing GLSL files](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1748), addressing shader compilation errors in USD. +- Enable color and unit transforms on [root nodes](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1757) in shader generation, addressing missing color transforms in USD. +- Store [document caches](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1753) in declaration order, addressing compiler-dependent behavior in nodedef lookups. +- Use [framework linkage](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1752) for OpenGL in MacOS builds, addressing build issues in downstream projects. +- Added a [missing vertex data prefix](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1762) in Vulkan GLSL shader generation. + ## [1.38.9] - 2024-02-26 ### Added From 091c35fb1b109af2ea51d489aab6bc28f98e087b Mon Sep 17 00:00:00 2001 From: howetuft <34142192+howetuft@users.noreply.github.com> Date: Thu, 11 Apr 2024 22:48:18 +0200 Subject: [PATCH 123/128] Fix OpenGL issue in Python virtual environment (#1766) See issue #1755 --- source/MaterialXRenderGlsl/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/MaterialXRenderGlsl/CMakeLists.txt b/source/MaterialXRenderGlsl/CMakeLists.txt index 27934bf5db..1748b70190 100644 --- a/source/MaterialXRenderGlsl/CMakeLists.txt +++ b/source/MaterialXRenderGlsl/CMakeLists.txt @@ -27,6 +27,10 @@ elseif(UNIX) message(FATAL_ERROR "Error in building MaterialXRenderGlsl: Xt was not found") endif() + if(SKBUILD) + set(OpenGL_GL_PREFERENCE LEGACY) + endif() + find_package(OpenGL REQUIRED) include_directories(${X11_INCLUDE_DIR}) endif() From 97505091af01390b888905237ff6aef432bff2dc Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Thu, 11 Apr 2024 14:20:33 -0700 Subject: [PATCH 124/128] Finalize changelog for 1.38.10 --- CHANGELOG.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe571c1693..eddf285ac2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## [1.38.10] - Development +## [1.38.10] - 2024-04-12 ### Added @@ -12,10 +12,11 @@ ### Fixed -- Move environment prefilter functions to their [referencing GLSL files](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1748), addressing shader compilation errors in USD. -- Enable color and unit transforms on [root nodes](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1757) in shader generation, addressing missing color transforms in USD. -- Store [document caches](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1753) in declaration order, addressing compiler-dependent behavior in nodedef lookups. -- Use [framework linkage](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1752) for OpenGL in MacOS builds, addressing build issues in downstream projects. +- Moved environment prefilter functions to their [referencing GLSL files](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1748), addressing shader compilation errors in USD. +- Enabled color and unit transforms on [root nodes](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1757) in shader generation, addressing missing color transforms in USD. +- Updated [document caches](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1753) to store elements in declaration order, addressing compiler-dependent behavior in nodedef lookups. +- Switched to [framework linkage](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1752) for OpenGL libraries on MacOS, addressing build issues in downstream projects. +- Switched to [legacy OpenGL libraries](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1766) for Python wheels on Linux, addressing missing OpenGL functionality in Python wheels. - Added a [missing vertex data prefix](https://github.com/AcademySoftwareFoundation/MaterialX/pull/1762) in Vulkan GLSL shader generation. ## [1.38.9] - 2024-02-26 From ae9f1d7b74aa49d4b895c536e8778eb013d4b8a0 Mon Sep 17 00:00:00 2001 From: JGamache-autodesk <56274617+JGamache-autodesk@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:45:15 -0400 Subject: [PATCH 125/128] Backport OpenPBR Surface to MaterialX 1.38.10 (#2082) Backports only the minimal code necessary to render native OpenPBR surface in MaterialX in a way that has no visual impact on the existing shaders and pbr nodes present in 1.38. Status: - GLSL -> Fully functional - MSL -> Fully functional. Required only backporting the inversesqrt fix on top of the GLSL code. - OSL -> As functional as the 1.39 branch. Getting it fully functional requires OSL v1.14 features not yet released like Zeltner fuzz and compensating OrenNayar. I was not able to find any mention of a 82 deg color update on the OSL Schlick node though. - MDL -> Compiles and validates, but no updated visuals until an updated MDL library is available. --- .github/workflows/main.yml | 105 ++- .github/workflows/release.yml | 43 ++ libraries/CMakeLists.txt | 11 +- libraries/bxdf/mx39_open_pbr_surface.mtlx | 679 ++++++++++++++++++ .../pbrlib/genglsl/lib/mx39_microfacet.glsl | 30 + .../genglsl/lib/mx39_microfacet_diffuse.glsl | 88 +++ .../genglsl/lib/mx39_microfacet_sheen.glsl | 108 +++ .../genglsl/lib/mx39_microfacet_specular.glsl | 419 +++++++++++ .../genglsl/lib/mx_environment_fis.glsl | 2 + .../genglsl/lib/mx_environment_none.glsl | 2 + .../genglsl/lib/mx_environment_prefilter.glsl | 2 + .../genglsl/lib/mx_transmission_opacity.glsl | 2 + .../genglsl/lib/mx_transmission_refract.glsl | 2 + ..._compensating_oren_nayar_diffuse_bsdf.glsl | 42 ++ .../genglsl/mx39_dielectric_tf_bsdf.glsl | 92 +++ .../mx39_generalized_schlick_tf_82_bsdf.glsl | 98 +++ .../genglsl/mx39_pbrlib_genglsl_impl.mtlx | 16 + .../genglsl/mx39_sheen_zeltner_bsdf.glsl | 38 + .../genmdl/mx39_pbrlib_genmdl_impl.mtlx | 16 + .../genmsl/mx39_pbrlib_genmsl_impl.mtlx | 16 + ...9_compensating_oren_nayar_diffuse_bsdf.osl | 5 + .../genosl/legacy/mx39_dielectric_tf_bsdf.osl | 36 + .../mx39_generalized_schlick_tf_82_bsdf.osl | 38 + .../pbrlib/genosl/mx39_dielectric_tf_bsdf.osl | 15 + .../mx39_generalized_schlick_tf_82_bsdf.osl | 15 + .../genosl/mx39_pbrlib_genosl_impl.legacy | 16 + .../genosl/mx39_pbrlib_genosl_impl.mtlx | 16 + libraries/pbrlib/pbrlib_defs.mtlx | 74 ++ python/Scripts/generateshader.py | 2 - .../OpenPbr/open_pbr_aluminum_brushed.mtlx | 13 + .../Examples/OpenPbr/open_pbr_carpaint.mtlx | 14 + .../Examples/OpenPbr/open_pbr_default.mtlx | 46 ++ .../Examples/OpenPbr/open_pbr_glass.mtlx | 13 + .../Examples/OpenPbr/open_pbr_honey.mtlx | 14 + .../Examples/OpenPbr/open_pbr_ketchup.mtlx | 14 + .../Examples/OpenPbr/open_pbr_lightbulb.mtlx | 10 + .../Examples/OpenPbr/open_pbr_pearl.mtlx | 20 + .../Examples/OpenPbr/open_pbr_soapbubble.mtlx | 15 + .../Examples/OpenPbr/open_pbr_velvet.mtlx | 13 + resources/Materials/TestSuite/_options.mtlx | 2 +- source/MaterialXGenMdl/MdlShaderGenerator.cpp | 3 + source/MaterialXGenShader/ShaderNode.cpp | 3 +- source/MaterialXRender/CMakeLists.txt | 3 + source/MaterialXTest/CMakeLists.txt | 3 + .../MaterialXGenGlsl/GenGlsl.cpp | 1 + .../MaterialXTest/MaterialXGenMdl/GenMdl.cpp | 1 + .../MaterialXTest/MaterialXGenMsl/GenMsl.cpp | 1 + .../MaterialXTest/MaterialXGenOsl/GenOsl.cpp | 1 + .../MaterialXGenShader/GenShaderUtil.cpp | 1 + source/MaterialXView/CMakeLists.txt | 2 +- source/MaterialXView/Main.cpp | 2 +- 51 files changed, 2162 insertions(+), 61 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 libraries/bxdf/mx39_open_pbr_surface.mtlx create mode 100644 libraries/pbrlib/genglsl/lib/mx39_microfacet.glsl create mode 100644 libraries/pbrlib/genglsl/lib/mx39_microfacet_diffuse.glsl create mode 100644 libraries/pbrlib/genglsl/lib/mx39_microfacet_sheen.glsl create mode 100644 libraries/pbrlib/genglsl/lib/mx39_microfacet_specular.glsl create mode 100644 libraries/pbrlib/genglsl/mx39_compensating_oren_nayar_diffuse_bsdf.glsl create mode 100644 libraries/pbrlib/genglsl/mx39_dielectric_tf_bsdf.glsl create mode 100644 libraries/pbrlib/genglsl/mx39_generalized_schlick_tf_82_bsdf.glsl create mode 100644 libraries/pbrlib/genglsl/mx39_pbrlib_genglsl_impl.mtlx create mode 100644 libraries/pbrlib/genglsl/mx39_sheen_zeltner_bsdf.glsl create mode 100644 libraries/pbrlib/genmdl/mx39_pbrlib_genmdl_impl.mtlx create mode 100644 libraries/pbrlib/genmsl/mx39_pbrlib_genmsl_impl.mtlx create mode 100644 libraries/pbrlib/genosl/legacy/mx39_compensating_oren_nayar_diffuse_bsdf.osl create mode 100644 libraries/pbrlib/genosl/legacy/mx39_dielectric_tf_bsdf.osl create mode 100644 libraries/pbrlib/genosl/legacy/mx39_generalized_schlick_tf_82_bsdf.osl create mode 100644 libraries/pbrlib/genosl/mx39_dielectric_tf_bsdf.osl create mode 100644 libraries/pbrlib/genosl/mx39_generalized_schlick_tf_82_bsdf.osl create mode 100644 libraries/pbrlib/genosl/mx39_pbrlib_genosl_impl.legacy create mode 100644 libraries/pbrlib/genosl/mx39_pbrlib_genosl_impl.mtlx create mode 100644 resources/Materials/Examples/OpenPbr/open_pbr_aluminum_brushed.mtlx create mode 100644 resources/Materials/Examples/OpenPbr/open_pbr_carpaint.mtlx create mode 100644 resources/Materials/Examples/OpenPbr/open_pbr_default.mtlx create mode 100644 resources/Materials/Examples/OpenPbr/open_pbr_glass.mtlx create mode 100644 resources/Materials/Examples/OpenPbr/open_pbr_honey.mtlx create mode 100644 resources/Materials/Examples/OpenPbr/open_pbr_ketchup.mtlx create mode 100644 resources/Materials/Examples/OpenPbr/open_pbr_lightbulb.mtlx create mode 100644 resources/Materials/Examples/OpenPbr/open_pbr_pearl.mtlx create mode 100644 resources/Materials/Examples/OpenPbr/open_pbr_soapbubble.mtlx create mode 100644 resources/Materials/Examples/OpenPbr/open_pbr_velvet.mtlx diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0c42bf93ad..7e01379f54 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,83 +18,75 @@ jobs: fail-fast: false matrix: include: - - name: Linux_GCC_9_Python37 - os: ubuntu-20.04 + - name: Linux_GCC_10_Python37 + os: ubuntu-22.04 compiler: gcc - compiler_version: "9" + compiler_version: "10" python: 3.7 - cmake_config: -DMATERIALX_BUILD_SHARED_LIBS=ON + cmake_config: -DMATERIALX_BUILD_SHARED_LIBS=ON -DMATERIALX_BUILD_MONOLITHIC=ON - - name: Linux_GCC_12_Python311 - os: ubuntu-22.04 + - name: Linux_GCC_13_Python311 + os: ubuntu-24.04 compiler: gcc - compiler_version: "12" + compiler_version: "13" python: 3.11 build_javascript: ON - - name: Linux_GCC_13_Python312 - os: ubuntu-22.04 + - name: Linux_GCC_14_Python312 + os: ubuntu-24.04 compiler: gcc - compiler_version: "13" + compiler_version: "14" python: 3.12 - static_analysis: ON - cmake_config: -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - name: Linux_GCC_CoverageAnalysis - os: ubuntu-22.04 + os: ubuntu-24.04 compiler: gcc compiler_version: "None" python: None coverage_analysis: ON cmake_config: -DMATERIALX_COVERAGE_ANALYSIS=ON -DMATERIALX_BUILD_RENDER=OFF -DMATERIALX_BUILD_PYTHON=OFF - - name: Linux_Clang_10_Python37 - os: ubuntu-20.04 + - name: Linux_Clang_13_Python37 + os: ubuntu-22.04 compiler: clang - compiler_version: "10" + compiler_version: "13" python: 3.7 cmake_config: -DMATERIALX_BUILD_SHARED_LIBS=ON - - name: Linux_Clang_15_Python312 - os: ubuntu-22.04 + - name: Linux_Clang_18_Python312 + os: ubuntu-24.04 compiler: clang - compiler_version: "15" + compiler_version: "18" python: 3.12 test_render: ON clang_format: ON - - name: Linux_Clang_DynamicAnalysis - os: ubuntu-22.04 - compiler: clang - compiler_version: "15" - python: None - cmake_config: -DMATERIALX_DYNAMIC_ANALYSIS=ON - dynamic_analysis: ON - - - name: MacOS_Xcode_13_Python37 - os: macos-12 + - name: MacOS_Xcode_14_Python39 + os: macos-13 compiler: xcode - compiler_version: "13.1" + compiler_version: "14.1" cmake_config: -DMATERIALX_BUILD_SHARED_LIBS=ON - python: 3.7 + python: 3.9 - name: MacOS_Xcode_14_Python311 - os: macos-13 + os: macos-14 compiler: xcode compiler_version: "14.3" python: 3.11 + static_analysis: ON + cmake_config: -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - name: MacOS_Xcode_15_Python312 os: macos-14 compiler: xcode - compiler_version: "15.0" + compiler_version: "15.4" python: 3.12 test_shaders: ON - name: iOS_Xcode_15 os: macos-14 compiler: xcode - compiler_version: "15.0" + compiler_version: "15.4" python: None cmake_config: -DMATERIALX_BUILD_IOS=ON -DCMAKE_OSX_SYSROOT=`xcrun --sdk iphoneos --show-sdk-path` -DCMAKE_OSX_ARCHITECTURES=arm64 @@ -128,14 +120,14 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install xorg-dev mesa-utils + sudo apt-get install xorg-dev if [ "${{ matrix.compiler_version }}" != 'None' ]; then if [ "${{ matrix.compiler }}" = "gcc" ]; then - sudo apt-get install -y g++-${{ matrix.compiler_version }} g++-${{ matrix.compiler_version }}-multilib + sudo apt-get install -y g++-${{ matrix.compiler_version }} echo "CC=gcc-${{ matrix.compiler_version }}" >> $GITHUB_ENV echo "CXX=g++-${{ matrix.compiler_version }}" >> $GITHUB_ENV else - sudo apt-get install -y clang-${{ matrix.compiler_version }} libc++-${{ matrix.compiler_version }}-dev libc++abi-${{ matrix.compiler_version }}-dev + sudo apt-get install -y clang-${{ matrix.compiler_version }} echo "CC=clang-${{ matrix.compiler_version }}" >> $GITHUB_ENV echo "CXX=clang++-${{ matrix.compiler_version }}" >> $GITHUB_ENV fi @@ -198,7 +190,7 @@ jobs: run: find source \( -name *.h -o -name *.cpp -o -name *.mm -o -name *.inl \) ! -path "*/External/*" ! -path "*/NanoGUI/*" | xargs clang-format -i --verbose - name: CMake Generate - run: cmake -S . -B build -DMATERIALX_BUILD_PYTHON=ON -DMATERIALX_BUILD_VIEWER=ON -DMATERIALX_BUILD_GRAPH_EDITOR=ON -DMATERIALX_TEST_RENDER=OFF -DMATERIALX_WARNINGS_AS_ERRORS=ON ${{matrix.cmake_config}} + run: cmake -S . -B build -DMATERIALX_BUILD_PYTHON=ON -DMATERIALX_BUILD_VIEWER=ON -DMATERIALX_BUILD_GRAPH_EDITOR=ON -DMATERIALX_BUILD_TESTS=ON -DMATERIALX_TEST_RENDER=OFF -DMATERIALX_WARNINGS_AS_ERRORS=ON ${{matrix.cmake_config}} - name: CMake Build run: cmake --build build --target install --config Release --parallel 2 @@ -220,6 +212,10 @@ jobs: python Scripts/generateshader.py ../resources/Materials/Examples/StandardSurface --target osl python Scripts/generateshader.py ../resources/Materials/Examples/StandardSurface --target mdl python Scripts/generateshader.py ../resources/Materials/Examples/StandardSurface --target msl + python Scripts/generateshader.py ../resources/Materials/Examples/OpenPbr --target glsl + python Scripts/generateshader.py ../resources/Materials/Examples/OpenPbr --target osl + python Scripts/generateshader.py ../resources/Materials/Examples/OpenPbr --target mdl + python Scripts/generateshader.py ../resources/Materials/Examples/OpenPbr --target msl working-directory: python - name: Shader Validation Tests (Windows) @@ -227,13 +223,14 @@ jobs: run: | vcpkg/vcpkg install glslang --triplet=x64-windows glslangValidator.exe -v - python python/Scripts/generateshader.py resources/Materials/Examples/StandardSurface --target glsl --validator glslangValidator.exe --vulkanGlsl True --validatorArgs="-V --aml" - python python/Scripts/generateshader.py resources/Materials/Examples/StandardSurface --target essl --validator glslangValidator.exe + python python/Scripts/generateshader.py resources/Materials/Examples --target glsl --validator glslangValidator.exe + python python/Scripts/generateshader.py resources/Materials/Examples --target essl --validator glslangValidator.exe - name: Shader Validation Tests (MacOS) if: matrix.test_shaders == 'ON' && runner.os == 'macOS' run: | - python python/Scripts/generateshader.py resources/Materials/Examples/StandardSurface --target msl --validator "xcrun metal --language=metal" --validatorArgs="-w" + python python/Scripts/generateshader.py resources/Materials/Examples --target msl --validator "xcrun metal --language=metal" --validatorArgs="-w" + python python/Scripts/generateshader.py resources/Materials/TestSuite/stdlib --target msl --validator "xcrun metal --language=metal" --validatorArgs="-w" - name: Coverage Analysis Tests if: matrix.coverage_analysis == 'ON' @@ -244,10 +241,14 @@ jobs: working-directory: build - name: Static Analysis Tests - if: matrix.static_analysis == 'ON' && runner.os == 'Linux' + if: matrix.static_analysis == 'ON' run: | - sudo apt-get install cppcheck - cppcheck --project=build/compile_commands.json --error-exitcode=1 --suppress=*:*/External/* --suppress=*:*/NanoGUI/* + if [ "${{ runner.os }}" = "Linux" ]; then + sudo apt-get install cppcheck + else + brew install cppcheck + fi + cppcheck --project=build/compile_commands.json --error-exitcode=1 --suppress=normalCheckLevelMaxBranches --suppress=*:*/External/* --suppress=*:*/NanoGUI/* - name: Initialize Virtual Framebuffer if: matrix.test_render == 'ON' && runner.os == 'Linux' @@ -255,7 +256,6 @@ jobs: Xvfb :1 -screen 0 1280x960x24 & echo "DISPLAY=:1" >> $GITHUB_ENV echo "LIBGL_ALWAYS_SOFTWARE=1" >> $GITHUB_ENV - echo "GALLIUM_DRIVER=llvmpipe" >> $GITHUB_ENV - name: Render Script Tests if: matrix.test_render == 'ON' @@ -269,6 +269,7 @@ jobs: run: | ../installed/bin/MaterialXView --material brass_average_baked.mtlx --mesh ../../resources/Geometry/sphere.obj --screenWidth 128 --screenHeight 128 --cameraZoom 1.4 --shadowMap false --captureFilename Viewer_BrassAverage.png ../installed/bin/MaterialXView --material usd_preview_surface_carpaint.mtlx --mesh ../../resources/Geometry/sphere.obj --screenWidth 128 --screenHeight 128 --cameraZoom 1.4 --shadowMap false --captureFilename Viewer_CarpaintTranslated.png + ../installed/bin/MaterialXView --material open_pbr_carpaint.mtlx --mesh ../../resources/Geometry/sphere.obj --screenWidth 128 --screenHeight 128 --cameraZoom 1.4 --shadowMap false --captureFilename Viewer_OpenPBRCarpaintTranslated.png ../installed/bin/MaterialXGraphEditor --material ../../resources/Materials/Examples/StandardSurface/standard_surface_marble_solid.mtlx --viewWidth 128 --viewHeight 128 --captureFilename GraphEditor_MarbleSolid.png working-directory: build/render @@ -331,8 +332,8 @@ jobs: working-directory: javascript/MaterialXView - name: Deploy Web Viewer - if: matrix.build_javascript == 'ON' && github.ref == 'refs/heads/main' - uses: JamesIves/github-pages-deploy-action@v4 + if: matrix.build_javascript == 'ON' && github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@v4.6.4 with: branch: gh-pages folder: javascript/MaterialXView/dist @@ -344,11 +345,10 @@ jobs: with: name: MaterialX_JavaScript path: javascript/build/installed/JavaScript/MaterialX - if-no-files-found: ignore sdist: name: Python SDist - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 if: github.repository == 'AcademySoftwareFoundation/MaterialX' outputs: sdist_filename: ${{ steps.generate.outputs.filename }} @@ -383,8 +383,8 @@ jobs: strategy: fail-fast: false matrix: - python-minor: ['7', '8', '9', '10', '11'] - os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] + python-minor: ['7', '8', '9', '10', '11', '12'] + os: ['ubuntu-22.04', 'windows-2022', 'macos-13'] steps: - name: Sync Repository @@ -402,7 +402,7 @@ jobs: path: sdist - name: Build Wheel - uses: pypa/cibuildwheel@v2.16.5 + uses: pypa/cibuildwheel@v2.19.2 with: package-dir: ${{ github.workspace }}/sdist/${{ needs.sdist.outputs.sdist_filename }} env: @@ -413,7 +413,6 @@ jobs: # manylinux2014 is CentOS 7 based. Which means GCC 10 and glibc 2.17. CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014 CIBW_BEFORE_ALL_LINUX: yum install -y libXt-devel - CIBW_BEFORE_ALL_MACOS: sudo xcode-select -switch /Applications/Xcode_13.4.app CIBW_BUILD_VERBOSITY: 1 CIBW_ENVIRONMENT: CMAKE_BUILD_PARALLEL_LEVEL=2 # CIBW_BUILD_FRONTEND: build # https://github.com/pypa/build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..6ddb62f2b4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,43 @@ +name: release + +on: + release: + types: [published] + +permissions: + contents: read + +jobs: + + release: + name: Release Signing + runs-on: ubuntu-latest + env: + RELEASE_TAG: ${{ github.ref_name }} + permissions: + contents: write + id-token: write + repository-projects: write + + steps: + - name: Sync Repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Create Archive Name + run: echo "MATERIALX_ARCHIVE=MaterialX-${RELEASE_TAG//v}" >> $GITHUB_ENV + + - name: Generate Archives + run: | + git archive --prefix ${MATERIALX_ARCHIVE}/ --output ${MATERIALX_ARCHIVE}.zip ${RELEASE_TAG} + git archive --prefix ${MATERIALX_ARCHIVE}/ --output ${MATERIALX_ARCHIVE}.tar.gz ${RELEASE_TAG} + + - name: Sign and Upload Archives + uses: sigstore/gh-action-sigstore-python@v3.0.0 + with: + inputs: | + ${{ env.MATERIALX_ARCHIVE }}.zip + ${{ env.MATERIALX_ARCHIVE }}.tar.gz + upload-signing-artifacts: true + release-signing-artifacts: false diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index d60a54cf3b..f9d7b55565 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -8,9 +8,13 @@ if(NOT SKBUILD) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION "${MATERIALX_INSTALL_STDLIB_PATH}" PATTERN "CMakeLists.txt" EXCLUDE - PATTERN "pbrlib_genosl_impl.*" EXCLUDE) + PATTERN "pbrlib_genosl_impl.*" EXCLUDE + PATTERN "mx39_pbrlib_genosl_impl.*" EXCLUDE) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/pbrlib/genosl/pbrlib_genosl_impl.${PBRLIB_SUFFIX}" DESTINATION "${MATERIALX_INSTALL_STDLIB_PATH}/pbrlib/genosl/" RENAME pbrlib_genosl_impl.mtlx) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/pbrlib/genosl/mx39_pbrlib_genosl_impl.${PBRLIB_SUFFIX}" + DESTINATION "${MATERIALX_INSTALL_STDLIB_PATH}/pbrlib/genosl/" RENAME mx39_pbrlib_genosl_impl.mtlx) + endif() set(MATERIALX_PYTHON_LIBRARIES_PATH "${MATERIALX_PYTHON_FOLDER_NAME}/${MATERIALX_INSTALL_STDLIB_PATH}") @@ -22,7 +26,10 @@ if(MATERIALX_BUILD_PYTHON) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION "${MATERIALX_PYTHON_LIBRARIES_PATH}" PATTERN "CMakeLists.txt" EXCLUDE - PATTERN "pbrlib_genosl_impl.*" EXCLUDE) + PATTERN "pbrlib_genosl_impl.*" EXCLUDE + PATTERN "mx39_pbrlib_genosl_impl.*" EXCLUDE) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/pbrlib/genosl/pbrlib_genosl_impl.${PBRLIB_SUFFIX}" DESTINATION "${MATERIALX_PYTHON_LIBRARIES_PATH}/pbrlib/genosl/" RENAME pbrlib_genosl_impl.mtlx) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/pbrlib/genosl/mx39_pbrlib_genosl_impl.${PBRLIB_SUFFIX}" + DESTINATION "${MATERIALX_PYTHON_LIBRARIES_PATH}/pbrlib/genosl/" RENAME mx39_pbrlib_genosl_impl.mtlx) endif() diff --git a/libraries/bxdf/mx39_open_pbr_surface.mtlx b/libraries/bxdf/mx39_open_pbr_surface.mtlx new file mode 100644 index 0000000000..42df378691 --- /dev/null +++ b/libraries/bxdf/mx39_open_pbr_surface.mtlx @@ -0,0 +1,679 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/pbrlib/genglsl/lib/mx39_microfacet.glsl b/libraries/pbrlib/genglsl/lib/mx39_microfacet.glsl new file mode 100644 index 0000000000..5637f388a0 --- /dev/null +++ b/libraries/pbrlib/genglsl/lib/mx39_microfacet.glsl @@ -0,0 +1,30 @@ +#include "mx_microfacet.glsl" + +float mx39_pow6(float x) +{ + float x2 = mx_square(x); + return mx_square(x2) * x2; +} + +// Generate a cosine-weighted sample on the unit hemisphere. +vec3 mx39_cosine_sample_hemisphere(vec2 Xi) +{ + float phi = 2.0 * M_PI * Xi.x; + float cosTheta = sqrt(Xi.y); + float sinTheta = sqrt(1.0 - Xi.y); + return vec3(cos(phi) * sinTheta, + sin(phi) * sinTheta, + cosTheta); +} + +// Construct an orthonormal basis from a unit vector. +// https://graphics.pixar.com/library/OrthonormalB/paper.pdf +mat3 mx39_orthonormal_basis(vec3 N) +{ + float sign = (N.z < 0.0) ? -1.0 : 1.0; + float a = -1.0 / (sign + N.z); + float b = N.x * N.y * a; + vec3 X = vec3(1.0 + sign * N.x * N.x * a, sign * b, -sign * N.x); + vec3 Y = vec3(b, sign + N.y * N.y * a, -N.y); + return mat3(X, Y, N); +} diff --git a/libraries/pbrlib/genglsl/lib/mx39_microfacet_diffuse.glsl b/libraries/pbrlib/genglsl/lib/mx39_microfacet_diffuse.glsl new file mode 100644 index 0000000000..c7ef22b78a --- /dev/null +++ b/libraries/pbrlib/genglsl/lib/mx39_microfacet_diffuse.glsl @@ -0,0 +1,88 @@ +#include "mx39_microfacet.glsl" +#include "mx_microfacet_diffuse.glsl" + +const float FUJII_CONSTANT_1 = 0.5 - 2.0 / (3.0 * M_PI); +const float FUJII_CONSTANT_2 = 2.0 / 3.0 - 28.0 / (15.0 * M_PI); + +// Qualitative Oren-Nayar diffuse with simplified math: +// https://www1.cs.columbia.edu/CAVE/publications/pdfs/Oren_SIGGRAPH94.pdf +float mx39_oren_nayar_diffuse(float NdotV, float NdotL, float LdotV, float roughness) +{ + float s = LdotV - NdotL * NdotV; + float stinv = (s > 0.0) ? s / max(NdotL, NdotV) : 0.0; + + float sigma2 = mx_square(roughness); + float A = 1.0 - 0.5 * (sigma2 / (sigma2 + 0.33)); + float B = 0.45 * sigma2 / (sigma2 + 0.09); + + return A + B * stinv; +} + +// Rational quadratic fit to Monte Carlo data for Oren-Nayar directional albedo. +float mx39_oren_nayar_diffuse_dir_albedo_analytic(float NdotV, float roughness) +{ + vec2 r = vec2(1.0, 1.0) + + vec2(-0.4297, -0.6076) * roughness + + vec2(-0.7632, -0.4993) * NdotV * roughness + + vec2(1.4385, 2.0315) * mx_square(roughness); + return r.x / r.y; +} + +float mx39_oren_nayar_diffuse_dir_albedo(float NdotV, float roughness) +{ + float dirAlbedo = mx39_oren_nayar_diffuse_dir_albedo_analytic(NdotV, roughness); + return clamp(dirAlbedo, 0.0, 1.0); +} + +// Improved Oren-Nayar diffuse from Fujii: +// https://mimosa-pudica.net/improved-oren-nayar.html +float mx39_oren_nayar_fujii_diffuse_dir_albedo(float cosTheta, float roughness) +{ + float A = 1.0 / (1.0 + FUJII_CONSTANT_1 * roughness); + float B = roughness * A; + float Si = sqrt(max(0.0, 1.0 - mx_square(cosTheta))); + float G = Si * (acos(clamp(cosTheta, -1.0, 1.0)) - Si * cosTheta) + + 2.0 * ((Si / cosTheta) * (1.0 - Si * Si * Si) - Si) / 3.0; + return A + (B * G * M_PI_INV); +} + +float mx39_oren_nayar_fujii_diffuse_avg_albedo(float roughness) +{ + float A = 1.0 / (1.0 + FUJII_CONSTANT_1 * roughness); + return A * (1.0 + FUJII_CONSTANT_2 * roughness); +} + +// Energy-compensated Oren-Nayar diffuse from OpenPBR Surface: +// https://academysoftwarefoundation.github.io/OpenPBR/ +vec3 mx39_oren_nayar_compensated_diffuse(float NdotV, float NdotL, float LdotV, float roughness, vec3 color) +{ + float s = LdotV - NdotL * NdotV; + float stinv = (s > 0.0) ? s / max(NdotL, NdotV) : s; + + // Compute the single-scatter lobe. + float A = 1.0 / (1.0 + FUJII_CONSTANT_1 * roughness); + vec3 lobeSingleScatter = color * A * (1.0 + roughness * stinv); + + // Compute the multi-scatter lobe. + float dirAlbedoV = mx39_oren_nayar_fujii_diffuse_dir_albedo(NdotV, roughness); + float dirAlbedoL = mx39_oren_nayar_fujii_diffuse_dir_albedo(NdotL, roughness); + float avgAlbedo = mx39_oren_nayar_fujii_diffuse_avg_albedo(roughness); + vec3 colorMultiScatter = mx_square(color) * avgAlbedo / + (vec3(1.0) - color * max(0.0, 1.0 - avgAlbedo)); + vec3 lobeMultiScatter = colorMultiScatter * + max(M_FLOAT_EPS, 1.0 - dirAlbedoV) * + max(M_FLOAT_EPS, 1.0 - dirAlbedoL) / + max(M_FLOAT_EPS, 1.0 - avgAlbedo); + + // Return the sum. + return lobeSingleScatter + lobeMultiScatter; +} + +vec3 mx39_oren_nayar_compensated_diffuse_dir_albedo(float cosTheta, float roughness, vec3 color) +{ + float dirAlbedo = mx39_oren_nayar_fujii_diffuse_dir_albedo(cosTheta, roughness); + float avgAlbedo = mx39_oren_nayar_fujii_diffuse_avg_albedo(roughness); + vec3 colorMultiScatter = mx_square(color) * avgAlbedo / + (vec3(1.0) - color * max(0.0, 1.0 - avgAlbedo)); + return mix(colorMultiScatter, color, dirAlbedo); +} diff --git a/libraries/pbrlib/genglsl/lib/mx39_microfacet_sheen.glsl b/libraries/pbrlib/genglsl/lib/mx39_microfacet_sheen.glsl new file mode 100644 index 0000000000..4f94e9e0e1 --- /dev/null +++ b/libraries/pbrlib/genglsl/lib/mx39_microfacet_sheen.glsl @@ -0,0 +1,108 @@ +#include "mx39_microfacet.glsl" +#include "mx_microfacet_sheen.glsl" + +float mx_inversesqrt(float x) +{ +#ifdef __METAL_VERSION__ + return ::rsqrt(x); +#else + return inversesqrt(x); +#endif +} + +// The following functions are adapted from https://github.com/tizian/ltc-sheen. +// "Practical Multiple-Scattering Sheen Using Linearly Transformed Cosines", Zeltner et al. + +// Gaussian fit to directional albedo table. +float mx39_zeltner_sheen_dir_albedo(float x, float y) +{ + float s = y*(0.0206607 + 1.58491*y)/(0.0379424 + y*(1.32227 + y)); + float m = y*(-0.193854 + y*(-1.14885 + y*(1.7932 - 0.95943*y*y)))/(0.046391 + y); + float o = y*(0.000654023 + (-0.0207818 + 0.119681*y)*y)/(1.26264 + y*(-1.92021 + y)); + return exp(-0.5*mx_square((x - m)/s))/(s*sqrt(2.0*M_PI)) + o; +} + +// Rational fits to LTC matrix coefficients. +float mx39_zeltner_sheen_ltc_aInv(float x, float y) +{ + return (2.58126*x + 0.813703*y)*y/(1.0 + 0.310327*x*x + 2.60994*x*y); +} + +float mx39_zeltner_sheen_ltc_bInv(float x, float y) +{ + return sqrt(1.0 - x)*(y - 1.0)*y*y*y/(0.0000254053 + 1.71228*x - 1.71506*x*y + 1.34174*y*y); +} + +// V and N are assumed to be unit vectors. +mat3 mx39_orthonormal_basis_ltc(vec3 V, vec3 N, float NdotV) +{ + // Generate a tangent vector in the plane of V and N. + // This required to correctly orient the LTC lobe. + vec3 X = V - N*NdotV; + float lenSqr = dot(X, X); + if (lenSqr > 0.0) + { + X *= mx_inversesqrt(lenSqr); + vec3 Y = cross(N, X); + return mat3(X, Y, N); + } + + // If lenSqr == 0, then V == N, so any orthonormal basis will do. + return mx39_orthonormal_basis(N); +} + +// Multiplication by directional albedo is handled by the calling function. +float mx39_zeltner_sheen_brdf(vec3 L, vec3 V, vec3 N, float NdotV, float roughness) +{ + mat3 toLTC = transpose(mx39_orthonormal_basis_ltc(V, N, NdotV)); + vec3 w = toLTC * L; + + float aInv = mx39_zeltner_sheen_ltc_aInv(NdotV, roughness); + float bInv = mx39_zeltner_sheen_ltc_bInv(NdotV, roughness); + + // Transform w to original configuration (clamped cosine). + // |aInv 0 bInv| + // wo = M^-1 . w = | 0 aInv 0| . w + // | 0 0 1| + vec3 wo = vec3(aInv*w.x + bInv*w.z, aInv * w.y, w.z); + float lenSqr = dot(wo, wo); + + // D(w) = Do(M^-1.w / ||M^-1.w||) . |M^-1| / ||M^-1.w||^3 + // = Do(M^-1.w) . |M^-1| / ||M^-1.w||^4 + // = Do(wo) . |M^-1| / dot(wo, wo)^2 + // = Do(wo) . aInv^2 / dot(wo, wo)^2 + // = Do(wo) . (aInv / dot(wo, wo))^2 + return max(wo.z, 0.0) * M_PI_INV * mx_square(aInv / lenSqr); +} + +vec3 mx39_zeltner_sheen_importance_sample(vec2 Xi, vec3 V, vec3 N, float roughness, out float pdf) +{ + float NdotV = clamp(dot(N, V), 0.0, 1.0); + roughness = clamp(roughness, 0.01, 1.0); // Clamp to range of original impl. + + vec3 wo = mx39_cosine_sample_hemisphere(Xi); + + float aInv = mx39_zeltner_sheen_ltc_aInv(NdotV, roughness); + float bInv = mx39_zeltner_sheen_ltc_bInv(NdotV, roughness); + + // Transform wo from original configuration (clamped cosine). + // |1/aInv 0 -bInv/aInv| + // w = M . wo = | 0 1/aInv 0| . wo + // | 0 0 1| + vec3 w = vec3(wo.x/aInv - wo.z*bInv/aInv, wo.y / aInv, wo.z); + + float lenSqr = dot(w, w); + w *= mx_inversesqrt(lenSqr); + + // D(w) = Do(wo) . ||M.wo||^3 / |M| + // = Do(wo / ||M.wo||) . ||M.wo||^4 / |M| + // = Do(w) . ||M.wo||^4 / |M| (possible because M doesn't change z component) + // = Do(w) . dot(w, w)^2 * aInv^2 + // = Do(w) . (aInv * dot(w, w))^2 + pdf = max(w.z, 0.0) * M_PI_INV * mx_square(aInv * lenSqr); + + mat3 fromLTC = mx39_orthonormal_basis_ltc(V, N, NdotV); + w = fromLTC * w; + + return w; +} diff --git a/libraries/pbrlib/genglsl/lib/mx39_microfacet_specular.glsl b/libraries/pbrlib/genglsl/lib/mx39_microfacet_specular.glsl new file mode 100644 index 0000000000..fa4badc7e5 --- /dev/null +++ b/libraries/pbrlib/genglsl/lib/mx39_microfacet_specular.glsl @@ -0,0 +1,419 @@ +#include "mx39_microfacet.glsl" +#include "mx_microfacet_specular.glsl" + +const int MX39_FRESNEL_MODEL_DIELECTRIC = 0; +const int MX39_FRESNEL_MODEL_CONDUCTOR = 1; +const int MX39_FRESNEL_MODEL_SCHLICK = 2; + +// Parameters for Fresnel calculations +struct Mx39FresnelData +{ + // Fresnel model + int model; + bool airy; + + // Physical Fresnel + vec3 ior; + vec3 extinction; + + // Generalized Schlick Fresnel + vec3 F0; + vec3 F82; + vec3 F90; + float exponent; + + // Thin film + float tf_thickness; + float tf_ior; + + // Refraction + bool refraction; +}; + +// Convert a real-valued index of refraction to normal-incidence reflectivity. +float mx39_ior_to_f0(float ior) +{ + return mx_square((ior - 1.0) / (ior + 1.0)); +} + +// Convert normal-incidence reflectivity to real-valued index of refraction. +float mx39_f0_to_ior(float F0) +{ + float sqrtF0 = sqrt(clamp(F0, 0.01, 0.99)); + return (1.0 + sqrtF0) / (1.0 - sqrtF0); +} +vec3 mx39_f0_to_ior(vec3 F0) +{ + vec3 sqrtF0 = sqrt(clamp(F0, 0.01, 0.99)); + return (vec3(1.0) + sqrtF0) / (vec3(1.0) - sqrtF0); +} + +// https://renderwonk.com/publications/wp-generalization-adobe/gen-adobe.pdf +vec3 mx39_fresnel_hoffman_schlick(float cosTheta, Mx39FresnelData fd) +{ + const float COS_THETA_MAX = 1.0 / 7.0; + const float COS_THETA_FACTOR = 1.0 / (COS_THETA_MAX * pow(1.0 - COS_THETA_MAX, 6.0)); + + float x = clamp(cosTheta, 0.0, 1.0); + vec3 a = mix(fd.F0, fd.F90, pow(1.0 - COS_THETA_MAX, fd.exponent)) * (vec3(1.0) - fd.F82) * COS_THETA_FACTOR; + return mix(fd.F0, fd.F90, pow(1.0 - x, fd.exponent)) - a * x * mx39_pow6(1.0 - x); +} + +// https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/ +float mx39_fresnel_dielectric(float cosTheta, float ior) +{ + float c = cosTheta; + float g2 = ior*ior + c*c - 1.0; + if (g2 < 0.0) + { + // Total internal reflection + return 1.0; + } + + float g = sqrt(g2); + return 0.5 * mx_square((g - c) / (g + c)) * + (1.0 + mx_square(((g + c) * c - 1.0) / ((g - c) * c + 1.0))); +} + +// https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/ +vec2 mx39_fresnel_dielectric_polarized(float cosTheta, float ior) +{ + float cosTheta2 = mx_square(clamp(cosTheta, 0.0, 1.0)); + float sinTheta2 = 1.0 - cosTheta2; + + float t0 = max(ior * ior - sinTheta2, 0.0); + float t1 = t0 + cosTheta2; + float t2 = 2.0 * sqrt(t0) * cosTheta; + float Rs = (t1 - t2) / (t1 + t2); + + float t3 = cosTheta2 * t0 + sinTheta2 * sinTheta2; + float t4 = t2 * sinTheta2; + float Rp = Rs * (t3 - t4) / (t3 + t4); + + return vec2(Rp, Rs); +} + +// https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/ +void mx39_fresnel_conductor_polarized(float cosTheta, vec3 n, vec3 k, out vec3 Rp, out vec3 Rs) +{ + float cosTheta2 = mx_square(clamp(cosTheta, 0.0, 1.0)); + float sinTheta2 = 1.0 - cosTheta2; + vec3 n2 = n * n; + vec3 k2 = k * k; + + vec3 t0 = n2 - k2 - vec3(sinTheta2); + vec3 a2plusb2 = sqrt(t0 * t0 + 4.0 * n2 * k2); + vec3 t1 = a2plusb2 + vec3(cosTheta2); + vec3 a = sqrt(max(0.5 * (a2plusb2 + t0), 0.0)); + vec3 t2 = 2.0 * a * cosTheta; + Rs = (t1 - t2) / (t1 + t2); + + vec3 t3 = cosTheta2 * a2plusb2 + vec3(sinTheta2 * sinTheta2); + vec3 t4 = t2 * sinTheta2; + Rp = Rs * (t3 - t4) / (t3 + t4); +} + +vec3 mx39_fresnel_conductor(float cosTheta, vec3 n, vec3 k) +{ + vec3 Rp, Rs; + mx39_fresnel_conductor_polarized(cosTheta, n, k, Rp, Rs); + return 0.5 * (Rp + Rs); +} + +// https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html +void mx39_fresnel_conductor_phase_polarized(float cosTheta, float eta1, vec3 eta2, vec3 kappa2, out vec3 phiP, out vec3 phiS) +{ + vec3 k2 = kappa2 / eta2; + vec3 sinThetaSqr = vec3(1.0) - cosTheta * cosTheta; + vec3 A = eta2*eta2*(vec3(1.0)-k2*k2) - eta1*eta1*sinThetaSqr; + vec3 B = sqrt(A*A + mx_square(2.0*eta2*eta2*k2)); + vec3 U = sqrt((A+B)/2.0); + vec3 V = max(vec3(0.0), sqrt((B-A)/2.0)); + + phiS = atan(2.0*eta1*V*cosTheta, U*U + V*V - mx_square(eta1*cosTheta)); + phiP = atan(2.0*eta1*eta2*eta2*cosTheta * (2.0*k2*U - (vec3(1.0)-k2*k2) * V), + mx_square(eta2*eta2*(vec3(1.0)+k2*k2)*cosTheta) - eta1*eta1*(U*U+V*V)); +} + +// A Practical Extension to Microfacet Theory for the Modeling of Varying Iridescence +// https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html +vec3 mx39_fresnel_airy(float cosTheta, Mx39FresnelData fd) +{ + // XYZ to CIE 1931 RGB color space (using neutral E illuminant) + const mat3 XYZ_TO_RGB = mat3(2.3706743, -0.5138850, 0.0052982, -0.9000405, 1.4253036, -0.0146949, -0.4706338, 0.0885814, 1.0093968); + + // Assume vacuum on the outside + float eta1 = 1.0; + float eta2 = max(fd.tf_ior, eta1); + vec3 eta3 = (fd.model == MX39_FRESNEL_MODEL_SCHLICK) ? mx39_f0_to_ior(fd.F0) : fd.ior; + vec3 kappa3 = (fd.model == MX39_FRESNEL_MODEL_SCHLICK) ? vec3(0.0) : fd.extinction; + float cosThetaT = sqrt(1.0 - (1.0 - mx_square(cosTheta)) * mx_square(eta1 / eta2)); + + // First interface + vec2 R12 = mx39_fresnel_dielectric_polarized(cosTheta, eta2 / eta1); + if (cosThetaT <= 0.0) + { + // Total internal reflection + R12 = vec2(1.0); + } + vec2 T121 = vec2(1.0) - R12; + + // Second interface + vec3 R23p, R23s; + if (fd.model == MX39_FRESNEL_MODEL_SCHLICK) + { + vec3 f = mx39_fresnel_hoffman_schlick(cosThetaT, fd); + R23p = 0.5 * f; + R23s = 0.5 * f; + } + else + { + mx39_fresnel_conductor_polarized(cosThetaT, eta3 / eta2, kappa3 / eta2, R23p, R23s); + } + + // Phase shift + float cosB = cos(atan(eta2 / eta1)); + vec2 phi21 = vec2(cosTheta < cosB ? 0.0 : M_PI, M_PI); + vec3 phi23p, phi23s; + if (fd.model == MX39_FRESNEL_MODEL_SCHLICK) + { + phi23p = vec3((eta3[0] < eta2) ? M_PI : 0.0, + (eta3[1] < eta2) ? M_PI : 0.0, + (eta3[2] < eta2) ? M_PI : 0.0); + phi23s = phi23p; + } + else + { + mx39_fresnel_conductor_phase_polarized(cosThetaT, eta2, eta3, kappa3, phi23p, phi23s); + } + vec3 r123p = max(sqrt(R12.x*R23p), 0.0); + vec3 r123s = max(sqrt(R12.y*R23s), 0.0); + + // Iridescence term + vec3 I = vec3(0.0); + vec3 Cm, Sm; + + // Optical path difference + float distMeters = fd.tf_thickness * 1.0e-9; + float opd = 2.0 * eta2 * cosThetaT * distMeters; + + // Iridescence term using spectral antialiasing for Parallel polarization + + // Reflectance term for m=0 (DC term amplitude) + vec3 Rs = (mx_square(T121.x) * R23p) / (vec3(1.0) - R12.x*R23p); + I += R12.x + Rs; + + // Reflectance term for m>0 (pairs of diracs) + Cm = Rs - T121.x; + for (int m=1; m<=2; m++) + { + Cm *= r123p; + Sm = 2.0 * mx_eval_sensitivity(float(m) * opd, float(m)*(phi23p+vec3(phi21.x))); + I += Cm*Sm; + } + + // Iridescence term using spectral antialiasing for Perpendicular polarization + + // Reflectance term for m=0 (DC term amplitude) + vec3 Rp = (mx_square(T121.y) * R23s) / (vec3(1.0) - R12.y*R23s); + I += R12.y + Rp; + + // Reflectance term for m>0 (pairs of diracs) + Cm = Rp - T121.y; + for (int m=1; m<=2; m++) + { + Cm *= r123s; + Sm = 2.0 * mx_eval_sensitivity(float(m) * opd, float(m)*(phi23s+vec3(phi21.y))); + I += Cm*Sm; + } + + // Average parallel and perpendicular polarization + I *= 0.5; + + // Convert back to RGB reflectance + I = clamp(XYZ_TO_RGB * I, 0.0, 1.0); + + return I; +} + +Mx39FresnelData mx39_init_fresnel_dielectric(float ior, float tf_thickness, float tf_ior) +{ + Mx39FresnelData fd; + fd.model = MX39_FRESNEL_MODEL_DIELECTRIC; + fd.airy = tf_thickness > 0.0; + fd.ior = vec3(ior); + fd.extinction = vec3(0.0); + fd.F0 = vec3(0.0); + fd.F82 = vec3(0.0); + fd.F90 = vec3(0.0); + fd.exponent = 0.0; + fd.tf_thickness = tf_thickness; + fd.tf_ior = tf_ior; + fd.refraction = false; + return fd; +} + +Mx39FresnelData mx39_init_fresnel_conductor(vec3 ior, vec3 extinction, float tf_thickness, float tf_ior) +{ + Mx39FresnelData fd; + fd.model = MX39_FRESNEL_MODEL_CONDUCTOR; + fd.airy = tf_thickness > 0.0; + fd.ior = ior; + fd.extinction = extinction; + fd.F0 = vec3(0.0); + fd.F82 = vec3(0.0); + fd.F90 = vec3(0.0); + fd.exponent = 0.0; + fd.tf_thickness = tf_thickness; + fd.tf_ior = tf_ior; + fd.refraction = false; + return fd; +} + +Mx39FresnelData mx39_init_fresnel_schlick(vec3 F0, vec3 F82, vec3 F90, float exponent, float tf_thickness, float tf_ior) +{ + Mx39FresnelData fd; + fd.model = MX39_FRESNEL_MODEL_SCHLICK; + fd.airy = tf_thickness > 0.0; + fd.ior = vec3(0.0); + fd.extinction = vec3(0.0); + fd.F0 = F0; + fd.F82 = F82; + fd.F90 = F90; + fd.exponent = exponent; + fd.tf_thickness = tf_thickness; + fd.tf_ior = tf_ior; + fd.refraction = false; + return fd; +} + +vec3 mx39_compute_fresnel(float cosTheta, Mx39FresnelData fd) +{ + if (fd.airy) + { + return mx39_fresnel_airy(cosTheta, fd); + } + else if (fd.model == MX39_FRESNEL_MODEL_DIELECTRIC) + { + return vec3(mx39_fresnel_dielectric(cosTheta, fd.ior.x)); + } + else if (fd.model == MX39_FRESNEL_MODEL_CONDUCTOR) + { + return mx39_fresnel_conductor(cosTheta, fd.ior, fd.extinction); + } + else + { + return mx39_fresnel_hoffman_schlick(cosTheta, fd); + } +} + +#ifdef MX39_USING_ENVIRONMENT_NONE +vec3 mx39_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, Mx39FresnelData fd) +{ + return vec3(0.0); +} +#endif + +#ifdef MX39_USING_ENVIRONMENT_PREFILTER +vec3 mx39_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, Mx39FresnelData fd) +{ + N = mx_forward_facing_normal(N, V); + vec3 L = fd.refraction ? mx_refraction_solid_sphere(-V, N, fd.ior.x) : -reflect(V, N); + + float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); + + float avgAlpha = mx_average_alpha(alpha); + vec3 F = mx39_compute_fresnel(NdotV, fd); + float G = mx_ggx_smith_G2(NdotV, NdotV, avgAlpha); + vec3 FG = fd.refraction ? vec3(1.0) - (F * G) : F * G; + + vec3 Li = mx_latlong_map_lookup(L, $envMatrix, mx_latlong_alpha_to_lod(avgAlpha), $envRadiance); + return Li * FG * $envLightIntensity; +} +#endif + +#ifdef MX39_USING_ENVIRONMENT_FIS +vec3 mx39_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, Mx39FresnelData fd) +{ + // Generate tangent frame. + X = normalize(X - dot(X, N) * N); + vec3 Y = cross(N, X); + mat3 tangentToWorld = mat3(X, Y, N); + + // Transform the view vector to tangent space. + V = vec3(dot(V, X), dot(V, Y), dot(V, N)); + + // Compute derived properties. + float NdotV = clamp(V.z, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(alpha); + float G1V = mx_ggx_smith_G1(NdotV, avgAlpha); + + // Integrate outgoing radiance using filtered importance sampling. + // http://cgg.mff.cuni.cz/~jaroslav/papers/2008-egsr-fis/2008-egsr-fis-final-embedded.pdf + vec3 radiance = vec3(0.0); + int envRadianceSamples = $envRadianceSamples; + for (int i = 0; i < envRadianceSamples; i++) + { + vec2 Xi = mx_spherical_fibonacci(i, envRadianceSamples); + + // Compute the half vector and incoming light direction. + vec3 H = mx_ggx_importance_sample_VNDF(Xi, V, alpha); + vec3 L = fd.refraction ? mx_refraction_solid_sphere(-V, H, fd.ior.x) : -reflect(V, H); + + // Compute dot products for this sample. + float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0); + float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0); + + // Sample the environment light from the given direction. + vec3 Lw = tangentToWorld * L; + float pdf = mx_ggx_NDF(H, alpha) * G1V / (4.0 * NdotV); + float lod = mx_latlong_compute_lod(Lw, pdf, float($envRadianceMips - 1), envRadianceSamples); + vec3 sampleColor = mx_latlong_map_lookup(Lw, $envMatrix, lod, $envRadiance); + + // Compute the Fresnel term. + vec3 F = mx39_compute_fresnel(VdotH, fd); + + // Compute the geometric term. + float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha); + + // Compute the combined FG term, which is inverted for refraction. + vec3 FG = fd.refraction ? vec3(1.0) - (F * G) : F * G; + + // Add the radiance contribution of this sample. + // From https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf + // incidentLight = sampleColor * NdotL + // microfacetSpecular = D * F * G / (4 * NdotL * NdotV) + // pdf = D * G1V / (4 * NdotV); + // radiance = incidentLight * microfacetSpecular / pdf + radiance += sampleColor * FG; + } + + // Apply the global component of the geometric term and normalize. + radiance /= G1V * float(envRadianceSamples); + + // Return the final radiance. + return radiance * $envLightIntensity; +} +#endif + +#ifdef MX39_USING_TRANSMISSION_OPACITY +vec3 mx39_surface_transmission(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, Mx39FresnelData fd, vec3 tint) +{ + return tint; +} +#endif + +#ifdef MX39_USING_TRANSMISSION_REFRACT +vec3 mx39_surface_transmission(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, Mx39FresnelData fd, vec3 tint) +{ + // Approximate the appearance of surface transmission as glossy + // environment map refraction, ignoring any scene geometry that might + // be visible through the surface. + fd.refraction = true; + if ($refractionTwoSided) + { + tint = mx_square(tint); + } + return mx39_environment_radiance(N, V, X, alpha, distribution, fd) * tint; +} +#endif diff --git a/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl b/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl index 0b28f3645f..6bfc64571e 100644 --- a/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_environment_fis.glsl @@ -67,3 +67,5 @@ vec3 mx_environment_irradiance(vec3 N) vec3 Li = mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance); return Li * $envLightIntensity; } + +#define MX39_USING_ENVIRONMENT_FIS diff --git a/libraries/pbrlib/genglsl/lib/mx_environment_none.glsl b/libraries/pbrlib/genglsl/lib/mx_environment_none.glsl index f0a1da5989..f535c84757 100644 --- a/libraries/pbrlib/genglsl/lib/mx_environment_none.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_environment_none.glsl @@ -9,3 +9,5 @@ vec3 mx_environment_irradiance(vec3 N) { return vec3(0.0); } + +#define MX39_USING_ENVIRONMENT_NONE diff --git a/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl b/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl index 778742c449..89e898a1e1 100644 --- a/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_environment_prefilter.glsl @@ -28,3 +28,5 @@ vec3 mx_environment_irradiance(vec3 N) vec3 Li = mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance); return Li * $envLightIntensity; } + +#define MX39_USING_ENVIRONMENT_PREFILTER diff --git a/libraries/pbrlib/genglsl/lib/mx_transmission_opacity.glsl b/libraries/pbrlib/genglsl/lib/mx_transmission_opacity.glsl index 2861d06194..54bef92ff4 100644 --- a/libraries/pbrlib/genglsl/lib/mx_transmission_opacity.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_transmission_opacity.glsl @@ -4,3 +4,5 @@ vec3 mx_surface_transmission(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio { return tint; } + +#define MX39_USING_TRANSMISSION_OPACITY diff --git a/libraries/pbrlib/genglsl/lib/mx_transmission_refract.glsl b/libraries/pbrlib/genglsl/lib/mx_transmission_refract.glsl index 64e496a384..4493321b4b 100644 --- a/libraries/pbrlib/genglsl/lib/mx_transmission_refract.glsl +++ b/libraries/pbrlib/genglsl/lib/mx_transmission_refract.glsl @@ -12,3 +12,5 @@ vec3 mx_surface_transmission(vec3 N, vec3 V, vec3 X, vec2 alpha, int distributio } return mx_environment_radiance(N, V, X, alpha, distribution, fd) * tint; } + +#define MX39_USING_TRANSMISSION_REFRACT diff --git a/libraries/pbrlib/genglsl/mx39_compensating_oren_nayar_diffuse_bsdf.glsl b/libraries/pbrlib/genglsl/mx39_compensating_oren_nayar_diffuse_bsdf.glsl new file mode 100644 index 0000000000..b93b5b8cd0 --- /dev/null +++ b/libraries/pbrlib/genglsl/mx39_compensating_oren_nayar_diffuse_bsdf.glsl @@ -0,0 +1,42 @@ +#include "lib/mx39_microfacet_diffuse.glsl" + +void mx39_compensating_oren_nayar_diffuse_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color, float roughness, vec3 normal, bool energy_compensation, inout BSDF bsdf) +{ + bsdf.throughput = vec3(0.0); + + if (weight < M_FLOAT_EPS) + { + return; + } + + normal = mx_forward_facing_normal(normal, V); + + float NdotV = clamp(dot(normal, V), M_FLOAT_EPS, 1.0); + float NdotL = clamp(dot(normal, L), M_FLOAT_EPS, 1.0); + float LdotV = clamp(dot(L, V), M_FLOAT_EPS, 1.0); + + vec3 diffuse = energy_compensation ? + mx39_oren_nayar_compensated_diffuse(NdotV, NdotL, LdotV, roughness, color) : + mx39_oren_nayar_diffuse(NdotV, NdotL, LdotV, roughness) * color; + bsdf.response = diffuse * occlusion * weight * NdotL * M_PI_INV; +} + +void mx39_compensating_oren_nayar_diffuse_bsdf_indirect(vec3 V, float weight, vec3 color, float roughness, vec3 normal, bool energy_compensation, inout BSDF bsdf) +{ + bsdf.throughput = vec3(0.0); + + if (weight < M_FLOAT_EPS) + { + return; + } + + normal = mx_forward_facing_normal(normal, V); + + float NdotV = clamp(dot(normal, V), M_FLOAT_EPS, 1.0); + + vec3 diffuse = energy_compensation ? + mx39_oren_nayar_compensated_diffuse_dir_albedo(NdotV, roughness, color) : + mx39_oren_nayar_diffuse_dir_albedo(NdotV, roughness) * color; + vec3 Li = mx_environment_irradiance(normal); + bsdf.response = Li * diffuse * weight; +} diff --git a/libraries/pbrlib/genglsl/mx39_dielectric_tf_bsdf.glsl b/libraries/pbrlib/genglsl/mx39_dielectric_tf_bsdf.glsl new file mode 100644 index 0000000000..3dc668c4fa --- /dev/null +++ b/libraries/pbrlib/genglsl/mx39_dielectric_tf_bsdf.glsl @@ -0,0 +1,92 @@ +#include "lib/mx39_microfacet_specular.glsl" + +void mx39_dielectric_tf_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 tint, float ior, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf) +{ + if (weight < M_FLOAT_EPS) + { + return; + } + + N = mx_forward_facing_normal(N, V); + + X = normalize(X - dot(X, N) * N); + vec3 Y = cross(N, X); + vec3 H = normalize(L + V); + + float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0); + float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); + float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0); + + vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(safeAlpha); + vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N)); + + vec3 safeTint = max(tint, 0.0); + Mx39FresnelData fd = mx39_init_fresnel_dielectric(ior, thinfilm_thickness, thinfilm_ior); + vec3 F = mx39_compute_fresnel(VdotH, fd); + float D = mx_ggx_NDF(Ht, safeAlpha); + float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha); + + float F0 = mx39_ior_to_f0(ior); + vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); + vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp; + bsdf.throughput = 1.0 - dirAlbedo * weight; + + // Note: NdotL is cancelled out + bsdf.response = D * F * G * comp * safeTint * occlusion * weight / (4.0 * NdotV); +} + +void mx39_dielectric_tf_bsdf_transmission(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf) +{ + if (weight < M_FLOAT_EPS) + { + return; + } + + N = mx_forward_facing_normal(N, V); + float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); + + vec3 safeTint = max(tint, 0.0); + Mx39FresnelData fd = mx39_init_fresnel_dielectric(ior, thinfilm_thickness, thinfilm_ior); + vec3 F = mx39_compute_fresnel(NdotV, fd); + + vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(safeAlpha); + + float F0 = mx39_ior_to_f0(ior); + vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); + vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp; + bsdf.throughput = 1.0 - dirAlbedo * weight; + + if (scatter_mode != 0) + { + bsdf.response = mx39_surface_transmission(N, V, X, safeAlpha, distribution, fd, safeTint) * weight; + } +} + +void mx39_dielectric_tf_bsdf_indirect(vec3 V, float weight, vec3 tint, float ior, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf) +{ + if (weight < M_FLOAT_EPS) + { + return; + } + + N = mx_forward_facing_normal(N, V); + + float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); + + vec3 safeTint = max(tint, 0.0); + Mx39FresnelData fd = mx39_init_fresnel_dielectric(ior, thinfilm_thickness, thinfilm_ior); + vec3 F = mx39_compute_fresnel(NdotV, fd); + + vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(safeAlpha); + + float F0 = mx39_ior_to_f0(ior); + vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); + vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp; + bsdf.throughput = 1.0 - dirAlbedo * weight; + + vec3 Li = mx39_environment_radiance(N, V, X, safeAlpha, distribution, fd); + bsdf.response = Li * safeTint * comp * weight; +} diff --git a/libraries/pbrlib/genglsl/mx39_generalized_schlick_tf_82_bsdf.glsl b/libraries/pbrlib/genglsl/mx39_generalized_schlick_tf_82_bsdf.glsl new file mode 100644 index 0000000000..512245784a --- /dev/null +++ b/libraries/pbrlib/genglsl/mx39_generalized_schlick_tf_82_bsdf.glsl @@ -0,0 +1,98 @@ +#include "lib/mx39_microfacet_specular.glsl" + +void mx39_generalized_schlick_tf_82_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color0, vec3 color82, vec3 color90, float exponent, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf) +{ + if (weight < M_FLOAT_EPS) + { + return; + } + + N = mx_forward_facing_normal(N, V); + + X = normalize(X - dot(X, N) * N); + vec3 Y = cross(N, X); + vec3 H = normalize(L + V); + + float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0); + float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); + float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0); + + vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(safeAlpha); + vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N)); + + vec3 safeColor0 = max(color0, 0.0); + vec3 safeColor82 = max(color82, 0.0); + vec3 safeColor90 = max(color90, 0.0); + Mx39FresnelData fd = mx39_init_fresnel_schlick(safeColor0, safeColor82, safeColor90, exponent, thinfilm_thickness, thinfilm_ior); + vec3 F = mx39_compute_fresnel(VdotH, fd); + float D = mx_ggx_NDF(Ht, safeAlpha); + float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha); + + vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); + vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp; + float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0)); + bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight); + + // Note: NdotL is cancelled out + bsdf.response = D * F * G * comp * occlusion * weight / (4.0 * NdotV); +} + +void mx39_generalized_schlick_tf_82_bsdf_transmission(vec3 V, float weight, vec3 color0, vec3 color82, vec3 color90, float exponent, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf) +{ + if (weight < M_FLOAT_EPS) + { + return; + } + + N = mx_forward_facing_normal(N, V); + float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); + + vec3 safeColor0 = max(color0, 0.0); + vec3 safeColor82 = max(color82, 0.0); + vec3 safeColor90 = max(color90, 0.0); + Mx39FresnelData fd = mx39_init_fresnel_schlick(safeColor0, safeColor82, safeColor90, exponent, thinfilm_thickness, thinfilm_ior); + vec3 F = mx39_compute_fresnel(NdotV, fd); + + vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(safeAlpha); + + vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); + vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp; + float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0)); + bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight); + + if (scatter_mode != 0) + { + float avgF0 = dot(safeColor0, vec3(1.0 / 3.0)); + fd.ior = vec3(mx39_f0_to_ior(avgF0)); + bsdf.response = mx39_surface_transmission(N, V, X, safeAlpha, distribution, fd, safeColor0) * weight; + } +} + +void mx39_generalized_schlick_tf_82_bsdf_indirect(vec3 V, float weight, vec3 color0, vec3 color82, vec3 color90, float exponent, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf) +{ + if (weight < M_FLOAT_EPS) + { + return; + } + + N = mx_forward_facing_normal(N, V); + float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); + + vec3 safeColor0 = max(color0, 0.0); + vec3 safeColor82 = max(color82, 0.0); + vec3 safeColor90 = max(color90, 0.0); + Mx39FresnelData fd = mx39_init_fresnel_schlick(safeColor0, safeColor82, safeColor90, exponent, thinfilm_thickness, thinfilm_ior); + vec3 F = mx39_compute_fresnel(NdotV, fd); + + vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(safeAlpha); + vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); + vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp; + float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0)); + bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight); + + vec3 Li = mx39_environment_radiance(N, V, X, safeAlpha, distribution, fd); + bsdf.response = Li * comp * weight; +} diff --git a/libraries/pbrlib/genglsl/mx39_pbrlib_genglsl_impl.mtlx b/libraries/pbrlib/genglsl/mx39_pbrlib_genglsl_impl.mtlx new file mode 100644 index 0000000000..3626896222 --- /dev/null +++ b/libraries/pbrlib/genglsl/mx39_pbrlib_genglsl_impl.mtlx @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/libraries/pbrlib/genglsl/mx39_sheen_zeltner_bsdf.glsl b/libraries/pbrlib/genglsl/mx39_sheen_zeltner_bsdf.glsl new file mode 100644 index 0000000000..c6a874a5da --- /dev/null +++ b/libraries/pbrlib/genglsl/mx39_sheen_zeltner_bsdf.glsl @@ -0,0 +1,38 @@ +#include "lib/mx39_microfacet_sheen.glsl" + +void mx39_sheen_zeltner_bsdf_reflection(vec3 L, vec3 V, vec3 P, float occlusion, float weight, vec3 color, float roughness, vec3 N, inout BSDF bsdf) +{ + if (weight < M_FLOAT_EPS) + { + return; + } + + N = mx_forward_facing_normal(N, V); + float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); + + roughness = clamp(roughness, 0.01, 1.0); // Clamp to range of original impl. + + vec3 fr = color * mx39_zeltner_sheen_brdf(L, V, N, NdotV, roughness); + float dirAlbedo = mx39_zeltner_sheen_dir_albedo(NdotV, roughness); + bsdf.throughput = vec3(1.0 - dirAlbedo * weight); + bsdf.response = dirAlbedo * fr * occlusion * weight; +} + +void mx39_sheen_zeltner_bsdf_indirect(vec3 V, float weight, vec3 color, float roughness, vec3 N, inout BSDF bsdf) +{ + if (weight < M_FLOAT_EPS) + { + return; + } + + N = mx_forward_facing_normal(N, V); + float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0); + + float dirAlbedo; + roughness = clamp(roughness, 0.01, 1.0); // Clamp to range of original impl. + dirAlbedo = mx39_zeltner_sheen_dir_albedo(NdotV, roughness); + + vec3 Li = mx_environment_irradiance(N); + bsdf.throughput = vec3(1.0 - dirAlbedo * weight); + bsdf.response = Li * color * dirAlbedo * weight; +} diff --git a/libraries/pbrlib/genmdl/mx39_pbrlib_genmdl_impl.mtlx b/libraries/pbrlib/genmdl/mx39_pbrlib_genmdl_impl.mtlx new file mode 100644 index 0000000000..f2dc8c184d --- /dev/null +++ b/libraries/pbrlib/genmdl/mx39_pbrlib_genmdl_impl.mtlx @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/libraries/pbrlib/genmsl/mx39_pbrlib_genmsl_impl.mtlx b/libraries/pbrlib/genmsl/mx39_pbrlib_genmsl_impl.mtlx new file mode 100644 index 0000000000..93fe12e647 --- /dev/null +++ b/libraries/pbrlib/genmsl/mx39_pbrlib_genmsl_impl.mtlx @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/libraries/pbrlib/genosl/legacy/mx39_compensating_oren_nayar_diffuse_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx39_compensating_oren_nayar_diffuse_bsdf.osl new file mode 100644 index 0000000000..2ce4dd07b1 --- /dev/null +++ b/libraries/pbrlib/genosl/legacy/mx39_compensating_oren_nayar_diffuse_bsdf.osl @@ -0,0 +1,5 @@ +void mx39_compensating_oren_nayar_diffuse_bsdf(float weight, color _color, float roughness, normal N, int energy_compensation, output BSDF bsdf) +{ + bsdf.response = _color * weight * oren_nayar(N, roughness); + bsdf.throughput = color(0.0); +} diff --git a/libraries/pbrlib/genosl/legacy/mx39_dielectric_tf_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx39_dielectric_tf_bsdf.osl new file mode 100644 index 0000000000..5d6c81fd36 --- /dev/null +++ b/libraries/pbrlib/genosl/legacy/mx39_dielectric_tf_bsdf.osl @@ -0,0 +1,36 @@ +#include "../lib/mx_microfacet_specular.osl" + +void mx39_dielectric_tf_bsdf(float weight, color tint, float ior, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf) +{ + if (scatter_mode == "T") + { + bsdf.response = tint * weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1); + bsdf.throughput = tint * weight; + return; + } + + float NdotV = clamp(dot(N,-I), M_FLOAT_EPS, 1.0); + float F0 = mx_ior_to_f0(ior); + float F = mx_fresnel_schlick(NdotV, F0); + + // Calculate compensation for multiple scattering. + // This should normally be done inside the closure + // but since vanilla OSL doesen't support this we + // add it here in shader code instead. + vector2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(safeAlpha); + float comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); + + // Calculate throughput from directional albedo. + float dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, ior) * comp; + bsdf.throughput = 1.0 - dirAlbedo * weight; + + if (scatter_mode == "R") + { + bsdf.response = tint * weight * comp * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 0); + } + else + { + bsdf.response = tint * weight * comp * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 2); + } +} diff --git a/libraries/pbrlib/genosl/legacy/mx39_generalized_schlick_tf_82_bsdf.osl b/libraries/pbrlib/genosl/legacy/mx39_generalized_schlick_tf_82_bsdf.osl new file mode 100644 index 0000000000..ac0e3928e5 --- /dev/null +++ b/libraries/pbrlib/genosl/legacy/mx39_generalized_schlick_tf_82_bsdf.osl @@ -0,0 +1,38 @@ +#include "../lib/mx_microfacet_specular.osl" + +void mx39_generalized_schlick_tf_82_bsdf(float weight, color color0, color color82, color color90, float exponent, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf) +{ + float avgF0 = dot(color0, color(1.0 / 3.0)); + float ior = mx_f0_to_ior(avgF0); + + if (scatter_mode == "T") + { + bsdf.response = weight * microfacet(distribution, N, U, roughness.x, roughness.y, ior, 1); + bsdf.throughput = weight; + return; + } + + float NdotV = fabs(dot(N,-I)); + color F = mx_fresnel_schlick(NdotV, color0, color90, exponent); + + // Calculate compensation for multiple scattering. + // This should normally be done inside the closure + // but since vanilla OSL doesen't support this we + // add it here in shader code instead. + vector2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0); + float avgAlpha = mx_average_alpha(safeAlpha); + color comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F); + + // Calculate throughput from directional albedo. + color dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, color0, color90) * comp; + float avgDirAlbedo = dot(dirAlbedo, color(1.0 / 3.0)); + bsdf.throughput = 1.0 - avgDirAlbedo * weight; + + // Calculate the reflection response, setting IOR to zero to disable internal Fresnel. + bsdf.response = F * comp * weight * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, 0.0, 0); + + if (scatter_mode == "RT") + { + bsdf.response += bsdf.throughput * microfacet(distribution, N, U, safeAlpha.x, safeAlpha.y, ior, 1); + } +} diff --git a/libraries/pbrlib/genosl/mx39_dielectric_tf_bsdf.osl b/libraries/pbrlib/genosl/mx39_dielectric_tf_bsdf.osl new file mode 100644 index 0000000000..5b4243506c --- /dev/null +++ b/libraries/pbrlib/genosl/mx39_dielectric_tf_bsdf.osl @@ -0,0 +1,15 @@ +void mx39_dielectric_tf_bsdf(float weight, color tint, float ior, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf) +{ + if (scatter_mode == "R") + { + bsdf = weight * dielectric_bsdf(N, U, tint, color(0.0), roughness.x, roughness.y, ior, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior); + } + else if (scatter_mode == "T") + { + bsdf = weight * dielectric_bsdf(N, U, color(0.0), tint, roughness.x, roughness.y, ior, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior); + } + else + { + bsdf = weight * dielectric_bsdf(N, U, tint, tint, roughness.x, roughness.y, ior, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior); + } +} diff --git a/libraries/pbrlib/genosl/mx39_generalized_schlick_tf_82_bsdf.osl b/libraries/pbrlib/genosl/mx39_generalized_schlick_tf_82_bsdf.osl new file mode 100644 index 0000000000..4fb9eac0c3 --- /dev/null +++ b/libraries/pbrlib/genosl/mx39_generalized_schlick_tf_82_bsdf.osl @@ -0,0 +1,15 @@ +void mx39_generalized_schlick_tf_82_bsdf(float weight, color color0, color color82, color color90, float exponent, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf) +{ + if (scatter_mode == "R") + { + bsdf = weight * generalized_schlick_bsdf(N, U, color(1.0), color(0.0), roughness.x, roughness.y, color0, color90, exponent, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior); + } + else if (scatter_mode == "T") + { + bsdf = weight * generalized_schlick_bsdf(N, U, color(0.0), color(1.0), roughness.x, roughness.y, color0, color90, exponent, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior); + } + else + { + bsdf = weight * generalized_schlick_bsdf(N, U, color(1.0), color(1.0), roughness.x, roughness.y, color0, color90, exponent, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior); + } +} diff --git a/libraries/pbrlib/genosl/mx39_pbrlib_genosl_impl.legacy b/libraries/pbrlib/genosl/mx39_pbrlib_genosl_impl.legacy new file mode 100644 index 0000000000..95af5056f4 --- /dev/null +++ b/libraries/pbrlib/genosl/mx39_pbrlib_genosl_impl.legacy @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/libraries/pbrlib/genosl/mx39_pbrlib_genosl_impl.mtlx b/libraries/pbrlib/genosl/mx39_pbrlib_genosl_impl.mtlx new file mode 100644 index 0000000000..df8d6a59e9 --- /dev/null +++ b/libraries/pbrlib/genosl/mx39_pbrlib_genosl_impl.mtlx @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/libraries/pbrlib/pbrlib_defs.mtlx b/libraries/pbrlib/pbrlib_defs.mtlx index e63625a45d..5fe6a6a773 100644 --- a/libraries/pbrlib/pbrlib_defs.mtlx +++ b/libraries/pbrlib/pbrlib_defs.mtlx @@ -417,4 +417,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/python/Scripts/generateshader.py b/python/Scripts/generateshader.py index f6158d270a..65b628d733 100644 --- a/python/Scripts/generateshader.py +++ b/python/Scripts/generateshader.py @@ -143,8 +143,6 @@ def main(): nodes = mx_gen_shader.findRenderableElements(doc) if not nodes: nodes = doc.getMaterialNodes() - if not nodes: - nodes = doc.getNodesOfType(mx.SURFACE_SHADER_TYPE_STRING) pathPrefix = '' if opts.outputPath and os.path.exists(opts.outputPath): diff --git a/resources/Materials/Examples/OpenPbr/open_pbr_aluminum_brushed.mtlx b/resources/Materials/Examples/OpenPbr/open_pbr_aluminum_brushed.mtlx new file mode 100644 index 0000000000..7f7072d416 --- /dev/null +++ b/resources/Materials/Examples/OpenPbr/open_pbr_aluminum_brushed.mtlx @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/resources/Materials/Examples/OpenPbr/open_pbr_carpaint.mtlx b/resources/Materials/Examples/OpenPbr/open_pbr_carpaint.mtlx new file mode 100644 index 0000000000..fd42fdf48d --- /dev/null +++ b/resources/Materials/Examples/OpenPbr/open_pbr_carpaint.mtlx @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/resources/Materials/Examples/OpenPbr/open_pbr_default.mtlx b/resources/Materials/Examples/OpenPbr/open_pbr_default.mtlx new file mode 100644 index 0000000000..8125541a99 --- /dev/null +++ b/resources/Materials/Examples/OpenPbr/open_pbr_default.mtlx @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Materials/Examples/OpenPbr/open_pbr_glass.mtlx b/resources/Materials/Examples/OpenPbr/open_pbr_glass.mtlx new file mode 100644 index 0000000000..a661b9d1f6 --- /dev/null +++ b/resources/Materials/Examples/OpenPbr/open_pbr_glass.mtlx @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/resources/Materials/Examples/OpenPbr/open_pbr_honey.mtlx b/resources/Materials/Examples/OpenPbr/open_pbr_honey.mtlx new file mode 100644 index 0000000000..41e076d231 --- /dev/null +++ b/resources/Materials/Examples/OpenPbr/open_pbr_honey.mtlx @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/resources/Materials/Examples/OpenPbr/open_pbr_ketchup.mtlx b/resources/Materials/Examples/OpenPbr/open_pbr_ketchup.mtlx new file mode 100644 index 0000000000..cda2ebdf7e --- /dev/null +++ b/resources/Materials/Examples/OpenPbr/open_pbr_ketchup.mtlx @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/resources/Materials/Examples/OpenPbr/open_pbr_lightbulb.mtlx b/resources/Materials/Examples/OpenPbr/open_pbr_lightbulb.mtlx new file mode 100644 index 0000000000..a915f842a4 --- /dev/null +++ b/resources/Materials/Examples/OpenPbr/open_pbr_lightbulb.mtlx @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/resources/Materials/Examples/OpenPbr/open_pbr_pearl.mtlx b/resources/Materials/Examples/OpenPbr/open_pbr_pearl.mtlx new file mode 100644 index 0000000000..83db774b8e --- /dev/null +++ b/resources/Materials/Examples/OpenPbr/open_pbr_pearl.mtlx @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Materials/Examples/OpenPbr/open_pbr_soapbubble.mtlx b/resources/Materials/Examples/OpenPbr/open_pbr_soapbubble.mtlx new file mode 100644 index 0000000000..af0faccb2a --- /dev/null +++ b/resources/Materials/Examples/OpenPbr/open_pbr_soapbubble.mtlx @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/resources/Materials/Examples/OpenPbr/open_pbr_velvet.mtlx b/resources/Materials/Examples/OpenPbr/open_pbr_velvet.mtlx new file mode 100644 index 0000000000..6fbc907f3d --- /dev/null +++ b/resources/Materials/Examples/OpenPbr/open_pbr_velvet.mtlx @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/resources/Materials/TestSuite/_options.mtlx b/resources/Materials/TestSuite/_options.mtlx index 99db2a9f50..e12a5b564b 100644 --- a/resources/Materials/TestSuite/_options.mtlx +++ b/resources/Materials/TestSuite/_options.mtlx @@ -74,7 +74,7 @@ - + diff --git a/source/MaterialXGenMdl/MdlShaderGenerator.cpp b/source/MaterialXGenMdl/MdlShaderGenerator.cpp index 5a1f39f48d..57c653bc83 100644 --- a/source/MaterialXGenMdl/MdlShaderGenerator.cpp +++ b/source/MaterialXGenMdl/MdlShaderGenerator.cpp @@ -192,15 +192,18 @@ MdlShaderGenerator::MdlShaderGenerator() : // registerImplementation("IM_dielectric_bsdf_" + MdlShaderGenerator::TARGET, ThinFilmReceiverNodeMdl::create); + registerImplementation("IM_dielectric_tf_bsdf_" + MdlShaderGenerator::TARGET, LayerableNodeMdl::create); // registerImplementation("IM_conductor_bsdf_" + MdlShaderGenerator::TARGET, ThinFilmReceiverNodeMdl::create); // registerImplementation("IM_generalized_schlick_bsdf_" + MdlShaderGenerator::TARGET, ThinFilmReceiverNodeMdl::create); + registerImplementation("IM_generalized_schlick_tf_82_bsdf_" + MdlShaderGenerator::TARGET, LayerableNodeMdl::create); // registerImplementation("IM_sheen_bsdf_" + MdlShaderGenerator::TARGET, LayerableNodeMdl::create); + registerImplementation("IM_sheen_zeltner_bsdf_" + MdlShaderGenerator::TARGET, LayerableNodeMdl::create); // registerImplementation("IM_image_float_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create); diff --git a/source/MaterialXGenShader/ShaderNode.cpp b/source/MaterialXGenShader/ShaderNode.cpp index 6e951b06e6..adcf71566b 100644 --- a/source/MaterialXGenShader/ShaderNode.cpp +++ b/source/MaterialXGenShader/ShaderNode.cpp @@ -235,7 +235,8 @@ ShaderNodePtr ShaderNode::create(const ShaderGraph* parent, const string& name, } else if (*primaryOutput->getType() == *Type::SURFACESHADER) { - if (nodeDefName == "ND_surface_unlit") + if (nodeDefName == "ND_surface_unlit" || + (stringStartsWith(nodeDefName, "ND_convert_") && stringEndsWith(nodeDefName, "_surfaceshader"))) { newNode->_classification = Classification::SHADER | Classification::SURFACE | Classification::UNLIT; } diff --git a/source/MaterialXRender/CMakeLists.txt b/source/MaterialXRender/CMakeLists.txt index 52d07e688e..654a9648bb 100644 --- a/source/MaterialXRender/CMakeLists.txt +++ b/source/MaterialXRender/CMakeLists.txt @@ -18,6 +18,9 @@ assign_source_group("Header Files" ${materialx_headers}) if(UNIX) add_compile_options(-Wno-unused-function) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + add_compile_options(-Wno-stringop-overflow) + endif() endif() add_library(${MATERIALX_MODULE_NAME} ${materialx_source} ${materialx_headers} ${materialx_inlined}) diff --git a/source/MaterialXTest/CMakeLists.txt b/source/MaterialXTest/CMakeLists.txt index 862a176b50..9d2bd578dd 100644 --- a/source/MaterialXTest/CMakeLists.txt +++ b/source/MaterialXTest/CMakeLists.txt @@ -98,6 +98,9 @@ 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) + add_custom_command(TARGET MaterialXTest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E rename + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libraries/pbrlib/genosl/mx39_pbrlib_genosl_impl.legacy ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libraries/pbrlib/genosl/mx39_pbrlib_genosl_impl.mtlx) endif() if(MATERIALX_BUILD_GEN_MDL) diff --git a/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp b/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp index 2cc4d7ccf4..e2857f1eb2 100644 --- a/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp +++ b/source/MaterialXTest/MaterialXGenGlsl/GenGlsl.cpp @@ -158,6 +158,7 @@ static void generateGlslCode(GlslType type = GlslType::Glsl400) 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/OpenPbr")); const mx::FilePath logPath("genglsl_" + GlslTypeToString(type) + "_generate_test.txt"); diff --git a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp index 8da7e22fe5..2cd48dd4c4 100644 --- a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp +++ b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp @@ -357,6 +357,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/OpenPbr")); const mx::FilePath logPath("genmdl_mdl_generate_test.txt"); diff --git a/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp b/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp index 03dbcbde69..62c108deca 100644 --- a/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp +++ b/source/MaterialXTest/MaterialXGenMsl/GenMsl.cpp @@ -124,6 +124,7 @@ static void generateMslCode() 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/OpenPbr")); const mx::FilePath logPath("genmsl_msl23_layout_generate_test.txt"); diff --git a/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp b/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp index 13a8b5ffdf..28156a41fe 100644 --- a/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp +++ b/source/MaterialXTest/MaterialXGenOsl/GenOsl.cpp @@ -183,6 +183,7 @@ static void generateOslCode() 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/OpenPbr")); const mx::FilePath logPath("genosl_vanilla_generate_test.txt"); diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp index 5aa1d7aa2d..3ed23848e6 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp @@ -355,6 +355,7 @@ void shaderGenPerformanceTest(mx::GenContext& context) // Read mtlx documents mx::FilePathVec testRootPaths; testRootPaths.push_back("resources/Materials/Examples/StandardSurface"); + testRootPaths.push_back("resources/Materials/Examples/OpenPbr"); std::vector loadedDocuments; mx::StringVec documentsPaths; diff --git a/source/MaterialXView/CMakeLists.txt b/source/MaterialXView/CMakeLists.txt index 1d9a329e46..e3e81a4b09 100644 --- a/source/MaterialXView/CMakeLists.txt +++ b/source/MaterialXView/CMakeLists.txt @@ -70,7 +70,7 @@ else() elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wno-deprecated) elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - add_compile_options(-Wno-format-truncation -Wno-use-after-free) + add_compile_options(-Wno-format-truncation -Wno-stringop-overflow -Wno-use-after-free) endif() # Disable NanoGUI compiler modifications for Clang diff --git a/source/MaterialXView/Main.cpp b/source/MaterialXView/Main.cpp index 904466c065..b2a9403f0f 100644 --- a/source/MaterialXView/Main.cpp +++ b/source/MaterialXView/Main.cpp @@ -72,7 +72,7 @@ int main(int argc, char* const argv[]) tokens.emplace_back(argv[i]); } - std::string materialFilename = "resources/Materials/Examples/StandardSurface/standard_surface_default.mtlx"; + std::string materialFilename = "resources/Materials/Examples/OpenPbr/open_pbr_default.mtlx"; std::string meshFilename = "resources/Geometry/shaderball.glb"; std::string envRadianceFilename = "resources/Lights/san_giuseppe_bridge_split.hdr"; mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath(); From d1c210f315c9616f932c7502276ddc1645c54e2d Mon Sep 17 00:00:00 2001 From: Lee Kerley <154285602+ld-kerley@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:51:32 -0800 Subject: [PATCH 126/128] Backport CC matrix fix to legacy 1.38 branch (#2096) Backporting #1960 to legacy 1.38 branch. This feels like a pretty easy bug fix backport that would be to everyones benefit. --- libraries/cmlib/cmlib_ng.mtlx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/cmlib/cmlib_ng.mtlx b/libraries/cmlib/cmlib_ng.mtlx index 8045e80a4d..7c318f8467 100644 --- a/libraries/cmlib/cmlib_ng.mtlx +++ b/libraries/cmlib/cmlib_ng.mtlx @@ -296,7 +296,7 @@ - + @@ -333,7 +333,7 @@ - + From 7d9d4728a1e11519984aa38fc76c1af900ab7ba3 Mon Sep 17 00:00:00 2001 From: JGamache-autodesk <56274617+JGamache-autodesk@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:53:28 -0500 Subject: [PATCH 127/128] Backport latest translation graphs to 1.38 (#2106) Adds @mkuo-lucasfilm OpenPBR Surface translation networks to the backport. Also includes tweaks for the USD translation and a small doc update for Standard Surface that was part of the translation graph work. --- libraries/bxdf/standard_surface.mtlx | 2 +- .../open_pbr_to_standard_surface.mtlx | 362 ++++++++++++++++++ .../standard_surface_to_open_pbr.mtlx | 309 +++++++++++++++ .../translation/standard_surface_to_usd.mtlx | 15 +- 4 files changed, 685 insertions(+), 3 deletions(-) create mode 100644 libraries/bxdf/translation/open_pbr_to_standard_surface.mtlx create mode 100644 libraries/bxdf/translation/standard_surface_to_open_pbr.mtlx diff --git a/libraries/bxdf/standard_surface.mtlx b/libraries/bxdf/standard_surface.mtlx index c7de68929a..9d4d23551e 100644 --- a/libraries/bxdf/standard_surface.mtlx +++ b/libraries/bxdf/standard_surface.mtlx @@ -81,7 +81,7 @@ + doc="The thickness of the thin film layer on a surface. Use for materials such as multitone car paint or soap bubbles (in nanometers)." /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/bxdf/translation/standard_surface_to_open_pbr.mtlx b/libraries/bxdf/translation/standard_surface_to_open_pbr.mtlx new file mode 100644 index 0000000000..efbe39a053 --- /dev/null +++ b/libraries/bxdf/translation/standard_surface_to_open_pbr.mtlx @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/bxdf/translation/standard_surface_to_usd.mtlx b/libraries/bxdf/translation/standard_surface_to_usd.mtlx index b6e28805dd..5da2457857 100644 --- a/libraries/bxdf/translation/standard_surface_to_usd.mtlx +++ b/libraries/bxdf/translation/standard_surface_to_usd.mtlx @@ -12,6 +12,8 @@ + + @@ -44,13 +46,18 @@ + + + + + - + @@ -74,10 +81,14 @@ - + + + + + From d43cd93551bb74c791352d96f603a1f9a5ef7ffa Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Sat, 23 Nov 2024 15:42:38 -0800 Subject: [PATCH 128/128] Backport update to GitHub CI This changelist backports an update to an Xcode version in our GitHub CI. --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7e01379f54..492110dd88 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -68,10 +68,10 @@ jobs: cmake_config: -DMATERIALX_BUILD_SHARED_LIBS=ON python: 3.9 - - name: MacOS_Xcode_14_Python311 + - name: MacOS_Xcode_15_Python311 os: macos-14 compiler: xcode - compiler_version: "14.3" + compiler_version: "15.1" python: 3.11 static_analysis: ON cmake_config: -DCMAKE_EXPORT_COMPILE_COMMANDS=ON