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] 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)
{