From 56355cf35412589b0a171f33b7962fd3800c734a Mon Sep 17 00:00:00 2001
From: Graham Linden <graham@lindenlab.com>
Date: Tue, 30 Oct 2018 15:56:08 +0100
Subject: [PATCH] SL-9966

Port over transport, gamma, atmospherics shader stub updates for per-fragment atmospherics.

Fix bindings of current/next noise map when current and next are the same (select only one and force blend factor to 0).
---
 .../class1/windlight/atmosphericsF.glsl       | 21 +++-
 .../shaders/class1/windlight/gammaF.glsl      | 21 +++-
 .../shaders/class1/windlight/transportF.glsl  | 25 ++++-
 .../shaders/class2/windlight/cloudsF.glsl     | 32 ++++--
 indra/newview/lldrawpoolwlsky.cpp             | 99 ++++++++++++++-----
 5 files changed, 151 insertions(+), 47 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
index 584bd568c5f..bf0a9048f03 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
@@ -23,16 +23,29 @@
  * $/LicenseInfo$
  */
  
+vec3 atmosFragAmbient(vec3 light, vec3 sunlit)
+{
+   return light;
+}
 
-
-vec3 atmosLighting(vec3 light)
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
 {
 	/* stub function for fallback compatibility on class1 hardware */
-	return light;
+   return light;
 }
 
+vec3 atmosFragAffectDirectionalLight(float light, vec3 sunlit)
+{
+   return light * sunlit;
+}
 
-void calcFragAtmospherics(vec3 inPositionEye, float ambFactor) {
+vec3 atmosLighting(vec3 light)
+{
+	return atmosFragLighting(light, vec3(0), vec3(1.0));
+}
+
+void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive)
+{
 	/* stub function for fallback compatibility on class1 hardware */
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
index 62f4e514494..b7f117fc5f7 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
@@ -23,17 +23,28 @@
  * $/LicenseInfo$
  */
  
-
-
+uniform int no_atmo;
 uniform vec4 gamma;
 
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
+vec3 scaleFragSoftClip(vec3 light)
+{
 	// For compatibility with lower cards. Do nothing.
 	return light;
 }
 
+/// Soft clips the light with a gamma correction
+vec3 scaleSoftClip(vec3 light)
+{
+	// For compatibility with lower cards. Do nothing.
+	return scaleFragSoftClip(light);
+}
+
+vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 atten)
+{
+	return (no_atmo == 1) ? light : mix(scaleFragSoftClip(light.rgb), light.rgb, atten);
+}
+
 vec3 fullbrightScaleSoftClip(vec3 light) {
-	return scaleSoftClip(light);
+    return fullbrightScaleSoftClipFrag(light, vec3(1));
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
index 7c95ecdb140..c3c83290173 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
@@ -22,25 +22,40 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+uniform int no_atmo;
 
-vec3 atmosTransport(vec3 light)
+vec3 atmosFragTransport(vec3 light, vec3 atten, vec3 additive)
 {
 	/* stub function for fallback compatibility on class1 hardware */
 	return light;
 }
 
-vec3 fullbrightAtmosTransport(vec3 light)
+vec3 fullbrightFragAtmosTransport(vec3 light, vec3 atten, vec3 additive)
 {
 	/* stub function for fallback compatibility on class1 hardware */
 	return light;
 }
 
+vec3 fullbrightFragShinyAtmosTransport(vec3 light, vec3 atten, vec3 additive)
+{
+	/* stub function for fallback compatibility on class1 hardware */
+    return light;
+}
 
-vec3 fullbrightShinyAtmosTransport(vec3 light)
+vec3 atmosTransport(vec3 light)
 {
 	/* stub function for fallback compatibility on class1 hardware */
-	return light;
+    return atmosFragTransport(light, vec3(1), vec3(0));
+}
+
+vec3 fullbrightAtmosTransport(vec3 light)
+{
+     return fullbrightFragAtmosTransport(light, vec3(1), vec3(0));
+}
+
+vec3 fullbrightShinyAtmosTransport(vec3 light)
+{
+    return fullbrightFragShinyAtmosTransport(light, vec3(1), vec3(0));
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index cdd84faba95..e3fa431ddfd 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -22,11 +22,13 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
+
+/*[EXTRA_CODE_HERE]*/ 
+
 #ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
+out vec4 frag_data[3];
 #else
-#define frag_color gl_FragColor
+#define frag_data gl_FragData
 #endif
 
 /////////////////////////////////////////////////////////////////////////
@@ -74,28 +76,37 @@ void main()
 	vec2 uv3 = vary_texcoord2.xy;
 	vec2 uv4 = vary_texcoord3.xy;
 
-    vec2 disturbance = vec2(cloudNoise(uv1 / 16.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+    vec2 disturbance  = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
+    vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
 
 	// Offset texture coords
-	uv1 += cloud_pos_density1.xy + disturbance;	//large texture, visible density
+	uv1 += cloud_pos_density1.xy + (disturbance * 0.02);	//large texture, visible density
 	uv2 += cloud_pos_density1.xy;	//large texture, self shadow
-	uv3 += cloud_pos_density2.xy + disturbance;	//small texture, visible density
+	uv3 += cloud_pos_density2.xy;	//small texture, visible density
 	uv4 += cloud_pos_density2.xy;	//small texture, self shadow
 
+    float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y));
+
+    cloudDensity *= 1.0 - (density_variance * density_variance);
 
 	// Compute alpha1, the main cloud opacity
 
 	float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
-	alpha1 = min(max(alpha1 + cloudDensity, 0.) * (10. + disturbance.y) * cloud_pos_density1.z, 1.);
+	alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
 
 	// And smooth
 	alpha1 = 1. - alpha1 * alpha1;
 	alpha1 = 1. - alpha1 * alpha1;	
 
+    if (alpha1 < 0.001f)
+    {
+        discard;
+    }
+
 	// Compute alpha2, for self shadowing effect
 	// (1 - alpha2) will later be used as percentage of incoming sunlight
 	float alpha2 = (cloudNoise(uv2).x - 0.5);
-	alpha2 = min(max(alpha2 + cloudDensity, 0.) * (2.5 + disturbance.x) * cloud_pos_density1.z, 1.);
+	alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
 
 	// And smooth
 	alpha2 = 1. - alpha2;
@@ -107,7 +118,8 @@ void main()
 	color *= 2.;
 
 	/// Gamma correct for WL (soft clip effect).
-	frag_color.rgb = scaleSoftClip(color.rgb);
-	frag_color.a = alpha1;
+	frag_data[0] = vec4(scaleSoftClip(color.rgb), alpha1);
+	frag_data[1] = vec4(0.0,0.0,0.0,0.0);
+	frag_data[2] = vec4(0,0,1,0);
 }
 
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index d6b062f5f6f..9f3cf8f78e0 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -29,20 +29,20 @@
 #include "lldrawpoolwlsky.h"
 
 #include "llerror.h"
-#include "llgl.h"
-#include "pipeline.h"
-#include "llviewercamera.h"
+#include "llface.h"
 #include "llimage.h"
-#include "llviewershadermgr.h"
+#include "llrender.h"
+#include "llatmosphere.h"
+#include "llenvironment.h" 
 #include "llglslshader.h"
+#include "llgl.h"
+
+#include "llviewerregion.h"
+#include "llviewershadermgr.h"
+#include "llviewercamera.h"
+#include "pipeline.h"
 #include "llsky.h"
 #include "llvowlsky.h"
-#include "llviewerregion.h"
-#include "llface.h"
-#include "llrender.h"
-
-#include "llenvironment.h" 
-#include "llatmosphere.h"
 
 static LLStaticHashedString sCamPosLocal("camPosLocal");
 static LLStaticHashedString sCustomAlpha("custom_alpha");
@@ -406,10 +406,6 @@ void LLDrawPoolWLSky::renderSkyCloudsAdvanced(const LLVector3& camPosLocal, F32
         LLPointer<LLViewerTexture> cloud_noise      = gSky.mVOSkyp->getCloudNoiseTex();
         LLPointer<LLViewerTexture> cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext();
 
-        S32 cloud_channel      = cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise);
-        S32 cloud_next_channel = cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, gSky.mVOSkyp->getCloudNoiseTexNext());
-        (void)cloud_channel, (void)cloud_next_channel;
-
         gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
         gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
 
@@ -459,6 +455,9 @@ void LLDrawPoolWLSky::renderSkyCloudsAdvanced(const LLVector3& camPosLocal, F32
         renderDome(camPosLocal, camHeightLocal, cloudshader);
 
 		cloudshader->unbind();
+
+        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+        gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
 	}
 }
 
@@ -466,17 +465,41 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32
 {
 	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
 	{
+        LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
 		LLGLSPipelineBlendSkyBox pipeline(true, true);
 		
 		cloudshader->bind();
 
-        cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, gSky.mVOSkyp->getCloudNoiseTex());
-        cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, gSky.mVOSkyp->getCloudNoiseTexNext());
-        
-        LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+        LLPointer<LLViewerTexture> cloud_noise      = gSky.mVOSkyp->getCloudNoiseTex();
+        LLPointer<LLViewerTexture> cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext();
+
+        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+        gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
 
-        F32 blend_factor   = psky ? psky->getBlendFactor()   : 0.0f;
         F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
+        F32 blend_factor   = psky ? psky->getBlendFactor() : 0.0f;
+
+        // if we even have sun disc textures to work with...
+        if (cloud_noise || cloud_noise_next)
+        {
+            if (cloud_noise && (!cloud_noise_next || (cloud_noise == cloud_noise_next)))
+            {
+                // Bind current and next sun textures
+                cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+                blend_factor = 0;
+            }
+            else if (cloud_noise_next && !cloud_noise)
+            {
+                cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+                blend_factor = 0;
+            }
+            else if (cloud_noise_next != cloud_noise)
+            {
+                cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+                cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+            }
+        }
 
         cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
         cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
@@ -485,6 +508,9 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32
         renderDome(camPosLocal, camHeightLocal, cloudshader);
 
 		cloudshader->unbind();
+
+        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+        gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
 	}
 }
 
@@ -492,17 +518,41 @@ void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeigh
 {
 	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
 	{
+        LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
         LLGLSPipelineBlendSkyBox pipeline(true, true);
 		
 		cloudshader->bind();
 
-        cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, gSky.mVOSkyp->getCloudNoiseTex());
-        cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, gSky.mVOSkyp->getCloudNoiseTexNext());
+        LLPointer<LLViewerTexture> cloud_noise      = gSky.mVOSkyp->getCloudNoiseTex();
+        LLPointer<LLViewerTexture> cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext();
 
-        LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+        gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
 
-        F32 blend_factor   = psky ? psky->getBlendFactor()   : 0.0f;
         F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
+        F32 blend_factor   = psky ? psky->getBlendFactor() : 0.0f;
+
+        // if we even have sun disc textures to work with...
+        if (cloud_noise || cloud_noise_next)
+        {
+            if (cloud_noise && (!cloud_noise_next || (cloud_noise == cloud_noise_next)))
+            {
+                // Bind current and next sun textures
+                cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+                blend_factor = 0;
+            }
+            else if (cloud_noise_next && !cloud_noise)
+            {
+                cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+                blend_factor = 0;
+            }
+            else if (cloud_noise_next != cloud_noise)
+            {
+                cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+                cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+            }
+        }
 
         cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
         cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
@@ -511,6 +561,9 @@ void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeigh
         renderDome(camPosLocal, camHeightLocal, cloudshader);
 
 		cloudshader->unbind();
+
+        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+        gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
 	}
 }
 
-- 
GitLab