From e16eb4ae4a73125bc4e74fc667aa99110ac77c29 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Wed, 27 Jul 2011 01:04:53 -0500
Subject: [PATCH] SH-1990 Fix for redundantly applying some color scaling to
 sky and water (also add some snazzy specular bloom from the sun)

---
 .../shaders/class1/deferred/softenLightF.glsl |  93 +++++---------
 .../class1/deferred/softenLightMSF.glsl       |  28 +++--
 .../shaders/class2/deferred/softenLightF.glsl |  59 +++++----
 .../class2/deferred/softenLightMSF.glsl       |  60 ++++++----
 .../shaders/class3/deferred/softenLightF.glsl | 113 ++++++------------
 5 files changed, 157 insertions(+), 196 deletions(-)

diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 60082f40d69..d327216a0cb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -270,72 +270,41 @@ void main()
 	vec4 diffuse = texture2DRect(diffuseRect, tc);
 	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
 	
-	calcAtmospherics(pos.xyz, 1.0);
+	vec3 col;
+	float bloom = 0.0;
+	if (diffuse.a < 0.9)
+	{
+		calcAtmospherics(pos.xyz, 1.0);
+	
+		col = atmosAmbient(vec3(0));
+		col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a));
 	
-	vec3 col = atmosAmbient(vec3(0));
-	col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a));
+		col *= diffuse.rgb;
 	
-	col *= diffuse.rgb;
+		if (spec.a > 0.0) // specular reflection
+		{
+			// the old infinite-sky shiny reflection
+			//
+			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+			float sa = dot(refnormpersp, vary_light.xyz);
+			vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).a;
+			
+			// add the two types of shiny together
+			vec3 spec_contrib = dumbshiny * spec.rgb;
+			bloom = dot(spec_contrib, spec_contrib);
+			col += spec_contrib;
+		}
 	
-	if (spec.a > 0.0) // specular reflection
+		col = atmosLighting(col);
+		col = scaleSoftClip(col);
+
+		col = mix(col.rgb, diffuse.rgb, diffuse.a);
+	}
+	else
 	{
-		// the old infinite-sky shiny reflection
-		//
-		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-		float sa = dot(refnormpersp, vary_light.xyz);
-		vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).a;
-
-		/*
-		// screen-space cheap fakey reflection map
-		//
-		vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz));
-		depth -= 0.5; // unbias depth
-		// first figure out where we'll make our 2D guess from
-		vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth;
-		// Offset the guess source a little according to a trivial
-		// checkerboard dither function and spec.a.
-		// This is meant to be similar to sampling a blurred version
-		// of the diffuse map.  LOD would be better in that regard.
-		// The goal of the blur is to soften reflections in surfaces
-		// with low shinyness, and also to disguise our lameness.
-		float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0
-		float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5);
-		ref2d += vec2(checkoffset, checkoffset);
-		ref2d += tc.xy; // use as offset from destination
-		// Get attributes from the 2D guess point.
-		// We average two samples of diffuse (not of anything else) per
-		// pixel to try to reduce aliasing some more.
-		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb +
-				     texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb);
-		float refdepth = texture2DRect(depthMap, ref2d).a;
-		vec3 refpos = getPosition_d(ref2d, refdepth).xyz;
-		vec3 refn = texture2DRect(normalMap, ref2d).rgb;
-		refn = normalize(vec3((refn.xy-0.5)*2.0,refn.z)); // unpack norm
-		// figure out how appropriate our guess actually was
-		float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos)));
-		// darken reflections from points which face away from the reflected ray - our guess was a back-face
-		//refapprop *= step(dot(refnorm, refn), 0.0);
-		refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant
-		// get appropriate light strength for guess-point.
-		// reflect light direction to increase the illusion that
-		// these are reflections.
-		vec3 reflight = reflect(lightnorm.xyz, norm.xyz);
-		float reflit = max(dot(refn, reflight.xyz), 0.0);
-		// apply sun color to guess-point, dampen according to inappropriateness of guess
-		float refmod = min(refapprop, reflit);
-		vec3 refprod = vary_SunlitColor * refcol.rgb * refmod;
-		vec3 ssshiny = (refprod * spec.a);
-		ssshiny *= 0.3; // dampen it even more
-		*/
-		vec3 ssshiny = vec3(0,0,0);
-
-		// add the two types of shiny together
-		col += (ssshiny + dumbshiny) * spec.rgb;
+		col = diffuse.rgb;
 	}
-	
-	col = atmosLighting(col);
-	col = scaleSoftClip(col);
-		
+
 	gl_FragColor.rgb = col;
-	gl_FragColor.a = 0.0;
+	gl_FragColor.a = bloom;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl
index 9dfacfb520c..2cce43e2bfb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightMSF.glsl
@@ -266,7 +266,7 @@ void main()
 	vec2 tc = vary_fragcoord.xy;
 	ivec2 itc = ivec2(tc);
 
-	vec3 fcol = vec3(0,0,0);
+	vec4 fcol = vec4(0,0,0,0);
 
 	for (int i = 0; i < samples; ++i)
 	{
@@ -280,17 +280,16 @@ void main()
 		float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
 	
 		vec4 diffuse = texelFetch(diffuseRect, itc, i);
-		if (diffuse.a >= 1.0)
-		{
-			fcol += diffuse.rgb;
-		}
-		else
+		vec3 col;
+		float bloom = 0.0;
+
+		if (diffuse.a < 0.9)
 		{
 			vec4 spec = texelFetch(specularRect, itc, i);
 	
 			calcAtmospherics(pos.xyz, 1.0);
 	
-			vec3 col = atmosAmbient(vec3(0));
+			col = atmosAmbient(vec3(0));
 			col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a));
 	
 			col *= diffuse.rgb;
@@ -304,15 +303,22 @@ void main()
 				vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).a;
 
 				// add the two types of shiny together
-				col += dumbshiny * spec.rgb;
+				vec3 spec_contrib = dumbshiny * spec.rgb;
+				bloom = dot(spec_contrib, spec_contrib);
+				col += spec_contrib;
 			}
 
 			col = atmosLighting(col);
 			col = scaleSoftClip(col);
-			fcol += col;
+			col = mix(col, diffuse.rgb, diffuse.a);
 		}
+		else
+		{
+			col = diffuse.rgb;
+		}
+
+		fcol += vec4(col, bloom);
 	}
 				
-	gl_FragColor.rgb = fcol.rgb/samples;
-	gl_FragColor.a = 0.0;
+	gl_FragColor = fcol/samples;
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 66a1a8515f2..f0c9b01671f 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -267,34 +267,49 @@ void main()
 	float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
 	
 	vec4 diffuse = texture2DRect(diffuseRect, tc);
-	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-	
-	vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
-	float scol = max(scol_ambocc.r, diffuse.a); 
-	float ambocc = scol_ambocc.g;
+
+	vec3 col;
+	float bloom = 0.0;
+
+	if (diffuse.a < 0.9)
+	{
+		vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
+		
+		vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+		float scol = max(scol_ambocc.r, diffuse.a); 
+		float ambocc = scol_ambocc.g;
 	
-	calcAtmospherics(pos.xyz, ambocc);
+		calcAtmospherics(pos.xyz, ambocc);
 	
-	vec3 col = atmosAmbient(vec3(0));
-	col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
+		col = atmosAmbient(vec3(0));
+		col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
 	
-	col *= diffuse.rgb;
+		col *= diffuse.rgb;
 	
-	if (spec.a > 0.0) // specular reflection
+		if (spec.a > 0.0) // specular reflection
+		{
+			// the old infinite-sky shiny reflection
+			//
+			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+			float sa = dot(refnormpersp, vary_light.xyz);
+			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
+
+			// add the two types of shiny together
+			vec3 spec_contrib = dumbshiny * spec.rgb;
+			bloom = dot(spec_contrib, spec_contrib);
+			col += spec_contrib;
+		}
+			
+		col = atmosLighting(col);
+		col = scaleSoftClip(col);
+
+		col = mix(col, diffuse.rgb, diffuse.a);
+	}
+	else
 	{
-		// the old infinite-sky shiny reflection
-		//
-		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-		float sa = dot(refnormpersp, vary_light.xyz);
-		vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
-
-		// add the two types of shiny together
-		col += dumbshiny * spec.rgb;
+		col = diffuse.rgb;
 	}
-	
-	col = atmosLighting(col);
-	col = scaleSoftClip(col);
 		
 	gl_FragColor.rgb = col;
-	gl_FragColor.a = 0.0;
+	gl_FragColor.a = bloom;
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl
index 0bae10ca7d2..3b572320c32 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightMSF.glsl
@@ -255,7 +255,7 @@ void main()
 	vec2 tc = vary_fragcoord.xy;
 	ivec2 itc = ivec2(tc);
 
-	vec3 fcol = vec3(0,0,0);
+	vec4 fcol = vec4(0,0,0,0);
 
 	vec2 scol_ambocc = texture2DRect(lightMap, tc).rg;
 	float ambocc = scol_ambocc.g;
@@ -270,38 +270,50 @@ void main()
 		float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
 	
 		vec4 diffuse = texelFetch(diffuseRect, itc, i);
-		vec4 spec = texelFetch(specularRect, itc, i);
+		vec3 col;
+		float bloom = 0.0;
+		if (diffuse.a < 0.9)
+		{
+			vec4 spec = texelFetch(specularRect, itc, i);
 	
-		float amb = 0;
+			float amb = 0;
 
-		float scol = max(scol_ambocc.r, diffuse.a); 
-		amb += ambocc;
+			float scol = max(scol_ambocc.r, diffuse.a); 
+			amb += ambocc;
 
-		calcAtmospherics(pos.xyz, ambocc);
+			calcAtmospherics(pos.xyz, ambocc);
+	
+			col = atmosAmbient(vec3(0));
+			col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
 	
-		vec3 col = atmosAmbient(vec3(0));
-		col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
+			col *= diffuse.rgb;
 	
-		col *= diffuse.rgb;
+			if (spec.a > 0.0) // specular reflection
+			{
+				// the old infinite-sky shiny reflection
+				//
+				vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+				float sa = dot(refnormpersp, vary_light.xyz);
+				vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
+
+				// add the two types of shiny together
+				vec3 spec_contrib = dumbshiny * spec.rgb;
+				bloom = dot(spec_contrib, spec_contrib);
+				col += spec_contrib;
+			}
 	
-		if (spec.a > 0.0) // specular reflection
+			col = atmosLighting(col);
+			col = scaleSoftClip(col);
+
+			col = mix(col, diffuse.rgb, diffuse.a);
+		}
+		else
 		{
-			// the old infinite-sky shiny reflection
-			//
-			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-			float sa = dot(refnormpersp, vary_light.xyz);
-			vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
-
-			// add the two types of shiny together
-			col += dumbshiny * spec.rgb;
+			col = diffuse.rgb;
 		}
-	
-		col = atmosLighting(col);
-		col = scaleSoftClip(col);
 
-		fcol += col;
+		fcol += vec4(col, bloom);
 	}
 		
-	gl_FragColor.rgb = fcol/samples; 
-	gl_FragColor.a = 0.0;
+	gl_FragColor = fcol/samples; 
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index d38d33cc219..1ae10a5faae 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -268,91 +268,50 @@ void main()
 	float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
 	
 	vec4 diffuse = texture2DRect(diffuseRect, tc);
-	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
+	vec3 col;
+	float bloom = 0.0;
+
+	if (diffuse.a < 0.9)
+	{
+		vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
 	
-	da = texture2D(lightFunc, vec2(da, 0.0)).a;
+		da = texture2D(lightFunc, vec2(da, 0.0)).a;
 		
-	vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
-	float scol = max(scol_ambocc.r, diffuse.a); 
-	float ambocc = scol_ambocc.g;
+		vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+		float scol = max(scol_ambocc.r, diffuse.a); 
+		float ambocc = scol_ambocc.g;
 	
-	calcAtmospherics(pos.xyz, ambocc);
+		calcAtmospherics(pos.xyz, ambocc);
 	
-	vec3 col = atmosAmbient(vec3(0));
-	col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
+		col = atmosAmbient(vec3(0));
+		col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
 	
-	col *= diffuse.rgb;
+		col *= diffuse.rgb;
 	
-	if (spec.a > 0.0) // specular reflection
+		if (spec.a > 0.0) // specular reflection
+		{
+			// the old infinite-sky shiny reflection
+			//
+			vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+			float sa = dot(refnormpersp, vary_light.xyz);
+			vec3 dumbshiny = vary_SunlitColor*scol*texture2D(lightFunc, vec2(sa, spec.a)).a;
+		
+			// add the two types of shiny together
+			vec3 spec_contrib = dumbshiny * spec.rgb;
+			bloom = dot(spec_contrib, spec_contrib);
+			col += spec_contrib;		
+		}
+	
+		col = atmosLighting(col);
+		col = scaleSoftClip(col);
+
+		col = mix(col, diffuse.rgb, diffuse.a);
+	}
+	else
 	{
-		// the old infinite-sky shiny reflection
-		//
-		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-		float sa = dot(refnormpersp, vary_light.xyz);
-		vec3 dumbshiny = vary_SunlitColor*scol*texture2D(lightFunc, vec2(sa, spec.a)).a;
-
-		/*
-		// screen-space cheap fakey reflection map
-		//
-		vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz));
-		depth -= 0.5; // unbias depth
-		// first figure out where we'll make our 2D guess from
-		vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth;
-		// Offset the guess source a little according to a trivial
-		// checkerboard dither function and spec.a.
-		// This is meant to be similar to sampling a blurred version
-		// of the diffuse map.  LOD would be better in that regard.
-		// The goal of the blur is to soften reflections in surfaces
-		// with low shinyness, and also to disguise our lameness.
-		float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0
-		float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5);
-
-		ref2d += vec2(checkoffset, checkoffset);
-		ref2d += tc.xy; // use as offset from destination
-		// Get attributes from the 2D guess point.
-		// We average two samples of diffuse (not of anything else) per
-		// pixel to try to reduce aliasing some more.
-		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb +
-				     texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb);
-		float refdepth = texture2DRect(depthMap, ref2d).a;
-		vec3 refpos = getPosition_d(ref2d, refdepth).xyz;
-		float refshad = texture2DRect(lightMap, ref2d).r;
-		vec3 refn = texture2DRect(normalMap, ref2d).rgb;
-		refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm
-		refn = normalize(refn);
-		// figure out how appropriate our guess actually was
-		float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos)));
-		// darken reflections from points which face away from the reflected ray - our guess was a back-face
-		//refapprop *= step(dot(refnorm, refn), 0.0);
-		refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant
-		// get appropriate light strength for guess-point.
-		// reflect light direction to increase the illusion that
-		// these are reflections.
-		vec3 reflight = reflect(lightnorm.xyz, norm.xyz);
-		float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad);
-		// apply sun color to guess-point, dampen according to inappropriateness of guess
-		float refmod = min(refapprop, reflit);
-		vec3 refprod = vary_SunlitColor * refcol.rgb * refmod;
-		vec3 ssshiny = (refprod * spec.a);
-		ssshiny *= 0.3; // dampen it even more
-		*/
-		vec3 ssshiny = vec3(0,0,0);
-
-		// add the two types of shiny together
-		col += (ssshiny + dumbshiny) * spec.rgb;
+		col = diffuse.rgb;
 	}
-	
-	col = atmosLighting(col);
-	col = scaleSoftClip(col);
 		
 	gl_FragColor.rgb = col;
-	
-	//gl_FragColor.rgb = gi_col.rgb;
-	gl_FragColor.a = 0.0;
-	
-	//gl_FragColor.rg = scol_ambocc.rg;
-	//gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb;
-	//gl_FragColor.rgb = norm.rgb*0.5+0.5;
-	//gl_FragColor.rgb = vec3(ambocc);
-	//gl_FragColor.rgb = vec3(scol);
+	gl_FragColor.a = bloom;
 }
-- 
GitLab