From 86427ec145c7b956ec9ff5d9aa7ddde630cf45e1 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 24 Feb 2023 14:54:25 -0600
Subject: [PATCH] SL-19212 Resurrect glare and apply to PBR materials as well
 (and fix color mismatch in legacy alpha vs opaque).

---
 .../shaders/class1/deferred/deferredUtil.glsl |  58 ++++++-
 .../shaders/class1/deferred/materialF.glsl    |  49 ++++++
 .../shaders/class1/deferred/pbralphaF.glsl    |  33 ++++
 .../shaders/class2/deferred/pbralphaF.glsl    |  32 ++--
 .../shaders/class3/deferred/materialF.glsl    | 162 +++++++++++-------
 .../shaders/class3/deferred/pointLightF.glsl  |   4 +-
 6 files changed, 248 insertions(+), 90 deletions(-)
 create mode 100644 indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl

diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index e71d080fc56..6ab966ae01a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -383,7 +383,8 @@ vec3 pbrIbl(vec3 diffuseColor,
             vec3 irradiance, // irradiance map sample
             float ao,       // ambient occlusion factor
             float nv,       // normal dot view vector
-            float perceptualRough)
+            float perceptualRough,
+            out vec3 specContrib)
 {
     // retrieve a scale and bias to F0. See [1], Figure 3
 	vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
@@ -393,9 +394,24 @@ vec3 pbrIbl(vec3 diffuseColor,
 	vec3 diffuse = diffuseLight * diffuseColor;
 	vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
 
+    specContrib = specular * ao;
+
 	return (diffuse + specular*0.5) * ao;  //reduce by half to place in appropriate color space for atmospherics
 }
 
+vec3 pbrIbl(vec3 diffuseColor,
+            vec3 specularColor,
+            vec3 radiance, // radiance map sample
+            vec3 irradiance, // irradiance map sample
+            float ao,       // ambient occlusion factor
+            float nv,       // normal dot view vector
+            float perceptualRough)
+{
+    vec3 specContrib;
+    return pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, nv, perceptualRough, specContrib);
+}
+
+
 // Encapsulate the various inputs used by the various functions in the shading equation
 // We store values in this struct to simplify the integration of alternative implementations
 // of the shading terms, outlined in the Readme.MD Appendix.
@@ -460,7 +476,8 @@ vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
                     float metallic,
                     vec3 n, // normal
                     vec3 v, // surface point to camera
-                    vec3 l) //surface point to light
+                    vec3 l, //surface point to light
+                    out vec3 specContrib) //specular contribution (exposed to alpha shaders to calculate "glare")
 {
     // make sure specular highlights from punctual lights don't fall off of polished surfaces
     perceptualRoughness = max(perceptualRoughness, 8.0/255.0);
@@ -506,17 +523,30 @@ vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
 	float G = geometricOcclusion(pbrInputs);
 	float D = microfacetDistribution(pbrInputs);
 
-	const vec3 u_LightColor = vec3(1.0);
-
 	// Calculation of analytical lighting contribution
 	vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
-	vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
+	specContrib = F * G * D / (4.0 * NdotL * NdotV);
 	// Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
-	vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib);
+	vec3 color = NdotL * (diffuseContrib + specContrib);
+
+    specContrib *= NdotL;
+    specContrib = max(specContrib, vec3(0));
 
     return color;
 }
 
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, 
+                    float perceptualRoughness, 
+                    float metallic,
+                    vec3 n, // normal
+                    vec3 v, // surface point to camera
+                    vec3 l) //surface point to light
+{
+    vec3 specContrib;
+
+    return pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n, v, l, specContrib);
+}
+
 void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor)
 {
     vec3 f0 = vec3(0.04);
@@ -525,15 +555,19 @@ void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor
     specularColor = mix(f0, baseColor, metallic);
 }
 
-vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, vec3 norm, float perceptualRoughness, vec3 light_dir, vec3 sunlit, float scol, vec3 radiance, vec3 irradiance, vec3 colorEmissive, float ao, vec3 additive, vec3 atten)
+vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, vec3 norm, float perceptualRoughness, vec3 light_dir, vec3 sunlit, float scol, vec3 radiance, vec3 irradiance, vec3 colorEmissive, float ao, vec3 additive, vec3 atten, out vec3 specContrib)
 {
     vec3 color = vec3(0);
 
     float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);
     
-    color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, 0.2);
+    vec3 ibl_spec;
+    color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, 0.2, ibl_spec);
     
-    color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir)) * sunlit * 2.75 * scol;
+    color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir), specContrib) * sunlit * 2.75 * scol;
+    specContrib *= sunlit * 2.75 * scol;
+    specContrib += ibl_spec;
+
     color += colorEmissive*0.5;
 
     color = atmosFragLightingLinear(color, additive, atten);
@@ -542,6 +576,12 @@ vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v,
     return color;
 }
 
+vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, vec3 norm, float perceptualRoughness, vec3 light_dir, vec3 sunlit, float scol, vec3 radiance, vec3 irradiance, vec3 colorEmissive, float ao, vec3 additive, vec3 atten)
+{
+    vec3 specContrib;
+    return pbrBaseLight(diffuseColor, specularColor, metallic, v, norm, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten, specContrib);
+}
+
 uniform vec4 waterPlane;
 uniform float waterSign;
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
new file mode 100644
index 00000000000..4b98e6708ff
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -0,0 +1,49 @@
+/**
+* @file materialF.glsl
+*
+* $LicenseInfo:firstyear=2023&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2023, 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$
+*/
+
+/*[EXTRA_CODE_HERE]*/
+
+// debug stub
+
+#define DIFFUSE_ALPHA_MODE_BLEND    1
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+out vec4 frag_color;
+#else
+out vec4 frag_data[3];
+#endif
+
+void main()
+{
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+    frag_color = vec4(0.5, 0, 1, 0.5);
+#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer 
+    // deferred path               // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
+    frag_data[0] = vec4(0.5, 0, 1, 0);    // gbuffer is sRGB for legacy materials
+    frag_data[1] = vec4(0); // XYZ = Specular color. W = Specular exponent.
+    frag_data[2] = vec4(0); // XY = Normal.  Z = Env. intensity. W = 1 skip atmos (mask off fog)
+#endif
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
new file mode 100644
index 00000000000..3f3c11517e3
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
@@ -0,0 +1,33 @@
+/** 
+ * @file pbralphaF.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, 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$
+ */
+
+ // debug stub
+
+out vec4 frag_color;
+
+void main()
+{
+    frag_color = vec4(1.0, 0, 0.5, 0.5);
+}
\ No newline at end of file
diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
index a95feb8e2f7..987b0ca1d5c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
@@ -107,16 +107,16 @@ vec3 pbrBaseLight(vec3 diffuseColor,
                   vec3 colorEmissive,
                   float ao,
                   vec3 additive,
-                  vec3 atten);
+                  vec3 atten,
+                  out vec3 specContrib);
 
 vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, 
                     float perceptualRoughness, 
                     float metallic,
                     vec3 n, // normal
                     vec3 v, // surface point to camera
-                    vec3 l); //surface point to light
-
-vec2 BRDF(float NoV, float roughness);
+                    vec3 l, //surface point to light
+                    out vec3 specContrib); 
 
 vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor, 
                     float perceptualRoughness, 
@@ -127,7 +127,7 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
                     vec3 lp, // light position
                     vec3 ld, // light direction (for spotlights)
                     vec3 lightColor,
-                    float lightSize, float falloff, float is_pointlight, float ambiance)
+                    float lightSize, float falloff, float is_pointlight, inout float glare, float ambiance)
 {
     vec3 color = vec3(0,0,0);
 
@@ -149,7 +149,10 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
 
         vec3 intensity = spot_atten * dist_atten * lightColor * 3.0;
 
-        color = intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
+        vec3 speccol;
+        color = intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv, speccol);
+        speccol *= intensity;
+        glare += max(max(speccol.r, speccol.g), speccol.b);
     }
 
     return color;
@@ -158,6 +161,7 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
 void main()
 {
     vec3 color = vec3(0,0,0);
+    float glare = 0.0;
 
     vec3  light_dir   = (sun_up_factor == 1) ? sun_dir : moon_dir;
     vec3  pos         = vary_position;
@@ -224,15 +228,14 @@ void main()
 
     vec3 v = -normalize(pos.xyz);
 
-    color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
-
-    float nv = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0);
-    vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRoughness);
+    vec3 spec;
+    color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten, spec);
+    glare += max(max(spec.r, spec.g), spec.b);
 
     vec3 light = vec3(0);
 
     // Punctual lights
-#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
+#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w);
 
     LIGHT_LOOP(1)
     LIGHT_LOOP(2)
@@ -246,11 +249,10 @@ void main()
 
     
     float a = basecolor.a*vertex_color.a;
-    vec3 spec = radiance; // *specularColor;
-    float lum = max(max(spec.r, spec.g), spec.b);
     
-    float f = brdf.y;
-    a += f;
+    glare = min(glare, 1.0);
+    a = max(a, glare);
+
     frag_color = vec4(color.rgb,a);
 }
 
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index 8d2a65d4a99..48dd8e942e4 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -92,7 +92,7 @@ uniform vec3 light_diffuse[8];
 float getAmbientClamp();
 void waterClip(vec3 pos);
 
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
 {
     // SL-14895 inverted attenuation work-around
     // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
@@ -170,6 +170,11 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
                 vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
                 speccol = clamp(speccol, vec3(0), vec3(1));
                 col += speccol;
+
+                float cur_glare = max(speccol.r, speccol.g);
+                cur_glare = max(cur_glare, speccol.b);
+                glare = max(glare, speccol.r);
+                glare += max(cur_glare, 0.0);
             }
         }
     }
@@ -218,83 +223,104 @@ VARYING vec2 vary_texcoord0;
 
 vec2 encode_normal(vec3 n);
 
-void main()
+// get the transformed normal and apply glossiness component from normal map
+vec3 getNormal(inout float glossiness)
 {
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-    waterClip(vary_position.xyz);
-#endif
+#ifdef HAS_NORMAL_MAP
+	vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
+    glossiness *= norm.a;
 
-    vec2 pos_screen = vary_texcoord0.xy;
+	norm.xyz = norm.xyz * 2 - 1;
 
-    vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
-	diffcol.rgb *= vertex_color.rgb;
+	return normalize(vec3(dot(norm.xyz,vary_mat0),
+			  dot(norm.xyz,vary_mat1),
+			  dot(norm.xyz,vary_mat2)));
+#else
+	return normalize(vary_normal);
+#endif
+}
 
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+vec4 getSpecular()
+{
+#ifdef HAS_SPECULAR_MAP
+    vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
+    spec.rgb *= specular_color.rgb;
+#else
+    vec4 spec = vec4(specular_color.rgb, 1.0);
+#endif
+    return spec;
+}
 
+void alphaMask(float alpha)
+{
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
     // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
     float bias = 0.001953125; // 1/512, or half an 8-bit quantization
-    if (diffcol.a < minimum_alpha-bias)
+    if (alpha < minimum_alpha-bias)
     {
         discard;
     }
 #endif
+}
 
-#ifdef HAS_SPECULAR_MAP
-    vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
-    spec.rgb *= specular_color.rgb;
-#else
-    vec4 spec = vec4(specular_color.rgb, 1.0);
+void waterClip()
+{
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+    waterClip(vary_position.xyz);
 #endif
+}
 
-#ifdef HAS_NORMAL_MAP
-	vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
-
-	norm.xyz = norm.xyz * 2 - 1;
+float getEmissive(vec4 diffcol)
+{
+#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
+	return emissive_brightness;
+#else
+	return max(diffcol.a, emissive_brightness);
+#endif
+}
 
-	vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
-			  dot(norm.xyz,vary_mat1),
-			  dot(norm.xyz,vary_mat2));
+float getShadow(vec3 pos, vec3 norm)
+{
+#ifdef HAS_SUN_SHADOW
+    #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+        return sampleDirectionalShadow(pos, norm, vary_texcoord0.xy);
+    #else
+        return 1;
+    #endif
 #else
-	vec4 norm = vec4(0,0,0,1.0);
-	vec3 tnorm = vary_normal;
+    return 1;
 #endif
+}
 
-    norm.xyz = normalize(tnorm.xyz);
+void main()
+{
+    waterClip();
 
-    vec2 abnormal = encode_normal(norm.xyz);
+    // diffcol == diffuse map combined with vertex color
+    vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
+	diffcol.rgb *= vertex_color.rgb;
 
-    vec4 final_color = diffcol;
+    alphaMask(diffcol.a);
 
-#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
-	final_color.a = emissive_brightness;
-#else
-	final_color.a = max(final_color.a, emissive_brightness);
-#endif
+    // spec == specular map combined with specular color
+    vec4 spec = getSpecular();
+    float glossiness = specular_color.a;
+    vec3 norm = getNormal(glossiness);
 
-    vec4 final_specular = spec;
-    
-#ifdef HAS_SPECULAR_MAP
-    vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, GBUFFER_FLAG_HAS_ATMOS);
-	final_specular.a = specular_color.a * norm.a;
-#else
-	vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, GBUFFER_FLAG_HAS_ATMOS);
-	final_specular.a = specular_color.a;
-#endif
+    vec2 abnormal = encode_normal(norm.xyz);
+
+    float emissive = getEmissive(diffcol);
 
 #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
     //forward rendering, output lit linear color
     diffcol.rgb = srgb_to_linear(diffcol.rgb);
-    final_specular.rgb = srgb_to_linear(final_specular.rgb);
+    spec.rgb = srgb_to_linear(spec.rgb);
 
     vec3 pos = vary_position;
 
-    float shadow = 1.0f;
-
-#ifdef HAS_SUN_SHADOW
-    shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
-#endif
+    float shadow = getShadow(pos, norm);
 
-    vec4 diffuse = final_color;
+    vec4 diffuse = diffcol;
 
     vec3 color = vec3(0,0,0);
 
@@ -310,7 +336,7 @@ void main()
     vec3 ambenv;
     vec3 glossenv;
     vec3 legacyenv;
-    sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos_screen, pos.xyz, norm.xyz, final_specular.a, env_intensity);
+    sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xy*0.5+0.5, pos.xyz, norm.xyz, glossiness, env_intensity);
     
     // use sky settings ambient or irradiance map sample, whichever is brighter
     color = max(amblit, ambenv);
@@ -322,28 +348,37 @@ void main()
 
     vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
 
-    if (final_specular.a > 0.0)  // specular reflection
+    float glare = 0.0;
+
+    if (glossiness > 0.0)  // specular reflection
     {
         float sa        = dot(normalize(refnormpersp), light_dir.xyz);
-        vec3  dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, final_specular.a)).r);
+        vec3  dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, glossiness)).r);
 
         // add the two types of shiny together
-        vec3 spec_contrib = dumbshiny * final_specular.rgb;
+        vec3 spec_contrib = dumbshiny * spec.rgb;
         bloom             = dot(spec_contrib, spec_contrib) / 6;
 
+        glare = max(spec_contrib.r, spec_contrib.g);
+        glare = max(glare, spec_contrib.b);
+
         color += spec_contrib;
 
-        applyGlossEnv(color, glossenv, final_specular, pos.xyz, norm.xyz);
+        applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
     }
 
-    color = mix(color.rgb, diffcol.rgb, diffuse.a);
+    color = mix(color.rgb, diffcol.rgb, emissive);
 
     if (env_intensity > 0.0)
     {  // add environmentmap
-        applyLegacyEnv(color, legacyenv, final_specular, pos.xyz, norm.xyz, env_intensity);
+        applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, env_intensity);
+
+        float cur_glare = max(max(legacyenv.r, legacyenv.g), legacyenv.b);
+        cur_glare *= env_intensity*4.0;
+        glare += cur_glare;
     }
 
-    color.rgb = mix(atmosFragLightingLinear(color.rgb, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), diffuse.a); 
+    color.rgb = mix(atmosFragLightingLinear(color.rgb, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), emissive); 
     color.rgb = scaleSoftClipFragLinear(color.rgb);
 
 #ifdef WATER_FOG
@@ -354,7 +389,7 @@ void main()
     vec3 npos = normalize(-pos.xyz);
     vec3 light = vec3(0, 0, 0);
 
-#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w );
+#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, spec, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w );
 
     LIGHT_LOOP(1)
         LIGHT_LOOP(2)
@@ -366,15 +401,16 @@ void main()
 
     color += light;
 
-    float al = diffcol.a*vertex_color.a;
-
+    glare = min(glare, 1.0);
+    float al = max(diffcol.a, glare) * vertex_color.a;
+    
     frag_color = vec4(color, al);
-#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer 
 
+#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer 
     // deferred path               // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
-    frag_data[0] = final_color;    // gbuffer is sRGB for legacy materials
-    frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
-    frag_data[2] = final_normal;   // XY = Normal.  Z = Env. intensity. W = 1 skip atmos (mask off fog)
+    frag_data[0] = vec4(diffcol.rgb, emissive);        // gbuffer is sRGB for legacy materials
+    frag_data[1] = vec4(spec.rgb, glossiness);           // XYZ = Specular color. W = Specular exponent.
+    frag_data[2] = vec4(encode_normal(norm), env_intensity, GBUFFER_FLAG_HAS_ATMOS);;   // XY = Normal.  Z = Env. intensity. W = 1 skip atmos (mask off fog)
 #endif
 }
 
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
index d9cbae45a60..8229ecbbb79 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -37,7 +37,6 @@ uniform sampler2D diffuseRect;
 uniform sampler2D specularRect;
 uniform sampler2D normalMap;
 uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
-uniform sampler2D noiseMap;
 uniform sampler2D lightFunc;
 uniform sampler2D depthMap;
 
@@ -126,8 +125,7 @@ void main()
         diffuse = srgb_to_linear(diffuse);
         spec.rgb = srgb_to_linear(spec.rgb);
 
-        float noise = texture2D(noiseMap, tc).b;
-        float lit = nl * dist_atten * noise;
+        float lit = nl * dist_atten;
 
         final_color = color.rgb*lit*diffuse;
 
-- 
GitLab