From 966dc7fc8fb1fade861e8070e9c5fbbfe4d0cb45 Mon Sep 17 00:00:00 2001
From: Graham Linden <graham@lindenlab.com>
Date: Thu, 24 Jan 2019 14:54:11 -0800
Subject: [PATCH] SL-10276 SL-9851

Fix cloud shaders to ignore clouds when cloud_scale is 0.

Fix creation of heavenly body geo to avoid degenerate vector math
and not randomly flip orientation when crossing zenith.

Add sun_up_factor to eliminate sun glow around moon when sun is down.
---
 indra/llrender/llshadermgr.cpp                |   2 +
 indra/llrender/llshadermgr.h                  |   1 +
 .../shaders/class1/deferred/cloudShadowF.glsl |  91 ++++---
 .../shaders/class1/deferred/cloudsF.glsl      |  73 +++---
 .../shaders/class1/deferred/cloudsV.glsl      |   5 +-
 .../shaders/class1/deferred/moonF.glsl        |  10 +-
 .../shaders/class1/deferred/moonV.glsl        |  12 +-
 .../class1/windlight/cloudShadowF.glsl        |  93 ++++---
 .../shaders/class2/deferred/skyF.glsl         | 196 +++++++-------
 .../shaders/class2/deferred/softenLightF.glsl |  12 -
 .../class2/windlight/atmosphericsF.glsl       |   3 +
 .../class2/windlight/atmosphericsV.glsl       | 202 ++++++++-------
 .../shaders/class2/windlight/cloudsF.glsl     |  73 +++---
 .../shaders/class2/windlight/cloudsV.glsl     | 245 +++++++++---------
 .../shaders/class2/windlight/skyV.glsl        |   4 +-
 .../shaders/class3/deferred/cloudShadowF.glsl |  91 ++++---
 .../shaders/class3/deferred/cloudsF.glsl      |  63 ++---
 .../shaders/class3/deferred/cloudsV.glsl      |  22 +-
 indra/newview/lldrawpoolwlsky.cpp             |   7 +-
 indra/newview/llvosky.cpp                     |  21 +-
 indra/newview/llvosky.h                       |   7 +-
 21 files changed, 650 insertions(+), 583 deletions(-)

diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 29d120a1350..9db8fd1f059 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1358,6 +1358,8 @@ void LLShaderMgr::initAttribsAndUniforms()
     mReservedUniforms.push_back("sh_input_g");
     mReservedUniforms.push_back("sh_input_b");
 
+    mReservedUniforms.push_back("sun_up_factor");
+
 	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
 
 	std::set<std::string> dupe_check;
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index c22fe447502..0b1a97d8804 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -248,6 +248,7 @@ class LLShaderMgr
         SH_INPUT_L1G,
         SH_INPUT_L1B,
 
+        SUN_UP_FACTOR,
 		END_RESERVED_UNIFORMS
 	} eGLSLReservedUniforms;
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
index d93baa03c64..035e979827b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
@@ -69,53 +69,60 @@ vec4 cloudNoise(vec2 uv)
 
 void main()
 {
-	// Set variables
-	vec2 uv1 = vary_texcoord0.xy;
-	vec2 uv2 = vary_texcoord1.xy;
-	vec2 uv3 = vary_texcoord2.xy;
-	float cloudDensity = 2.0 * (cloud_shadow - 0.25);
+    // Set variables
+    vec2 uv1 = vary_texcoord0.xy;
+    vec2 uv2 = vary_texcoord1.xy;
+    vec2 uv3 = vary_texcoord2.xy;
+    float cloudDensity = 2.0 * (cloud_shadow - 0.25);
 
-	vec2 uv4 = vary_texcoord3.xy;
-
-    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 * 0.02);	//large texture, visible density
-	uv2 += cloud_pos_density1.xy;	//large texture, self shadow
-	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 * cloud_pos_density1.z, 1.);
-
-	// And smooth
-	alpha1 = 1. - alpha1 * alpha1;
-	alpha1 = 1. - alpha1 * alpha1;	
-
-    if (alpha1 < 0.001f)
+    if (cloud_scale >= 0.0001)
     {
-        discard;
+        vec2 uv4 = vary_texcoord3.xy;
+    
+        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 * 0.02);    //large texture, visible density
+        uv2 += cloud_pos_density1.xy;   //large texture, self shadow
+        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 * 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 * cloud_pos_density1.z, 1.);
+    
+        // And smooth
+        alpha2 = 1. - alpha2;
+        alpha2 = 1. - alpha2 * alpha2;  
+    
+        frag_color = vec4(alpha1, alpha1, alpha1, 1);
+    }
+    else
+    {
+        frag_color = vec4(1);
     }
-
-	// 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 * cloud_pos_density1.z, 1.);
-
-	// And smooth
-	alpha2 = 1. - alpha2;
-	alpha2 = 1. - alpha2 * alpha2;	
-
-    frag_color = vec4(alpha1, alpha1, alpha1, 1);
 
 #if !defined(DEPTH_CLAMP)
-	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+    gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
 #endif
 
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index fe69233e68e..60ccfa64dbc 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -65,60 +65,65 @@ vec4 cloudNoise(vec2 uv)
 
 void main()
 {
-	// Set variables
-	vec2 uv1 = vary_texcoord0.xy;
-	vec2 uv2 = vary_texcoord1.xy;
+    // Set variables
+    vec2 uv1 = vary_texcoord0.xy;
+    vec2 uv2 = vary_texcoord1.xy;
 
-	vec4 cloudColorSun = vary_CloudColorSun;
-	vec4 cloudColorAmbient = vary_CloudColorAmbient;
-	float cloudDensity = vary_CloudDensity;
-	vec2 uv3 = vary_texcoord2.xy;
-	vec2 uv4 = vary_texcoord3.xy;
+    vec4 cloudColorSun = vary_CloudColorSun;
+    vec4 cloudColorAmbient = vary_CloudColorAmbient;
+    float cloudDensity = vary_CloudDensity;
+    vec2 uv3 = vary_texcoord2.xy;
+    vec2 uv4 = vary_texcoord3.xy;
+
+    if (cloud_scale < 0.001)
+    {
+        discard;
+    }
 
     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 * 0.02);	//large texture, visible density
-	uv2 += cloud_pos_density1.xy;	//large texture, self shadow
-	uv3 += cloud_pos_density2.xy;	//small texture, visible density
-	uv4 += cloud_pos_density2.xy;	//small texture, self shadow
+    // Offset texture coords
+    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;   //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
+    // 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 * cloud_pos_density1.z, 1.);
+    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
-	alpha1 = 1. - alpha1 * alpha1;
-	alpha1 = 1. - alpha1 * alpha1;	
+    // 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 * cloud_pos_density1.z, 1.);
+    // 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 * cloud_pos_density1.z, 1.);
 
-	// And smooth
-	alpha2 = 1. - alpha2;
-	alpha2 = 1. - alpha2 * alpha2;	
+    // And smooth
+    alpha2 = 1. - alpha2;
+    alpha2 = 1. - alpha2 * alpha2;  
 
-	// Combine
-	vec4 color;
-	color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
-	color *= 2.;
+    // Combine
+    vec4 color;
+    color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
+    color *= 2.;
 
-	/// Gamma correct for WL (soft clip effect).
-	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);
+    /// Gamma correct for WL (soft clip effect).
+    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/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
index 17f425475c8..fe336fc3a85 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
@@ -58,6 +58,7 @@ uniform float density_multiplier;
 uniform float max_y;
 
 uniform vec4 glow;
+uniform float sun_up_factor;
 
 uniform vec4 cloud_color;
 
@@ -131,6 +132,8 @@ void main()
 	temp2.x = pow(temp2.x, glow.z);
 		// glow.z should be negative, so we're doing a sort of (1 / "angle") function
 
+        temp2.x *= sun_up_factor;
+
 	// Add "minimum anti-solar illumination"
 	temp2.x += .25;
 
@@ -170,7 +173,7 @@ void main()
 	// Texture coords
 	vary_texcoord0 = texcoord0;
 	vary_texcoord0.xy -= 0.5;
-	vary_texcoord0.xy /= cloud_scale;
+	vary_texcoord0.xy /= max(0.001, cloud_scale);
 	vary_texcoord0.xy += 0.5;
 
 	vary_texcoord1 = vary_texcoord0;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
index 8bf4551abc0..7265275e364 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -45,8 +45,8 @@ VARYING vec2 vary_texcoord0;
 
 void main() 
 {
-	vec4 moonA = texture2D(diffuseMap, vary_texcoord0.xy);
-	vec4 moonB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+    vec4 moonA = texture2D(diffuseMap, vary_texcoord0.xy);
+    vec4 moonB = texture2D(altDiffuseMap, vary_texcoord0.xy);
     vec4 c     = mix(moonA, moonB, blend_factor);
 
     // mix factor which blends when sunlight is brighter
@@ -58,8 +58,8 @@ void main()
     vec3 exp = vec3(1.0 - mix * moon_brightness) * 2.0  - 1.0;
     c.rgb = pow(c.rgb, exp);
 
-	frag_data[0] = vec4(c.rgb, c.a);
-	frag_data[1] = vec4(0.0);
-	frag_data[2] = vec4(0.0f);
+    frag_data[0] = vec4(c.rgb, c.a);
+    frag_data[1] = vec4(0.0);
+    frag_data[2] = vec4(0.0f);
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
index 0325ecead94..0a68fc82f77 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
@@ -36,13 +36,13 @@ void calcAtmospherics(vec3 eye_pos);
 
 void main()
 {
-	//transform vertex
-	vec4 vert = vec4(position.xyz, 1.0);
-	vec4 pos = (modelview_matrix * vert);
+    //transform vertex
+    vec4 vert = vec4(position.xyz, 1.0);
+    vec4 pos = (modelview_matrix * vert);
 
-	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+    gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
 
     calcAtmospherics(pos.xyz);
-	
-	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+    
+    vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
 }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
index d93baa03c64..69a3c59cb39 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
@@ -69,53 +69,60 @@ vec4 cloudNoise(vec2 uv)
 
 void main()
 {
-	// Set variables
-	vec2 uv1 = vary_texcoord0.xy;
-	vec2 uv2 = vary_texcoord1.xy;
-	vec2 uv3 = vary_texcoord2.xy;
-	float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
-	vec2 uv4 = vary_texcoord3.xy;
-
-    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 * 0.02);	//large texture, visible density
-	uv2 += cloud_pos_density1.xy;	//large texture, self shadow
-	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 * cloud_pos_density1.z, 1.);
-
-	// And smooth
-	alpha1 = 1. - alpha1 * alpha1;
-	alpha1 = 1. - alpha1 * alpha1;	
-
-    if (alpha1 < 0.001f)
+    if (cloud_scale >= 0.0001)
     {
-        discard;
+        // Set variables
+        vec2 uv1 = vary_texcoord0.xy;
+        vec2 uv2 = vary_texcoord1.xy;
+        vec2 uv3 = vary_texcoord2.xy;
+        float cloudDensity = 2.0 * (cloud_shadow - 0.25);
+    
+        vec2 uv4 = vary_texcoord3.xy;
+    
+        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 * 0.02);    //large texture, visible density
+        uv2 += cloud_pos_density1.xy;   //large texture, self shadow
+        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 * 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 * cloud_pos_density1.z, 1.);
+    
+        // And smooth
+        alpha2 = 1. - alpha2;
+        alpha2 = 1. - alpha2 * alpha2;  
+    
+        frag_color = vec4(alpha1, alpha1, alpha1, 1);
+    }
+    else
+    {
+        frag_color = vec4(1);
     }
-
-	// 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 * cloud_pos_density1.z, 1.);
-
-	// And smooth
-	alpha2 = 1. - alpha2;
-	alpha2 = 1. - alpha2 * alpha2;	
-
-    frag_color = vec4(alpha1, alpha1, alpha1, 1);
 
 #if !defined(DEPTH_CLAMP)
-	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+    gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
 #endif
 
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
index 09ad6e70d68..6ddd7e7c86a 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
@@ -45,6 +45,7 @@ uniform float density_multiplier;
 uniform float max_y;
 
 uniform vec4 glow;
+uniform float sun_up_factor;
 
 uniform vec4 cloud_color;
 
@@ -88,98 +89,99 @@ vec3 scaleSoftClip(vec3 light);
 void main()
 {
 
-	// World / view / projection
-	// Get relative position
-	vec3 P = pos.xyz - camPosLocal.xyz + vec3(0,50,0);
-
-	// Set altitude
-	if (P.y > 0.)
-	{
-		P *= (max_y / P.y);
-	}
-	else
-	{
-		P *= (-32000. / P.y);
-	}
-
-	// Can normalize then
-	vec3 Pn = normalize(P);
-	float  Plen = length(P);
-
-	// Initialize temp variables
-	vec4 temp1 = vec4(0.);
-	vec4 temp2 = vec4(0.);
-	vec4 blue_weight;
-	vec4 haze_weight;
-	vec4 sunlight = sunlight_color;
-	vec4 light_atten;
-
-
-	// Sunlight attenuation effect (hue and brightness) due to atmosphere
-	// this is used later for sunlight modulation at various altitudes
-	light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
-
-	// Calculate relative weights
-	temp1 = blue_density + haze_density;
-	blue_weight = blue_density / temp1;
-	haze_weight = haze_density / temp1;
-
-	// Compute sunlight from P & lightnorm (for long rays like sky)
-	temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// Distance
-	temp2.z = Plen * density_multiplier;
-
-	// Transparency (-> temp1)
-	// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
-	// compiler gets confused.
-	temp1 = exp(-temp1 * temp2.z);
-
-
-	// Compute haze glow
-	temp2.x = dot(Pn, lightnorm.xyz);
-	temp2.x = 1. - temp2.x;
-		// temp2.x is 0 at the sun and increases away from sun
-	temp2.x = max(temp2.x, .001);	
-		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-	temp2.x *= glow.x;
-		// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
-	temp2.x = pow(temp2.x, glow.z);
-		// glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
-	// Add "minimum anti-solar illumination"
-	temp2.x += .25;
-
-
-	// Haze color above cloud
-	vec4 color = (	  blue_horizon * blue_weight * (sunlight + ambient)
-				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient)
-			 );	
-
-
-	// Increase ambient when there are more clouds
-	vec4 tmpAmbient = ambient;
-	tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; 
-
-	// Dim sunlight by cloud shadow percentage
-	sunlight *= (1. - cloud_shadow);
-
-	// Haze color below cloud
-	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient)
-				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
-			 );	
-
-	// Final atmosphere additive
-	color *= (1. - temp1);
-	
-	// Attenuate cloud color by atmosphere
-	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds
-
-	// At horizon, blend high altitude sky color towards the darker color below the clouds
-	color += (additiveColorBelowCloud - color) * (1. - sqrt(temp1));
-	
+    // World / view / projection
+    // Get relative position
+    vec3 P = pos.xyz - camPosLocal.xyz + vec3(0,50,0);
+
+    // Set altitude
+    if (P.y > 0.)
+    {
+        P *= (max_y / P.y);
+    }
+    else
+    {
+        P *= (-32000. / P.y);
+    }
+
+    // Can normalize then
+    vec3 Pn = normalize(P);
+    float  Plen = length(P);
+
+    // Initialize temp variables
+    vec4 temp1 = vec4(0.);
+    vec4 temp2 = vec4(0.);
+    vec4 blue_weight;
+    vec4 haze_weight;
+    vec4 sunlight = sunlight_color;
+    vec4 light_atten;
+
+
+    // Sunlight attenuation effect (hue and brightness) due to atmosphere
+    // this is used later for sunlight modulation at various altitudes
+    light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+
+    // Calculate relative weights
+    temp1 = blue_density + haze_density;
+    blue_weight = blue_density / temp1;
+    haze_weight = haze_density / temp1;
+
+    // Compute sunlight from P & lightnorm (for long rays like sky)
+    temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
+    temp2.y = 1. / temp2.y;
+    sunlight *= exp( - light_atten * temp2.y);
+
+    // Distance
+    temp2.z = Plen * density_multiplier;
+
+    // Transparency (-> temp1)
+    // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
+    // compiler gets confused.
+    temp1 = exp(-temp1 * temp2.z);
+
+
+    // Compute haze glow
+    temp2.x = dot(Pn, lightnorm.xyz);
+    temp2.x = 1. - temp2.x;
+        // temp2.x is 0 at the sun and increases away from sun
+    temp2.x = max(temp2.x, .001);   
+        // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+    temp2.x *= glow.x;
+        // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+    temp2.x = pow(temp2.x, glow.z);
+        // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+    // Add "minimum anti-solar illumination"
+    temp2.x += .25;
+
+    temp2.x *= sun_up_factor;
+
+    // Haze color above cloud
+    vec4 color = (    blue_horizon * blue_weight * (sunlight + ambient)
+                + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient)
+             ); 
+
+
+    // Increase ambient when there are more clouds
+    vec4 tmpAmbient = ambient;
+    tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; 
+
+    // Dim sunlight by cloud shadow percentage
+    sunlight *= (1. - cloud_shadow);
+
+    // Haze color below cloud
+    vec4 additiveColorBelowCloud = (      blue_horizon * blue_weight * (sunlight + tmpAmbient)
+                + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
+             ); 
+
+    // Final atmosphere additive
+    color *= (1. - temp1);
+    
+    // Attenuate cloud color by atmosphere
+    temp1 = sqrt(temp1);    //less atmos opacity (more transparency) below clouds
+
+    // At horizon, blend high altitude sky color towards the darker color below the clouds
+    color += (additiveColorBelowCloud - color) * (1. - sqrt(temp1));
+    
     float optic_d = dot(Pn, lightnorm.xyz);
 
     vec3 halo_22 = halo22(optic_d);
@@ -188,11 +190,11 @@ void main()
 
     color.rgb += halo_22;
 
-	color *= 2.;
+    color *= 2.;
 
-	/// Gamma correct for WL (soft clip effect).
-	frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);
-	frag_data[1] = vec4(0.0,0.0,0.0,0.0);
-	frag_data[2] = vec4(0.5,0.5,0.0,1.0); //1.0 in norm.w masks off fog
+    /// Gamma correct for WL (soft clip effect).
+    frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);
+    frag_data[1] = vec4(0.0,0.0,0.0,0.0);
+    frag_data[2] = vec4(0.5,0.5,0.0,1.0); //1.0 in norm.w masks off fog
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index c5d317ad370..c80e7fce188 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -48,21 +48,9 @@ uniform float blur_fidelity;
 uniform vec4 morphFactor;
 uniform vec3 camPosLocal;
 //uniform vec4 camPosWorld;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
 uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float distance_multiplier;
 uniform float max_y;
-uniform vec4 glow;
 uniform float global_gamma;
-uniform float scene_light_strength;
 uniform mat3 env_mat;
 uniform vec4 shadow_clip;
 uniform mat3 ssao_effect_mat;
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
index 2a629f4f423..5cf3cd1dd2d 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
@@ -42,6 +42,7 @@ uniform vec4 glow;
 uniform float scene_light_strength;
 uniform mat3 ssao_effect_mat;
 uniform int no_atmo;
+uniform float sun_up_factor;
 
 vec3 scaleSoftClipFrag(vec3 light);
 
@@ -117,6 +118,8 @@ void calcFragAtmospherics(vec3 inPositionEye, float ambFactor, out vec3 sunlit,
 
     //add "minimum anti-solar illumination"
     temp2.x += .25;
+
+    temp2.x *= sun_up_factor;
     
     //increase ambient when there are more clouds
     vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
index 7a6bcd53a16..8c1a7c62815 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
@@ -54,110 +54,112 @@ uniform float density_multiplier;
 uniform float distance_multiplier;
 uniform float max_y;
 uniform vec4 glow;
+uniform float sun_up_factor;
 
 void calcAtmospherics(vec3 inPositionEye) {
 
-	vec3 P = inPositionEye;
-	setPositionEye(P);
-	
-	//(TERRAIN) limit altitude
-	if (P.y > max_y) P *= (max_y / P.y);
-	if (P.y < -max_y) P *= (-max_y / P.y);
-
-	vec3 tmpLightnorm = lightnorm.xyz;
-
-	vec3 Pn = normalize(P);
-	float  Plen = length(P);
-
-	vec4 temp1 = vec4(0);
-	vec3 temp2 = vec3(0);
-	vec4 blue_weight;
-	vec4 haze_weight;
-	vec4 sunlight = sunlight_color;
-	vec4 light_atten;
-
-	//sunlight attenuation effect (hue and brightness) due to atmosphere
-	//this is used later for sunlight modulation at various altitudes
-	light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
-		//I had thought blue_density and haze_density should have equal weighting,
-		//but attenuation due to haze_density tends to seem too strong
-
-	temp1 = blue_density + vec4(haze_density);
-	blue_weight = blue_density / temp1;
-	haze_weight = vec4(haze_density) / temp1;
-
-	//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
-	temp2.y = max(0.0, tmpLightnorm.y);
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// main atmospheric scattering line integral
-	temp2.z = Plen * density_multiplier;
-
-	// Transparency (-> temp1)
-	// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
-	// compiler gets confused.
-	temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
-	//final atmosphere attenuation factor
-	setAtmosAttenuation(temp1.rgb);
-	//vary_AtmosAttenuation = distance_multiplier / 10000.;
-	//vary_AtmosAttenuation = density_multiplier * 100.;
-	//vary_AtmosAttenuation = vec4(Plen / 100000., 0., 0., 1.);
-
-	//compute haze glow
-	//(can use temp2.x as temp because we haven't used it yet)
-	temp2.x = dot(Pn, tmpLightnorm.xyz);
-	temp2.x = 1. - temp2.x;
-		//temp2.x is 0 at the sun and increases away from sun
-	temp2.x = max(temp2.x, .03);	//was glow.y
-		//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-	temp2.x *= glow.x;
-		//higher glow.x gives dimmer glow (because next step is 1 / "angle")
-	temp2.x = pow(temp2.x, glow.z);
-		//glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
-	//add "minimum anti-solar illumination"
-	temp2.x += .25;
-
-
-	//increase ambient when there are more clouds
-	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
-
-    vec3 additive =	
-		vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
-	  + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
-		  + tmpAmbient));
+    vec3 P = inPositionEye;
+    setPositionEye(P);
+    
+    //(TERRAIN) limit altitude
+    if (P.y > max_y) P *= (max_y / P.y);
+    if (P.y < -max_y) P *= (-max_y / P.y);
+
+    vec3 tmpLightnorm = lightnorm.xyz;
+
+    vec3 Pn = normalize(P);
+    float  Plen = length(P);
+
+    vec4 temp1 = vec4(0);
+    vec3 temp2 = vec3(0);
+    vec4 blue_weight;
+    vec4 haze_weight;
+    vec4 sunlight = sunlight_color;
+    vec4 light_atten;
+
+    //sunlight attenuation effect (hue and brightness) due to atmosphere
+    //this is used later for sunlight modulation at various altitudes
+    light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+        //I had thought blue_density and haze_density should have equal weighting,
+        //but attenuation due to haze_density tends to seem too strong
+
+    temp1 = blue_density + vec4(haze_density);
+    blue_weight = blue_density / temp1;
+    haze_weight = vec4(haze_density) / temp1;
+
+    //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
+    temp2.y = max(0.0, tmpLightnorm.y);
+    temp2.y = 1. / temp2.y;
+    sunlight *= exp( - light_atten * temp2.y);
+
+    // main atmospheric scattering line integral
+    temp2.z = Plen * density_multiplier;
+
+    // Transparency (-> temp1)
+    // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
+    // compiler gets confused.
+    temp1 = exp(-temp1 * temp2.z * distance_multiplier);
+
+    //final atmosphere attenuation factor
+    setAtmosAttenuation(temp1.rgb);
+    //vary_AtmosAttenuation = distance_multiplier / 10000.;
+    //vary_AtmosAttenuation = density_multiplier * 100.;
+    //vary_AtmosAttenuation = vec4(Plen / 100000., 0., 0., 1.);
+
+    //compute haze glow
+    //(can use temp2.x as temp because we haven't used it yet)
+    temp2.x = dot(Pn, tmpLightnorm.xyz);
+    temp2.x = 1. - temp2.x;
+        //temp2.x is 0 at the sun and increases away from sun
+    temp2.x = max(temp2.x, .03);    //was glow.y
+        //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+    temp2.x *= glow.x;
+        //higher glow.x gives dimmer glow (because next step is 1 / "angle")
+    temp2.x = pow(temp2.x, glow.z);
+        //glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+        temp2.x *= sun_up_factor;
+
+    //add "minimum anti-solar illumination"
+    temp2.x += .25;
+
+    //increase ambient when there are more clouds
+    vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
+
+    vec3 additive = 
+        vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
+      + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
+          + tmpAmbient));
     additive = normalize(additive);
 
-	//haze color
-	//setAdditiveColor(
-	//	vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
-	//  + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
-	//	  + tmpAmbient)));
-	
-	//brightness of surface both sunlight and ambient
-	setSunlitColor(vec3(sunlight * .5));
-	setAmblitColor(vec3(tmpAmbient * .25));
-	setAdditiveColor(additive * vec3(1.0 - exp(-temp2.z * distance_multiplier)) * 0.5);
-
-	// vary_SunlitColor = vec3(0);
-	// vary_AmblitColor = vec3(0);
-	// vary_AdditiveColor = vec4(Pn, 1.0);
-
-	/*
-	const float cloudShadowScale = 100.;
-	// Get cloud uvs for shadowing
-	vec3 cloudPos = inPositionEye + camPosWorld - cloudShadowScale / 2.;
-	vary_CloudUVs.xy = cloudPos.xz / cloudShadowScale;
-
-	// We can take uv1 and multiply it by (TerrainSpan / CloudSpan)
-//	cloudUVs *= (((worldMaxZ - worldMinZ) * 20) /40000.);
-	vary_CloudUVs *= (10000./40000.);
-
-	// Offset by sun vector * (CloudAltitude / CloudSpan)
-	vary_CloudUVs.x += tmpLightnorm.x / tmpLightnorm.y * (3000./40000.);
-	vary_CloudUVs.y += tmpLightnorm.z / tmpLightnorm.y * (3000./40000.);
-	*/
+    //haze color
+    //setAdditiveColor(
+    //  vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
+    //  + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
+    //    + tmpAmbient)));
+    
+    //brightness of surface both sunlight and ambient
+    setSunlitColor(vec3(sunlight * .5));
+    setAmblitColor(vec3(tmpAmbient * .25));
+    setAdditiveColor(additive * vec3(1.0 - exp(-temp2.z * distance_multiplier)) * 0.5);
+
+    // vary_SunlitColor = vec3(0);
+    // vary_AmblitColor = vec3(0);
+    // vary_AdditiveColor = vec4(Pn, 1.0);
+
+    /*
+    const float cloudShadowScale = 100.;
+    // Get cloud uvs for shadowing
+    vec3 cloudPos = inPositionEye + camPosWorld - cloudShadowScale / 2.;
+    vary_CloudUVs.xy = cloudPos.xz / cloudShadowScale;
+
+    // We can take uv1 and multiply it by (TerrainSpan / CloudSpan)
+//  cloudUVs *= (((worldMaxZ - worldMinZ) * 20) /40000.);
+    vary_CloudUVs *= (10000./40000.);
+
+    // Offset by sun vector * (CloudAltitude / CloudSpan)
+    vary_CloudUVs.x += tmpLightnorm.x / tmpLightnorm.y * (3000./40000.);
+    vary_CloudUVs.y += tmpLightnorm.z / tmpLightnorm.y * (3000./40000.);
+    */
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index e3fa431ddfd..93024bf4e71 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -66,60 +66,65 @@ vec4 cloudNoise(vec2 uv)
 
 void main()
 {
-	// Set variables
-	vec2 uv1 = vary_texcoord0.xy;
-	vec2 uv2 = vary_texcoord1.xy;
+    // Set variables
+    vec2 uv1 = vary_texcoord0.xy;
+    vec2 uv2 = vary_texcoord1.xy;
 
-	vec4 cloudColorSun = vary_CloudColorSun;
-	vec4 cloudColorAmbient = vary_CloudColorAmbient;
-	float cloudDensity = vary_CloudDensity;
-	vec2 uv3 = vary_texcoord2.xy;
-	vec2 uv4 = vary_texcoord3.xy;
+    vec4 cloudColorSun = vary_CloudColorSun;
+    vec4 cloudColorAmbient = vary_CloudColorAmbient;
+    float cloudDensity = vary_CloudDensity;
+    vec2 uv3 = vary_texcoord2.xy;
+    vec2 uv4 = vary_texcoord3.xy;
+
+    if (cloud_scale < 0.001)
+    {
+        discard;
+    }
 
     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 * 0.02);	//large texture, visible density
-	uv2 += cloud_pos_density1.xy;	//large texture, self shadow
-	uv3 += cloud_pos_density2.xy;	//small texture, visible density
-	uv4 += cloud_pos_density2.xy;	//small texture, self shadow
+    // Offset texture coords
+    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;   //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
+    // 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 * cloud_pos_density1.z, 1.);
+    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
-	alpha1 = 1. - alpha1 * alpha1;
-	alpha1 = 1. - alpha1 * alpha1;	
+    // 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 * cloud_pos_density1.z, 1.);
+    // 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 * cloud_pos_density1.z, 1.);
 
-	// And smooth
-	alpha2 = 1. - alpha2;
-	alpha2 = 1. - alpha2 * alpha2;	
+    // And smooth
+    alpha2 = 1. - alpha2;
+    alpha2 = 1. - alpha2 * alpha2;  
 
-	// Combine
-	vec4 color;
-	color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
-	color *= 2.;
+    // Combine
+    vec4 color;
+    color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
+    color *= 2.;
 
-	/// Gamma correct for WL (soft clip effect).
-	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);
+    /// Gamma correct for WL (soft clip effect).
+    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/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
index c1dd45cd672..644cd5a35b8 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
@@ -57,6 +57,7 @@ uniform float density_multiplier;
 uniform float max_y;
 
 uniform vec4 glow;
+uniform float sun_up_factor;
 
 uniform vec4 cloud_color;
 
@@ -65,126 +66,128 @@ uniform float cloud_scale;
 void main()
 {
 
-	// World / view / projection
-	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
-	vary_texcoord0 = texcoord0;
-
-	// Get relative position
-	vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
-
-	// Set altitude
-	if (P.y > 0.)
-	{
-		P *= (max_y / P.y);
-	}
-	else
-	{
-		P *= (-32000. / P.y);
-	}
-
-	// Can normalize then
-	vec3 Pn = normalize(P);
-	float  Plen = length(P);
-
-	// Initialize temp variables
-	vec4 temp1 = vec4(0.);
-	vec4 temp2 = vec4(0.);
-	vec4 blue_weight;
-	vec4 haze_weight;
-	vec4 sunlight = sunlight_color;
-	vec4 light_atten;
-
-
-	// Sunlight attenuation effect (hue and brightness) due to atmosphere
-	// this is used later for sunlight modulation at various altitudes
-	light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
-
-	// Calculate relative weights
-	temp1 = blue_density + haze_density;
-	blue_weight = blue_density / temp1;
-	haze_weight = haze_density / temp1;
-
-	// Compute sunlight from P & lightnorm (for long rays like sky)
-	temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// Distance
-	temp2.z = Plen * density_multiplier;
-
-	// Transparency (-> temp1)
-	// ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
-	// compiler gets confused.
-	temp1 = exp(-temp1 * temp2.z);
-
-
-	// Compute haze glow
-	temp2.x = dot(Pn, lightnorm.xyz);
-	temp2.x = 1. - temp2.x;
-		// temp2.x is 0 at the sun and increases away from sun
-	temp2.x = max(temp2.x, .001);	
-		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
-	temp2.x *= glow.x;
-		// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
-	temp2.x = pow(temp2.x, glow.z);
-		// glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
-	// Add "minimum anti-solar illumination"
-	temp2.x += .25;
-
-	// Increase ambient when there are more clouds
-	vec4 tmpAmbient = ambient;
-	tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; 
-
-	// Dim sunlight by cloud shadow percentage
-	sunlight *= (1. - cloud_shadow);
-
-	// Haze color below cloud
-	vec4 additiveColorBelowCloud = (	  blue_horizon * blue_weight * (sunlight + tmpAmbient)
-				+ (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
-			 );	
-
-	// CLOUDS
-
-	sunlight = sunlight_color;
-	temp2.y = max(0., lightnorm.y * 2.);
-	temp2.y = 1. / temp2.y;
-	sunlight *= exp( - light_atten * temp2.y);
-
-	// Cloud color out
-	vary_CloudColorSun = (sunlight * temp2.x) * cloud_color;
-	vary_CloudColorAmbient = tmpAmbient * cloud_color;
-	
-	// Attenuate cloud color by atmosphere
-	temp1 = sqrt(temp1);	//less atmos opacity (more transparency) below clouds
-	vary_CloudColorSun *= temp1;
-	vary_CloudColorAmbient *= temp1;
-	vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1);
-
-	// Make a nice cloud density based on the cloud_shadow value that was passed in.
-	vary_CloudDensity = 2. * (cloud_shadow - 0.25);
-
-
-	// Texture coords
-	vary_texcoord0 = texcoord0;
-	vary_texcoord0.xy -= 0.5;
-	vary_texcoord0.xy /= cloud_scale;
-	vary_texcoord0.xy += 0.5;
-
-	vary_texcoord1 = vary_texcoord0;
-	vary_texcoord1.x += lightnorm.x * 0.0125;
-	vary_texcoord1.y += lightnorm.z * 0.0125;
-
-	vary_texcoord2 = vary_texcoord0 * 16.;
-	vary_texcoord3 = vary_texcoord1 * 16.;
-
-	// Combine these to minimize register use
-	vary_CloudColorAmbient += oHazeColorBelowCloud;
-
-	// needs this to compile on mac
-	//vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
-
-	// END CLOUDS
+    // World / view / projection
+    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+    vary_texcoord0 = texcoord0;
+
+    // Get relative position
+    vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
+
+    // Set altitude
+    if (P.y > 0.)
+    {
+        P *= (max_y / P.y);
+    }
+    else
+    {
+        P *= (-32000. / P.y);
+    }
+
+    // Can normalize then
+    vec3 Pn = normalize(P);
+    float  Plen = length(P);
+
+    // Initialize temp variables
+    vec4 temp1 = vec4(0.);
+    vec4 temp2 = vec4(0.);
+    vec4 blue_weight;
+    vec4 haze_weight;
+    vec4 sunlight = sunlight_color;
+    vec4 light_atten;
+
+
+    // Sunlight attenuation effect (hue and brightness) due to atmosphere
+    // this is used later for sunlight modulation at various altitudes
+    light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+
+    // Calculate relative weights
+    temp1 = blue_density + haze_density;
+    blue_weight = blue_density / temp1;
+    haze_weight = haze_density / temp1;
+
+    // Compute sunlight from P & lightnorm (for long rays like sky)
+    temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
+    temp2.y = 1. / temp2.y;
+    sunlight *= exp( - light_atten * temp2.y);
+
+    // Distance
+    temp2.z = Plen * density_multiplier;
+
+    // Transparency (-> temp1)
+    // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
+    // compiler gets confused.
+    temp1 = exp(-temp1 * temp2.z);
+
+
+    // Compute haze glow
+    temp2.x = dot(Pn, lightnorm.xyz);
+    temp2.x = 1. - temp2.x;
+        // temp2.x is 0 at the sun and increases away from sun
+    temp2.x = max(temp2.x, .001);   
+        // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+    temp2.x *= glow.x;
+        // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+    temp2.x = pow(temp2.x, glow.z);
+        // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+    temp2.x *= sun_up_factor;
+
+    // Add "minimum anti-solar illumination"
+    temp2.x += .25;
+
+    // Increase ambient when there are more clouds
+    vec4 tmpAmbient = ambient;
+    tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; 
+
+    // Dim sunlight by cloud shadow percentage
+    sunlight *= (1. - cloud_shadow);
+
+    // Haze color below cloud
+    vec4 additiveColorBelowCloud = (      blue_horizon * blue_weight * (sunlight + tmpAmbient)
+                + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
+             ); 
+
+    // CLOUDS
+
+    sunlight = sunlight_color;
+    temp2.y = max(0., lightnorm.y * 2.);
+    temp2.y = 1. / temp2.y;
+    sunlight *= exp( - light_atten * temp2.y);
+
+    // Cloud color out
+    vary_CloudColorSun = (sunlight * temp2.x) * cloud_color;
+    vary_CloudColorAmbient = tmpAmbient * cloud_color;
+    
+    // Attenuate cloud color by atmosphere
+    temp1 = sqrt(temp1);    //less atmos opacity (more transparency) below clouds
+    vary_CloudColorSun *= temp1;
+    vary_CloudColorAmbient *= temp1;
+    vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1);
+
+    // Make a nice cloud density based on the cloud_shadow value that was passed in.
+    vary_CloudDensity = 2. * (cloud_shadow - 0.25);
+
+
+    // Texture coords
+    vary_texcoord0 = texcoord0;
+    vary_texcoord0.xy -= 0.5;
+    vary_texcoord0.xy /= max(0.001, cloud_scale);
+    vary_texcoord0.xy += 0.5;
+
+    vary_texcoord1 = vary_texcoord0;
+    vary_texcoord1.x += lightnorm.x * 0.0125;
+    vary_texcoord1.y += lightnorm.z * 0.0125;
+
+    vary_texcoord2 = vary_texcoord0 * 16.;
+    vary_texcoord3 = vary_texcoord1 * 16.;
+
+    // Combine these to minimize register use
+    vary_CloudColorAmbient += oHazeColorBelowCloud;
+
+    // needs this to compile on mac
+    //vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
+
+    // END CLOUDS
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
index 3788ddaf2d4..04cf4052b80 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
@@ -50,7 +50,7 @@ uniform float density_multiplier;
 uniform float max_y;
 
 uniform vec4 glow;
-
+uniform float sun_up_factor;
 uniform vec4 cloud_color;
 
 void main()
@@ -119,6 +119,8 @@ void main()
 	temp2.x = pow(temp2.x, glow.z);
 		// glow.z should be negative, so we're doing a sort of (1 / "angle") function
 
+        temp2.x *= sun_up_factor;
+
 	// Add "minimum anti-solar illumination"
 	temp2.x += .25;
 
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
index 65af2821be3..95d5b52b458 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
@@ -67,48 +67,55 @@ vec4 computeMoments(float depth, float alpha);
 
 void main()
 {
-	// Set variables
-	vec2 uv1 = vary_texcoord0.xy;
-	vec2 uv2 = vary_texcoord1.xy;
-	vec2 uv3 = vary_texcoord2.xy;
-	float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
-	vec2 uv4 = vary_texcoord3.xy;
-
-    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 * 0.02);	//large texture, visible density
-	uv2 += cloud_pos_density1.xy;	//large texture, self shadow
-	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 * cloud_pos_density1.z, 1.);
-
-	// And smooth
-	alpha1 = 1. - alpha1 * alpha1;
-	alpha1 = 1. - alpha1 * alpha1;	
-
-    if (alpha1 < 0.001f)
+    if (cloud_scale >= 0.001)
     {
-        discard;
+        // Set variables
+        vec2 uv1 = vary_texcoord0.xy;
+        vec2 uv2 = vary_texcoord1.xy;
+        vec2 uv3 = vary_texcoord2.xy;
+        float cloudDensity = 2.0 * (cloud_shadow - 0.25);
+    
+        vec2 uv4 = vary_texcoord3.xy;
+    
+        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 * 0.02);    //large texture, visible density
+        uv2 += cloud_pos_density1.xy;   //large texture, self shadow
+        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 * 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 * cloud_pos_density1.z, 1.);
+    
+        // And smooth
+        alpha2 = 1. - alpha2;
+        alpha2 = 1. - alpha2 * alpha2;  
+    
+        frag_color = computeMoments(length(pos), alpha1);
+    }
+    else
+    {
+        frag_color = vec4(0);
     }
-
-	// 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 * cloud_pos_density1.z, 1.);
-
-	// And smooth
-	alpha2 = 1. - alpha2;
-	alpha2 = 1. - alpha2 * alpha2;	
-
-    frag_color = computeMoments(length(pos), alpha1);
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
index 015caad7498..c111456782a 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
@@ -81,47 +81,52 @@ vec4 cloudNoise(vec2 uv)
 
 void main()
 {
-	// Set variables
-	vec2 uv1 = vary_texcoord0.xy;
-	vec2 uv2 = vary_texcoord1.xy;
-	vec2 uv3 = vary_texcoord2.xy;
-	float cloudDensity = 2.0 * (cloud_shadow - 0.25);
+    // Set variables
+    vec2 uv1 = vary_texcoord0.xy;
+    vec2 uv2 = vary_texcoord1.xy;
+    vec2 uv3 = vary_texcoord2.xy;
+    float cloudDensity = 2.0 * (cloud_shadow - 0.25);
 
-	vec2 uv4 = vary_texcoord3.xy;
+    if (cloud_scale < 0.001)
+    {
+        discard;
+    }
+
+    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);
 
-	// Offset texture coords
-	uv1 += cloud_pos_density1.xy + disturbance;	//large texture, visible density
-	uv2 += cloud_pos_density1.xy;	//large texture, self shadow
-	uv3 += cloud_pos_density2.xy + disturbance;	//small texture, visible density
-	uv4 += cloud_pos_density2.xy;	//small texture, self shadow
+    // Offset texture coords
+    uv1 += cloud_pos_density1.xy + disturbance; //large texture, visible density
+    uv2 += cloud_pos_density1.xy;   //large texture, self shadow
+    uv3 += cloud_pos_density2.xy + disturbance; //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));
 
     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 * cloud_pos_density1.z, 1.);
+    // 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 * cloud_pos_density1.z, 1.);
 
-	// And smooth
-	alpha1 = 1. - alpha1 * alpha1;
-	alpha1 = 1. - alpha1 * alpha1;	
+    // 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 * cloud_pos_density1.z, 1.);
+    // 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 * cloud_pos_density1.z, 1.);
 
-	// And smooth
-	alpha2 = 1. - alpha2;
-	alpha2 = 1. - alpha2 * alpha2;	
+    // And smooth
+    alpha2 = 1. - alpha2;
+    alpha2 = 1. - alpha2 * alpha2;  
 
     vec3 view_ray = vary_pos.xyz + camPosLocal;
 
@@ -135,8 +140,8 @@ void main()
 
     vec3 sun_color = vec3(1.0) - exp(-radiance_sun * 0.0001);
 
-	// Combine
-	vec4 color;
+    // Combine
+    vec4 color;
 
     vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
 
@@ -156,8 +161,8 @@ void main()
     color.rgb = pow(color.rgb, vec3(1.0 / 2.2));
     color.rgb += amb;
 
-	frag_data[0] = vec4(color.rgb, alpha1);
-	frag_data[1] = vec4(0);
-	frag_data[2] = vec4(0,1,0,1);
+    frag_data[0] = vec4(color.rgb, alpha1);
+    frag_data[1] = vec4(0);
+    frag_data[2] = vec4(0,1,0,1);
 }
 
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
index 53b6d88ef5e..71e422ddf06 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
@@ -49,22 +49,22 @@ void main()
 {
     vary_pos = position;
 
-	// World / view / projection
-	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+    // World / view / projection
+    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
 
-	// Texture coords
-	vary_texcoord0 = texcoord0;
-	vary_texcoord0.xy -= 0.5;
-    vary_texcoord0.xy /= cloud_scale;
+    // Texture coords
+    vary_texcoord0 = texcoord0;
+    vary_texcoord0.xy -= 0.5;
+    vary_texcoord0.xy /= max(0.001, cloud_scale);
     vary_texcoord0.xy += 0.5;
 
-	vary_texcoord1 = vary_texcoord0;
-	vary_texcoord1.x += lightnorm.x * 0.0125;
+    vary_texcoord1 = vary_texcoord0;
+    vary_texcoord1.x += lightnorm.x * 0.0125;
     vary_texcoord1.y += lightnorm.z * 0.0125;
 
-	vary_texcoord2 = vary_texcoord0 * 16.;
-	vary_texcoord3 = vary_texcoord1 * 16.;
+    vary_texcoord2 = vary_texcoord0 * 16.;
+    vary_texcoord3 = vary_texcoord1 * 16.;
 
-	// END CLOUDS
+    // END CLOUDS
 }
 
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index e6306b391a9..f9ab241988a 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -232,6 +232,8 @@ void LLDrawPoolWLSky::renderSkyHazeAdvanced(const LLVector3& camPosLocal, F32 ca
 
 	    sky_shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
 
+        sky_shader->uniform1f(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1.0f : 0.0f);
+
         sky_shader->uniform3f(sCamPosLocal, camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
 
         renderFsSky(camPosLocal, camHeightLocal, sky_shader);
@@ -266,6 +268,8 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
         sky_shader->uniform1f(LLShaderMgr::DROPLET_RADIUS, droplet_radius);
         sky_shader->uniform1f(LLShaderMgr::ICE_LEVEL, ice_level);
 
+        sky_shader->uniform1f(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1.0f : 0.0f);
+
         /// Render the skydome
         renderDome(origin, camHeightLocal, sky_shader);	
 
@@ -475,7 +479,7 @@ void LLDrawPoolWLSky::renderSkyCloudsAdvanced(const LLVector3& camPosLocal, F32
 
         cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
         cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
-
+        cloudshader->uniform1f(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1.0f : 0.0f);
         cloudshader->uniform3f(sCamPosLocal, camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
 
 		/// Render the skydome
@@ -530,6 +534,7 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32
 
         cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
         cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
+        cloudshader->uniform1f(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1.0f : 0.0f);
 
 		/// Render the skydome
         renderDome(camPosLocal, camHeightLocal, cloudshader);
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index af078251b30..7b5a922bbd5 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -243,6 +243,16 @@ LLHeavenBody::LLHeavenBody(const F32 rad)
 	mColorCached.setToBlack();
 }
 
+const LLQuaternion& LLHeavenBody::getRotation() const
+{
+    return mRotation;
+}
+
+void LLHeavenBody::setRotation(const LLQuaternion& rot)
+{
+    mRotation = rot;
+}
+
 const LLVector3& LLHeavenBody::getDirection() const
 {
     return mDirection;
@@ -738,6 +748,9 @@ void LLVOSky::updateDirections(void)
     mSun.setDirection(psky->getSunDirection());
 	mMoon.setDirection(psky->getMoonDirection());
 
+    mSun.setRotation(psky->getSunRotation());
+	mMoon.setRotation(psky->getMoonRotation());
+
     mSun.setColor(psky->getSunlightColor());
 	mMoon.setColor(psky->getMoonDiffuse());
 
@@ -1199,11 +1212,13 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const
 	S32 index_offset;
 	LLFace *facep;
 
-	LLVector3 to_dir   = hb.getDirection();
+    LLQuaternion rot    = hb.getRotation();
+	LLVector3 to_dir    = LLVector3::x_axis * rot;
+    LLVector3 hb_right  = LLVector3::y_axis * rot;
+	LLVector3 hb_up     = LLVector3::z_axis * rot;
+
 	LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST;
 
-	LLVector3 hb_right = to_dir % LLVector3::z_axis;
-	LLVector3 hb_up = hb_right % to_dir;
 	hb_right.normalize();
 	hb_up.normalize();
 
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 0713661295b..a9ef5474b67 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -30,6 +30,7 @@
 #include "stdtypes.h"
 #include "v3color.h"
 #include "v4coloru.h"
+#include "llquaternion.h"
 #include "llviewertexture.h"
 #include "llviewerobject.h"
 #include "llframetimer.h"
@@ -38,7 +39,7 @@
 #include "lllegacyatmospherics.h"
 
 const F32 SKY_BOX_MULT			= 16.0f;
-const F32 HEAVENLY_BODY_DIST	= HORIZON_DIST - 10.f;
+const F32 HEAVENLY_BODY_DIST	= HORIZON_DIST - 20.f;
 const F32 HEAVENLY_BODY_FACTOR	= 0.1f;
 const F32 HEAVENLY_BODY_SCALE	= HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR;
 
@@ -132,6 +133,7 @@ class LLHeavenBody
 	LLColor3		mColorCached;
 	F32				mIntensity;
 	LLVector3		mDirection;				// direction of the local heavenly body
+    LLQuaternion    mRotation;
 	LLVector3		mAngularVelocity;		// velocity of the local heavenly body
 
 	F32				mDiskRadius;
@@ -147,6 +149,9 @@ class LLHeavenBody
 	LLHeavenBody(const F32 rad);
 	~LLHeavenBody() {}
 
+    const LLQuaternion& getRotation() const;
+    void                setRotation(const LLQuaternion& rot);
+
 	const LLVector3& getDirection()	const;
 	void setDirection(const LLVector3 &direction);
 	void setAngularVelocity(const LLVector3 &ang_vel);
-- 
GitLab