From 1f79379bf215c5368337c64b4f72c7c9ef3e09c2 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Wed, 5 Apr 2023 11:55:51 -0500
Subject: SL-19538 Followup -- tune exposure parameters and clamp local light
 ambiance.  Make render targets 16F and scrube NaNs (thanks Rye).  Update
 midday. (#154)

---
 indra/newview/app_settings/settings.xml            | 55 ++++++++++++++++++++++
 .../shaders/class1/deferred/exposureF.glsl         |  3 +-
 .../class2/windlight/atmosphericsHelpersV.glsl     |  4 --
 .../shaders/class3/deferred/multiPointLightF.glsl  |  2 +-
 .../shaders/class3/deferred/pointLightF.glsl       |  2 +-
 .../shaders/class3/deferred/softenLightF.glsl      |  9 ++--
 indra/newview/llenvironment.cpp                    |  2 +-
 indra/newview/llreflectionmapmanager.cpp           |  7 +++
 indra/newview/llreflectionmapmanager.h             |  3 ++
 indra/newview/pipeline.cpp                         | 40 +++++++++++++---
 10 files changed, 106 insertions(+), 21 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 9ae33a85b4..063f4fcf96 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10447,6 +10447,61 @@
       <key>Value</key>
       <integer>3</integer>
     </map>
+  <key>RenderSkyHDRScale</key>
+  <map>
+    <key>Comment</key>
+    <string>Amount to over-brighten sun for HDR effect during the day</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>3.0</real>
+  </map>
+  <key>RenderReflectionProbeMaxLocalLightAmbiance</key>
+  <map>
+    <key>Comment</key>
+    <string>Maximum effective probe ambiance for local lights</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>4.0</real>
+  </map>
+  <key>RenderDynamicExposureMin</key>
+  <map>
+    <key>Comment</key>
+    <string>Minimum dynamic exposure amount</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>0.125</real>
+  </map>
+  <key>RenderDynamicExposureMax</key>
+  <map>
+    <key>Comment</key>
+    <string>Maximum dynamic exposure amount</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>1.3</real>
+  </map>
+  <key>RenderDynamicExposureCoefficient</key>
+  <map>
+    <key>Comment</key>
+    <string>Luminance coefficient for dynamic exposure</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>0.3</real>
+  </map>
     <key>RenderShaderLODThreshold</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
index 861b78c961..4c860cdde0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
@@ -36,6 +36,7 @@ uniform sampler2D exposureMap;
 uniform float dt;
 uniform vec2 noiseVec;
 
+uniform vec3 dynamic_exposure_params;
 
 float lum(vec3 col)
 {
@@ -81,7 +82,7 @@ void main()
 
     float L = lum(col);
 
-    float s = clamp(0.175/L, 0.125, 1.3);
+    float s = clamp(dynamic_exposure_params.x/L, dynamic_exposure_params.y, dynamic_exposure_params.z);
 
 
     float prev = texture(exposureMap, vec2(0.5,0.5)).r;
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
index 257a76c663..6ecbfaecb1 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
@@ -54,8 +54,4 @@ vec3 scaleDownLight(vec3 light)
     return (light / scene_light_strength );
 }
 
-vec3 scaleUpLight(vec3 light)
-{
-    return (light * scene_light_strength);
-}
 
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
index 0fb30559d4..23ba95949a 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
@@ -176,7 +176,7 @@ void main()
         }
     }
 
-    frag_color.rgb = final_color;
+    frag_color.rgb = max(final_color, vec3(0));
     frag_color.a   = 0.0;
 #endif // LOCAL_LIGHT_KILL
 
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
index 8229ecbbb7..30b96ce8dc 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -151,6 +151,6 @@ void main()
         }
     }
 
-    frag_color.rgb = final_color;
+    frag_color.rgb = max(final_color, vec3(0));
     frag_color.a = 0.0;
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 7953360054..99beb0d890 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -90,6 +90,8 @@ uniform vec4 waterPlane;
 vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 #endif
 
+uniform float sky_hdr_scale;
+
 void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
 
 vec3 pbrBaseLight(vec3 diffuseColor,
@@ -196,22 +198,17 @@ void main()
         vec3 v = -normalize(pos.xyz);
         color = vec3(1,0,1);
         color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
-
         
         if (do_atmospherics)
         {
-            color = linear_to_srgb(color);
             color = atmosFragLightingLinear(color, additive, atten);
-            color = srgb_to_linear(color);
         }
-        
-        
     }
     else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
     {
         //should only be true of WL sky, just port over base color value
         color = srgb_to_linear(texture2D(emissiveRect, tc).rgb);
-        color *= sun_up_factor + 1.0;
+        color *= sun_up_factor * sky_hdr_scale + 1.0;
     }
     else
     {
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 84ddb3ca99..26e7c6c66e 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -812,7 +812,7 @@ const F64Seconds LLEnvironment::TRANSITION_SLOW(10.0f);
 const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
 
 const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb");
-const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("e4391f43-74d6-d889-19fb-99a4a3ad6c5c");
+const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("d9950f9a-f693-be73-0384-13ee97b8ca10");
 const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("084e26cd-a900-28e8-08d0-64a9de5c15e2");
 const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("8a01b97a-cb20-c1ea-ac63-f7ea84ad0090");
 
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index bccd76415f..8252b4be36 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -464,6 +464,13 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
     // hacky hot-swap of camera specific render targets
     gPipeline.mRT = &gPipeline.mAuxillaryRT;
 
+    mLightScale = 1.f;
+    static LLCachedControl<F32> max_local_light_ambiance(gSavedSettings, "RenderReflectionProbeMaxLocalLightAmbiance", 8.f);
+    if (!isRadiancePass() && probe->getAmbiance() > max_local_light_ambiance)
+    {
+        mLightScale = max_local_light_ambiance / probe->getAmbiance();
+    }
+
     if (probe == mDefaultProbe)
     {
         touch_default_probe(probe);
diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h
index fef308541d..9a46af58b3 100644
--- a/indra/newview/llreflectionmapmanager.h
+++ b/indra/newview/llreflectionmapmanager.h
@@ -187,5 +187,8 @@ private:
 
     // maximum LoD of reflection probes (mip levels - 1)
     F32 mMaxProbeLOD = 6.f;
+
+    // amount to scale local lights during an irradiance map update (set during updateProbeFace and used by LLPipeline)
+    F32 mLightScale = 1.f;
 };
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 11deff5bff..1222613c66 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -796,7 +796,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 	if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true)) return false;
 	if (!addDeferredAttachments(mRT->deferredScreen)) return false;
 	
-	GLuint screenFormat = GL_RGBA16;
+	GLuint screenFormat = GL_RGBA16F;
         
 	if (!mRT->screen.allocate(resX, resY, screenFormat)) return false;
 
@@ -813,7 +813,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
 		
 	if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
 	{ //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa
-		if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16)) return false;
+		if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16F)) return false;
 	}
 	else
 	{
@@ -5631,6 +5631,14 @@ void LLPipeline::setupHWLights()
         return;
     }
 
+    F32 light_scale = 1.f;
+
+    if (gCubeSnapshot)
+    { //darken local lights when probe ambiance is above 1
+        light_scale = mReflectionMapManager.mLightScale;
+    }
+
+
     LLEnvironment& environment = LLEnvironment::instance();
     LLSettingsSky::ptr_t psky = environment.getCurrentSky();
 
@@ -5730,7 +5738,7 @@ void LLPipeline::setupHWLights()
 			}
 			
             //send linear light color to shader
-			LLColor4  light_color = light->getLightLinearColor();
+            LLColor4  light_color = light->getLightLinearColor() * light_scale;
 			light_color.mV[3] = 0.0f;
 
 			F32 fade = iter->fade;
@@ -7277,6 +7285,7 @@ void LLPipeline::renderFinalize()
             
             gExposureProgram.bind();
 
+
             S32 channel = 0;
             channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
             if (channel > -1)
@@ -7296,11 +7305,17 @@ void LLPipeline::renderFinalize()
                 mLastExposure.bindTexture(0, channel);
             }
 
+            static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f);
+            static LLCachedControl<F32> dynamic_exposure_min(gSavedSettings, "RenderDynamicExposureMin", 0.125f);
+            static LLCachedControl<F32> dynamic_exposure_max(gSavedSettings, "RenderDynamicExposureMax", 1.3f);
+
             static LLStaticHashedString dt("dt");
             static LLStaticHashedString noiseVec("noiseVec");
+            static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
             gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
             gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
-           
+            gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, dynamic_exposure_min, dynamic_exposure_max);
+
             mScreenTriangleVB->setBuffer();
             mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 
@@ -7876,6 +7891,13 @@ void LLPipeline::renderDeferredLighting()
 
     llassert(!sRenderingHUDs);
 
+    F32 light_scale = 1.f;
+
+    if (gCubeSnapshot)
+    { //darken local lights when probe ambiance is above 1
+        light_scale = mReflectionMapManager.mLightScale;
+    }
+
     LLRenderTarget *screen_target         = &mRT->screen;
     LLRenderTarget* deferred_light_target = &mRT->deferredLight;
 
@@ -8032,9 +8054,13 @@ void LLPipeline::renderDeferredLighting()
             LL_PROFILE_GPU_ZONE("atmospherics");
             bindDeferredShader(soften_shader);
 
+            static LLCachedControl<F32> sky_scale(gSavedSettings, "RenderSkyHDRScale", 1.f);
+            static LLStaticHashedString sky_hdr_scale("sky_hdr_scale");
+
             LLEnvironment &environment = LLEnvironment::instance();
             soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
             soften_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
+            soften_shader.uniform1f(sky_hdr_scale, sky_scale);
 
             soften_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
 
@@ -8111,7 +8137,7 @@ void LLPipeline::renderDeferredLighting()
                     F32        s = volume->getLightRadius() * 1.5f;
 
                     // send light color to shader in linear space
-                    LLColor3 col = volume->getLightLinearColor();
+                    LLColor3 col = volume->getLightLinearColor() * light_scale;
 
                     if (col.magVecSquared() < 0.001f)
                     {
@@ -8205,7 +8231,7 @@ void LLPipeline::renderDeferredLighting()
                     setupSpotLight(gDeferredSpotLightProgram, drawablep);
 
                     // send light color to shader in linear space
-                    LLColor3 col = volume->getLightLinearColor();
+                    LLColor3 col = volume->getLightLinearColor() * light_scale;
 
                     gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
                     gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
@@ -8280,7 +8306,7 @@ void LLPipeline::renderDeferredLighting()
                     setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
 
                     // send light color to shader in linear space
-                    LLColor3 col = volume->getLightLinearColor();
+                    LLColor3 col = volume->getLightLinearColor() * light_scale;
 
                     gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
                     gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, light_size_final);
-- 
cgit v1.2.3