diff --git a/libraries/stdlib/genglsl/mx_image_color3.glsl b/libraries/stdlib/genglsl/mx_image_color3.glsl
index 802318f475..8c4c039554 100644
--- a/libraries/stdlib/genglsl/mx_image_color3.glsl
+++ b/libraries/stdlib/genglsl/mx_image_color3.glsl
@@ -2,13 +2,6 @@
void mx_image_color3(sampler2D tex_sampler, int layer, vec3 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec3 result)
{
- if (textureSize(tex_sampler, 0).x > 1)
- {
- vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
- result = texture(tex_sampler, uv).rgb;
- }
- else
- {
- result = defaultval;
- }
+ vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
+ result = texture(tex_sampler, uv).rgb;
}
diff --git a/libraries/stdlib/genglsl/mx_image_color4.glsl b/libraries/stdlib/genglsl/mx_image_color4.glsl
index e74ad9445f..7541b9da04 100644
--- a/libraries/stdlib/genglsl/mx_image_color4.glsl
+++ b/libraries/stdlib/genglsl/mx_image_color4.glsl
@@ -2,13 +2,6 @@
void mx_image_color4(sampler2D tex_sampler, int layer, vec4 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec4 result)
{
- if (textureSize(tex_sampler, 0).x > 1)
- {
- vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
- result = texture(tex_sampler, uv);
- }
- else
- {
- result = defaultval;
- }
+ vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
+ result = texture(tex_sampler, uv);
}
diff --git a/libraries/stdlib/genglsl/mx_image_float.glsl b/libraries/stdlib/genglsl/mx_image_float.glsl
index 9b831035d2..0a402a101c 100644
--- a/libraries/stdlib/genglsl/mx_image_float.glsl
+++ b/libraries/stdlib/genglsl/mx_image_float.glsl
@@ -2,13 +2,6 @@
void mx_image_float(sampler2D tex_sampler, int layer, float defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out float result)
{
- if (textureSize(tex_sampler, 0).x > 1)
- {
- vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
- result = texture(tex_sampler, uv).r;
- }
- else
- {
- result = defaultval;
- }
+ vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
+ result = texture(tex_sampler, uv).r;
}
diff --git a/libraries/stdlib/genglsl/mx_image_vector2.glsl b/libraries/stdlib/genglsl/mx_image_vector2.glsl
index 124cb09287..42a7235297 100644
--- a/libraries/stdlib/genglsl/mx_image_vector2.glsl
+++ b/libraries/stdlib/genglsl/mx_image_vector2.glsl
@@ -2,13 +2,6 @@
void mx_image_vector2(sampler2D tex_sampler, int layer, vec2 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec2 result)
{
- if (textureSize(tex_sampler, 0).x > 1)
- {
- vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
- result = texture(tex_sampler, uv).rg;
- }
- else
- {
- result = defaultval;
- }
+ vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
+ result = texture(tex_sampler, uv).rg;
}
diff --git a/libraries/stdlib/genglsl/mx_image_vector3.glsl b/libraries/stdlib/genglsl/mx_image_vector3.glsl
index 840e60fe6f..d49eab735e 100644
--- a/libraries/stdlib/genglsl/mx_image_vector3.glsl
+++ b/libraries/stdlib/genglsl/mx_image_vector3.glsl
@@ -2,13 +2,6 @@
void mx_image_vector3(sampler2D tex_sampler, int layer, vec3 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec3 result)
{
- if (textureSize(tex_sampler, 0).x > 1)
- {
- vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
- result = texture(tex_sampler, uv).rgb;
- }
- else
- {
- result = defaultval;
- }
+ vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
+ result = texture(tex_sampler, uv).rgb;
}
diff --git a/libraries/stdlib/genglsl/mx_image_vector4.glsl b/libraries/stdlib/genglsl/mx_image_vector4.glsl
index f4b61d83f0..c8bdc66fc4 100644
--- a/libraries/stdlib/genglsl/mx_image_vector4.glsl
+++ b/libraries/stdlib/genglsl/mx_image_vector4.glsl
@@ -2,13 +2,6 @@
void mx_image_vector4(sampler2D tex_sampler, int layer, vec4 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec4 result)
{
- if (textureSize(tex_sampler, 0).x > 1)
- {
- vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
- result = texture(tex_sampler, uv);
- }
- else
- {
- result = defaultval;
- }
+ vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
+ result = texture(tex_sampler, uv);
}
diff --git a/resources/Materials/TestSuite/stdlib/texture/image_default.mtlx b/resources/Materials/TestSuite/stdlib/texture/image_default.mtlx
new file mode 100644
index 0000000000..89b99c3c39
--- /dev/null
+++ b/resources/Materials/TestSuite/stdlib/texture/image_default.mtlx
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/MaterialXGraphEditor/RenderView.cpp b/source/MaterialXGraphEditor/RenderView.cpp
index faf48f543a..f36a492502 100644
--- a/source/MaterialXGraphEditor/RenderView.cpp
+++ b/source/MaterialXGraphEditor/RenderView.cpp
@@ -720,7 +720,7 @@ void RenderView::loadEnvironmentLight()
envIrradianceMap = _imageHandler->acquireImage(envIrradiancePath);
// If not found, then generate an irradiance map via spherical harmonics.
- if (envIrradianceMap == _imageHandler->getInvalidImage())
+ if (envIrradianceMap == _imageHandler->getZeroImage())
{
mx::Sh3ColorCoeffs shIrradiance = mx::projectEnvironment(envRadianceMap, true);
envIrradianceMap = mx::renderEnvironment(shIrradiance, IRRADIANCE_MAP_WIDTH, IRRADIANCE_MAP_HEIGHT);
diff --git a/source/MaterialXRender/ImageHandler.cpp b/source/MaterialXRender/ImageHandler.cpp
index bc43b617ff..d54a18fedd 100644
--- a/source/MaterialXRender/ImageHandler.cpp
+++ b/source/MaterialXRender/ImageHandler.cpp
@@ -56,9 +56,6 @@ ImageHandler::ImageHandler(ImageLoaderPtr imageLoader)
{
addLoader(imageLoader);
_zeroImage = createUniformImage(2, 2, 4, Image::BaseType::UINT8, Color4(0.0f));
-
- // Generated shaders interpret 1x1 textures as invalid images.
- _invalidImage = createUniformImage(1, 1, 4, Image::BaseType::UINT8, Color4(0.0f));
}
void ImageHandler::addLoader(ImageLoaderPtr loader)
@@ -118,7 +115,7 @@ bool ImageHandler::saveImage(const FilePath& filePath,
return false;
}
-ImagePtr ImageHandler::acquireImage(const FilePath& filePath)
+ImagePtr ImageHandler::acquireImage(const FilePath& filePath, const Color4& defaultColor)
{
// Resolve the input filepath.
FilePath resolvedFilePath = filePath;
@@ -142,9 +139,12 @@ ImagePtr ImageHandler::acquireImage(const FilePath& filePath)
return image;
}
- // No valid image was found, so cache the sentinel invalid image.
- cacheImage(resolvedFilePath, _invalidImage);
- return _invalidImage;
+ // No valid image was found, so generate a uniform texture with the given default color.
+ // TODO: This step assumes that the missing image and its default color are in the same
+ // color space, which is not always the case.
+ ImagePtr defaultImage = createUniformImage(1, 1, 4, Image::BaseType::UINT8, defaultColor);
+ cacheImage(resolvedFilePath, defaultImage);
+ return defaultImage;
}
bool ImageHandler::bindImage(ImagePtr, const ImageSamplingProperties&)
@@ -189,7 +189,7 @@ ImageVec ImageHandler::getReferencedImages(ConstDocumentPtr doc)
if (file)
{
ImagePtr image = acquireImage(file->getResolvedValueString());
- if (image && image != _invalidImage)
+ if (image)
{
imageVec.push_back(image);
}
@@ -214,14 +214,6 @@ ImagePtr ImageHandler::loadImage(const FilePath& filePath)
}
if (image)
{
- // Generated shaders interpret 1x1 textures as invalid images, so valid 1x1
- // images must be resized.
- if (image->getWidth() == 1 && image->getHeight() == 1)
- {
- image = createUniformImage(2, 2, image->getChannelCount(),
- image->getBaseType(), image->getTexelColor(0, 0));
- }
-
return image;
}
}
@@ -288,23 +280,23 @@ void ImageSamplingProperties::setProperties(const string& fileNameUniform,
root = root.substr(0, pos);
}
- const string uaddressmodeStr = root + UADDRESS_MODE_SUFFIX;
- const ShaderPort* port = uniformBlock.find(uaddressmodeStr);
+ const ShaderPort* port = uniformBlock.find(root + UADDRESS_MODE_SUFFIX);
ValuePtr intValue = port ? port->getValue() : nullptr;
uaddressMode = ImageSamplingProperties::AddressMode(intValue && intValue->isA() ? intValue->asA() : INVALID_MAPPED_INT_VALUE);
- const string vaddressmodeStr = root + VADDRESS_MODE_SUFFIX;
- port = uniformBlock.find(vaddressmodeStr);
+ port = uniformBlock.find(root + VADDRESS_MODE_SUFFIX);
intValue = port ? port->getValue() : nullptr;
vaddressMode = ImageSamplingProperties::AddressMode(intValue && intValue->isA() ? intValue->asA() : INVALID_MAPPED_INT_VALUE);
- const string filtertypeStr = root + FILTER_TYPE_SUFFIX;
- port = uniformBlock.find(filtertypeStr);
+ port = uniformBlock.find(root + FILTER_TYPE_SUFFIX);
intValue = port ? port->getValue() : nullptr;
filterType = ImageSamplingProperties::FilterType(intValue && intValue->isA() ? intValue->asA() : INVALID_MAPPED_INT_VALUE);
- const string defaultColorStr = root + DEFAULT_COLOR_SUFFIX;
- port = uniformBlock.find(defaultColorStr);
+ port = uniformBlock.find(root + DEFAULT_COLOR_SUFFIX);
+ if (!port)
+ {
+ port = uniformBlock.find(root + DEFAULT_COLOR_SUFFIX + "_cm_in");
+ }
ValuePtr colorValue = port ? port->getValue() : nullptr;
if (colorValue)
{
diff --git a/source/MaterialXRender/ImageHandler.h b/source/MaterialXRender/ImageHandler.h
index ee1fe127c4..c744eb2f6a 100644
--- a/source/MaterialXRender/ImageHandler.h
+++ b/source/MaterialXRender/ImageHandler.h
@@ -188,7 +188,7 @@ class MX_RENDER_API ImageHandler
/// found in the cache, then each image loader will be applied in turn.
/// @param filePath File path of the image.
/// @return On success, a shared pointer to the acquired image.
- ImagePtr acquireImage(const FilePath& filePath);
+ ImagePtr acquireImage(const FilePath& filePath, const Color4& defaultColor = Color4(0.0f));
/// Bind an image for rendering.
/// @param image The image to bind.
@@ -247,13 +247,6 @@ class MX_RENDER_API ImageHandler
return _zeroImage;
}
- /// Return the sentinel invalid image, representing images that cannot be loaded
- /// and should be replaced with their declared default value.
- ImagePtr getInvalidImage() const
- {
- return _invalidImage;
- }
-
/// Acquire all images referenced by the given document, and return the
/// images in a vector.
ImageVec getReferencedImages(ConstDocumentPtr doc);
@@ -278,7 +271,6 @@ class MX_RENDER_API ImageHandler
FileSearchPath _searchPath;
StringResolverPtr _resolver;
ImagePtr _zeroImage;
- ImagePtr _invalidImage;
};
MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXRenderGlsl/GlslMaterial.cpp b/source/MaterialXRenderGlsl/GlslMaterial.cpp
index ef7a0ed0c2..ce4582d44f 100644
--- a/source/MaterialXRenderGlsl/GlslMaterial.cpp
+++ b/source/MaterialXRenderGlsl/GlslMaterial.cpp
@@ -209,7 +209,7 @@ ImagePtr GlslMaterial::bindImage(const FilePath& filePath, const std::string& un
imageHandler->setFilenameResolver(resolver);
// Acquire the given image.
- ImagePtr image = imageHandler->acquireImage(filePath);
+ ImagePtr image = imageHandler->acquireImage(filePath, samplingProperties.defaultColor);
if (!image)
{
return nullptr;
diff --git a/source/MaterialXRenderGlsl/GlslProgram.cpp b/source/MaterialXRenderGlsl/GlslProgram.cpp
index a60997716a..900cac0ef1 100644
--- a/source/MaterialXRenderGlsl/GlslProgram.cpp
+++ b/source/MaterialXRenderGlsl/GlslProgram.cpp
@@ -491,7 +491,7 @@ ImagePtr GlslProgram::bindTexture(unsigned int uniformType, int uniformLocation,
uniformType >= GL_SAMPLER_1D && uniformType <= GL_SAMPLER_CUBE)
{
// Acquire the image.
- ImagePtr image = imageHandler->acquireImage(filePath);
+ ImagePtr image = imageHandler->acquireImage(filePath, samplingProperties.defaultColor);
if (imageHandler->bindImage(image, samplingProperties))
{
GLTextureHandlerPtr textureHandler = std::static_pointer_cast(imageHandler);
diff --git a/source/MaterialXRenderMsl/MslMaterial.mm b/source/MaterialXRenderMsl/MslMaterial.mm
index 7e9cd38adc..66fc0462f2 100644
--- a/source/MaterialXRenderMsl/MslMaterial.mm
+++ b/source/MaterialXRenderMsl/MslMaterial.mm
@@ -199,7 +199,7 @@
imageHandler->setFilenameResolver(resolver);
// Acquire the given image.
- return imageHandler->acquireImage(filePath);
+ return imageHandler->acquireImage(filePath, samplingProperties.defaultColor);
}
void MslMaterial::bindLighting(LightHandlerPtr lightHandler,
diff --git a/source/MaterialXRenderMsl/MslPipelineStateObject.mm b/source/MaterialXRenderMsl/MslPipelineStateObject.mm
index 84a615fd61..4f8378ae46 100644
--- a/source/MaterialXRenderMsl/MslPipelineStateObject.mm
+++ b/source/MaterialXRenderMsl/MslPipelineStateObject.mm
@@ -542,7 +542,7 @@ int GetStrideOfMetalType(MTLDataType type)
{
// Acquire the image.
string error;
- ImagePtr image = imageHandler->acquireImage(filePath);
+ ImagePtr image = imageHandler->acquireImage(filePath, samplingProperties.defaultColor);
imageHandler->bindImage(image, samplingProperties);
return bindTexture(renderCmdEncoder, uniformLocation, image, imageHandler);
}
diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp
index ecbb4352fc..6346658d07 100644
--- a/source/MaterialXView/Viewer.cpp
+++ b/source/MaterialXView/Viewer.cpp
@@ -474,7 +474,7 @@ void Viewer::loadEnvironmentLight()
}
// Look for an irradiance map using an expected filename convention.
- mx::ImagePtr envIrradianceMap = _imageHandler->getInvalidImage();
+ mx::ImagePtr envIrradianceMap = _imageHandler->getZeroImage();
if (!_normalizeEnvironment && !_splitDirectLight)
{
mx::FilePath envIrradiancePath = _envRadianceFilename.getParentPath() / IRRADIANCE_MAP_FOLDER / _envRadianceFilename.getBaseName();
@@ -482,7 +482,7 @@ void Viewer::loadEnvironmentLight()
}
// If not found, then generate an irradiance map via spherical harmonics.
- if (envIrradianceMap == _imageHandler->getInvalidImage())
+ if (envIrradianceMap == _imageHandler->getZeroImage())
{
if (_generateReferenceIrradiance)
{
diff --git a/source/PyMaterialX/PyMaterialXRender/PyImageHandler.cpp b/source/PyMaterialX/PyMaterialXRender/PyImageHandler.cpp
index 7ece49d60b..d261bc7306 100644
--- a/source/PyMaterialX/PyMaterialXRender/PyImageHandler.cpp
+++ b/source/PyMaterialX/PyMaterialXRender/PyImageHandler.cpp
@@ -41,7 +41,8 @@ void bindPyImageHandler(py::module& mod)
.def("addLoader", &mx::ImageHandler::addLoader)
.def("saveImage", &mx::ImageHandler::saveImage,
py::arg("filePath"), py::arg("image"), py::arg("verticalFlip") = false)
- .def("acquireImage", &mx::ImageHandler::acquireImage)
+ .def("acquireImage", &mx::ImageHandler::acquireImage,
+ py::arg("filePath"), py::arg("defaultColor") = mx::Color4(0.0f))
.def("bindImage", &mx::ImageHandler::bindImage)
.def("unbindImage", &mx::ImageHandler::unbindImage)
.def("unbindImages", &mx::ImageHandler::unbindImages)
@@ -54,6 +55,5 @@ void bindPyImageHandler(py::module& mod)
py::arg("image") = nullptr)
.def("clearImageCache", &mx::ImageHandler::clearImageCache)
.def("getZeroImage", &mx::ImageHandler::getZeroImage)
- .def("getInvalidImage", &mx::ImageHandler::getInvalidImage)
.def("getReferencedImages", &mx::ImageHandler::getReferencedImages);
}