diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 00c1edb55a2a8b539b439154ad551b326e8ae566..82c67a1066b55ca1560444a7dcc8dc645aff34e2 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -1209,6 +1209,14 @@ LLColor3 LLSettingsSky::getLightTransmittance(F32 distance) const
     return transmittance;
 }
 
+// SL-16127: getTotalDensity() and getDensityMultiplier() call LLSettingsSky::getColor() and LLSettingsSky::getFloat() respectively which are S-L-O-W
+LLColor3 LLSettingsSky::getLightTransmittanceFast( const LLColor3& total_density, const F32 density_multiplier, const F32 distance ) const
+{
+    // Transparency (-> density) from Beer's law
+    LLColor3 transmittance = componentExp(total_density * -(density_multiplier * distance));
+    return transmittance;
+}
+
 // performs soft scale clip and gamma correction ala the shader implementation
 // scales colors down to 0 - 1 range preserving relative ratios
 LLColor3 LLSettingsSky::gammaCorrect(const LLColor3& in) const
diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h
index 412791164327d9e7c3dcebfa5fca437f9a069b6a..77d9d8e87cafcd3bc8076def0570107cc9059ca8 100644
--- a/indra/llinventory/llsettingssky.h
+++ b/indra/llinventory/llsettingssky.h
@@ -252,6 +252,7 @@ class LLSettingsSky: public LLSettingsBase
 
     LLColor3 getLightAttenuation(F32 distance) const;
     LLColor3 getLightTransmittance(F32 distance) const;
+    LLColor3 getLightTransmittanceFast(const LLColor3& total_density, const F32 density_multiplier, const F32 distance) const;
     LLColor3 getTotalDensity() const;
     LLColor3 gammaCorrect(const LLColor3& in) const;
 
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp
index a2acb3efe2d9532fa8cefede51ad09f4d1beae04..9eda254b25e28debe0cf7205c47b4c3cd0931493 100644
--- a/indra/newview/lllegacyatmospherics.cpp
+++ b/indra/newview/lllegacyatmospherics.cpp
@@ -211,8 +211,8 @@ LLColor4 LLAtmospherics::calcSkyColorInDir(AtmosphericsVars& vars, const LLVecto
 // This cubemap is used as "environmentMap" in indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
 LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny)
 {
-	F32 sky_saturation = 0.25f;
-	F32 land_saturation = 0.1f;
+	const F32 sky_saturation = 0.25f;
+	const F32 land_saturation = 0.1f;
 
 	if (isShiny && dir.mV[VZ] < -0.02f)
 	{
@@ -270,11 +270,12 @@ LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, Atm
 //       indra\newview\lllegacyatmospherics.cpp
 void LLAtmospherics::calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVector3 & Pn, AtmosphericsVars& vars)
 {
-    LLColor3    blue_density = vars.blue_density;
-    LLColor3    blue_horizon = vars.blue_horizon;
-    F32         haze_horizon = vars.haze_horizon;
-    F32         haze_density = vars.haze_density;
-    F32         density_multiplier = vars.density_multiplier;
+    const LLColor3    blue_density = vars.blue_density;
+    const LLColor3    blue_horizon = vars.blue_horizon;
+    const F32         haze_horizon = vars.haze_horizon;
+    const F32         haze_density = vars.haze_density;
+    const F32         density_multiplier = vars.density_multiplier;
+
     F32         max_y = vars.max_y;
     LLVector4   sun_norm = vars.sun_norm;
 
@@ -313,7 +314,7 @@ void LLAtmospherics::calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVect
 	// Sunlight attenuation effect (hue and brightness) due to atmosphere
 	// this is used later for sunlight modulation at various altitudes
 	LLColor3 light_atten = vars.light_atten;
-    LLColor3 light_transmittance = psky->getLightTransmittance(Plen);
+    LLColor3 light_transmittance = psky->getLightTransmittanceFast(vars.total_density, vars.density_multiplier, Plen);
     (void)light_transmittance; // silence Clang warn-error
 
 	// Calculate relative weights
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 878d7287ede083fa1b371d42f9934da2343b6a7d..edf8c40bd3cd32506b5b5e06cfb047336a0810ec 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -1,25 +1,25 @@
-/** 
+/**
  * @file llvosky.cpp
  * @brief LLVOSky class implementation
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -64,7 +64,9 @@ namespace
     const S32 NUM_TILES_X = 8;
     const S32 NUM_TILES_Y = 4;
     const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y;
-    const S32 NUM_CUBEMAP_FACES = 6;
+    const S32 NUM_CUBEMAP_FACES = 6; // See sResolution for face dimensions
+    const S32 TOTAL_TILES = NUM_CUBEMAP_FACES * NUM_TILES;
+    const S32 MAX_TILES = TOTAL_TILES + 1;
 
 // Heavenly body constants
     const F32 SUN_DISK_RADIUS	= 0.5f;
@@ -113,7 +115,7 @@ void LLSkyTex::init(bool isShiny)
 		mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE);
 		mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
 		mImageRaw[i] = new LLImageRaw(sResolution, sResolution, sComponents);
-		
+
 		initEmpty(i);
 	}
 }
@@ -208,7 +210,7 @@ void LLSkyTex::create()
 }
 
 void LLSkyTex::createGLImage(S32 which)
-{	
+{
 	mTexture[which]->setExplicitFormat(GL_RGBA8, GL_RGBA);
 	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);
 	mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -433,7 +435,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
 	{
 		mFace[i] = NULL;
 	}
-	
+
 	mCameraPosAgent = gAgentCamera.getCameraPositionAgent();
 	mAtmHeight = ATM_HEIGHT;
 	mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS);
@@ -461,30 +463,12 @@ void LLVOSky::init()
     llassert(!mInitialized);
 
     // Update sky at least once to get correct initial sun/moon directions and lighting calcs performed
-    LLEnvironment::instance().getCurrentSky()->update();
-
-	updateDirections();
-
     LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+    psky->update();
 
-    // invariants across whole sky tex process...
-    m_atmosphericsVars.blue_density = psky->getBlueDensity();    
-    m_atmosphericsVars.blue_horizon = psky->getBlueHorizon();
-    m_atmosphericsVars.haze_density = psky->getHazeDensity();
-    m_atmosphericsVars.haze_horizon = psky->getHazeHorizon();
-    m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier();
-    m_atmosphericsVars.max_y = psky->getMaxY();
-    m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
-    m_atmosphericsVars.sunlight = psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor();
-    m_atmosphericsVars.ambient = psky->getAmbientColor();    
-    m_atmosphericsVars.glow = psky->getGlow();
-    m_atmosphericsVars.cloud_shadow = psky->getCloudShadow();
-    m_atmosphericsVars.dome_radius = psky->getDomeRadius();
-    m_atmosphericsVars.dome_offset = psky->getDomeOffset();
-    m_atmosphericsVars.light_atten = psky->getLightAttenuation(m_atmosphericsVars.max_y);
-    m_atmosphericsVars.light_transmittance = psky->getLightTransmittance(m_atmosphericsVars.max_y);
-    m_atmosphericsVars.total_density = psky->getTotalDensity();
-    m_atmosphericsVars.gamma = psky->getGamma();
+    updateDirections(psky);
+
+    cacheEnvironment(psky,m_atmosphericsVars);
 
 	// Initialize the cached normalized direction vectors
 	for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
@@ -492,7 +476,7 @@ void LLVOSky::init()
 		for (S32 tile = 0; tile < NUM_TILES; ++tile)
 		{
 			initSkyTextureDirs(side, tile);
-            createSkyTexture(m_atmosphericsVars, side, tile);
+            createSkyTexture(psky, m_atmosphericsVars, side, tile);
 		}
         mSkyTex[side].create();
         mShinyTex[side].create();
@@ -509,28 +493,33 @@ void LLVOSky::init()
 }
 
 
+void LLVOSky::cacheEnvironment(LLSettingsSky::ptr_t psky,AtmosphericsVars& atmosphericsVars)
+{
+    // invariants across whole sky tex process...
+    atmosphericsVars.blue_density = psky->getBlueDensity();
+    atmosphericsVars.blue_horizon = psky->getBlueHorizon();
+    atmosphericsVars.haze_density = psky->getHazeDensity();
+    atmosphericsVars.haze_horizon = psky->getHazeHorizon();
+    atmosphericsVars.density_multiplier = psky->getDensityMultiplier();
+    atmosphericsVars.distance_multiplier = psky->getDistanceMultiplier();
+    atmosphericsVars.max_y = psky->getMaxY();
+    atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
+    atmosphericsVars.sunlight = psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor();
+    atmosphericsVars.ambient = psky->getAmbientColor();
+    atmosphericsVars.glow = psky->getGlow();
+    atmosphericsVars.cloud_shadow = psky->getCloudShadow();
+    atmosphericsVars.dome_radius = psky->getDomeRadius();
+    atmosphericsVars.dome_offset = psky->getDomeOffset();
+    atmosphericsVars.light_atten = psky->getLightAttenuation(atmosphericsVars.max_y);
+    atmosphericsVars.light_transmittance = psky->getLightTransmittance(atmosphericsVars.max_y);
+    atmosphericsVars.total_density = psky->getTotalDensity();
+    atmosphericsVars.gamma = psky->getGamma();
+}
+
 void LLVOSky::calc()
 {
     LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
-
-    // invariants across whole sky tex process...
-    m_atmosphericsVars.blue_density = psky->getBlueDensity();    
-    m_atmosphericsVars.blue_horizon = psky->getBlueHorizon();
-    m_atmosphericsVars.haze_density = psky->getHazeDensity();
-    m_atmosphericsVars.haze_horizon = psky->getHazeHorizon();
-    m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier();
-    m_atmosphericsVars.distance_multiplier = psky->getDistanceMultiplier();
-    m_atmosphericsVars.max_y = psky->getMaxY();
-    m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
-    m_atmosphericsVars.sunlight = psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor();
-    m_atmosphericsVars.ambient = psky->getAmbientColor();    
-    m_atmosphericsVars.glow = psky->getGlow();
-    m_atmosphericsVars.cloud_shadow = psky->getCloudShadow();
-    m_atmosphericsVars.dome_radius = psky->getDomeRadius();
-    m_atmosphericsVars.dome_offset = psky->getDomeOffset();
-    m_atmosphericsVars.light_atten = psky->getLightAttenuation(m_atmosphericsVars.max_y);
-    m_atmosphericsVars.light_transmittance = psky->getLightTransmittance(m_atmosphericsVars.max_y);
-    m_atmosphericsVars.gamma = psky->getGamma();
+    cacheEnvironment(psky,m_atmosphericsVars);
 
 	mSun.setColor(psky->getSunDiffuse());
 	mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));
@@ -541,14 +530,14 @@ void LLVOSky::calc()
 	mMoon.renewColor();
 }
 
-void LLVOSky::initCubeMap() 
+void LLVOSky::initCubeMap()
 {
 	std::vector<LLPointer<LLImageRaw> > images;
 	for (S32 side = 0; side < NUM_CUBEMAP_FACES; side++)
 	{
 		images.push_back(mShinyTex[side].getImageRaw());
 	}
-	
+
 	if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
 	{
         mCubeMap = new LLCubeMap(false);
@@ -592,12 +581,12 @@ void LLVOSky::restoreGL()
         setMoonTextures(psky->getMoonTextureId(), psky->getNextMoonTextureId());
     }
 
-	updateDirections();
+	updateDirections(psky);
 
 	if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
-		{
+	{
 		initCubeMap();
-		}
+	}
 
     forceSkyUpdate();
 
@@ -640,10 +629,8 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile)
 	}
 }
 
-void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile)
+void LLVOSky::createSkyTexture(LLSettingsSky::ptr_t psky, AtmosphericsVars& vars, const S32 side, const S32 tile)
 {
-	LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
-
 	S32 tile_x = tile % NUM_TILES_X;
 	S32 tile_y = tile / NUM_TILES_X;
 
@@ -655,22 +642,20 @@ void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32
 	{
 		for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x)
 		{
-			mSkyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mSkyTex[side].getDir(x, y), false), x, y);
-			mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mShinyTex[side].getDir(x, y), true), x, y);
+			mSkyTex  [side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mSkyTex  [side].getDir(x, y), false), x, y);
+			mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mShinyTex[side].getDir(x, y), true ), x, y);
 		}
 	}
 }
 
-void LLVOSky::updateDirections(void)
+void LLVOSky::updateDirections(LLSettingsSky::ptr_t psky)
 {
-    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
-
     mSun.setDirection(psky->getSunDirection());
-	mMoon.setDirection(psky->getMoonDirection());
+    mMoon.setDirection(psky->getMoonDirection());
     mSun.setRotation(psky->getSunRotation());
-	mMoon.setRotation(psky->getMoonRotation());
-	mSun.renewDirection();
-	mMoon.renewDirection();
+    mMoon.setRotation(psky->getMoonRotation());
+    mSun.renewDirection();
+    mMoon.renewDirection();
 }
 
 void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time)
@@ -691,11 +676,6 @@ bool LLVOSky::updateSky()
     LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
 
 	if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)))
-	{
-		return TRUE;
-	}
-
-	if (mDead)
 	{
 		// It's dead.  Don't update it.
 		return TRUE;
@@ -707,17 +687,15 @@ bool LLVOSky::updateSky()
 	}
 
 	static S32 next_frame = 0;
-	const S32 total_no_tiles = NUM_CUBEMAP_FACES * NUM_TILES;
-	const S32 cycle_frame_no = total_no_tiles + 1;
-	
+
     mNeedUpdate = mForceUpdate;
 
 	++next_frame;
-	next_frame = next_frame % cycle_frame_no;
+	next_frame = next_frame % MAX_TILES;
 
-	mInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no;
+	mInterpVal = (!mInitialized) ? 1 : (F32)next_frame / MAX_TILES;
 	LLHeavenBody::setInterpVal( mInterpVal );
-	updateDirections();
+	updateDirections(psky);
 
     if (!mCubeMap)
 	{
@@ -725,7 +703,7 @@ bool LLVOSky::updateSky()
         mForceUpdate = FALSE;
         return TRUE;
 	}
-	
+
     if (mCubeMapUpdateStage < 0)
     {
         LL_RECORD_BLOCK_TIME(FTM_VOSKY_CALC);
@@ -815,7 +793,7 @@ bool LLVOSky::updateSky()
         // instead of executing per face, or may be can be moved to shaders)
         for (S32 tile = 0; tile < NUM_TILES; tile++)
         {
-            createSkyTexture(m_atmosphericsVars, side, tile);
+            createSkyTexture(psky, m_atmosphericsVars, side, tile);
         }
         mCubeMapUpdateStage++;
     }
@@ -889,10 +867,10 @@ void LLVOSky::setSunScale(F32 sun_scale)
 void LLVOSky::setMoonScale(F32 moon_scale)
 {
     mMoonScale = moon_scale;
-	}
-	
+}
+
 void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next)
-	{
+{
     // We test the UUIDs here because we explicitly do not want the default image returned by getFetchedTexture in that case...
     mSunTexturep[0] = sun_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
     mSunTexturep[1] = sun_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
@@ -910,32 +888,32 @@ void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_textur
         LLViewerTexture* current_tex1 = mFace[FACE_SUN]->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
 
         if (current_tex0 && (mSunTexturep[0] != current_tex0) && current_tex0->isViewerMediaTexture())
-			{
+        {
             static_cast<LLViewerMediaTexture*>(current_tex0)->removeMediaFromFace(mFace[FACE_SUN]);
         }
 
         if (current_tex1 && (mSunTexturep[1] != current_tex1) && current_tex1->isViewerMediaTexture())
-				{
+        {
             static_cast<LLViewerMediaTexture*>(current_tex1)->removeMediaFromFace(mFace[FACE_SUN]);
-						}
+        }
 
         mFace[FACE_SUN]->setTexture(LLRender::DIFFUSE_MAP, mSunTexturep[0]);
 
         if (can_use_wl)
         {
             if (mSunTexturep[1])
-						{
-	            mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);            
-						}
+            {
+                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();
-			
+
     bool can_use_wl = gPipeline.canUseWindLightShaders();
 
     mMoonTexturep[0] = moon_texture.isNull()      ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
@@ -944,17 +922,17 @@ void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_tex
     if (mFace[FACE_MOON])
     {
         if (mMoonTexturep[0])
-		{
-	        mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
-	}
+        {
+            mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+        }
         mFace[FACE_MOON]->setTexture(LLRender::DIFFUSE_MAP, mMoonTexturep[0]);
 
         if (mMoonTexturep[1] && can_use_wl)
-	{
-	        mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+        {
+            mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
             mFace[FACE_MOON]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mMoonTexturep[1]);
-	}
-	}
+        }
+    }
 }
 
 void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next)
@@ -963,7 +941,7 @@ void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLU
 
     mCloudNoiseTexturep[0] = cloud_noise_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
     mCloudNoiseTexturep[1] = cloud_noise_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
-	
+
     if (mCloudNoiseTexturep[0])
 	{
 	    mCloudNoiseTexturep[0]->setAddressMode(LLTexUnit::TAM_WRAP);
@@ -986,15 +964,15 @@ void LLVOSky::setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_
     mBloomTexturep[1] = bloom_tex_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(bloom_tex_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 
     if (mBloomTexturep[0])
-{	
-	    mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+    {
+        mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
     }
 
     if (mBloomTexturep[1])
-	{
-	    mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+    {
+        mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
     }
-	}
+}
 
 static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Sky Geometry");
 
@@ -1029,11 +1007,11 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
 	LLStrider<LLVector2> texCoordsp;
 	LLStrider<U16> indicesp;
 	U16 index_offset;
-	LLFace *face;	
+	LLFace *face;
 
 	for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
 	{
-		face = mFace[FACE_SIDE0 + side]; 
+		face = mFace[FACE_SIDE0 + side];
 
 		if (!face->getVertexBuffer())
 		{
@@ -1045,7 +1023,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
 			face->setVertexBuffer(buff);
 
 			index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
-			
+
 			S32 vtx = 0;
 			S32 curr_bit = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X
 			S32 side_dir = side & 1;  // even - 0, odd - 1
@@ -1164,11 +1142,11 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const
 
 	hb.setVisible(TRUE);
 
-	facep = mFace[f]; 
+	facep = mFace[f];
 
 	if (!facep->getVertexBuffer())
 	{
-		facep->setSize(4, 6);	
+		facep->setSize(4, 6);
 		LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
 		if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE))
 		{
@@ -1402,7 +1380,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
 		dt_clip = -0.1f;
 	}
 
-	LLFace *face = mFace[FACE_REFLECTION]; 
+	LLFace *face = mFace[FACE_REFLECTION];
 
     if (face)
     {
@@ -1420,13 +1398,13 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
 		face->setGeomIndex(0);
 		face->setVertexBuffer(buff);
 	}
-	
+
 	LLStrider<LLVector3> verticesp;
 	LLStrider<LLVector3> normalsp;
 	LLStrider<LLVector2> texCoordsp;
 	LLStrider<U16> indicesp;
 	S32 index_offset;
-	
+
 	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
 	if (-1 == index_offset)
 	{
@@ -1444,7 +1422,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
 
         LLColor4 hb_refl_col = (1 - attenuation) * hb_col + attenuation * getSkyFogColor();
 	face->setFaceColor(hb_refl_col);
-	
+
 	LLVector3 v_far[2];
 	v_far[0] = v_refl_corner[1];
 	v_far[1] = v_refl_corner[3];
@@ -1568,52 +1546,53 @@ void LLVOSky::updateFog(const F32 distance)
 	}
 
 void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir_cfr, const LLVector3 &moon_dir_cfr)
-	{
-    mSun.setDirection(sun_dir_cfr);	
-	mMoon.setDirection(moon_dir_cfr);
+{
+    mSun.setDirection(sun_dir_cfr);
+    mMoon.setDirection(moon_dir_cfr);
 
-	// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
-	// on the upward facing faces of cubes.
-	{
-	    // Same as dot product with the up direction + clamp.
-	    F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
-	    sunDot *= sunDot;	
-
-	    // Create normalized vector that has the sunDir pushed south about an hour and change.
-	    LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
-		
-	    // Blend between normal sun dir and adjusted sun dir based on how close we are
-	    // to having the sun overhead.
-	    mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot);
-	    mBumpSunDir.normalize();
-		}
-	updateDirections();
-	}
+    // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
+    // on the upward facing faces of cubes.
+    // Same as dot product with the up direction + clamp.
+    F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
+    sunDot *= sunDot;
+
+    // Create normalized vector that has the sunDir pushed south about an hour and change.
+    LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
+
+    // Blend between normal sun dir and adjusted sun dir based on how close we are
+    // to having the sun overhead.
+    mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot);
+    mBumpSunDir.normalize();
+
+    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+    updateDirections(psky);
+}
 
 void LLVOSky::setSunDirectionCFR(const LLVector3 &sun_dir_cfr)
-	{
-    mSun.setDirection(sun_dir_cfr);	
+{
+    mSun.setDirection(sun_dir_cfr);
 
-	// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
-	// on the upward facing faces of cubes.
-    {
-	// Same as dot product with the up direction + clamp.
-	    F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
-	sunDot *= sunDot;	
+    // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
+    // on the upward facing faces of cubes.
+    // Same as dot product with the up direction + clamp.
+    F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
+    sunDot *= sunDot;
 
-	// Create normalized vector that has the sunDir pushed south about an hour and change.
-	    LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
+    // Create normalized vector that has the sunDir pushed south about an hour and change.
+    LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
 
-	// Blend between normal sun dir and adjusted sun dir based on how close we are
-	// to having the sun overhead.
-	    mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot);
-	mBumpSunDir.normalize();
-    }
-	updateDirections();
+    // Blend between normal sun dir and adjusted sun dir based on how close we are
+    // to having the sun overhead.
+    mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot);
+    mBumpSunDir.normalize();
+
+    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+    updateDirections(psky);
 }
 
 void LLVOSky::setMoonDirectionCFR(const LLVector3 &moon_dir_cfr)
 {
-	mMoon.setDirection(moon_dir_cfr);
-	updateDirections();
+    mMoon.setDirection(moon_dir_cfr);
+    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+    updateDirections(psky);
 }
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 39e42bbb2420c9d185bb398ff1ba9d8ef8d0d898..793dcf4cbf5d4a8ba400b8d0f6df532f3ef1785b 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -214,12 +214,12 @@ class LLVOSky : public LLStaticViewerObject
 	// Initialize/delete data that's only inited once per class.
 	void init();
 	void initCubeMap();
-	void initEmpty();
 	
 	void cleanupGL();
 	void restoreGL();
 
     void calc();
+    void cacheEnvironment(LLSettingsSky::ptr_t psky, AtmosphericsVars& atmosphericsVars);
 
 	/*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
 	bool updateSky();
@@ -253,8 +253,6 @@ class LLVOSky : public LLStaticViewerObject
     LLColor4 getSkyFogColor() const                        { return m_legacyAtmospherics.getFogColor(); }
     LLColor4 getGLFogColor() const                      { return m_legacyAtmospherics.getGLFogColor(); }
 
-    LLColor4U getFadeColor() const;
-
 	void setCloudDensity(F32 cloud_density)				{ mCloudDensity = cloud_density; }
 	void setWind ( const LLVector3& wind )				{ mWind = wind.length(); }
 
@@ -299,10 +297,10 @@ class LLVOSky : public LLStaticViewerObject
 protected:
 	~LLVOSky();
 
-	void updateDirections(void);
+	void updateDirections(LLSettingsSky::ptr_t psky);
 
 	void initSkyTextureDirs(const S32 side, const S32 tile);
-	void createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile);
+	void createSkyTexture(LLSettingsSky::ptr_t psky, AtmosphericsVars& vars, const S32 side, const S32 tile);
 
 	LLPointer<LLViewerFetchedTexture> mSunTexturep[2];
 	LLPointer<LLViewerFetchedTexture> mMoonTexturep[2];