From c7479098f5a60de0e14e18d427067338f0f6c6a6 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 13 Jun 2013 14:33:59 -0500
Subject: NORSPEC-261 Better blending of environment map.

---
 .../shaders/class1/deferred/softenLightF.glsl      | 790 ++++++++++-----------
 .../shaders/class2/deferred/softenLightF.glsl      |  80 +--
 2 files changed, 433 insertions(+), 437 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index f7920f7595..4cae08b0b9 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -1,396 +1,394 @@
-/** 
- * @file softenLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
- 
-#extension GL_ARB_texture_rectangle : enable
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect positionMap;
-uniform sampler2DRect normalMap;
-uniform sampler2DRect lightMap;
-uniform sampler2DRect depthMap;
-uniform samplerCube environmentMap;
-uniform sampler2D	  lightFunc;
-
-uniform float blur_size;
-uniform float blur_fidelity;
-
-// Inputs
-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 mat3 ssao_effect_mat;
-
-uniform vec3 sun_dir;
-VARYING vec2 vary_fragcoord;
-
-vec3 vary_PositionEye;
-
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
-	vec2 sn;
-	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
-	return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
-	vec3 n;
-	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
-	n.z = sqrt(1.0f - dot(n.xy,n.xy));
-	return n;
-}
-#else
-vec3 decode_normal (vec2 enc)
-{
-    vec2 fenc = enc*4-2;
-    float f = dot(fenc,fenc);
-    float g = sqrt(1-f/4);
-    vec3 n;
-    n.xy = fenc*g;
-    n.z = 1-f/2;
-    return n;
-}
-#endif
-
-vec4 getPosition_d(vec2 pos_screen, float depth)
-{
-	vec2 sc = pos_screen.xy*2.0;
-	sc /= screen_res;
-	sc -= vec2(1.0,1.0);
-	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
-	vec4 pos = inv_proj * ndc;
-	pos /= pos.w;
-	pos.w = 1.0;
-	return pos;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{ //get position in screen space (world units) given window coordinate and depth map
-	float depth = texture2DRect(depthMap, pos_screen.xy).a;
-	return getPosition_d(pos_screen, depth);
-}
-
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
-vec3 getSunlitColor()
-{
-	return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
-	return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
-	return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
-	return vary_AtmosAttenuation;
-}
-
-void setPositionEye(vec3 v)
-{
-	vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
-	vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
-	vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
-	vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
-	vary_AtmosAttenuation = v;
-}
-
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
-	vec3 P = inPositionEye;
-	setPositionEye(P);
-	
-	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);
-	
-	//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;
-	
-	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas
-	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
-	 * // The following line of code performs the equivalent of:
-	 * float ambAlpha = tmpAmbient.a;
-	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
-	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
-	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
-	 */
-	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
-	//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(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma);
-	setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma);
-	setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);
-}
-
-vec3 atmosLighting(vec3 light)
-{
-	light *= getAtmosAttenuation().r;
-	light += getAdditiveColor();
-	return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
-	light *= getAtmosAttenuation().r;
-	light += getAdditiveColor() * 2.0;
-	return light;
-}
-
-vec3 fullbrightAtmosTransport(vec3 light) {
-	float brightness = dot(light.rgb, vec3(0.33333));
-
-	return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
-}
-
-
-
-vec3 atmosGetDiffuseSunlightColor()
-{
-	return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
-	return (light / scene_light_strength );
-}
-
-vec3 scaleUpLight(vec3 light)
-{
-	return (light * scene_light_strength);
-}
-
-vec3 atmosAmbient(vec3 light)
-{
-	return getAmblitColor() + light / 2.0;
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
-	return getSunlitColor() * lightIntensity;
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
-	//soft clip effect:
-	light = 1. - clamp(light, vec3(0.), vec3(1.));
-	light = 1. - pow(light, gamma.xxx);
-
-	return light;
-}
-
-
-vec3 fullbrightScaleSoftClip(vec3 light)
-{
-	//soft clip effect:
-	return light;
-}
-
-void main() 
-{
-	vec2 tc = vary_fragcoord.xy;
-	float depth = texture2DRect(depthMap, tc.xy).r;
-	vec3 pos = getPosition_d(tc, depth).xyz;
-	vec4 norm = texture2DRect(normalMap, tc);
-	float envIntensity = norm.z;
-	norm.xyz = decode_normal(norm.xy); // unpack norm
-		
-	float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
-
-	vec4 diffuse = texture2DRect(diffuseRect, tc);
-	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-	vec3 col;
-	float bloom = 0.0;
-	{
-		calcAtmospherics(pos.xyz, 1.0);
-	
-		col = atmosAmbient(vec3(0));
-		float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
-		ambient *= 0.5;
-		ambient *= ambient;
-		ambient = (1.0-ambient);
-
-		col.rgb *= ambient;
-
-		col += atmosAffectDirectionalLight(max(min(da, 1.0) * 2.6, 0.0));
-	
-		col *= diffuse.rgb;
-	
-		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
-		if (spec.a > 0.0) // specular reflection
-		{
-			// the old infinite-sky shiny reflection
-			//
-			
-			float sa = dot(refnormpersp, sun_dir.xyz);
-			vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);
-			
-			// add the two types of shiny together
-			vec3 spec_contrib = dumbshiny * spec.rgb;
-			bloom = dot(spec_contrib, spec_contrib) / 6;
-			col += spec_contrib;
-		}
-		
-		
-		col = mix(col.rgb, pow(diffuse.rgb, vec3(1.0/2.2)), diffuse.a);
-		
-		
-		if (envIntensity > 0.0)
-		{ //add environmentmap
-			vec3 env_vec = env_mat * refnormpersp;
-			
-			float exponent = mix(2.2, 1.0, diffuse.a);
-			vec3 refcol = pow(textureCube(environmentMap, env_vec).rgb, vec3(exponent))*exponent;
-
-			col = mix(col.rgb, refcol, 
-				envIntensity);  
-
-		}
-
-		float exponent = mix(1.0, 2.2, diffuse.a);
-		col = pow(col, vec3(exponent));
-				
-		if (norm.w < 0.5)
-		{
-			col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
-			col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
-		}
-
-		//col = vec3(1,0,1);
-		//col.g = envIntensity;
-	}
-	
-	frag_color.rgb = col;
-
-	frag_color.a = bloom;
-}
+/** 
+ * @file softenLightF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+ 
+#extension GL_ARB_texture_rectangle : enable
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect specularRect;
+uniform sampler2DRect positionMap;
+uniform sampler2DRect normalMap;
+uniform sampler2DRect lightMap;
+uniform sampler2DRect depthMap;
+uniform samplerCube environmentMap;
+uniform sampler2D	  lightFunc;
+
+uniform float blur_size;
+uniform float blur_fidelity;
+
+// Inputs
+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 mat3 ssao_effect_mat;
+
+uniform vec3 sun_dir;
+VARYING vec2 vary_fragcoord;
+
+vec3 vary_PositionEye;
+
+vec3 vary_SunlitColor;
+vec3 vary_AmblitColor;
+vec3 vary_AdditiveColor;
+vec3 vary_AtmosAttenuation;
+
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+	vec2 sn;
+	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+	return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+	vec3 n;
+	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+	n.z = sqrt(1.0f - dot(n.xy,n.xy));
+	return n;
+}
+#else
+vec3 decode_normal (vec2 enc)
+{
+    vec2 fenc = enc*4-2;
+    float f = dot(fenc,fenc);
+    float g = sqrt(1-f/4);
+    vec3 n;
+    n.xy = fenc*g;
+    n.z = 1-f/2;
+    return n;
+}
+#endif
+
+vec4 getPosition_d(vec2 pos_screen, float depth)
+{
+	vec2 sc = pos_screen.xy*2.0;
+	sc /= screen_res;
+	sc -= vec2(1.0,1.0);
+	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+	vec4 pos = inv_proj * ndc;
+	pos /= pos.w;
+	pos.w = 1.0;
+	return pos;
+}
+
+vec4 getPosition(vec2 pos_screen)
+{ //get position in screen space (world units) given window coordinate and depth map
+	float depth = texture2DRect(depthMap, pos_screen.xy).a;
+	return getPosition_d(pos_screen, depth);
+}
+
+vec3 getPositionEye()
+{
+	return vary_PositionEye;
+}
+vec3 getSunlitColor()
+{
+	return vary_SunlitColor;
+}
+vec3 getAmblitColor()
+{
+	return vary_AmblitColor;
+}
+vec3 getAdditiveColor()
+{
+	return vary_AdditiveColor;
+}
+vec3 getAtmosAttenuation()
+{
+	return vary_AtmosAttenuation;
+}
+
+void setPositionEye(vec3 v)
+{
+	vary_PositionEye = v;
+}
+
+void setSunlitColor(vec3 v)
+{
+	vary_SunlitColor = v;
+}
+
+void setAmblitColor(vec3 v)
+{
+	vary_AmblitColor = v;
+}
+
+void setAdditiveColor(vec3 v)
+{
+	vary_AdditiveColor = v;
+}
+
+void setAtmosAttenuation(vec3 v)
+{
+	vary_AtmosAttenuation = v;
+}
+
+void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
+
+	vec3 P = inPositionEye;
+	setPositionEye(P);
+	
+	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);
+	
+	//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;
+	
+	/*  decrease value and saturation (that in HSV, not HSL) for occluded areas
+	 * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
+	 * // The following line of code performs the equivalent of:
+	 * float ambAlpha = tmpAmbient.a;
+	 * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
+	 * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
+	 * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
+	 */
+	tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
+
+	//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(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma);
+	setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma);
+	setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);
+}
+
+vec3 atmosLighting(vec3 light)
+{
+	light *= getAtmosAttenuation().r;
+	light += getAdditiveColor();
+	return (2.0 * light);
+}
+
+vec3 atmosTransport(vec3 light) {
+	light *= getAtmosAttenuation().r;
+	light += getAdditiveColor() * 2.0;
+	return light;
+}
+
+vec3 fullbrightAtmosTransport(vec3 light) {
+	float brightness = dot(light.rgb, vec3(0.33333));
+
+	return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+}
+
+
+
+vec3 atmosGetDiffuseSunlightColor()
+{
+	return getSunlitColor();
+}
+
+vec3 scaleDownLight(vec3 light)
+{
+	return (light / scene_light_strength );
+}
+
+vec3 scaleUpLight(vec3 light)
+{
+	return (light * scene_light_strength);
+}
+
+vec3 atmosAmbient(vec3 light)
+{
+	return getAmblitColor() + light / 2.0;
+}
+
+vec3 atmosAffectDirectionalLight(float lightIntensity)
+{
+	return getSunlitColor() * lightIntensity;
+}
+
+vec3 scaleSoftClip(vec3 light)
+{
+	//soft clip effect:
+	light = 1. - clamp(light, vec3(0.), vec3(1.));
+	light = 1. - pow(light, gamma.xxx);
+
+	return light;
+}
+
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+	//soft clip effect:
+	return light;
+}
+
+void main() 
+{
+	vec2 tc = vary_fragcoord.xy;
+	float depth = texture2DRect(depthMap, tc.xy).r;
+	vec3 pos = getPosition_d(tc, depth).xyz;
+	vec4 norm = texture2DRect(normalMap, tc);
+	float envIntensity = norm.z;
+	norm.xyz = decode_normal(norm.xy); // unpack norm
+		
+	float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
+
+	vec4 diffuse = texture2DRect(diffuseRect, tc);
+	
+	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
+	vec3 col;
+	float bloom = 0.0;
+	{
+		calcAtmospherics(pos.xyz, 1.0);
+	
+		col = atmosAmbient(vec3(0));
+		float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+		ambient *= 0.5;
+		ambient *= ambient;
+		ambient = (1.0-ambient);
+
+		//col.rgb *= ambient;
+
+		col += atmosAffectDirectionalLight(max(min(da, 1.0) * 2.8, 0.0));
+	
+		col *= diffuse.rgb;
+	
+		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+		if (spec.a > 0.0) // specular reflection
+		{
+			// the old infinite-sky shiny reflection
+			//
+			
+			float sa = dot(refnormpersp, sun_dir.xyz);
+			vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);
+			
+			// add the two types of shiny together
+			vec3 spec_contrib = dumbshiny * spec.rgb;
+			bloom = dot(spec_contrib, spec_contrib) / 6;
+			col += spec_contrib;
+		}
+		
+		
+		col = mix(col.rgb, diffuse.rgb, diffuse.a);
+				
+		if (envIntensity > 0.0)
+		{ //add environmentmap
+			vec3 env_vec = env_mat * refnormpersp;
+			
+			
+			vec3 refcol = textureCube(environmentMap, env_vec).rgb;
+
+			col = mix(pow(col.rgb, vec3(1.0/2.2)), refcol, 
+				envIntensity);  
+
+			col = pow(col, vec3(2.2));
+		}
+				
+		if (norm.w < 0.5)
+		{
+			col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
+			col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
+		}
+
+		//col = vec3(1,0,1);
+		//col.g = envIntensity;
+	}
+
+	frag_color.rgb = col;
+
+	frag_color.a = bloom;
+}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 520b3bbd47..eb83fab6b5 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -78,38 +78,38 @@ vec3 vary_AtmosAttenuation;
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
 
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
-	vec2 sn;
-	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
-	return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
-	vec3 n;
-	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
-	n.z = sqrt(1.0f - dot(n.xy,n.xy));
-	return n;
-}
-#else
-vec2 encode_normal(vec3 n)
-{
-	float f = sqrt(8 * n.z + 8);
-	return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
-    vec2 fenc = enc*4-2;
-    float f = dot(fenc,fenc);
-    float g = sqrt(1-f/4);
-    vec3 n;
-    n.xy = fenc*g;
-    n.z = 1-f/2;
-    return n;
-}
+#ifdef SINGLE_FP_ONLY
+vec2 encode_normal(vec3 n)
+{
+	vec2 sn;
+	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
+	return sn;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+	vec3 n;
+	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
+	n.z = sqrt(1.0f - dot(n.xy,n.xy));
+	return n;
+}
+#else
+vec2 encode_normal(vec3 n)
+{
+	float f = sqrt(8 * n.z + 8);
+	return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+    vec2 fenc = enc*4-2;
+    float f = dot(fenc,fenc);
+    float g = sqrt(1-f/4);
+    vec3 n;
+    n.xy = fenc*g;
+    n.z = 1-f/2;
+    return n;
+}
 #endif
 
 vec4 getPosition_d(vec2 pos_screen, float depth)
@@ -374,23 +374,21 @@ void main()
 		}
 	
 		
-		col = mix(col.rgb, pow(diffuse.rgb, vec3(1.0/2.2)), diffuse.a);
-		
-		
+		col = mix(col.rgb, diffuse.rgb, diffuse.a);
+				
 		if (envIntensity > 0.0)
 		{ //add environmentmap
 			vec3 env_vec = env_mat * refnormpersp;
 			
-			float exponent = mix(2.2, 1.0, diffuse.a);
-			vec3 refcol = pow(textureCube(environmentMap, env_vec).rgb, vec3(exponent))*exponent;
+			
+			vec3 refcol = textureCube(environmentMap, env_vec).rgb;
 
-			col = mix(col.rgb, refcol, 
+			col = mix(pow(col.rgb, vec3(1.0/2.2)), refcol, 
 				envIntensity);  
 
-		}
+			col = pow(col, vec3(2.2));
 
-		float exponent = mix(1.0, 2.2, diffuse.a);
-		col = pow(col, vec3(exponent));
+		}
 				
 		if (norm.w < 0.5)
 		{
-- 
cgit v1.2.3