From fc8d0de673da0e02915556008a365aca67472eba Mon Sep 17 00:00:00 2001
From: Graham Linden <graham@lindenlab.com>
Date: Mon, 11 Jun 2018 22:39:57 +0100
Subject: Make cloud rendering use textures defined in sky settings and add
 code to shaders to lerp between current and next cloud texture.

---
 .../shaders/class1/deferred/cloudsF.glsl           | 14 +++++-
 .../app_settings/shaders/class1/deferred/skyF.glsl |  1 -
 .../shaders/class2/windlight/cloudsF.glsl          | 14 +++++-
 .../shaders/class2/windlight/skyF.glsl             |  1 -
 .../shaders/class3/deferred/cloudsF.glsl           | 15 +++++-
 .../app_settings/shaders/class3/deferred/skyF.glsl |  1 -
 indra/newview/lldrawpoolwlsky.cpp                  | 54 ++++------------------
 indra/newview/lldrawpoolwlsky.h                    |  4 --
 indra/newview/llsettingsvo.cpp                     |  1 +
 indra/newview/llsky.cpp                            |  7 +++
 indra/newview/llsky.h                              |  1 +
 indra/newview/llvosky.cpp                          | 21 +++++++++
 indra/newview/llvosky.h                            |  8 ++++
 13 files changed, 83 insertions(+), 59 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index 7b971fcc66..1a4cdff23d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -39,6 +39,8 @@ VARYING vec4 vary_CloudColorAmbient;
 VARYING float vary_CloudDensity;
 
 uniform sampler2D cloud_noise_texture;
+uniform sampler2D cloud_noise_texture_next;
+uniform float blend_factor;
 uniform vec4 cloud_pos_density1;
 uniform vec4 cloud_pos_density2;
 uniform vec4 gamma;
@@ -57,6 +59,14 @@ vec3 scaleSoftClip(vec3 light) {
 	return light;
 }
 
+vec4 cloudNoise(vec2 uv)
+{
+   vec4 a = texture2D(cloud_noise_texture, uv);
+   vec4 b = texture2D(cloud_noise_texture_next, uv);
+   vec4 cloud_noise_sample = mix(a, b, blend_factor);
+   return cloud_noise_sample;
+}
+
 void main()
 {
 	// Set variables
@@ -77,7 +87,7 @@ void main()
 
 
 	// Compute alpha1, the main cloud opacity
-	float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z;
+	float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
 	alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.);
 
 	// And smooth
@@ -87,7 +97,7 @@ void main()
 
 	// Compute alpha2, for self shadowing effect
 	// (1 - alpha2) will later be used as percentage of incoming sunlight
-	float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5);
+	float alpha2 = (cloudNoise(uv2).x - 0.5);
 	alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
 
 	// And smooth
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index 4511237e4d..8e4696cfaa 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -37,7 +37,6 @@ out vec4 frag_data[3];
 
 VARYING vec4 vary_HazeColor;
 
-uniform sampler2D cloud_noise_texture;
 uniform vec4 gamma;
 
 /// Soft clips the light with a gamma correction
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index 96c70651b1..e0c7e18a6f 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -42,6 +42,8 @@ VARYING vec2 vary_texcoord2;
 VARYING vec2 vary_texcoord3;
 
 uniform sampler2D cloud_noise_texture;
+uniform sampler2D cloud_noise_texture_next;
+uniform float blend_factor;
 uniform vec4 cloud_pos_density1;
 uniform vec4 cloud_pos_density2;
 uniform vec4 gamma;
@@ -55,6 +57,14 @@ vec3 scaleSoftClip(vec3 light) {
 	return light;
 }
 
+vec4 cloudNoise(vec2 uv)
+{
+    vec4 a = texture2D(cloud_noise_texture, uv);
+    vec4 b = texture2D(cloud_noise_texture_next, uv);
+    vec4 samp = mix(a, b, blend_factor);
+	return samp;
+}
+
 void main()
 {
 	// Set variables
@@ -75,7 +85,7 @@ void main()
 
 
 	// Compute alpha1, the main cloud opacity
-	float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z;
+	float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
 	alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.);
 
 	// And smooth
@@ -85,7 +95,7 @@ void main()
 
 	// Compute alpha2, for self shadowing effect
 	// (1 - alpha2) will later be used as percentage of incoming sunlight
-	float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5);
+	float alpha2 = (cloudNoise(uv2).x - 0.5);
 	alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
 
 	// And smooth
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
index 2a0ca35278..25fd0584f8 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
@@ -35,7 +35,6 @@ out vec4 frag_color;
 
 VARYING vec4 vary_HazeColor;
 
-uniform sampler2D cloud_noise_texture;
 uniform vec4 gamma;
 
 /// Soft clips the light with a gamma correction
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
index 96c70651b1..44b41cc0b8 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
@@ -42,10 +42,21 @@ VARYING vec2 vary_texcoord2;
 VARYING vec2 vary_texcoord3;
 
 uniform sampler2D cloud_noise_texture;
+uniform sampler2D cloud_noise_texture_next;
+uniform float blend_factor;
 uniform vec4 cloud_pos_density1;
 uniform vec4 cloud_pos_density2;
 uniform vec4 gamma;
 
+vec4 cloudNoise(vec2 uv)
+{
+	vec4 a = texture2D(cloud_noise_texture, uv);
+	vec4 b = texture2D(cloud_noise_texture_next, uv);
+    vec4 samp = mix(a, b, blend_factor);
+	return samp;
+}
+
+
 /// Soft clips the light with a gamma correction
 vec3 scaleSoftClip(vec3 light) {
 	//soft clip effect:
@@ -75,7 +86,7 @@ void main()
 
 
 	// Compute alpha1, the main cloud opacity
-	float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z;
+	float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
 	alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.);
 
 	// And smooth
@@ -85,7 +96,7 @@ void main()
 
 	// Compute alpha2, for self shadowing effect
 	// (1 - alpha2) will later be used as percentage of incoming sunlight
-	float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5);
+	float alpha2 = (cloudNoise(uv2).x - 0.5);
 	alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
 
 	// And smooth
diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
index 5185a9f8f4..a439aa64d7 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
@@ -36,7 +36,6 @@ uniform vec3 cameraPosLocal;
 uniform vec3 sun_dir;
 uniform float sun_size;
 
-uniform sampler2D cloud_noise_texture;
 uniform sampler2D transmittance_texture;
 uniform sampler3D scattering_texture;
 uniform sampler3D single_mie_scattering_texture;
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 3e74b06a7f..0126f1e2ca 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -46,10 +46,6 @@
 
 static LLStaticHashedString sCamPosLocal("camPosLocal");
 
-LLPointer<LLViewerTexture> LLDrawPoolWLSky::sCloudNoiseTexture = NULL;
-
-LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL;
-
 static LLGLSLShader* cloud_shader = NULL;
 static LLGLSLShader* sky_shader = NULL;
 static LLGLSLShader* moon_shader = NULL;
@@ -57,40 +53,10 @@ static LLGLSLShader* moon_shader = NULL;
 LLDrawPoolWLSky::LLDrawPoolWLSky(void) :
 	LLDrawPool(POOL_WL_SKY)
 {
-	const std::string cloudNoiseFilename(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "clouds2.tga"));
-	LL_INFOS() << "loading WindLight cloud noise from " << cloudNoiseFilename << LL_ENDL;
-
-	LLPointer<LLImageFormatted> cloudNoiseFile(LLImageFormatted::createFromExtension(cloudNoiseFilename));
-
-	if(cloudNoiseFile.isNull()) {
-		LL_ERRS() << "Error: Failed to load cloud noise image " << cloudNoiseFilename << LL_ENDL;
-	}
-
-	if(cloudNoiseFile->load(cloudNoiseFilename))
-	{
-		sCloudNoiseRawImage = new LLImageRaw();
-
-		if(cloudNoiseFile->decode(sCloudNoiseRawImage, 0.0f))
-		{
-			//debug use			
-			LL_DEBUGS() << "cloud noise raw image width: " << sCloudNoiseRawImage->getWidth() << " : height: " << sCloudNoiseRawImage->getHeight() << " : components: " << 
-				(S32)sCloudNoiseRawImage->getComponents() << " : data size: " << sCloudNoiseRawImage->getDataSize() << LL_ENDL ;
-			llassert_always(sCloudNoiseRawImage->getData()) ;
-
-			sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
-		}
-		else
-		{
-			sCloudNoiseRawImage = NULL ;
-		}
-	}
 }
 
 LLDrawPoolWLSky::~LLDrawPoolWLSky()
 {
-	//LL_INFOS() << "destructing wlsky draw pool." << LL_ENDL;
-	sCloudNoiseTexture = NULL;
-	sCloudNoiseRawImage = NULL;
 }
 
 LLViewerTexture *LLDrawPoolWLSky::getDebugTexture()
@@ -192,9 +158,10 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
         sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, light_dir.mV);
 
         // clouds are rendered along with sky in adv atmo
-        if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && sCloudNoiseTexture.notNull())
+        if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
         {
-            sky_shader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, sCloudNoiseTexture);
+            sky_shader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, gSky.mVOSkyp->getCloudNoiseTex());
+            sky_shader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, gSky.mVOSkyp->getCloudNoiseTexNext());
         }
 
         renderFsSky(camPosLocal, camHeightLocal, sky_shader);
@@ -280,22 +247,23 @@ void LLDrawPoolWLSky::renderStars(void) const
 
 void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal) const
 {
-#if REMOVE_BEFORE_FLIGHT
-	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && sCloudNoiseTexture.notNull())
+	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
 	{
 		LLGLEnable blend(GL_BLEND);
 		gGL.setSceneBlendType(LLRender::BT_ALPHA);
 		
-		gGL.getTexUnit(0)->bind(sCloudNoiseTexture);
+		gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getCloudNoiseTex());
+        gGL.getTexUnit(1)->bind(gSky.mVOSkyp->getCloudNoiseTexNext());
 
 		cloud_shader->bind();
+        F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
+        cloud_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
 
 		/// Render the skydome
         renderDome(camPosLocal, camHeightLocal, cloud_shader);
 
 		cloud_shader->unbind();
 	}
-#endif
 }
 
 void LLDrawPoolWLSky::renderHeavenlyBodies()
@@ -477,15 +445,9 @@ void LLDrawPoolWLSky::resetDrawOrders()
 //static
 void LLDrawPoolWLSky::cleanupGL()
 {
-	sCloudNoiseTexture = NULL;
 }
 
 //static
 void LLDrawPoolWLSky::restoreGL()
 {
-	if(sCloudNoiseRawImage.notNull())
-	{
-		sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
-	}
 }
-
diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
index 2beb2867db..db08d9b99a 100644
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -81,10 +81,6 @@ private:
 	void renderStars(void) const;
 	void renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal) const;
 	void renderHeavenlyBodies();
-
-private:
-	static LLPointer<LLViewerTexture> sCloudNoiseTexture;
-	static LLPointer<LLImageRaw> sCloudNoiseRawImage;
 };
 
 #endif // LL_DRAWPOOLWLSKY_H
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 0ec7db2ed7..95bcf127ae 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -522,6 +522,7 @@ void LLSettingsVOSky::updateSettings()
     gSky.setSunAndMoonDirectionsCFR(sun_direction_cfr, moon_direction_cfr);
     gSky.setSunTextures(getSunTextureId(), getNextSunTextureId());
     gSky.setMoonTextures(getMoonTextureId(), getNextMoonTextureId());
+    gSky.setCloudNoiseTextures(getCloudNoiseTextureId(), getNextCloudNoiseTextureId());
 }
 
 void LLSettingsVOSky::applySpecial(void *ptarget)
diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp
index 6b7db9bb01..5d85778da5 100644
--- a/indra/newview/llsky.cpp
+++ b/indra/newview/llsky.cpp
@@ -143,6 +143,13 @@ void LLSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_textu
 	}
 }
 
+void LLSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next)
+{
+    if(mVOSkyp.notNull()) {
+        mVOSkyp->setCloudNoiseTextures(cloud_noise_texture, cloud_noise_texture_next);
+	}
+}
+
 void LLSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_direction, const LLVector3 &moon_direction)
 {
     if(mVOSkyp.notNull()) {
diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h
index b618b9bfe6..cc5db2c7ec 100644
--- a/indra/newview/llsky.h
+++ b/indra/newview/llsky.h
@@ -58,6 +58,7 @@ public:
 
     void setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next);
     void setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next);
+    void setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next);
 
 	LLColor4 getSkyFogColor() const;
 
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 359415b185..e8ca286074 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -816,6 +816,27 @@ void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_tex
     }
 }
 
+void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next)
+{
+    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+    LLUUID cloud_noise_tex = cloud_noise_texture.isNull() ? psky->GetDefaultCloudNoiseTextureId() : cloud_noise_texture;
+    LLUUID cloud_noise_tex_next = cloud_noise_texture_next.isNull() ? (cloud_noise_texture.isNull() ? psky->GetDefaultCloudNoiseTextureId() : cloud_noise_texture) : cloud_noise_texture_next;
+
+    mCloudNoiseTexturep[0] = LLViewerTextureManager::getFetchedTexture(cloud_noise_tex, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+    mCloudNoiseTexturep[1] = LLViewerTextureManager::getFetchedTexture(cloud_noise_tex_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+
+    if (mCloudNoiseTexturep[0])
+    {
+	    mCloudNoiseTexturep[0]->setAddressMode(LLTexUnit::TAM_WRAP);
+    }
+
+    if (mCloudNoiseTexturep[1])
+    {
+	    mCloudNoiseTexturep[1]->setAddressMode(LLTexUnit::TAM_WRAP);
+    }
+}
+
 static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Sky Geometry");
 
 BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index d6d294de6a..d7f7700dd0 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -272,9 +272,16 @@ public:
 	LLViewerTexture*	getSunTex() const					{ return mSunTexturep[0];   }
 	LLViewerTexture*	getMoonTex() const					{ return mMoonTexturep[0];  }
 	LLViewerTexture*	getBloomTex() const					{ return mBloomTexturep;    }
+    LLViewerTexture*	getCloudNoiseTex() const			{ return mCloudNoiseTexturep[0]; }
+
+    LLViewerTexture*	getSunTexNext() const					{ return mSunTexturep[1];   }
+	LLViewerTexture*	getMoonTexNext() const					{ return mMoonTexturep[1];  }
+	LLViewerTexture*	getBloomTexNext() const					{ return mBloomTexturep;    }
+    LLViewerTexture*	getCloudNoiseTexNext() const			{ return mCloudNoiseTexturep[1]; }
 
     void setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next);
     void setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next);
+    void setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next);
 
 	void forceSkyUpdate(void)							{ mForceUpdate = TRUE; }
 
@@ -292,6 +299,7 @@ protected:
 
 	LLPointer<LLViewerFetchedTexture> mSunTexturep[2];
 	LLPointer<LLViewerFetchedTexture> mMoonTexturep[2];
+    LLPointer<LLViewerFetchedTexture> mCloudNoiseTexturep[2];
 	LLPointer<LLViewerFetchedTexture> mBloomTexturep;
 
 	static S32			sResolution;
-- 
cgit v1.2.3