diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 1b5c154378881110523fa833ca5c288a82aa40fa..13420fc0010e07816f97e0a99bb4b3cd80e73638 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -500,6 +500,9 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li
 	    }
 	}
 
+    LLColor4 specular(psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor());
+    shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
+
 	sTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f;
 	
 	S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
diff --git a/indra/newview/lllegacyatmospherics.h b/indra/newview/lllegacyatmospherics.h
index e304ac3043cc141b4068e8fe3a2ae2f5fcb7c64f..95700227f94fac8ca49a5a413c603861c8b55c0e 100644
--- a/indra/newview/lllegacyatmospherics.h
+++ b/indra/newview/lllegacyatmospherics.h
@@ -206,6 +206,8 @@ class AtmosphericsVars
     {
     }
 
+    LL_FORCE_INLINE friend bool operator==(const AtmosphericsVars& a, const AtmosphericsVars& b);
+
     LLColor3  hazeColor;
     LLColor3  hazeColorBelowCloud;
 	LLColor3  cloudColorSun;
@@ -231,6 +233,115 @@ class AtmosphericsVars
     LLColor3 total_density;
 };
 
+bool operator==(const AtmosphericsVars& a, const AtmosphericsVars& b)
+{
+    if (a.hazeColor != b.hazeColor)
+    {
+        return false;
+    }
+
+    if (a.hazeColorBelowCloud != b.hazeColorBelowCloud)
+    {
+        return false;
+    }
+
+    if (a.cloudColorSun != b.cloudColorSun)
+    {
+        return false;
+    }
+
+    if (a.cloudColorAmbient != b.cloudColorAmbient)
+    {
+        return false;
+    }
+
+    if (a.cloudDensity != b.cloudDensity)
+    {
+        return false;
+    }
+
+    if (a.density_multiplier != b.density_multiplier)
+    {
+        return false;
+    }
+
+    if (a.haze_horizon != b.haze_horizon)
+    {
+        return false;
+    }
+
+    if (a.haze_density != b.haze_density)
+    {
+        return false;
+    }
+
+    if (a.blue_horizon != b.blue_horizon)
+    {
+        return false;
+    }
+
+    if (a.blue_density != b.blue_density)
+    {
+        return false;
+    }
+
+    if (a.dome_offset != b.dome_offset)
+    {
+        return false;
+    }
+
+    if (a.dome_radius != b.dome_radius)
+    {
+        return false;
+    }
+
+    if (a.cloud_shadow != b.cloud_shadow)
+    {
+        return false;
+    }
+
+    if (a.glow != b.glow)
+    {
+        return false;
+    }
+
+    if (a.ambient != b.ambient)
+    {
+        return false;
+    }
+
+    if (a.sunlight != b.sunlight)
+    {
+        return false;
+    }
+
+    if (a.sun_norm != b.sun_norm)
+    {
+        return false;
+    }
+
+    if (a.gamma != b.gamma)
+    {
+        return false;
+    }
+
+    if (a.max_y != b.max_y)
+    {
+        return false;
+    }
+
+    if (a.distance_multiplier != b.distance_multiplier)
+    {
+        return false;
+    }
+
+    // light_atten, light_transmittance, total_density
+    // are ignored as they always change when the values above do
+    // they're just shared calc across the sky map generation to save cycles
+
+    return true;
+}
+
 class LLAtmospherics
 {
 public:    
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 8d5c0f04cd9735fdbe16ec1436877e0d23a28cd2..78c782eb5f79eca23345ff1b32908baea0e197af 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -479,7 +479,7 @@ void LLVOSky::init()
     m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier();
     m_atmosphericsVars.max_y = psky->getMaxY();
     m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
-    m_atmosphericsVars.sunlight = psky->getSunlightColor();
+    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();
@@ -531,7 +531,7 @@ void LLVOSky::calc()
     m_atmosphericsVars.distance_multiplier = psky->getDistanceMultiplier();
     m_atmosphericsVars.max_y = psky->getMaxY();
     m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
-    m_atmosphericsVars.sunlight = psky->getSunlightColor();
+    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();
@@ -750,7 +750,9 @@ bool LLVOSky::updateSky()
 
     calc();
 
-    if (mForceUpdate && mForceUpdateThrottle.hasExpired())
+    bool same_atmospherics = m_lastAtmosphericsVars == m_atmosphericsVars;
+
+    if (mForceUpdate && mForceUpdateThrottle.hasExpired() && !same_atmospherics)
 	{
         LL_RECORD_BLOCK_TIME(FTM_VOSKY_UPDATEFORCED);
 
@@ -758,6 +760,8 @@ bool LLVOSky::updateSky()
 
 		LLSkyTex::stepCurrent();
 		
+        m_lastAtmosphericsVars = m_atmosphericsVars;
+
 		if (!direction.isExactlyZero())
 		{
             mLastTotalAmbient = total_ambient;