From cd0295a62e7978120428a6ce682d561b72998db6 Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Thu, 11 Jun 2026 16:35:06 +0200 Subject: [PATCH 01/11] Adjust nodedef to use new values and defaults Note: `useMetaData` requires more clarification and will not be included in the current PR. --- libraries/bxdf/usd_preview_surface.mtlx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/bxdf/usd_preview_surface.mtlx b/libraries/bxdf/usd_preview_surface.mtlx index f89e561c3d..e9aee89fd3 100644 --- a/libraries/bxdf/usd_preview_surface.mtlx +++ b/libraries/bxdf/usd_preview_surface.mtlx @@ -38,8 +38,9 @@ - - + + + From 89b886b062a8fa6d66a24cb6ed6ab68508101b37 Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Sun, 14 Jun 2026 00:03:32 +0200 Subject: [PATCH 02/11] Rename AddressMode enum values and fix default wrap mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renames CONSTANT→BLACK and PERIODIC→REPEAT in ImageSamplingProperties::AddressMode to match standard GPU/USD terminology, and changes the default (UNSPECIFIED) address mode from Repeat to ClampToBorder across GL, Metal, and Slang backends so unspecified samplers black-border rather than tile. --- source/MaterialXRender/ImageHandler.h | 5 +++-- source/MaterialXRenderGlsl/GLTextureHandler.cpp | 2 +- source/MaterialXRenderGlsl/GlslMaterial.cpp | 4 ++-- source/MaterialXRenderGlsl/GlslProgram.cpp | 2 +- source/MaterialXRenderMsl/MetalTextureHandler.mm | 4 ++-- source/MaterialXRenderSlang/SlangTextureHandler.cpp | 5 ++--- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source/MaterialXRender/ImageHandler.h b/source/MaterialXRender/ImageHandler.h index 6510623e63..a1bb94e4ab 100644 --- a/source/MaterialXRender/ImageHandler.h +++ b/source/MaterialXRender/ImageHandler.h @@ -56,10 +56,11 @@ class MX_RENDER_API ImageSamplingProperties enum class AddressMode : int { UNSPECIFIED = -1, - CONSTANT = 0, + BLACK = 0, CLAMP = 1, - PERIODIC = 2, + REPEAT = 2, MIRROR = 3 + // TODO (#2899): Should include the useMetaData enumeration which is implemented in OpenUSD. }; /// Address mode in U diff --git a/source/MaterialXRenderGlsl/GLTextureHandler.cpp b/source/MaterialXRenderGlsl/GLTextureHandler.cpp index 6dd9dee02c..f7bc40712e 100644 --- a/source/MaterialXRenderGlsl/GLTextureHandler.cpp +++ b/source/MaterialXRenderGlsl/GLTextureHandler.cpp @@ -201,7 +201,7 @@ int GLTextureHandler::mapAddressModeToGL(ImageSamplingProperties::AddressMode ad GL_MIRRORED_REPEAT }; - int addressMode = GL_REPEAT; + int addressMode = GL_CLAMP_TO_BORDER; if (addressModeEnum != ImageSamplingProperties::AddressMode::UNSPECIFIED) { addressMode = ADDRESS_MODES[static_cast(addressModeEnum)]; diff --git a/source/MaterialXRenderGlsl/GlslMaterial.cpp b/source/MaterialXRenderGlsl/GlslMaterial.cpp index 4a2826a9a4..0575cf8603 100644 --- a/source/MaterialXRenderGlsl/GlslMaterial.cpp +++ b/source/MaterialXRenderGlsl/GlslMaterial.cpp @@ -266,8 +266,8 @@ void GlslMaterial::bindLighting(LightHandlerPtr lightHandler, ImageHandlerPtr im if (shadowState.ambientOcclusionMap && _glProgram->hasUniform(HW::AMB_OCC_MAP)) { ImageSamplingProperties samplingProperties; - samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; - samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; + samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::REPEAT; + samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::REPEAT; samplingProperties.filterType = ImageSamplingProperties::FilterType::LINEAR; // Bind the ambient occlusion map. diff --git a/source/MaterialXRenderGlsl/GlslProgram.cpp b/source/MaterialXRenderGlsl/GlslProgram.cpp index f3b0a6a469..90956c88a1 100644 --- a/source/MaterialXRenderGlsl/GlslProgram.cpp +++ b/source/MaterialXRenderGlsl/GlslProgram.cpp @@ -605,7 +605,7 @@ void GlslProgram::bindLighting(LightHandlerPtr lightHandler, ImageHandlerPtr ima if (image && hasUniform(env.first)) { ImageSamplingProperties samplingProperties; - samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; + samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::REPEAT; samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::CLAMP; samplingProperties.filterType = ImageSamplingProperties::FilterType::LINEAR; diff --git a/source/MaterialXRenderMsl/MetalTextureHandler.mm b/source/MaterialXRenderMsl/MetalTextureHandler.mm index 7a6167ad59..084a4ab9b7 100644 --- a/source/MaterialXRenderMsl/MetalTextureHandler.mm +++ b/source/MaterialXRenderMsl/MetalTextureHandler.mm @@ -41,7 +41,7 @@ [samplerDesc setSAddressMode:mapAddressModeToMetal(samplingProperties.uaddressMode)]; [samplerDesc setRAddressMode:mapAddressModeToMetal(samplingProperties.uaddressMode)]; [samplerDesc setTAddressMode:mapAddressModeToMetal(samplingProperties.vaddressMode)]; - [samplerDesc setBorderColor:samplingProperties.defaultColor[0] == 0 ? MTLSamplerBorderColorOpaqueBlack : MTLSamplerBorderColorOpaqueWhite]; + [samplerDesc setBorderColor:MTLSamplerBorderColorOpaqueBlack]; MTLSamplerMinMagFilter minmagFilter; MTLSamplerMipFilter mipFilter; mapFilterTypeToMetal(samplingProperties.filterType, samplingProperties.enableMipmaps, minmagFilter, mipFilter); @@ -332,7 +332,7 @@ MTLSamplerAddressModeMirrorRepeat }; - MTLSamplerAddressMode addressMode = MTLSamplerAddressModeRepeat; + MTLSamplerAddressMode addressMode = MTLSamplerAddressModeClampToBorderColor; if (addressModeEnum != ImageSamplingProperties::AddressMode::UNSPECIFIED) { addressMode = addressModes[static_cast(addressModeEnum)]; diff --git a/source/MaterialXRenderSlang/SlangTextureHandler.cpp b/source/MaterialXRenderSlang/SlangTextureHandler.cpp index 2b6d8c1b41..9d6c66573c 100644 --- a/source/MaterialXRenderSlang/SlangTextureHandler.cpp +++ b/source/MaterialXRenderSlang/SlangTextureHandler.cpp @@ -162,12 +162,11 @@ rhi::TextureAddressingMode SlangTextureHandler::mapAddressModeToSlang(ImageSampl switch (addressModeEnum) { case ImageSamplingProperties::AddressMode::UNSPECIFIED: - return rhi::TextureAddressingMode::Wrap; - case ImageSamplingProperties::AddressMode::CONSTANT: + case ImageSamplingProperties::AddressMode::BLACK: return rhi::TextureAddressingMode::ClampToBorder; case ImageSamplingProperties::AddressMode::CLAMP: return rhi::TextureAddressingMode::ClampToEdge; - case ImageSamplingProperties::AddressMode::PERIODIC: + case ImageSamplingProperties::AddressMode::REPEAT: return rhi::TextureAddressingMode::Wrap; case ImageSamplingProperties::AddressMode::MIRROR: return rhi::TextureAddressingMode::MirrorRepeat; From b9e84cd50e5ec8b8e1e31d7937eb2fef326f8c65 Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Sun, 14 Jun 2026 00:09:18 +0200 Subject: [PATCH 03/11] Fix remaining MSL address modes --- source/MaterialXRenderMsl/MslMaterial.mm | 4 ++-- source/MaterialXRenderMsl/MslPipelineStateObject.mm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/MaterialXRenderMsl/MslMaterial.mm b/source/MaterialXRenderMsl/MslMaterial.mm index 54e299ddff..d9c8d97f6f 100644 --- a/source/MaterialXRenderMsl/MslMaterial.mm +++ b/source/MaterialXRenderMsl/MslMaterial.mm @@ -232,8 +232,8 @@ if (shadowState.ambientOcclusionMap && _glProgram->hasUniform(TEXTURE_NAME(HW::AMB_OCC_MAP))) { ImageSamplingProperties samplingProperties; - samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; - samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; + samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::REPEAT; + samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::REPEAT; samplingProperties.filterType = ImageSamplingProperties::FilterType::LINEAR; // Bind the ambient occlusion map. diff --git a/source/MaterialXRenderMsl/MslPipelineStateObject.mm b/source/MaterialXRenderMsl/MslPipelineStateObject.mm index dff7bbc8f1..45812394fa 100644 --- a/source/MaterialXRenderMsl/MslPipelineStateObject.mm +++ b/source/MaterialXRenderMsl/MslPipelineStateObject.mm @@ -716,7 +716,7 @@ int GetStrideOfMetalType(MTLDataType type) if (image) { ImageSamplingProperties samplingProperties; - samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; + samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::REPEAT; samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::CLAMP; samplingProperties.filterType = ImageSamplingProperties::FilterType::LINEAR; bindTexture(imageHandler, uniformName, image, samplingProperties); From 89671af7954c57901f0028847654f32f72cb5c8e Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Sun, 14 Jun 2026 00:15:11 +0200 Subject: [PATCH 04/11] Make black wrap mode the default --- libraries/bxdf/usd_preview_surface.mtlx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/bxdf/usd_preview_surface.mtlx b/libraries/bxdf/usd_preview_surface.mtlx index e9aee89fd3..ae2c6fa9b6 100644 --- a/libraries/bxdf/usd_preview_surface.mtlx +++ b/libraries/bxdf/usd_preview_surface.mtlx @@ -38,9 +38,9 @@ - - - + + + From d76a211cadd80924335225acdd46ee2ded2e8a02 Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Sun, 14 Jun 2026 11:45:40 +0200 Subject: [PATCH 05/11] Add fallback case for useMetaData --- source/MaterialXRender/ImageHandler.h | 3 +- .../MaterialXRenderGlsl/GLTextureHandler.cpp | 5 + .../MaterialXRenderMsl/MetalTextureHandler.mm | 103 ++++++++++++++---- .../SlangTextureHandler.cpp | 2 + 4 files changed, 90 insertions(+), 23 deletions(-) diff --git a/source/MaterialXRender/ImageHandler.h b/source/MaterialXRender/ImageHandler.h index a1bb94e4ab..a15e07970b 100644 --- a/source/MaterialXRender/ImageHandler.h +++ b/source/MaterialXRender/ImageHandler.h @@ -59,7 +59,8 @@ class MX_RENDER_API ImageSamplingProperties BLACK = 0, CLAMP = 1, REPEAT = 2, - MIRROR = 3 + MIRROR = 3, + USE_META_DATA = 4, // TODO (#2899): Should include the useMetaData enumeration which is implemented in OpenUSD. }; diff --git a/source/MaterialXRenderGlsl/GLTextureHandler.cpp b/source/MaterialXRenderGlsl/GLTextureHandler.cpp index f7bc40712e..13da0c0b4f 100644 --- a/source/MaterialXRenderGlsl/GLTextureHandler.cpp +++ b/source/MaterialXRenderGlsl/GLTextureHandler.cpp @@ -202,6 +202,11 @@ int GLTextureHandler::mapAddressModeToGL(ImageSamplingProperties::AddressMode ad }; int addressMode = GL_CLAMP_TO_BORDER; + // useMetaData falls back to black for now. + if (addressModeEnum == ImageSamplingProperties::AddressMode::USE_META_DATA) + { + return addressMode; + } if (addressModeEnum != ImageSamplingProperties::AddressMode::UNSPECIFIED) { addressMode = ADDRESS_MODES[static_cast(addressModeEnum)]; diff --git a/source/MaterialXRenderMsl/MetalTextureHandler.mm b/source/MaterialXRenderMsl/MetalTextureHandler.mm index 084a4ab9b7..d54b3ea63b 100644 --- a/source/MaterialXRenderMsl/MetalTextureHandler.mm +++ b/source/MaterialXRenderMsl/MetalTextureHandler.mm @@ -3,10 +3,12 @@ // SPDX-License-Identifier: Apache-2.0 // +#include "MaterialXRender/ImageHandler.h" #include #include #include +#include #include MATERIALX_NAMESPACE_BEGIN @@ -316,8 +318,7 @@ MTLSamplerAddressMode MetalTextureHandler::mapAddressModeToMetal(ImageSamplingProperties::AddressMode addressModeEnum) { - const vector addressModes - { + const vector addressModes{ // Constant color. Use clamp to border // with border color to achieve this MTLSamplerAddressModeClampToBorderColor, @@ -333,10 +334,16 @@ }; MTLSamplerAddressMode addressMode = MTLSamplerAddressModeClampToBorderColor; + // useMetaData falls back to black for now. + if (addressModeEnum == ImageSamplingProperties::AddressMode::USE_META_DATA) + { + return addressMode; + } if (addressModeEnum != ImageSamplingProperties::AddressMode::UNSPECIFIED) { addressMode = addressModes[static_cast(addressModeEnum)]; } + return addressMode; } @@ -382,44 +389,96 @@ dataType = MTLDataTypeChar; switch (channelCount) { - case 4: pixelFormat = srgb ? MTLPixelFormatRGBA8Unorm_sRGB : MTLPixelFormatRGBA8Unorm; dataType = MTLDataTypeChar4; break; - case 3: pixelFormat = srgb ? MTLPixelFormatRGBA8Unorm_sRGB : MTLPixelFormatRGBA8Unorm; dataType = MTLDataTypeChar3; break; - case 2: pixelFormat = MTLPixelFormatRG8Unorm; dataType = MTLDataTypeChar2; break; - case 1: pixelFormat = MTLPixelFormatR8Unorm; dataType = MTLDataTypeChar; break; - default: throw Exception("Unsupported channel count in mapTextureFormatToMetal"); + case 4: + pixelFormat = srgb ? MTLPixelFormatRGBA8Unorm_sRGB : MTLPixelFormatRGBA8Unorm; + dataType = MTLDataTypeChar4; + break; + case 3: + pixelFormat = srgb ? MTLPixelFormatRGBA8Unorm_sRGB : MTLPixelFormatRGBA8Unorm; + dataType = MTLDataTypeChar3; + break; + case 2: + pixelFormat = MTLPixelFormatRG8Unorm; + dataType = MTLDataTypeChar2; + break; + case 1: + pixelFormat = MTLPixelFormatR8Unorm; + dataType = MTLDataTypeChar; + break; + default: + throw Exception("Unsupported channel count in mapTextureFormatToMetal"); } } else if (baseType == Image::BaseType::UINT16) { switch (channelCount) { - case 4: pixelFormat = MTLPixelFormatRGBA16Uint; dataType = MTLDataTypeShort4; break; - case 3: pixelFormat = MTLPixelFormatRGBA16Uint; dataType = MTLDataTypeShort3; break; - case 2: pixelFormat = MTLPixelFormatRG16Uint; dataType = MTLDataTypeShort2; break; - case 1: pixelFormat = MTLPixelFormatR16Uint; dataType = MTLDataTypeShort; break; - default: throw Exception("Unsupported channel count in mapTextureFormatToMetal"); + case 4: + pixelFormat = MTLPixelFormatRGBA16Uint; + dataType = MTLDataTypeShort4; + break; + case 3: + pixelFormat = MTLPixelFormatRGBA16Uint; + dataType = MTLDataTypeShort3; + break; + case 2: + pixelFormat = MTLPixelFormatRG16Uint; + dataType = MTLDataTypeShort2; + break; + case 1: + pixelFormat = MTLPixelFormatR16Uint; + dataType = MTLDataTypeShort; + break; + default: + throw Exception("Unsupported channel count in mapTextureFormatToMetal"); } } else if (baseType == Image::BaseType::HALF) { switch (channelCount) { - case 4: pixelFormat = MTLPixelFormatRGBA16Float; dataType = MTLDataTypeHalf4; break; - case 3: pixelFormat = MTLPixelFormatRGBA16Float; dataType = MTLDataTypeHalf3; break; - case 2: pixelFormat = MTLPixelFormatRG16Float; dataType = MTLDataTypeHalf2; break; - case 1: pixelFormat = MTLPixelFormatR16Float; dataType = MTLDataTypeHalf ; break; - default: throw Exception("Unsupported channel count in mapTextureFormatToMetal"); + case 4: + pixelFormat = MTLPixelFormatRGBA16Float; + dataType = MTLDataTypeHalf4; + break; + case 3: + pixelFormat = MTLPixelFormatRGBA16Float; + dataType = MTLDataTypeHalf3; + break; + case 2: + pixelFormat = MTLPixelFormatRG16Float; + dataType = MTLDataTypeHalf2; + break; + case 1: + pixelFormat = MTLPixelFormatR16Float; + dataType = MTLDataTypeHalf; + break; + default: + throw Exception("Unsupported channel count in mapTextureFormatToMetal"); } } else if (baseType == Image::BaseType::FLOAT) { switch (channelCount) { - case 4: pixelFormat = MTLPixelFormatRGBA32Float; dataType = MTLDataTypeFloat4; break; - case 3: pixelFormat = MTLPixelFormatRGBA32Float; dataType = MTLDataTypeFloat3; break; - case 2: pixelFormat = MTLPixelFormatRG32Float; dataType = MTLDataTypeFloat2; break; - case 1: pixelFormat = MTLPixelFormatR32Float; dataType = MTLDataTypeFloat; break; - default: throw Exception("Unsupported channel count in mapTextureFormatToMetal"); + case 4: + pixelFormat = MTLPixelFormatRGBA32Float; + dataType = MTLDataTypeFloat4; + break; + case 3: + pixelFormat = MTLPixelFormatRGBA32Float; + dataType = MTLDataTypeFloat3; + break; + case 2: + pixelFormat = MTLPixelFormatRG32Float; + dataType = MTLDataTypeFloat2; + break; + case 1: + pixelFormat = MTLPixelFormatR32Float; + dataType = MTLDataTypeFloat; + break; + default: + throw Exception("Unsupported channel count in mapTextureFormatToMetal"); } } else diff --git a/source/MaterialXRenderSlang/SlangTextureHandler.cpp b/source/MaterialXRenderSlang/SlangTextureHandler.cpp index 9d6c66573c..76359f77f0 100644 --- a/source/MaterialXRenderSlang/SlangTextureHandler.cpp +++ b/source/MaterialXRenderSlang/SlangTextureHandler.cpp @@ -162,6 +162,8 @@ rhi::TextureAddressingMode SlangTextureHandler::mapAddressModeToSlang(ImageSampl switch (addressModeEnum) { case ImageSamplingProperties::AddressMode::UNSPECIFIED: + // useMetaData falls back to black for now + case ImageSamplingProperties::AddressMode::USE_META_DATA: case ImageSamplingProperties::AddressMode::BLACK: return rhi::TextureAddressingMode::ClampToBorder; case ImageSamplingProperties::AddressMode::CLAMP: From da68906c97586fbcf230f20690dbf3c9ed77b070 Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Sun, 14 Jun 2026 12:05:07 +0200 Subject: [PATCH 06/11] Add new test cases --- .../definition/definition_using_definitions.mtlx | 12 ++++++------ .../TestSuite/stdlib/texture/image_addressing.mtlx | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/resources/Materials/TestSuite/stdlib/definition/definition_using_definitions.mtlx b/resources/Materials/TestSuite/stdlib/definition/definition_using_definitions.mtlx index 55a8cfa707..06dab7bf6e 100644 --- a/resources/Materials/TestSuite/stdlib/definition/definition_using_definitions.mtlx +++ b/resources/Materials/TestSuite/stdlib/definition/definition_using_definitions.mtlx @@ -176,8 +176,8 @@ - - + + @@ -232,8 +232,8 @@ - - + + @@ -288,8 +288,8 @@ - - + + diff --git a/resources/Materials/TestSuite/stdlib/texture/image_addressing.mtlx b/resources/Materials/TestSuite/stdlib/texture/image_addressing.mtlx index 5f99395bce..422c98a718 100644 --- a/resources/Materials/TestSuite/stdlib/texture/image_addressing.mtlx +++ b/resources/Materials/TestSuite/stdlib/texture/image_addressing.mtlx @@ -37,7 +37,7 @@ - + @@ -53,7 +53,7 @@ - + @@ -68,8 +68,8 @@ - - + + From a110a7a346b91f07be67f845bc6c1b1017009392 Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Sun, 14 Jun 2026 12:05:41 +0200 Subject: [PATCH 07/11] Adjust library documents --- libraries/bxdf/gltf_pbr.mtlx | 40 +++++----- libraries/bxdf/usd_preview_surface.mtlx | 5 +- libraries/stdlib/stdlib_defs.mtlx | 24 +++--- libraries/stdlib/stdlib_ng.mtlx | 98 ++++++++++++------------- 4 files changed, 83 insertions(+), 84 deletions(-) diff --git a/libraries/bxdf/gltf_pbr.mtlx b/libraries/bxdf/gltf_pbr.mtlx index edc7d40ec1..893aedf0ae 100644 --- a/libraries/bxdf/gltf_pbr.mtlx +++ b/libraries/bxdf/gltf_pbr.mtlx @@ -377,8 +377,8 @@ - - + + @@ -396,8 +396,8 @@ - - + + @@ -437,8 +437,8 @@ - - + + @@ -492,8 +492,8 @@ - - + + @@ -547,8 +547,8 @@ - - + + @@ -601,8 +601,8 @@ - - + + @@ -651,8 +651,8 @@ - - + + @@ -703,8 +703,8 @@ - - + + @@ -747,8 +747,8 @@ - - + + @@ -766,8 +766,8 @@ - - + + diff --git a/libraries/bxdf/usd_preview_surface.mtlx b/libraries/bxdf/usd_preview_surface.mtlx index ae2c6fa9b6..e17c27007f 100644 --- a/libraries/bxdf/usd_preview_surface.mtlx +++ b/libraries/bxdf/usd_preview_surface.mtlx @@ -38,9 +38,8 @@ - - - + + diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index aa12006e8e..5d8b60b197 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -128,8 +128,8 @@ - - + + @@ -141,8 +141,8 @@ - - + + @@ -154,8 +154,8 @@ - - + + @@ -167,8 +167,8 @@ - - + + @@ -180,8 +180,8 @@ - - + + @@ -193,8 +193,8 @@ - - + + diff --git a/libraries/stdlib/stdlib_ng.mtlx b/libraries/stdlib/stdlib_ng.mtlx index 5b9b592ffb..6062e2e2e2 100644 --- a/libraries/stdlib/stdlib_ng.mtlx +++ b/libraries/stdlib/stdlib_ng.mtlx @@ -35,8 +35,8 @@ - - + + @@ -65,8 +65,8 @@ - - + + @@ -95,8 +95,8 @@ - - + + @@ -125,8 +125,8 @@ - - + + @@ -155,8 +155,8 @@ - - + + @@ -185,8 +185,8 @@ - - + + @@ -241,7 +241,7 @@ - + @@ -318,8 +318,8 @@ - - + + @@ -330,8 +330,8 @@ - - + + @@ -342,8 +342,8 @@ - - + + @@ -472,8 +472,8 @@ - - + + @@ -484,8 +484,8 @@ - - + + @@ -496,8 +496,8 @@ - - + + @@ -626,8 +626,8 @@ - - + + @@ -638,8 +638,8 @@ - - + + @@ -650,8 +650,8 @@ - - + + @@ -780,8 +780,8 @@ - - + + @@ -792,8 +792,8 @@ - - + + @@ -804,8 +804,8 @@ - - + + @@ -934,8 +934,8 @@ - - + + @@ -946,8 +946,8 @@ - - + + @@ -958,8 +958,8 @@ - - + + @@ -1088,8 +1088,8 @@ - - + + @@ -1100,8 +1100,8 @@ - - + + @@ -1112,8 +1112,8 @@ - - + + From 54699a1d6c4cec771d5ee135bf44881a7feed215 Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Sun, 14 Jun 2026 12:08:55 +0200 Subject: [PATCH 08/11] Versioning: map old constant and periodic to black and repeat --- source/MaterialXCore/Version.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/source/MaterialXCore/Version.cpp b/source/MaterialXCore/Version.cpp index 689b9cf720..1e116efe96 100644 --- a/source/MaterialXCore/Version.cpp +++ b/source/MaterialXCore/Version.cpp @@ -1436,6 +1436,34 @@ void Document::upgradeVersion() node->getParent()->removeChild(node->getName()); } + // Rename image address mode values to align with OpenUSD terminology. + const std::unordered_map ADDRESS_MODE_RENAME = + { + { "constant", "black" }, + { "periodic", "repeat" } + }; + for (ElementPtr elem : traverseTree()) + { + NodePtr node = elem->asA(); + if (!node) + { + continue; + } + for (const string& inputName : { string("uaddressmode"), string("vaddressmode"), + string("wrapS"), string("wrapT") }) + { + InputPtr input = node->getInput(inputName); + if (input) + { + auto it = ADDRESS_MODE_RENAME.find(input->getValueString()); + if (it != ADDRESS_MODE_RENAME.end()) + { + input->setValueString(it->second); + } + } + } + } + minorVersion = 39; } From 2b4c738585a8e1f5f0651e2eb5429966f504721e Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Sun, 14 Jun 2026 12:31:29 +0200 Subject: [PATCH 09/11] Change remaining enum case --- source/MaterialXView/RenderPipelineGL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/MaterialXView/RenderPipelineGL.cpp b/source/MaterialXView/RenderPipelineGL.cpp index 74b300b53d..df3ca4eb02 100644 --- a/source/MaterialXView/RenderPipelineGL.cpp +++ b/source/MaterialXView/RenderPipelineGL.cpp @@ -162,7 +162,7 @@ void GLRenderPipeline::updatePrefilteredMap() // Bind the source texture mx::ImageSamplingProperties samplingProperties; - samplingProperties.uaddressMode = mx::ImageSamplingProperties::AddressMode::PERIODIC; + samplingProperties.uaddressMode = mx::ImageSamplingProperties::AddressMode::REPEAT; samplingProperties.vaddressMode = mx::ImageSamplingProperties::AddressMode::CLAMP; samplingProperties.filterType = mx::ImageSamplingProperties::FilterType::LINEAR; imageHandler->bindImage(srcTex, samplingProperties); From 13798a16b3fcc85e8b3610d62ef2ecda000f4b0d Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Sun, 14 Jun 2026 14:47:34 +0200 Subject: [PATCH 10/11] Remove header --- source/MaterialXRenderMsl/MetalTextureHandler.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/source/MaterialXRenderMsl/MetalTextureHandler.mm b/source/MaterialXRenderMsl/MetalTextureHandler.mm index d54b3ea63b..b904e475f3 100644 --- a/source/MaterialXRenderMsl/MetalTextureHandler.mm +++ b/source/MaterialXRenderMsl/MetalTextureHandler.mm @@ -8,7 +8,6 @@ #include #include -#include #include MATERIALX_NAMESPACE_BEGIN From ef0deda0b15127869e2766cd3ff4740e11da9576 Mon Sep 17 00:00:00 2001 From: Benjamin Beilharz Date: Fri, 19 Jun 2026 10:43:32 +0200 Subject: [PATCH 11/11] Restrict USD wrap mode changes to UsdUVTexture, keep constant/black distinct Per review feedback: revert the address-mode renaming in gltf_pbr.mtlx, stdlib_ng.mtlx, and the affected test resources, since only UsdUVTexture should pick up the OpenUSD wrap mode naming. The generic image node keeps its original "constant"/"periodic" defaults, with "black", "repeat", and "useMetaData" added as new enum options rather than replacements, so UsdUVTexture's wrapS/wrapT can still pass through to the inner image node. AddressMode in ImageHandler.h now keeps CONSTANT and PERIODIC alongside the new BLACK, REPEAT, and USE_META_DATA values, since constant (clamp to a configurable default color) and black (always clamp to black) are not interchangeable. Updated the GL/Metal/Slang texture handlers accordingly, and the 1.39 upgrade path no longer rewrites "constant" to "black". --- libraries/bxdf/gltf_pbr.mtlx | 40 +++--- libraries/stdlib/stdlib_defs.mtlx | 24 ++-- libraries/stdlib/stdlib_ng.mtlx | 98 ++++++------- .../definition_using_definitions.mtlx | 12 +- .../stdlib/texture/image_addressing.mtlx | 8 +- source/MaterialXCore/Version.cpp | 63 ++++---- source/MaterialXRender/ImageHandler.h | 15 +- .../MaterialXRenderGlsl/GLTextureHandler.cpp | 128 ++++++++++++----- source/MaterialXRenderGlsl/GlslMaterial.cpp | 4 +- source/MaterialXRenderGlsl/GlslProgram.cpp | 41 ++---- .../MaterialXRenderMsl/MetalTextureHandler.mm | 29 ++-- source/MaterialXRenderMsl/MslMaterial.mm | 4 +- .../MslPipelineStateObject.mm | 136 ++++++++---------- .../SlangTextureHandler.cpp | 16 ++- source/MaterialXView/RenderPipelineGL.cpp | 63 ++++---- 15 files changed, 351 insertions(+), 330 deletions(-) diff --git a/libraries/bxdf/gltf_pbr.mtlx b/libraries/bxdf/gltf_pbr.mtlx index 893aedf0ae..edc7d40ec1 100644 --- a/libraries/bxdf/gltf_pbr.mtlx +++ b/libraries/bxdf/gltf_pbr.mtlx @@ -377,8 +377,8 @@ - - + + @@ -396,8 +396,8 @@ - - + + @@ -437,8 +437,8 @@ - - + + @@ -492,8 +492,8 @@ - - + + @@ -547,8 +547,8 @@ - - + + @@ -601,8 +601,8 @@ - - + + @@ -651,8 +651,8 @@ - - + + @@ -703,8 +703,8 @@ - - + + @@ -747,8 +747,8 @@ - - + + @@ -766,8 +766,8 @@ - - + + diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index 5d8b60b197..1a19bd95f1 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -128,8 +128,8 @@ - - + + @@ -141,8 +141,8 @@ - - + + @@ -154,8 +154,8 @@ - - + + @@ -167,8 +167,8 @@ - - + + @@ -180,8 +180,8 @@ - - + + @@ -193,8 +193,8 @@ - - + + diff --git a/libraries/stdlib/stdlib_ng.mtlx b/libraries/stdlib/stdlib_ng.mtlx index 6062e2e2e2..5b9b592ffb 100644 --- a/libraries/stdlib/stdlib_ng.mtlx +++ b/libraries/stdlib/stdlib_ng.mtlx @@ -35,8 +35,8 @@ - - + + @@ -65,8 +65,8 @@ - - + + @@ -95,8 +95,8 @@ - - + + @@ -125,8 +125,8 @@ - - + + @@ -155,8 +155,8 @@ - - + + @@ -185,8 +185,8 @@ - - + + @@ -241,7 +241,7 @@ - + @@ -318,8 +318,8 @@ - - + + @@ -330,8 +330,8 @@ - - + + @@ -342,8 +342,8 @@ - - + + @@ -472,8 +472,8 @@ - - + + @@ -484,8 +484,8 @@ - - + + @@ -496,8 +496,8 @@ - - + + @@ -626,8 +626,8 @@ - - + + @@ -638,8 +638,8 @@ - - + + @@ -650,8 +650,8 @@ - - + + @@ -780,8 +780,8 @@ - - + + @@ -792,8 +792,8 @@ - - + + @@ -804,8 +804,8 @@ - - + + @@ -934,8 +934,8 @@ - - + + @@ -946,8 +946,8 @@ - - + + @@ -958,8 +958,8 @@ - - + + @@ -1088,8 +1088,8 @@ - - + + @@ -1100,8 +1100,8 @@ - - + + @@ -1112,8 +1112,8 @@ - - + + diff --git a/resources/Materials/TestSuite/stdlib/definition/definition_using_definitions.mtlx b/resources/Materials/TestSuite/stdlib/definition/definition_using_definitions.mtlx index 06dab7bf6e..55a8cfa707 100644 --- a/resources/Materials/TestSuite/stdlib/definition/definition_using_definitions.mtlx +++ b/resources/Materials/TestSuite/stdlib/definition/definition_using_definitions.mtlx @@ -176,8 +176,8 @@ - - + + @@ -232,8 +232,8 @@ - - + + @@ -288,8 +288,8 @@ - - + + diff --git a/resources/Materials/TestSuite/stdlib/texture/image_addressing.mtlx b/resources/Materials/TestSuite/stdlib/texture/image_addressing.mtlx index 422c98a718..5f99395bce 100644 --- a/resources/Materials/TestSuite/stdlib/texture/image_addressing.mtlx +++ b/resources/Materials/TestSuite/stdlib/texture/image_addressing.mtlx @@ -37,7 +37,7 @@ - + @@ -53,7 +53,7 @@ - + @@ -68,8 +68,8 @@ - - + + diff --git a/source/MaterialXCore/Version.cpp b/source/MaterialXCore/Version.cpp index 1e116efe96..51bc48fd74 100644 --- a/source/MaterialXCore/Version.cpp +++ b/source/MaterialXCore/Version.cpp @@ -977,34 +977,24 @@ void Document::upgradeVersion() // Upgrade from 1.38 to 1.39 if (majorVersion == 1 && minorVersion == 38) { - const std::unordered_map CHANNEL_INDEX_MAP = - { - { 'r', 0 }, { 'g', 1 }, { 'b', 2 }, { 'a', 3 }, - { 'x', 0 }, { 'y', 1 }, { 'z', 2 }, { 'w', 3 } + const std::unordered_map CHANNEL_INDEX_MAP = { + { 'r', 0 }, { 'g', 1 }, { 'b', 2 }, { 'a', 3 }, { 'x', 0 }, { 'y', 1 }, { 'z', 2 }, { 'w', 3 } }; - const std::unordered_map CHANNEL_CONSTANT_MAP = - { + const std::unordered_map CHANNEL_CONSTANT_MAP = { { '0', 0.0f }, { '1', 1.0f } }; - const std::unordered_map CHANNEL_COUNT_MAP = - { + const std::unordered_map CHANNEL_COUNT_MAP = { { "float", 1 }, - { "color3", 3 }, { "color4", 4 }, - { "vector2", 2 }, { "vector3", 3 }, { "vector4", 4 } + { "color3", 3 }, + { "color4", 4 }, + { "vector2", 2 }, + { "vector3", 3 }, + { "vector4", 4 } }; - const std::array, 10> CHANNEL_CONVERT_PATTERNS = - { { - { "rgb", 3 }, { "rgb", 4 }, { "rgba", 4 }, - { "xyz", 3 }, { "xyz", 4 }, { "xyzw", 4 }, - { "rr", 1 }, { "rrr", 1 }, - { "xx", 1 }, { "xxx", 1 } - } }; - const std::array, 3> CHANNEL_ATTRIBUTE_PATTERNS = - { { - { { "xx", "xxx", "xxxx" }, "float" }, - { { "xyz", "x", "y", "z" }, "vector3" }, - { { "rgba", "a" }, "color4" } - } }; + const std::array, 10> CHANNEL_CONVERT_PATTERNS = { { { "rgb", 3 }, { "rgb", 4 }, { "rgba", 4 }, { "xyz", 3 }, { "xyz", 4 }, { "xyzw", 4 }, { "rr", 1 }, { "rrr", 1 }, { "xx", 1 }, { "xxx", 1 } } }; + const std::array, 3> CHANNEL_ATTRIBUTE_PATTERNS = { { { { "xx", "xxx", "xxxx" }, "float" }, + { { "xyz", "x", "y", "z" }, "vector3" }, + { { "rgba", "a" }, "color4" } } }; // Convert channels attributes to legacy swizzle nodes, which are then converted // to modern nodes in a second pass. @@ -1281,7 +1271,7 @@ void Document::upgradeVersion() } } else if (sourceType != destType && std::find(CHANNEL_CONVERT_PATTERNS.begin(), CHANNEL_CONVERT_PATTERNS.end(), - std::make_pair(channelString, sourceChannelCount)) != CHANNEL_CONVERT_PATTERNS.end()) + std::make_pair(channelString, sourceChannelCount)) != CHANNEL_CONVERT_PATTERNS.end()) { // Replace swizzle with convert. node->setCategory("convert"); @@ -1405,7 +1395,7 @@ void Document::upgradeVersion() // Clear tangent-space input. node->removeInput("space"); - // If the normal or tangent inputs are set and the bitangent input is not, + // If the normal or tangent inputs are set and the bitangent input is not, // the bitangent should be set to normalize(cross(N, T)) InputPtr normalInput = node->getInput("normal"); InputPtr tangentInput = node->getInput("tangent"); @@ -1436,12 +1426,12 @@ void Document::upgradeVersion() node->getParent()->removeChild(node->getName()); } - // Rename image address mode values to align with OpenUSD terminology. - const std::unordered_map ADDRESS_MODE_RENAME = - { - { "constant", "black" }, - { "periodic", "repeat" } - }; + // Rename the UsdUVTexture "periodic" wrap mode to "repeat", aligning with the + // terminology used by the OpenUSD UsdUVTexture schema. This is purely a naming + // change: "periodic" and "repeat" describe identical sampling behavior. Unlike + // "periodic"/"repeat", "constant" and "black" are not interchangeable -- "constant" + // clamps to the node's configurable default color, while "black" always clamps to + // black -- so no rename is applied for that case. for (ElementPtr elem : traverseTree()) { NodePtr node = elem->asA(); @@ -1449,17 +1439,12 @@ void Document::upgradeVersion() { continue; } - for (const string& inputName : { string("uaddressmode"), string("vaddressmode"), - string("wrapS"), string("wrapT") }) + for (const string& inputName : { string("wrapS"), string("wrapT") }) { InputPtr input = node->getInput(inputName); - if (input) + if (input && input->getValueString() == "periodic") { - auto it = ADDRESS_MODE_RENAME.find(input->getValueString()); - if (it != ADDRESS_MODE_RENAME.end()) - { - input->setValueString(it->second); - } + input->setValueString("repeat"); } } } diff --git a/source/MaterialXRender/ImageHandler.h b/source/MaterialXRender/ImageHandler.h index a15e07970b..a0c7581a43 100644 --- a/source/MaterialXRender/ImageHandler.h +++ b/source/MaterialXRender/ImageHandler.h @@ -56,12 +56,13 @@ class MX_RENDER_API ImageSamplingProperties enum class AddressMode : int { UNSPECIFIED = -1, - BLACK = 0, + CONSTANT = 0, CLAMP = 1, - REPEAT = 2, + PERIODIC = 2, MIRROR = 3, - USE_META_DATA = 4, - // TODO (#2899): Should include the useMetaData enumeration which is implemented in OpenUSD. + BLACK = 4, + REPEAT = 5, + USE_META_DATA = 6 }; /// Address mode in U @@ -96,11 +97,11 @@ struct MX_RENDER_API ImageSamplingKeyHasher { size_t operator()(const ImageSamplingProperties& k) const { - return (size_t) k.enableMipmaps + // 1 bit - (((size_t) k.filterType & 3) << 1) + // 2 bit + return (size_t) k.enableMipmaps + // 1 bit + (((size_t) k.filterType & 3) << 1) + // 2 bit ((((size_t) k.uaddressMode + 1) & 7) << 3) + // 3 bit ((((size_t) k.vaddressMode + 1) & 7) << 6) + // 3 bit - ((((size_t) k.defaultColor[0] + 1)) << 9) ; + ((((size_t) k.defaultColor[0] + 1)) << 9); } }; diff --git a/source/MaterialXRenderGlsl/GLTextureHandler.cpp b/source/MaterialXRenderGlsl/GLTextureHandler.cpp index 13da0c0b4f..d6b465861c 100644 --- a/source/MaterialXRenderGlsl/GLTextureHandler.cpp +++ b/source/MaterialXRenderGlsl/GLTextureHandler.cpp @@ -64,7 +64,15 @@ bool GLTextureHandler::bindImage(ImagePtr image, const ImageSamplingProperties& GLint magFilterType = mapFilterTypeToGL(samplingProperties.filterType); GLint uaddressMode = mapAddressModeToGL(samplingProperties.uaddressMode); GLint vaddressMode = mapAddressModeToGL(samplingProperties.vaddressMode); - Color4 borderColor(samplingProperties.defaultColor); + + // The "black" and "useMetaData" address modes always clamp to a black border, + // regardless of the node's configured default color. The "constant" address + // mode instead clamps to the node's default color as its border. + bool forceBlackBorder = (samplingProperties.uaddressMode == ImageSamplingProperties::AddressMode::BLACK || + samplingProperties.uaddressMode == ImageSamplingProperties::AddressMode::USE_META_DATA || + samplingProperties.vaddressMode == ImageSamplingProperties::AddressMode::BLACK || + samplingProperties.vaddressMode == ImageSamplingProperties::AddressMode::USE_META_DATA); + Color4 borderColor = forceBlackBorder ? Color4(0.0f, 0.0f, 0.0f, 0.0f) : Color4(samplingProperties.defaultColor); glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor.data()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, uaddressMode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, vaddressMode); @@ -185,8 +193,7 @@ int GLTextureHandler::getNextAvailableTextureLocation() int GLTextureHandler::mapAddressModeToGL(ImageSamplingProperties::AddressMode addressModeEnum) { - const std::array ADDRESS_MODES - { + const std::array ADDRESS_MODES{ // Constant color. Use clamp to border // with border color to achieve this GL_CLAMP_TO_BORDER, @@ -194,19 +201,23 @@ int GLTextureHandler::mapAddressModeToGL(ImageSamplingProperties::AddressMode ad // Clamp GL_CLAMP_TO_EDGE, - // Repeat + // Periodic GL_REPEAT, // Mirror - GL_MIRRORED_REPEAT + GL_MIRRORED_REPEAT, + + // Black. Use clamp to border with a black border color to achieve this. + GL_CLAMP_TO_BORDER, + + // Repeat + GL_REPEAT, + + // useMetaData falls back to black for now. + GL_CLAMP_TO_BORDER }; - int addressMode = GL_CLAMP_TO_BORDER; - // useMetaData falls back to black for now. - if (addressModeEnum == ImageSamplingProperties::AddressMode::USE_META_DATA) - { - return addressMode; - } + int addressMode = GL_REPEAT; if (addressModeEnum != ImageSamplingProperties::AddressMode::UNSPECIFIED) { addressMode = ADDRESS_MODES[static_cast(addressModeEnum)]; @@ -228,11 +239,20 @@ void GLTextureHandler::mapTextureFormatToGL(Image::BaseType baseType, unsigned i { switch (channelCount) { - case 4: glFormat = GL_RGBA; break; - case 3: glFormat = GL_RGB; break; - case 2: glFormat = GL_RG; break; - case 1: glFormat = GL_RED; break; - default: throw Exception("Unsupported channel count in mapTextureFormatToGL"); + case 4: + glFormat = GL_RGBA; + break; + case 3: + glFormat = GL_RGB; + break; + case 2: + glFormat = GL_RG; + break; + case 1: + glFormat = GL_RED; + break; + default: + throw Exception("Unsupported channel count in mapTextureFormatToGL"); } if (baseType == Image::BaseType::UINT8 || baseType == Image::BaseType::INT8) @@ -240,11 +260,20 @@ void GLTextureHandler::mapTextureFormatToGL(Image::BaseType baseType, unsigned i glType = baseType == Image::BaseType::UINT8 ? GL_UNSIGNED_BYTE : GL_BYTE; switch (channelCount) { - case 4: glInternalFormat = srgb ? GL_SRGB8_ALPHA8 : GL_RGBA8; break; - case 3: glInternalFormat = srgb ? GL_SRGB8 : GL_RGB8; break; - case 2: glInternalFormat = GL_RG8; break; - case 1: glInternalFormat = GL_R8; break; - default: throw Exception("Unsupported channel count in mapTextureFormatToGL"); + case 4: + glInternalFormat = srgb ? GL_SRGB8_ALPHA8 : GL_RGBA8; + break; + case 3: + glInternalFormat = srgb ? GL_SRGB8 : GL_RGB8; + break; + case 2: + glInternalFormat = GL_RG8; + break; + case 1: + glInternalFormat = GL_R8; + break; + default: + throw Exception("Unsupported channel count in mapTextureFormatToGL"); } } else if (baseType == Image::BaseType::UINT16 || baseType == Image::BaseType::INT16) @@ -252,11 +281,20 @@ void GLTextureHandler::mapTextureFormatToGL(Image::BaseType baseType, unsigned i glType = baseType == Image::BaseType::UINT16 ? GL_UNSIGNED_SHORT : GL_SHORT; switch (channelCount) { - case 4: glInternalFormat = GL_RGBA16; break; - case 3: glInternalFormat = GL_RGB16; break; - case 2: glInternalFormat = GL_RG16; break; - case 1: glInternalFormat = GL_R16; break; - default: throw Exception("Unsupported channel count in mapTextureFormatToGL"); + case 4: + glInternalFormat = GL_RGBA16; + break; + case 3: + glInternalFormat = GL_RGB16; + break; + case 2: + glInternalFormat = GL_RG16; + break; + case 1: + glInternalFormat = GL_R16; + break; + default: + throw Exception("Unsupported channel count in mapTextureFormatToGL"); } } else if (baseType == Image::BaseType::HALF) @@ -264,11 +302,20 @@ void GLTextureHandler::mapTextureFormatToGL(Image::BaseType baseType, unsigned i glType = GL_HALF_FLOAT; switch (channelCount) { - case 4: glInternalFormat = GL_RGBA16F; break; - case 3: glInternalFormat = GL_RGB16F; break; - case 2: glInternalFormat = GL_RG16F; break; - case 1: glInternalFormat = GL_R16F; break; - default: throw Exception("Unsupported channel count in mapTextureFormatToGL"); + case 4: + glInternalFormat = GL_RGBA16F; + break; + case 3: + glInternalFormat = GL_RGB16F; + break; + case 2: + glInternalFormat = GL_RG16F; + break; + case 1: + glInternalFormat = GL_R16F; + break; + default: + throw Exception("Unsupported channel count in mapTextureFormatToGL"); } } else if (baseType == Image::BaseType::FLOAT) @@ -276,11 +323,20 @@ void GLTextureHandler::mapTextureFormatToGL(Image::BaseType baseType, unsigned i glType = GL_FLOAT; switch (channelCount) { - case 4: glInternalFormat = GL_RGBA32F; break; - case 3: glInternalFormat = GL_RGB32F; break; - case 2: glInternalFormat = GL_RG32F; break; - case 1: glInternalFormat = GL_R32F; break; - default: throw Exception("Unsupported channel count in mapTextureFormatToGL"); + case 4: + glInternalFormat = GL_RGBA32F; + break; + case 3: + glInternalFormat = GL_RGB32F; + break; + case 2: + glInternalFormat = GL_RG32F; + break; + case 1: + glInternalFormat = GL_R32F; + break; + default: + throw Exception("Unsupported channel count in mapTextureFormatToGL"); } } else diff --git a/source/MaterialXRenderGlsl/GlslMaterial.cpp b/source/MaterialXRenderGlsl/GlslMaterial.cpp index 0575cf8603..4a2826a9a4 100644 --- a/source/MaterialXRenderGlsl/GlslMaterial.cpp +++ b/source/MaterialXRenderGlsl/GlslMaterial.cpp @@ -266,8 +266,8 @@ void GlslMaterial::bindLighting(LightHandlerPtr lightHandler, ImageHandlerPtr im if (shadowState.ambientOcclusionMap && _glProgram->hasUniform(HW::AMB_OCC_MAP)) { ImageSamplingProperties samplingProperties; - samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::REPEAT; - samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::REPEAT; + samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; + samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; samplingProperties.filterType = ImageSamplingProperties::FilterType::LINEAR; // Bind the ambient occlusion map. diff --git a/source/MaterialXRenderGlsl/GlslProgram.cpp b/source/MaterialXRenderGlsl/GlslProgram.cpp index 90956c88a1..cba9684b13 100644 --- a/source/MaterialXRenderGlsl/GlslProgram.cpp +++ b/source/MaterialXRenderGlsl/GlslProgram.cpp @@ -585,16 +585,13 @@ void GlslProgram::bindLighting(LightHandlerPtr lightHandler, ImageHandlerPtr ima ImagePtr envRadiance = nullptr; if (lightHandler->getIndirectLighting()) { - envRadiance = lightHandler->getUsePrefilteredMap() ? - lightHandler->getEnvPrefilteredMap() : - lightHandler->getEnvRadianceMap(); + envRadiance = lightHandler->getUsePrefilteredMap() ? lightHandler->getEnvPrefilteredMap() : lightHandler->getEnvRadianceMap(); } else { envRadiance = imageHandler->getZeroImage(); } - ImageMap envImages = - { + ImageMap envImages = { { HW::ENV_RADIANCE, envRadiance }, { HW::ENV_IRRADIANCE, lightHandler->getIndirectLighting() ? lightHandler->getEnvIrradianceMap() : imageHandler->getZeroImage() } }; @@ -605,7 +602,7 @@ void GlslProgram::bindLighting(LightHandlerPtr lightHandler, ImageHandlerPtr ima if (image && hasUniform(env.first)) { ImageSamplingProperties samplingProperties; - samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::REPEAT; + samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::CLAMP; samplingProperties.filterType = ImageSamplingProperties::FilterType::LINEAR; @@ -956,12 +953,10 @@ const GlslProgram::InputMap& GlslProgram::updateUniformsList() const auto& variableSemantic = v->getSemantic(); const auto populateUniformInput = - [this, variablePath, variableUnit, variableColorspace, variableSemantic, &errors, uniforms, &uniformTypeMismatchFound] - (TypeDesc typedesc, const string& variableName, ConstValuePtr variableValue) -> void + [this, variablePath, variableUnit, variableColorspace, variableSemantic, &errors, uniforms, &uniformTypeMismatchFound](TypeDesc typedesc, const string& variableName, ConstValuePtr variableValue) -> void { auto populateUniformInput_impl = - [this, variablePath, variableUnit, variableColorspace, variableSemantic, &errors, uniforms, &uniformTypeMismatchFound] - (TypeDesc typedesc_impl, const string& variableName_impl, ConstValuePtr variableValue_impl, auto& populateUniformInput_ref) -> void + [this, variablePath, variableUnit, variableColorspace, variableSemantic, &errors, uniforms, &uniformTypeMismatchFound](TypeDesc typedesc_impl, const string& variableName_impl, ConstValuePtr variableValue_impl, auto& populateUniformInput_ref) -> void { if (!typedesc_impl.isStruct()) { @@ -995,14 +990,7 @@ const GlslProgram::InputMap& GlslProgram::updateUniformsList() else { errors.push_back( - "Pixel shader uniform block type mismatch [" + uniforms.getName() + "]. " - + "Name: \"" + variableName_impl - + "\". Type: \"" + typedesc_impl.getName() - + "\". Semantic: \"" + variableSemantic - + "\". Value: \"" + (variableValue_impl ? variableValue_impl->getValueString() : "") - + "\". Unit: \"" + (!variableUnit.empty() ? variableUnit : "") - + "\". Colorspace: \"" + (!variableColorspace.empty() ? variableColorspace : "") - + "\". GLType: " + std::to_string(glType)); + "Pixel shader uniform block type mismatch [" + uniforms.getName() + "]. " + "Name: \"" + variableName_impl + "\". Type: \"" + typedesc_impl.getName() + "\". Semantic: \"" + variableSemantic + "\". Value: \"" + (variableValue_impl ? variableValue_impl->getValueString() : "") + "\". Unit: \"" + (!variableUnit.empty() ? variableUnit : "") + "\". Colorspace: \"" + (!variableColorspace.empty() ? variableColorspace : "") + "\". GLType: " + std::to_string(glType)); uniformTypeMismatchFound = true; } } @@ -1056,15 +1044,7 @@ const GlslProgram::InputMap& GlslProgram::updateUniformsList() else { errors.push_back( - "Vertex shader uniform block type mismatch [" + uniforms.getName() + "]. " - + "Name: \"" + v->getVariable() - + "\". Type: \"" + v->getType().getName() - + "\". Semantic: \"" + v->getSemantic() - + "\". Value: \"" + (v->getValue() ? v->getValue()->getValueString() : "") - + "\". Unit: \"" + (!v->getUnit().empty() ? v->getUnit() : "") - + "\". Colorspace: \"" + (!v->getColorSpace().empty() ? v->getColorSpace() : "") - + "\". GLType: " + std::to_string(mapTypeToOpenGLType(v->getType())) - ); + "Vertex shader uniform block type mismatch [" + uniforms.getName() + "]. " + "Name: \"" + v->getVariable() + "\". Type: \"" + v->getType().getName() + "\". Semantic: \"" + v->getSemantic() + "\". Value: \"" + (v->getValue() ? v->getValue()->getValueString() : "") + "\". Unit: \"" + (!v->getUnit().empty() ? v->getUnit() : "") + "\". Colorspace: \"" + (!v->getColorSpace().empty() ? v->getColorSpace() : "") + "\". GLType: " + std::to_string(mapTypeToOpenGLType(v->getType()))); uniformTypeMismatchFound = true; } } @@ -1181,12 +1161,7 @@ const GlslProgram::InputMap& GlslProgram::updateAttributesList() else { errors.push_back( - "Vertex shader attribute type mismatch in block. Name: \"" + v->getVariable() - + "\". Type: \"" + v->getType().getName() - + "\". Semantic: \"" + v->getSemantic() - + "\". Value: \"" + (v->getValue() ? v->getValue()->getValueString() : "") - + "\". GLType: " + std::to_string(mapTypeToOpenGLType(v->getType())) - ); + "Vertex shader attribute type mismatch in block. Name: \"" + v->getVariable() + "\". Type: \"" + v->getType().getName() + "\". Semantic: \"" + v->getSemantic() + "\". Value: \"" + (v->getValue() ? v->getValue()->getValueString() : "") + "\". GLType: " + std::to_string(mapTypeToOpenGLType(v->getType()))); uniformTypeMismatchFound = true; } } diff --git a/source/MaterialXRenderMsl/MetalTextureHandler.mm b/source/MaterialXRenderMsl/MetalTextureHandler.mm index b904e475f3..040fbcf789 100644 --- a/source/MaterialXRenderMsl/MetalTextureHandler.mm +++ b/source/MaterialXRenderMsl/MetalTextureHandler.mm @@ -42,7 +42,14 @@ [samplerDesc setSAddressMode:mapAddressModeToMetal(samplingProperties.uaddressMode)]; [samplerDesc setRAddressMode:mapAddressModeToMetal(samplingProperties.uaddressMode)]; [samplerDesc setTAddressMode:mapAddressModeToMetal(samplingProperties.vaddressMode)]; - [samplerDesc setBorderColor:MTLSamplerBorderColorOpaqueBlack]; + // Metal samplers only support a small set of fixed border colors. The "black" and + // "useMetaData" address modes always clamp to opaque black, while "constant" clamps + // to an approximation of the node's configurable default color. + bool forceBlackBorder = (samplingProperties.uaddressMode == ImageSamplingProperties::AddressMode::BLACK || + samplingProperties.uaddressMode == ImageSamplingProperties::AddressMode::USE_META_DATA || + samplingProperties.vaddressMode == ImageSamplingProperties::AddressMode::BLACK || + samplingProperties.vaddressMode == ImageSamplingProperties::AddressMode::USE_META_DATA); + [samplerDesc setBorderColor:(forceBlackBorder || samplingProperties.defaultColor[0] == 0) ? MTLSamplerBorderColorOpaqueBlack : MTLSamplerBorderColorOpaqueWhite]; MTLSamplerMinMagFilter minmagFilter; MTLSamplerMipFilter mipFilter; mapFilterTypeToMetal(samplingProperties.filterType, samplingProperties.enableMipmaps, minmagFilter, mipFilter); @@ -325,19 +332,23 @@ // Clamp MTLSamplerAddressModeClampToEdge, - // Repeat + // Periodic MTLSamplerAddressModeRepeat, // Mirror - MTLSamplerAddressModeMirrorRepeat + MTLSamplerAddressModeMirrorRepeat, + + // Black. Use clamp to border with a black border color to achieve this. + MTLSamplerAddressModeClampToBorderColor, + + // Repeat + MTLSamplerAddressModeRepeat, + + // useMetaData falls back to black for now. + MTLSamplerAddressModeClampToBorderColor }; - MTLSamplerAddressMode addressMode = MTLSamplerAddressModeClampToBorderColor; - // useMetaData falls back to black for now. - if (addressModeEnum == ImageSamplingProperties::AddressMode::USE_META_DATA) - { - return addressMode; - } + MTLSamplerAddressMode addressMode = MTLSamplerAddressModeRepeat; if (addressModeEnum != ImageSamplingProperties::AddressMode::UNSPECIFIED) { addressMode = addressModes[static_cast(addressModeEnum)]; diff --git a/source/MaterialXRenderMsl/MslMaterial.mm b/source/MaterialXRenderMsl/MslMaterial.mm index d9c8d97f6f..54e299ddff 100644 --- a/source/MaterialXRenderMsl/MslMaterial.mm +++ b/source/MaterialXRenderMsl/MslMaterial.mm @@ -232,8 +232,8 @@ if (shadowState.ambientOcclusionMap && _glProgram->hasUniform(TEXTURE_NAME(HW::AMB_OCC_MAP))) { ImageSamplingProperties samplingProperties; - samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::REPEAT; - samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::REPEAT; + samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; + samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; samplingProperties.filterType = ImageSamplingProperties::FilterType::LINEAR; // Bind the ambient occlusion map. diff --git a/source/MaterialXRenderMsl/MslPipelineStateObject.mm b/source/MaterialXRenderMsl/MslPipelineStateObject.mm index 45812394fa..26d3b129eb 100644 --- a/source/MaterialXRenderMsl/MslPipelineStateObject.mm +++ b/source/MaterialXRenderMsl/MslPipelineStateObject.mm @@ -95,15 +95,24 @@ MTLVertexFormat GetMetalFormatFromMetalType(MTLDataType type) { switch (type) { - case MTLDataTypeFloat : return MTLVertexFormatFloat; - case MTLDataTypeFloat2: return MTLVertexFormatFloat2; - case MTLDataTypeFloat3: return MTLVertexFormatFloat3; - case MTLDataTypeFloat4: return MTLVertexFormatFloat4; - case MTLDataTypeInt: return MTLVertexFormatInt; - case MTLDataTypeInt2: return MTLVertexFormatInt2; - case MTLDataTypeInt3: return MTLVertexFormatInt3; - case MTLDataTypeInt4: return MTLVertexFormatInt4; - default: return MTLVertexFormatInvalid; + case MTLDataTypeFloat: + return MTLVertexFormatFloat; + case MTLDataTypeFloat2: + return MTLVertexFormatFloat2; + case MTLDataTypeFloat3: + return MTLVertexFormatFloat3; + case MTLDataTypeFloat4: + return MTLVertexFormatFloat4; + case MTLDataTypeInt: + return MTLVertexFormatInt; + case MTLDataTypeInt2: + return MTLVertexFormatInt2; + case MTLDataTypeInt3: + return MTLVertexFormatInt3; + case MTLDataTypeInt4: + return MTLVertexFormatInt4; + default: + return MTLVertexFormatInvalid; } return MTLVertexFormatInt; } @@ -113,14 +122,19 @@ int GetStrideOfMetalType(MTLDataType type) switch (type) { case MTLDataTypeInt: - case MTLDataTypeFloat: return 1 * 4; + case MTLDataTypeFloat: + return 1 * 4; case MTLDataTypeInt2: - case MTLDataTypeFloat2: return 2 * 4; + case MTLDataTypeFloat2: + return 2 * 4; case MTLDataTypeInt3: - case MTLDataTypeFloat3: return 3 * 4; + case MTLDataTypeFloat3: + return 3 * 4; case MTLDataTypeInt4: - case MTLDataTypeFloat4: return 4 * 4; - default: return 0; + case MTLDataTypeFloat4: + return 4 * 4; + default: + return 0; } return 0; @@ -232,12 +246,12 @@ int GetStrideOfMetalType(MTLDataType type) if (_shader->hasAttribute(HW::ATTR_TRANSPARENT)) { - psoDesc.colorAttachments[0].blendingEnabled = YES; - psoDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; - psoDesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; - psoDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; - psoDesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha; - psoDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + psoDesc.colorAttachments[0].blendingEnabled = YES; + psoDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; + psoDesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; + psoDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; + psoDesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha; + psoDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; psoDesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; _alphaBlendingEnabled = true; @@ -682,9 +696,7 @@ int GetStrideOfMetalType(MTLDataType type) ImageMap envLights; if (lightHandler->getIndirectLighting()) { - envLights[HW::ENV_RADIANCE] = lightHandler->getUsePrefilteredMap() ? - lightHandler->getEnvPrefilteredMap() : - lightHandler->getEnvRadianceMap(); + envLights[HW::ENV_RADIANCE] = lightHandler->getUsePrefilteredMap() ? lightHandler->getEnvPrefilteredMap() : lightHandler->getEnvRadianceMap(); envLights[HW::ENV_IRRADIANCE] = lightHandler->getEnvIrradianceMap(); } else @@ -692,7 +704,8 @@ int GetStrideOfMetalType(MTLDataType type) envLights[HW::ENV_RADIANCE] = imageHandler->getZeroImage(); envLights[HW::ENV_IRRADIANCE] = imageHandler->getZeroImage(); } - for (const auto& env : envLights) { + for (const auto& env : envLights) + { const auto uniformName = TEXTURE_NAME(env.first); auto iblUniform = uniformList.find(uniformName); @@ -716,7 +729,7 @@ int GetStrideOfMetalType(MTLDataType type) if (image) { ImageSamplingProperties samplingProperties; - samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::REPEAT; + samplingProperties.uaddressMode = ImageSamplingProperties::AddressMode::PERIODIC; samplingProperties.vaddressMode = ImageSamplingProperties::AddressMode::CLAMP; samplingProperties.filterType = ImageSamplingProperties::FilterType::LINEAR; bindTexture(imageHandler, uniformName, image, samplingProperties); @@ -909,12 +922,10 @@ int GetStrideOfMetalType(MTLDataType type) const auto uboObjectName = string(arg.name.UTF8String); const auto addUniformToList = - [this, uboObjectName] - (MTLStructMember* member, int index, int size, const string& memberNamePrefix) -> void + [this, uboObjectName](MTLStructMember* member, int index, int size, const string& memberNamePrefix) -> void { auto addUniformToList_impl = - [this, uboObjectName] - (MTLStructMember* member, int index, int size, const string& memberNamePrefix, auto& addUniformToList_ref) -> void + [this, uboObjectName](MTLStructMember* member, int index, int size, const string& memberNamePrefix, auto& addUniformToList_ref) -> void { auto memberName = memberNamePrefix + member.name.UTF8String; @@ -1012,12 +1023,10 @@ int GetStrideOfMetalType(MTLDataType type) const string& variableSemantic = v->getSemantic(); const auto populateUniformInput = - [this, uniforms, variablePath, variableSemantic, &errors, &uniformTypeMismatchFound] - (TypeDesc variableTypeDesc, const string& variableName, ConstValuePtr variableValue) -> void + [this, uniforms, variablePath, variableSemantic, &errors, &uniformTypeMismatchFound](TypeDesc variableTypeDesc, const string& variableName, ConstValuePtr variableValue) -> void { auto populateUniformInput_impl = - [this, uniforms, variablePath, variableSemantic, &errors, &uniformTypeMismatchFound] - (TypeDesc variableTypeDesc, const string& variableName, ConstValuePtr variableValue, auto& populateUniformInput_ref) -> void + [this, uniforms, variablePath, variableSemantic, &errors, &uniformTypeMismatchFound](TypeDesc variableTypeDesc, const string& variableName, ConstValuePtr variableValue, auto& populateUniformInput_ref) -> void { // There is no way to match with an unnamed variable if (variableName.empty()) @@ -1036,8 +1045,9 @@ int GetStrideOfMetalType(MTLDataType type) { auto inputIt = _uniformList.find(variableName); - if (inputIt == _uniformList.end()) { - if(variableTypeDesc == Type::FILENAME) + if (inputIt == _uniformList.end()) + { + if (variableTypeDesc == Type::FILENAME) { inputIt = _uniformList.find(TEXTURE_NAME(variableName)); } @@ -1059,13 +1069,7 @@ int GetStrideOfMetalType(MTLDataType type) else { errors.push_back( - "Pixel shader uniform block type mismatch [" + uniforms.getName() + "]. " - + "Name: \"" + variableName - + "\". Type: \"" + variableTypeDesc.getName() - + "\". Semantic: \"" + variableSemantic - + "\". Value: \"" + (variableValue ? variableValue->getValueString() : "") - + "\". resourceType: " + std::to_string(mapTypeToMetalType(variableTypeDesc)) - ); + "Pixel shader uniform block type mismatch [" + uniforms.getName() + "]. " + "Name: \"" + variableName + "\". Type: \"" + variableTypeDesc.getName() + "\". Semantic: \"" + variableSemantic + "\". Value: \"" + (variableValue ? variableValue->getValueString() : "") + "\". resourceType: " + std::to_string(mapTypeToMetalType(variableTypeDesc))); uniformTypeMismatchFound = true; } } @@ -1114,14 +1118,7 @@ int GetStrideOfMetalType(MTLDataType type) else { errors.push_back( - "Vertex shader uniform block type mismatch [" + uniforms.getName() + "]. " - + "Name: \"" + v->getVariable() - + "\". Type: \"" + v->getType().getName() - + "\". Semantic: \"" + v->getSemantic() - + "\". Value: \"" + (v->getValue() ? v->getValue()->getValueString() : "") - + "\". Unit: \"" + (!v->getUnit().empty() ? v->getUnit() : "") - + "\". resourceType: " + std::to_string(mapTypeToMetalType(v->getType())) - ); + "Vertex shader uniform block type mismatch [" + uniforms.getName() + "]. " + "Name: \"" + v->getVariable() + "\". Type: \"" + v->getType().getName() + "\". Semantic: \"" + v->getSemantic() + "\". Value: \"" + (v->getValue() ? v->getValue()->getValueString() : "") + "\". Unit: \"" + (!v->getUnit().empty() ? v->getUnit() : "") + "\". resourceType: " + std::to_string(mapTypeToMetalType(v->getType()))); uniformTypeMismatchFound = true; } } @@ -1368,16 +1365,14 @@ throw ExceptionRenderError( if (!setCommonUniform(lightHandler, cam, member.name.UTF8String, uniformBufferData, member.offset)) { const auto setUniformValue = - [this, setValue] - (MTLStructMember* member, const string& uniformName, std::vector& uniformBufferData, int offset ) -> void + [this, setValue](MTLStructMember* member, const string& uniformName, std::vector& uniformBufferData, int offset) -> void { auto setUniformValue_impl = - [this, setValue] - (MTLStructMember* member, const string& uniformName, std::vector& uniformBufferData, int offset, auto &setUniformValue_ref ) -> void + [this, setValue](MTLStructMember* member, const string& uniformName, std::vector& uniformBufferData, int offset, auto& setUniformValue_ref) -> void { - if(MTLArrayType* arrayMember = member.arrayType) + if (MTLArrayType* arrayMember = member.arrayType) { - for(int i = 0; i < arrayMember.arrayLength; ++i) + for (int i = 0; i < arrayMember.arrayLength; ++i) { for (MTLStructMember* ArrayOfStructMember in arrayMember.elementStructType.members) { @@ -1386,7 +1381,7 @@ throw ExceptionRenderError( if (uniformInfo != _uniformList.end()) { auto value = uniformInfo->second->value; - if(value) + if (value) { setValue(value, uniformBufferData, offset + i * arrayMember.stride + ArrayOfStructMember.offset); } @@ -1399,8 +1394,8 @@ throw ExceptionRenderError( // this code does not support struct recursion yet.... for (MTLStructMember* subMember in structMember.members) { - string subUniformName = uniformName+"."+subMember.name.UTF8String; - setUniformValue_ref(subMember, subUniformName, uniformBufferData, offset+subMember.offset, setUniformValue_ref); + string subUniformName = uniformName + "." + subMember.name.UTF8String; + setUniformValue_ref(subMember, subUniformName, uniformBufferData, offset + subMember.offset, setUniformValue_ref); } } else @@ -1409,7 +1404,7 @@ throw ExceptionRenderError( if (uniformInfo != _uniformList.end()) { auto value = uniformInfo->second->value; - if(value) + if (value) { setValue(value, uniformBufferData, offset); } @@ -1471,14 +1466,14 @@ throw ExceptionRenderError( // A "filename" is not indicative of type, so just return a 2d sampler. return MTLDataTypeTexture; } - else if (type == Type::BSDF || - type == Type::MATERIAL || + else if (type == Type::BSDF || + type == Type::MATERIAL || type == Type::DISPLACEMENTSHADER || - type == Type::EDF || - type == Type::VDF || - type == Type::SURFACESHADER || - type == Type::LIGHTSHADER || - type == Type::VOLUMESHADER || + type == Type::EDF || + type == Type::VDF || + type == Type::SURFACESHADER || + type == Type::LIGHTSHADER || + type == Type::VOLUMESHADER || type.isStruct()) return MTLDataTypeStruct; @@ -1530,12 +1525,7 @@ throw ExceptionRenderError( else { errors.push_back( - "Vertex shader attribute type mismatch in block. Name: \"" + v->getVariable() - + "\". Type: \"" + v->getType().getName() - + "\". Semantic: \"" + v->getSemantic() - + "\". Value: \"" + (v->getValue() ? v->getValue()->getValueString() : "") - + "\". resourceType: " + std::to_string(mapTypeToMetalType(v->getType())) - ); + "Vertex shader attribute type mismatch in block. Name: \"" + v->getVariable() + "\". Type: \"" + v->getType().getName() + "\". Semantic: \"" + v->getSemantic() + "\". Value: \"" + (v->getValue() ? v->getValue()->getValueString() : "") + "\". resourceType: " + std::to_string(mapTypeToMetalType(v->getType()))); uniformTypeMismatchFound = true; } } diff --git a/source/MaterialXRenderSlang/SlangTextureHandler.cpp b/source/MaterialXRenderSlang/SlangTextureHandler.cpp index 76359f77f0..bcee79c107 100644 --- a/source/MaterialXRenderSlang/SlangTextureHandler.cpp +++ b/source/MaterialXRenderSlang/SlangTextureHandler.cpp @@ -110,10 +110,12 @@ rhi::ComPtr SlangTextureHandler::getSamplerState(const ImageSampl samplerDesc.maxLOD = 0.f; // Border color not supported in Vulkan - samplerDesc.borderColor[0] = samplingProperties.defaultColor[0]; - samplerDesc.borderColor[1] = samplingProperties.defaultColor[1]; - samplerDesc.borderColor[2] = samplingProperties.defaultColor[2]; - samplerDesc.borderColor[3] = samplingProperties.defaultColor[3]; + bool forceBlackBorder = (samplingProperties.uaddressMode == ImageSamplingProperties::AddressMode::BLACK || samplingProperties.uaddressMode == ImageSamplingProperties::AddressMode::USE_META_DATA || samplingProperties.vaddressMode == ImageSamplingProperties::AddressMode::BLACK || samplingProperties.vaddressMode == ImageSamplingProperties::AddressMode::USE_META_DATA); + Color4 borderColor = forceBlackBorder ? Color4(0.0f, 0.0f, 0.0f, 0.0f) : samplingProperties.defaultColor; + samplerDesc.borderColor[0] = borderColor[0]; + samplerDesc.borderColor[1] = borderColor[1]; + samplerDesc.borderColor[2] = borderColor[2]; + samplerDesc.borderColor[3] = borderColor[3]; if (samplingProperties.filterType != ImageSamplingProperties::FilterType::CLOSEST) samplerDesc.maxAnisotropy = 16; @@ -162,14 +164,16 @@ rhi::TextureAddressingMode SlangTextureHandler::mapAddressModeToSlang(ImageSampl switch (addressModeEnum) { case ImageSamplingProperties::AddressMode::UNSPECIFIED: + case ImageSamplingProperties::AddressMode::PERIODIC: + case ImageSamplingProperties::AddressMode::REPEAT: + return rhi::TextureAddressingMode::Wrap; + case ImageSamplingProperties::AddressMode::CONSTANT: // useMetaData falls back to black for now case ImageSamplingProperties::AddressMode::USE_META_DATA: case ImageSamplingProperties::AddressMode::BLACK: return rhi::TextureAddressingMode::ClampToBorder; case ImageSamplingProperties::AddressMode::CLAMP: return rhi::TextureAddressingMode::ClampToEdge; - case ImageSamplingProperties::AddressMode::REPEAT: - return rhi::TextureAddressingMode::Wrap; case ImageSamplingProperties::AddressMode::MIRROR: return rhi::TextureAddressingMode::MirrorRepeat; } diff --git a/source/MaterialXView/RenderPipelineGL.cpp b/source/MaterialXView/RenderPipelineGL.cpp index df3ca4eb02..746441ab6c 100644 --- a/source/MaterialXView/RenderPipelineGL.cpp +++ b/source/MaterialXView/RenderPipelineGL.cpp @@ -58,11 +58,11 @@ void GLRenderPipeline::resizeFramebuffer(int, int, void*) void GLRenderPipeline::updateAlbedoTable(int tableSize) { - auto& genContext = _viewer->_genContext; - auto& stdLib = _viewer->_stdLib; - auto& lightHandler = _viewer->_lightHandler; - auto& imageHandler = _viewer->_imageHandler; - + auto& genContext = _viewer->_genContext; + auto& stdLib = _viewer->_stdLib; + auto& lightHandler = _viewer->_lightHandler; + auto& imageHandler = _viewer->_imageHandler; + if (lightHandler->getAlbedoTable()) { return; @@ -91,8 +91,7 @@ void GLRenderPipeline::updateAlbedoTable(int tableSize) material->bindShader(); if (material->getProgram()->hasUniform(mx::HW::ALBEDO_TABLE_SIZE)) { - std::static_pointer_cast(material)->getProgram() - ->bindUniform(mx::HW::ALBEDO_TABLE_SIZE, mx::Value::createValue(tableSize)); + std::static_pointer_cast(material)->getProgram()->bindUniform(mx::HW::ALBEDO_TABLE_SIZE, mx::Value::createValue(tableSize)); } _viewer->renderScreenSpaceQuad(material); @@ -112,9 +111,9 @@ void GLRenderPipeline::updateAlbedoTable(int tableSize) void GLRenderPipeline::updatePrefilteredMap() { - auto& genContext = _viewer->_genContext; - auto& lightHandler = _viewer->_lightHandler; - auto& imageHandler = _viewer->_imageHandler; + auto& genContext = _viewer->_genContext; + auto& lightHandler = _viewer->_lightHandler; + auto& imageHandler = _viewer->_imageHandler; if (lightHandler->getEnvPrefilteredMap()) { @@ -145,7 +144,7 @@ void GLRenderPipeline::updatePrefilteredMap() mx::ImagePtr outTex = mx::Image::create(w, h, 3, mx::Image::BaseType::HALF); glImageHandler->createRenderResources(outTex, true, true); - mx::GlslProgramPtr program = material->getProgram(); + mx::GlslProgramPtr program = material->getProgram(); try { @@ -155,14 +154,14 @@ void GLRenderPipeline::updatePrefilteredMap() // Create framebuffer unsigned int framebuffer; glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, 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::REPEAT; + samplingProperties.uaddressMode = mx::ImageSamplingProperties::AddressMode::PERIODIC; samplingProperties.vaddressMode = mx::ImageSamplingProperties::AddressMode::CLAMP; samplingProperties.filterType = mx::ImageSamplingProperties::FilterType::LINEAR; imageHandler->bindImage(srcTex, samplingProperties); @@ -177,7 +176,7 @@ void GLRenderPipeline::updatePrefilteredMap() _viewer->renderScreenSpaceQuad(material); - glDeleteFramebuffers(1, &framebuffer); + glDeleteFramebuffers(1, &framebuffer); w /= 2; h /= 2; @@ -206,12 +205,12 @@ void GLRenderPipeline::updatePrefilteredMap() mx::ImagePtr GLRenderPipeline::getShadowMap(int shadowMapSize) { - auto& genContext = _viewer->_genContext; - auto& imageHandler = _viewer->_imageHandler; - auto& shadowCamera = _viewer->_shadowCamera; - auto& stdLib = _viewer->_stdLib; + auto& genContext = _viewer->_genContext; + auto& imageHandler = _viewer->_imageHandler; + auto& shadowCamera = _viewer->_shadowCamera; + auto& stdLib = _viewer->_stdLib; auto& geometryHandler = _viewer->_geometryHandler; - + if (!_viewer->_shadowMap) { // Generate shaders for shadow rendering. @@ -282,7 +281,8 @@ mx::ImagePtr GLRenderPipeline::getShadowMap(int shadowMapSize) if (textureLocation >= 0) { std::static_pointer_cast(_viewer->_shadowBlurMaterial) - ->getProgram()->bindUniform("image_file", mx::Value::createValue(textureLocation)); + ->getProgram() + ->bindUniform("image_file", mx::Value::createValue(textureLocation)); } } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -304,18 +304,17 @@ mx::ImagePtr GLRenderPipeline::getShadowMap(int shadowMapSize) return _viewer->_shadowMap; } - void GLRenderPipeline::renderFrame(void*, int shadowMapSize, const char* dirLightNodeCat) { - auto& genContext = _viewer->_genContext; - auto& lightHandler = _viewer->_lightHandler; - auto& imageHandler = _viewer->_imageHandler; - auto& viewCamera = _viewer->_viewCamera; - auto& envCamera = _viewer->_envCamera; - auto& shadowCamera = _viewer->_shadowCamera; + auto& genContext = _viewer->_genContext; + auto& lightHandler = _viewer->_lightHandler; + auto& imageHandler = _viewer->_imageHandler; + auto& viewCamera = _viewer->_viewCamera; + auto& envCamera = _viewer->_envCamera; + auto& shadowCamera = _viewer->_shadowCamera; float lightRotation = _viewer->_lightRotation; - auto& searchPath = _viewer->_searchPath; - auto& geometryHandler = _viewer->_geometryHandler; + auto& searchPath = _viewer->_searchPath; + auto& geometryHandler = _viewer->_geometryHandler; // Update prefiltered environment. if (lightHandler->getUsePrefilteredMap() && !_viewer->_materialAssignments.empty()) @@ -346,7 +345,7 @@ void GLRenderPipeline::renderFrame(void*, int shadowMapSize, const char* dirLigh { shadowState.shadowMap = shadowMap; shadowState.shadowMatrix = viewCamera->getWorldMatrix().getInverse() * - shadowCamera->getWorldViewProjMatrix(); + shadowCamera->getWorldViewProjMatrix(); } else { @@ -520,7 +519,7 @@ void GLRenderPipeline::bakeTextures() // Release any render resources generated by the baking process. imageHandler->releaseRenderResources(); } - + // After the baker has been destructed, restore state for scene rendering. glfwMakeContextCurrent(_viewer->m_glfw_window); glfwGetFramebufferSize(_viewer->m_glfw_window, &_viewer->m_fbsize[0], &_viewer->m_fbsize[1]); @@ -532,7 +531,7 @@ void GLRenderPipeline::bakeTextures() mx::ImagePtr GLRenderPipeline::getFrameImage() { glFlush(); - + const auto& size = _viewer->m_size; const auto& pixel_ratio = _viewer->m_pixel_ratio;