diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 4763215cffec659ff464a8b0b908a561428a2965..38574c4ef8202e9c646e6b285f177172ac89a59f 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -602,8 +602,8 @@ LLSD LLSettingsSky::defaults()
 
     dfltsetting[SETTING_BLOOM_TEXTUREID]    = IMG_BLOOM1;
     dfltsetting[SETTING_CLOUD_TEXTUREID]    = DEFAULT_CLOUD_ID;
-    dfltsetting[SETTING_MOON_TEXTUREID]     = DEFAULT_MOON_ID; // gMoonTextureID;   // These two are returned by the login... wow!
-    dfltsetting[SETTING_SUN_TEXTUREID]      = DEFAULT_SUN_ID;  // gSunTextureID;
+    dfltsetting[SETTING_MOON_TEXTUREID]     = GetDefaultMoonTextureId();
+    dfltsetting[SETTING_SUN_TEXTUREID]      = GetDefaultSunTextureId();
 
     dfltsetting[SETTING_TYPE] = "sky";
 
@@ -1053,3 +1053,13 @@ LLUUID LLSettingsSky::GetDefaultAssetId()
 {
     return DEFAULT_ASSET_ID;
 }
+
+LLUUID LLSettingsSky::GetDefaultSunTextureId()
+{
+    return DEFAULT_SUN_ID;
+}
+
+LLUUID LLSettingsSky::GetDefaultMoonTextureId()
+{
+    return DEFAULT_MOON_ID;
+}
diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h
index fd613e429929ab994627eedd6851f71d2f2d2a3e..0cdd0646248f45ec51f7959247a7cb98104f8d51 100644
--- a/indra/llinventory/llsettingssky.h
+++ b/indra/llinventory/llsettingssky.h
@@ -412,6 +412,8 @@ class LLSettingsSky: public LLSettingsBase
     virtual LLSettingsBase::ptr_t buildDerivedClone() SETTINGS_OVERRIDE { return buildClone(); }
 
     static LLUUID GetDefaultAssetId();
+    static LLUUID GetDefaultSunTextureId();
+    static LLUUID GetDefaultMoonTextureId();
 
 protected:
     static const std::string SETTING_LEGACY_EAST_ANGLE;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 37bcf0c16380d28d266eb3cc0105ebc37b28597d..ff79efcc5b9bf70eda3f673c97f9f7fff64dcee2 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -767,18 +767,19 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
 	S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap");
 	S32 specularMap = glGetUniformLocationARB(mProgramObject, "specularMap");
 	S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");
+    S32 altDiffuseMap = glGetUniformLocationARB(mProgramObject, "altDiffuseMap");
 	S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");
 
 	std::set<S32> skip_index;
 
-	if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap))
+	if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap || -1 != altDiffuseMap))
 	{
 		GLenum type;
 		GLsizei length;
 		GLint size = -1;
 		char name[1024];
 
-		diffuseMap = specularMap = bumpMap = environmentMap = -1;
+		diffuseMap = altDiffuseMap = specularMap = bumpMap = environmentMap = -1;
 
 		for (S32 i = 0; i < activeCount; i++)
 		{
@@ -815,6 +816,12 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
 				environmentMap = i;
 				continue;
 			}
+
+            if (-1 == altDiffuseMap && std::string(name) == "altDiffuseMap")
+			{
+				altDiffuseMap = i;
+				continue;
+			}
 		}
 
 		bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 1bc5e89eacaa497708a2b82644f6bd37dfcc3b95..62cd526550dc37907ba7aff4db67e728b4f4cae1 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -265,10 +265,11 @@ class LLRender
 
 	enum eTexIndex
 	{
-		DIFFUSE_MAP = 0,
-		NORMAL_MAP,
-		SPECULAR_MAP,
-		NUM_TEXTURE_CHANNELS,
+		DIFFUSE_MAP           = 0,
+        ALTERNATE_DIFFUSE_MAP = 1,
+		NORMAL_MAP            = 1,
+		SPECULAR_MAP          = 2,        
+		NUM_TEXTURE_CHANNELS  = 3,
 	};
 
 	enum eVolumeTexIndex
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index f00d97cd47318ca785ead1b9d585ded324af28a0..ebdfbd89b2acd49dc57539a507738aa57809038c 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -552,8 +552,8 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string&
 
 	if (log.length() > 0)
 	{
-        LL_DEBUGS() << "Shader loading from " << fname << ":\n" << LL_ENDL;
-        LL_DEBUGS() << log << LL_ENDL;
+        LL_WARNS("ShaderLoading") << "Shader loading from " << fname << ":\n" << LL_ENDL;
+        LL_WARNS("ShaderLoading") << log << LL_ENDL;
 	}
  }
 
@@ -1144,6 +1144,7 @@ void LLShaderMgr::initAttribsAndUniforms()
 	mReservedUniforms.push_back("color");
 		
 	mReservedUniforms.push_back("diffuseMap");
+    mReservedUniforms.push_back("altDiffuseMap");
 	mReservedUniforms.push_back("specularMap");
 	mReservedUniforms.push_back("bumpMap");
 	mReservedUniforms.push_back("environmentMap");
@@ -1309,6 +1310,7 @@ void LLShaderMgr::initAttribsAndUniforms()
     mReservedUniforms.push_back("scattering_texture");
     mReservedUniforms.push_back("single_mie_scattering_texture");
     mReservedUniforms.push_back("irradiance_texture");
+    mReservedUniforms.push_back("blend_factor");
 
 	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
 
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 9919dbe31a7926b95741ac2f34115d6ab72b18af..3fac21883f096b14addfca0cc43be646a8949b66 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -74,6 +74,7 @@ class LLShaderMgr
 		PROJECTOR_AMBIENT_LOD,
 		DIFFUSE_COLOR,
 		DIFFUSE_MAP,
+        ALTERNATE_DIFFUSE_MAP,
 		SPECULAR_MAP,
 		BUMP_MAP,
 		ENVIRONMENT_MAP,
@@ -227,6 +228,7 @@ class LLShaderMgr
         SCATTER_TEX,
         SINGLE_MIE_SCATTER_TEX,
         ILLUMINANCE_TEX,
+        BLEND_FACTOR,
 
 		END_RESERVED_UNIFORMS
 	} eGLSLReservedUniforms;
diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
index 0d8dab0a4191bd347c4ffb559118a2f578330373..e918bdcb9de4188ea8eed393c7142cbeeeaa1c72 100644
--- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
@@ -56,41 +56,7 @@ VARYING vec4 refCoord;
 VARYING vec4 littleWave;
 VARYING vec4 view;
 
-vec4 applyWaterFog(vec4 color, vec3 viewVec)
-{
-	//normalize view vector
-	vec3 view = normalize(viewVec);
-	float es = -view.z;
-
-	//find intersection point with water plane and eye vector
-	
-	//get eye depth
-	float e0 = max(-waterPlane.w, 0.0);
-	
-	//get object depth
-	float depth = length(viewVec);
-		
-	//get "thickness" of water
-	float l = max(depth, 0.1);
-
-	float kd = waterFogDensity;
-	float ks = waterFogKS;
-	vec4 kc = waterFogColor;
-	
-	float F = 0.98;
-	
-	float t1 = -kd * pow(F, ks * e0);
-	float t2 = kd + ks * es;
-	float t3 = pow(F, t2*l) - 1.0;
-	
-	float L = min(t1/t2*t3, 1.0);
-	
-	float D = pow(0.98, l*kd);
-	//return vec4(1.0, 0.0, 1.0, 1.0);
-	return color * D + kc * L;
-	//depth /= 10.0;
-	//return vec4(depth,depth,depth,0.0);
-}
+vec4 applyWaterFogView(vec3 pos, vec4 color);
 
 void main() 
 {
@@ -108,5 +74,5 @@ void main()
 		
 	vec4 fb = texture2D(screenTex, distort);
 	
-	frag_color = applyWaterFog(fb,view.xyz);
+	frag_color = applyWaterFogView(view.xyz, fb);
 }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
index 14b08b1da4476341855de1ffed46c8d25608ec8a..4d0d8882b9b9e1dcdc5d9f93ca99cba0915d8977 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
@@ -41,18 +41,23 @@ uniform vec4 sunlight_color;
 uniform vec3 lumWeights;
 uniform float minLuminance;
 uniform sampler2D diffuseMap;
+uniform sampler2D altDiffuseMap;
+uniform float blend_factor; // interp factor between moon A/B
 VARYING vec2 vary_texcoord0;
 
 void main() 
 {
-	vec4 c = texture2D(diffuseMap, vary_texcoord0.xy);
+	vec4 moonA = texture2D(diffuseMap, vary_texcoord0.xy);
+	vec4 moonB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+    vec4 c     = mix(moonA, moonB, blend_factor);
+
 	c.rgb = fullbrightAtmosTransport(c.rgb);
     c.rgb = fullbrightScaleSoftClip(c.rgb);
     c.rgb = pow(c.rgb, vec3(0.45f));
     // mix factor which blends when sunlight is brighter
     // and shows true moon color at night
     float mix = dot(normalize(sunlight_color.rgb), lumWeights);
-    mix = smoothstep(-0.5f, 2.0f, lum);
+    mix = smoothstep(-0.5f, 2.0f, mix);
 	frag_color = vec4(c.rgb, mix * c.a);
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 371b32406cd14595e24c1dc97ee3d87b9e9c6ea8..9f56bff4c2cf6219242034eb291932351dbb1b41 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -105,7 +105,7 @@ vec4 getPosition(vec2 pos_screen)
 
 
 #ifdef WATER_FOG
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color);
+vec4 applyWaterFogView(vec3 pos, vec4 color);
 #endif
 
 void main() 
@@ -198,7 +198,7 @@ void main()
 		}
 
 		#ifdef WATER_FOG
-			vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
+			vec4 fogged = applyWaterFogView(pos,vec4(col, bloom));
 			col = fogged.rgb;
 			bloom = fogged.a;
 		#endif
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 9cd59c61ec27f01ef3e2b9ea1a4598ae0ec993b9..1ecf0ab8f94d6d27aa6df85f0b1249a4960ad2b1 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -68,15 +68,6 @@ F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
 LLDrawPoolWater::LLDrawPoolWater() :
 	LLFacePool(POOL_WATER)
 {
-	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
-	gGL.getTexUnit(0)->bind(mHBTex[0]) ;
-	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
-
-	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
-	gGL.getTexUnit(0)->bind(mHBTex[1]);
-	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
-
-
 	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE);
 	llassert(mWaterImagep);
 	mWaterImagep->setNoDelete();
@@ -461,7 +452,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
 
 	LLGLSNoFog noFog;
 
-	gGL.getTexUnit(0)->bind(mHBTex[dr]);
+	gGL.getTexUnit(0)->bind((dr == 0) ? voskyp->getSunTex() : voskyp->getMoonTex());
 
 	LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));
 	face->renderIndexed();
@@ -536,14 +527,14 @@ void LLDrawPoolWater::shade()
 	
 	if (eyedepth < 0.f && LLPipeline::sWaterReflections)
 	{
-	if (deferred_render)
-	{
-			shader = &gDeferredUnderWaterProgram;
-	}
+	    if (deferred_render)
+	    {
+            shader = &gDeferredUnderWaterProgram;
+	    }
 		else
-	{
-		shader = &gUnderWaterProgram;
-	}
+        {
+	        shader = &gUnderWaterProgram;
+        }
 	}
 	else if (deferred_render)
 	{
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index 55f892d2499add3eb947cf75dcd36ce3c33705f5..5df84bc8f08b55c60a4ade826457c8c7382a7ff6 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -37,7 +37,6 @@ class LLWaterSurface;
 class LLDrawPoolWater: public LLFacePool
 {
 protected:
-	LLPointer<LLViewerTexture> mHBTex[2];
 	LLPointer<LLViewerTexture> mWaterImagep;
 	LLPointer<LLViewerTexture> mOpaqueWaterImagep;
 	LLPointer<LLViewerTexture> mWaterNormp;
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 7a7739da03f7fb25772fde0658fb6d0b7e495ccc..3e74b06a7f5b4db18890df7bc665d9d29499139e 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -338,6 +338,8 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
 			moon_shader->bind();
             moon_shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, color.mV);
             moon_shader->uniform3fv(LLShaderMgr::GLOW_LUM_WEIGHTS, 1, LLPipeline::RenderGlowLumWeights.mV);
+            F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
+            moon_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
 		}
 
 		LLFacePool::LLOverrideFaceColor color_override(this, color);
@@ -388,10 +390,11 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
 		    gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
 
 		    gDeferredStarProgram.bind();
-		    // *NOTE: have to bind a texture here since register combiners blending in
+		    // *NOTE: have to bind moon textures here since register combiners blending in
 		    // renderStars() requires something to be bound and we might as well only
-		    // bind the moon's texture once.		
-		    gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture());
+		    // bind the moon textures once.		
+		    gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(LLRender::DIFFUSE_MAP));
+            gGL.getTexUnit(1)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP));
 
 		    renderHeavenlyBodies();
 
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 3f2247c9c52de60f38ee3bd95c1bfa42ac29f3b2..1acb1650cdffbfaa809aa1c66a0148f30aba3d1c 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -306,6 +306,11 @@ void LLFace::setDiffuseMap(LLViewerTexture* tex)
 	setTexture(LLRender::DIFFUSE_MAP, tex);
 }
 
+void LLFace::setAlternateDiffuseMap(LLViewerTexture* tex)
+{
+    setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, tex);
+}
+
 void LLFace::setNormalMap(LLViewerTexture* tex)
 {
 	setTexture(LLRender::NORMAL_MAP, tex);
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index ee545acb94104c53bde604d81844acab02e1000f..8531df856105960b1df02e0d7dfebee313b3f86f 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -106,6 +106,7 @@ class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16>
 	void			setDiffuseMap(LLViewerTexture* tex);
 	void			setNormalMap(LLViewerTexture* tex);
 	void			setSpecularMap(LLViewerTexture* tex);
+    void			setAlternateDiffuseMap(LLViewerTexture* tex);
 	void            switchTexture(U32 ch, LLViewerTexture* new_texture);
 	void            dirtyTexture();
 	LLXformMatrix*	getXform()			const	{ return mXform; }
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 5991c42c97215522c4a96c4b4a69e6e968966efc..b5fb889669d2e7a6822520e576a3655aa2e414ee 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -520,6 +520,8 @@ void LLSettingsVOSky::updateSettings()
     LLVector3 sun_direction_cfr(sun_direction.mV[0],   -sun_direction.mV[1],  sun_direction.mV[2]);
     LLVector3 moon_direction_cfr(moon_direction.mV[0], -moon_direction.mV[1], moon_direction.mV[2]);
     gSky.setSunAndMoonDirectionsCFR(sun_direction_cfr, moon_direction_cfr);
+    gSky.setSunTextures(getSunTextureId(), getNextSunTextureId());
+    gSky.setMoonTextures(getMoonTextureId(), getNextMoonTextureId());
 }
 
 void LLSettingsVOSky::applySpecial(void *ptarget)
diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp
index bb108fa6ac3815e95c8b5828548b275fa30ba16a..6b7db9bb01cfd162e726f753d0d8f4c42cf11bef 100644
--- a/indra/newview/llsky.cpp
+++ b/indra/newview/llsky.cpp
@@ -129,6 +129,20 @@ void LLSky::resetVertexBuffers()
 	}
 }
 
+void LLSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next)
+{
+    if(mVOSkyp.notNull()) {
+        mVOSkyp->setSunTextures(sun_texture, sun_texture_next);
+	}
+}
+
+void LLSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next)
+{
+    if(mVOSkyp.notNull()) {
+        mVOSkyp->setMoonTextures(moon_texture, moon_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 4b3b06b33f7979ae19574a8059d478fc12d9c22c..b618b9bfe62eef3546741e0e5d3e781bdee93f3c 100644
--- a/indra/newview/llsky.h
+++ b/indra/newview/llsky.h
@@ -56,6 +56,9 @@ class LLSky
     void setSunDirectionCFR(const LLVector3 &sun_direction);
     void setMoonDirectionCFR(const LLVector3 &moon_direction);
 
+    void setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next);
+    void setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next);
+
 	LLColor4 getSkyFogColor() const;
 
 	void setCloudDensityAtAgent(F32 cloud_density);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index e7a149ac0cd1b8c24925d58cfa942f800c6b7793..7430a2578f685813b4268cddb7d5650b08395f20 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -3499,6 +3499,8 @@ bool process_login_success_response()
 		}
 	}
 
+// LAPRAS
+#if 0
 	LLSD global_textures = response["global-textures"][0];
 	if(global_textures.size())
 	{
@@ -3516,8 +3518,8 @@ bool process_login_success_response()
 		{
 			gMoonTextureID = id;
 		}
-
 	}
+#endif
 
 	// set the location of the Agent Appearance service, from which we can request
 	// avatar baked textures if they are supported by the current region
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 48c72d8dc0002e574017819a9b120672d8d04580..ebbf331d30c73261c3ef9acfb1737c6234260def 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -1060,12 +1060,12 @@ BOOL LLViewerShaderMgr::loadShadersWater()
 		//load under water vertex shader
 		gUnderWaterProgram.mName = "Underwater Shader";
 		gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
+        gUnderWaterProgram.mFeatures.hasWaterFog = true;
 		gUnderWaterProgram.mShaderFiles.clear();
 		gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
 		gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
-		gUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER];
-		gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		
+		gUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER];        
+		gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;		
 		success = gUnderWaterProgram.createShader(NULL, NULL);
 	}
 
@@ -1860,6 +1860,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		// load water shader
 		gDeferredUnderWaterProgram.mName = "Deferred Under Water Shader";
 		gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
+        gDeferredUnderWaterProgram.mFeatures.hasWaterFog = true;
 		gDeferredUnderWaterProgram.mFeatures.hasGamma = true;
 		gDeferredUnderWaterProgram.mFeatures.hasTransport = true;
 		gDeferredUnderWaterProgram.mFeatures.hasSrgb = true;
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 6d066ecfd9e8d59612863b321b43da8cb029b759..359415b185d3f62c03e27ae296f52840d2977834 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -74,9 +74,10 @@ static const LLVector2 TEX11 = LLVector2(1.f, 1.f);
 static const F32 LIGHT_DIRECTION_THRESHOLD = (F32) cosf(DEG_TO_RAD * 1.f);
 static const F32 COLOR_CHANGE_THRESHOLD = 0.01f;
 
+// LAPRAS
 // Exported globals
-LLUUID gSunTextureID = IMG_SUN;
-LLUUID gMoonTextureID = IMG_MOON;
+//LLUUID gSunTextureID = IMG_SUN;
+//LLUUID gMoonTextureID = IMG_MOON;
 
 /***************************************
 		SkyTex
@@ -387,10 +388,11 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
 	mSun.setIntensity(SUN_INTENSITY);
 	mMoon.setIntensity(0.1f * SUN_INTENSITY);
 
-	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
-	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
-	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
-	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
+	//mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+	//mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
+	//mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+	//mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
+
 	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
 	mBloomTexturep->setNoDelete() ;
 	mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -481,10 +483,15 @@ void LLVOSky::restoreGL()
 	{
 		mSkyTex[i].restoreGL();
 	}
-	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
-	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
-	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
-	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
+
+    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+    if (psky)
+    {
+        setSunTextures(psky->getSunTextureId(), psky->getNextSunTextureId());
+        setMoonTextures(psky->getMoonTextureId(), psky->getNextMoonTextureId());
+    }
+
 	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
 	mBloomTexturep->setNoDelete() ;
 	mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -715,10 +722,28 @@ bool LLVOSky::updateSky()
 
 void LLVOSky::updateTextures()
 {
-	if (mSunTexturep)
+	if (mSunTexturep[0])
+	{
+		mSunTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA );
+    }
+
+    if (mSunTexturep[1])
+	{
+		mSunTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA );
+    }
+
+    if (mMoonTexturep[0])
+	{
+		mMoonTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA );
+    }
+
+    if (mMoonTexturep[1])
 	{
-		mSunTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
-		mMoonTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
+		mMoonTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA );
+    }   
+
+    if (mBloomTexturep)
+    {
 		mBloomTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
 	}
 }
@@ -737,13 +762,60 @@ LLDrawable *LLVOSky::createDrawable(LLPipeline *pipeline)
 		mFace[FACE_SIDE0 + i] = mDrawable->addFace(poolp, NULL);
 	}
 
-	mFace[FACE_SUN] = mDrawable->addFace(poolp, mSunTexturep);
-	mFace[FACE_MOON] = mDrawable->addFace(poolp, mMoonTexturep);
-	mFace[FACE_BLOOM] = mDrawable->addFace(poolp, mBloomTexturep);
+	mFace[FACE_SUN]   = mDrawable->addFace(poolp, nullptr);
+	mFace[FACE_MOON]  = mDrawable->addFace(poolp, nullptr);
+	mFace[FACE_BLOOM] = mDrawable->addFace(poolp, nullptr);
 
 	return mDrawable;
 }
 
+void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next)
+{
+    mSunTexturep[0] = LLViewerTextureManager::getFetchedTexture(sun_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+    mSunTexturep[1] = LLViewerTextureManager::getFetchedTexture(sun_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+
+    if (mFace[FACE_SUN])
+    {
+        if (mSunTexturep[0])
+        {
+	        mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+        }
+        mFace[FACE_SUN]->setTexture(LLRender::DIFFUSE_MAP, mSunTexturep[0]);
+    
+        if (mSunTexturep[1])
+        {
+	        mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+            mFace[FACE_SUN]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mSunTexturep[1]);
+        }
+    }
+}
+
+void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next)
+{
+    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+    LLUUID moon_tex = moon_texture.isNull() ? psky->GetDefaultMoonTextureId() : moon_texture;
+    LLUUID moon_tex_next = moon_texture_next.isNull() ? (moon_texture.isNull() ? psky->GetDefaultMoonTextureId() : moon_texture) : moon_texture_next;
+
+    mMoonTexturep[0] = LLViewerTextureManager::getFetchedTexture(moon_tex, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+    mMoonTexturep[1] = LLViewerTextureManager::getFetchedTexture(moon_tex_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+
+    if (mFace[FACE_MOON])
+    {
+        if (mMoonTexturep[0])
+        {
+	        mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+        }
+        mFace[FACE_MOON]->setTexture(LLRender::DIFFUSE_MAP, mMoonTexturep[0]);
+    
+        if (mMoonTexturep[1])
+        {
+	        mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+            mFace[FACE_MOON]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mMoonTexturep[1]);
+        }
+    }
+}
+
 static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Sky Geometry");
 
 BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
@@ -849,44 +921,18 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
 	const F32 height_above_water = camera_height - water_height;
 
 	bool sun_flag = FALSE;
-
 	if (mSun.isVisible())
-	{
-		if (mMoon.isVisible())
-		{
-			sun_flag = look_at * mSun.getDirection() > 0;
-		}
-		else
-		{
-			sun_flag = TRUE;
-		}
+	{        
+        sun_flag = !mMoon.isVisible() || ((look_at * mSun.getDirection()) > 0);
 	}
 	
-	if (height_above_water > 0)
-	{
-		bool render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0;
-
-		if (sun_flag)
-		{
-			setDrawRefl(0);
-			if (render_ref)
-			{
-				updateReflectionGeometry(drawable, height_above_water, mSun);
-			}
-		}
-		else
-		{
-			setDrawRefl(1);
-			if (render_ref)
-			{
-				updateReflectionGeometry(drawable, height_above_water, mMoon);
-			}
-		}
-	}
-	else
-	{
-		setDrawRefl(-1);
-	}
+    bool above_water = (height_above_water > 0);
+    bool render_ref  = above_water && gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0;
+    setDrawRefl(above_water ? (sun_flag ? 0 : 1) : -1);
+    if (render_ref)
+	{        
+        updateReflectionGeometry(drawable, height_above_water, mSun);
+    }
 
 	LLPipeline::sCompiles++;
 	return TRUE;
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 3d77c3f8e9a94d52040b85343cf808362ecf6025..d6d294de6a12f9d94844c4d9e29fe467cd6f0b9f 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -45,8 +45,8 @@ const F32 HEAVENLY_BODY_SCALE	= HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR;
 // HACK: Allow server to change sun and moon IDs.
 // I can't figure out how to pass the appropriate
 // information into the LLVOSky constructor.  JC
-extern LLUUID gSunTextureID;
-extern LLUUID gMoonTextureID;
+//extern LLUUID gSunTextureID;
+//extern LLUUID gMoonTextureID;
 
 class LLFace;
 class LLHaze;
@@ -269,9 +269,13 @@ class LLVOSky : public LLStaticViewerObject
 	bool isReflFace(const LLFace* face) const			{ return face == mFace[FACE_REFLECTION]; }
 	LLFace* getReflFace() const							{ return mFace[FACE_REFLECTION]; }
 
-	LLViewerTexture*	getSunTex() const					{ return mSunTexturep; }
-	LLViewerTexture*	getMoonTex() const					{ return mMoonTexturep; }
-	LLViewerTexture*	getBloomTex() const					{ return mBloomTexturep; }
+	LLViewerTexture*	getSunTex() const					{ return mSunTexturep[0];   }
+	LLViewerTexture*	getMoonTex() const					{ return mMoonTexturep[0];  }
+	LLViewerTexture*	getBloomTex() const					{ return mBloomTexturep;    }
+
+    void setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next);
+    void setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next);
+
 	void forceSkyUpdate(void)							{ mForceUpdate = TRUE; }
 
 public:
@@ -286,8 +290,8 @@ class LLVOSky : public LLStaticViewerObject
 	void initSkyTextureDirs(const S32 side, const S32 tile);
 	void createSkyTexture(const S32 side, const S32 tile);
 
-	LLPointer<LLViewerFetchedTexture> mSunTexturep;
-	LLPointer<LLViewerFetchedTexture> mMoonTexturep;
+	LLPointer<LLViewerFetchedTexture> mSunTexturep[2];
+	LLPointer<LLViewerFetchedTexture> mMoonTexturep[2];
 	LLPointer<LLViewerFetchedTexture> mBloomTexturep;
 
 	static S32			sResolution;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 7d6881f8a86c2b4bbfe6090ff1e721f84d15e309..d4c8d4f923f87a9bc6bc379c6dbb82c53cdb9e10 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2152,7 +2152,7 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
 
 		switch(range_it->second.map)
 		{
-		case LLRender::DIFFUSE_MAP:
+		    case LLRender::DIFFUSE_MAP:
 			{
 				if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode())
 				{ //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
@@ -2194,9 +2194,8 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
 
 				mat->setSpecularID(LLUUID::null);
 			} break;
-		case LLRender::NUM_TEXTURE_CHANNELS:
-				//nothing to do, make compiler happy
-			break;
+        default:
+            break;
 		} //switch
 	} //for