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