From bdb53fd56d56c659941e7e63f83cefc366acef6d Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Thu, 16 Nov 2023 16:46:12 -0600
Subject: SL-20611 Make haze effect local lights -- move sky and water haze to
 their own passes and unify sky and water haze in forward rendering shaders.

---
 .../shaders/class1/deferred/fullbrightF.glsl       |  16 +-
 .../shaders/class1/environment/waterFogF.glsl      |  48 ++-
 .../class1/windlight/atmosphericsHelpersV.glsl     |   1 -
 .../shaders/class1/windlight/atmosphericsV.glsl    |   1 -
 .../class1/windlight/atmosphericsVarsF.glsl        |   2 +-
 .../class1/windlight/atmosphericsVarsV.glsl        |  11 -
 .../class1/windlight/atmosphericsVarsWaterF.glsl   |  50 ---
 .../class1/windlight/atmosphericsVarsWaterV.glsl   |  81 ----
 .../shaders/class2/deferred/alphaF.glsl            |  14 +-
 .../shaders/class2/deferred/pbralphaF.glsl         |  15 +-
 .../shaders/class3/deferred/fullbrightShinyF.glsl  |   3 +
 .../shaders/class3/deferred/hazeF.glsl             | 109 +++++
 .../shaders/class3/deferred/materialF.glsl         |  16 +-
 .../shaders/class3/deferred/softenLightF.glsl      |  34 --
 .../shaders/class3/deferred/waterHazeF.glsl        |  58 +++
 .../shaders/class3/environment/underWaterF.glsl    |   4 +-
 .../shaders/class3/environment/waterF.glsl         |   3 +-
 indra/newview/lldrawpoolalpha.cpp                  |  10 +-
 indra/newview/lldrawpoolavatar.cpp                 |   9 +-
 indra/newview/lldrawpoolmaterials.cpp              |   9 +-
 indra/newview/lldrawpoolsimple.cpp                 |   8 -
 indra/newview/llsettingsvo.cpp                     |   2 +-
 indra/newview/llviewercamera.cpp                   |  59 +--
 indra/newview/llviewershadermgr.cpp                | 441 +++------------------
 indra/newview/llviewershadermgr.h                  |  11 +-
 indra/newview/pipeline.cpp                         |  66 ++-
 26 files changed, 366 insertions(+), 715 deletions(-)
 delete mode 100644 indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
 delete mode 100644 indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
 create mode 100644 indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 5d58cc91cd..2798c59f1c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -35,9 +35,7 @@ in vec3 vary_position;
 in vec4 vertex_color;
 in vec2 vary_texcoord0;
 
-#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
-#endif
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 
 vec3 srgb_to_linear(vec3 cs);
 vec3 linear_to_srgb(vec3 cl);
@@ -86,18 +84,14 @@ void main()
     calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten);
 #endif
 
-#ifdef WATER_FOG
-    
-    vec4 fogged = applyWaterFogView(pos, vec4(color.rgb, final_alpha));
-    color.rgb = fogged.rgb;
-    color.a   = fogged.a;
-#else
-    color.a   = final_alpha;
-#endif
 
 #ifndef IS_HUD
     color.rgb = srgb_to_linear(color.rgb);
     color.rgb = atmosFragLighting(color.rgb, additive, atten);
+
+    vec4 fogged = applyWaterFogViewLinear(pos, vec4(color.rgb, final_alpha));
+    color.rgb = fogged.rgb;
+    color.a   = fogged.a;
 #endif
 
     frag_color = max(color, vec4(0));
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index cfdb393b34..140e01cc2a 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -30,12 +30,12 @@ uniform vec4 waterFogColor;
 uniform float waterFogDensity;
 uniform float waterFogKS;
 
-vec3 getPositionEye();
-
 vec3 srgb_to_linear(vec3 col);
 vec3 linear_to_srgb(vec3 col);
 
-vec4 applyWaterFogView(vec3 pos, vec4 color)
+// get a water fog color that will apply the appropriate haze to a color given
+// a blend function of (ONE, SOURCE_ALPHA)
+vec4 getWaterFogViewNoClip(vec3 pos)
 {
     vec3 view = normalize(pos);
     //normalize view vector
@@ -67,38 +67,44 @@ vec4 applyWaterFogView(vec3 pos, vec4 color)
     float L = min(t1/t2*t3, 1.0);
     
     float D = pow(0.98, l*kd);
+
+    return vec4(srgb_to_linear(kc.rgb*L), D);
+}
+
+vec4 getWaterFogView(vec3 pos)
+{
+    if (dot(pos, waterPlane.xyz) + waterPlane.w > 0.0)
+    {
+        return vec4(0,0,0,1);
+    }
+
+    return getWaterFogViewNoClip(pos);
+}
+
+vec4 applyWaterFogView(vec3 pos, vec4 color)
+{
+    vec4 fogged = getWaterFogView(pos);
     
-    color.rgb = color.rgb * D + kc.rgb * L;
+    color.rgb = color.rgb * fogged.a + fogged.rgb;
 
     return color;
 }
 
-vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color, vec3 sunlit)
+vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color)
 {
-    color.rgb = linear_to_srgb(color.rgb);
-    color = applyWaterFogView(pos, color);
-    color.rgb = srgb_to_linear(color.rgb);
+    vec4 fogged = getWaterFogViewNoClip(pos);
+    color.rgb *= fogged.a;
+    color.rgb += fogged.rgb;
     return color;
 }
 
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit)
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color)
 {
     if (dot(pos, waterPlane.xyz) + waterPlane.w > 0.0)
     {
         return color;
     }
 
-    return applyWaterFogViewLinearNoClip(pos, color, sunlit);
-}
-
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color)
-{
-    return applyWaterFogViewLinear(pos, color, vec3(1));
-}
-
-vec4 applyWaterFog(vec4 color)
-{
-    //normalize view vector
-    return applyWaterFogViewLinear(getPositionEye(), color);
+    return applyWaterFogViewLinearNoClip(pos, color);
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
index 6ecbfaecb1..4f88aed765 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
@@ -30,7 +30,6 @@ vec3 getSunlitColor();
 vec3 getAmblitColor();
 vec3 getAdditiveColor();
 vec3 getAtmosAttenuation();
-vec3 getPositionEye();
 
 uniform float scene_light_strength;
 
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
index cc3617ba61..7b59e07243 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
@@ -42,7 +42,6 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
 
 void calcAtmospherics(vec3 inPositionEye) {
     vec3 P = inPositionEye;
-    setPositionEye(P);
     vec3 tmpsunlit = vec3(1);
     vec3 tmpamblit = vec3(1);
     vec3 tmpaddlit = vec3(1);
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
index 34669a6796..9d5f60b313 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
@@ -44,5 +44,5 @@ vec3 getAdditiveColor()
 
 vec3 getAtmosAttenuation()
 {
-	return vec3(vary_AtmosAttenuation);
+	return vary_AtmosAttenuation;
 }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
index 1b854d80b3..0617bc9908 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
@@ -31,7 +31,6 @@ vec3 additive_color;
 vec3 atmos_attenuation;
 vec3 sunlit_color;
 vec3 amblit_color;
-vec3 position_eye;
 
 vec3 getSunlitColor()
 {
@@ -51,16 +50,6 @@ vec3 getAtmosAttenuation()
 	return atmos_attenuation;
 }
 
-vec3 getPositionEye()
-{
-	return position_eye;
-}
-
-void setPositionEye(vec3 v)
-{
-	position_eye = v;
-}
-
 void setSunlitColor(vec3 v)
 {
 	sunlit_color  = v;
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
deleted file mode 100644
index 7a6741fe0e..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
+++ /dev/null
@@ -1,50 +0,0 @@
-/** 
- * @file class2\wl\atmosphericVarsWaterF.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$
- */
- 
-in vec3 vary_PositionEye;
-in vec3 vary_AdditiveColor;
-in vec3 vary_AtmosAttenuation;
-
-vec3 getSunlitColor()
-{
-	return vec3(0,0,0);
-}
-vec3 getAmblitColor()
-{
-	return vec3(0,0,0);
-}
-vec3 getAdditiveColor()
-{
-	return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
-	return vary_AtmosAttenuation;
-}
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
deleted file mode 100644
index 23c3aed4d8..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
+++ /dev/null
@@ -1,81 +0,0 @@
-/** 
- * @file class2\wl\atmosphericVarsWaterV.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$
- */
- 
-out vec3 vary_PositionEye;
-out vec3 vary_AdditiveColor;
-out vec3 vary_AtmosAttenuation;
-
-vec3 atmos_attenuation;
-vec3 sunlit_color;
-vec3 amblit_color;
-
-vec3 getSunlitColor()
-{
-	return sunlit_color;
-}
-vec3 getAmblitColor()
-{
-	return amblit_color;
-}
-
-vec3 getAdditiveColor()
-{
-	return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
-	return atmos_attenuation;
-}
-
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
-
-void setPositionEye(vec3 v)
-{
-	vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
-	sunlit_color  = v;
-}
-
-void setAmblitColor(vec3 v)
-{
-	amblit_color = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
-	vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
-	atmos_attenuation = v;
-	vary_AtmosAttenuation = v;
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index b63f3b60f9..07fa5cd01c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -65,9 +65,7 @@ uniform vec3 light_diffuse[8];
 
 void waterClip(vec3 pos);
 
-#ifdef WATER_FOG
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
-#endif
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 
 vec3 srgb_to_linear(vec3 c);
 vec3 linear_to_srgb(vec3 c);
@@ -270,12 +268,6 @@ void main()
 
     color.rgb *= diffuse_linear.rgb;
 
-    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
-
-#ifdef WATER_FOG
-    color = applyWaterFogViewLinear(pos.xyz, color, sunlit_linear);
-#endif // WATER_FOG
-
     vec4 light = vec4(0,0,0,0);
     
    #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
@@ -291,6 +283,10 @@ void main()
     // sum local light contrib in linear colorspace
     color.rgb += light.rgb;
 
+    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
+
+    color = applyWaterFogViewLinear(pos.xyz, color);
+
 #endif // #else // FOR_IMPOSTOR
 
 #ifdef IS_HUD
diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
index 35d752be02..80c1769b15 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
@@ -84,9 +84,7 @@ vec3 linear_to_srgb(vec3 c);
 void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
 vec3 atmosFragLightingLinear(vec3 color, vec3 additive, vec3 atten);
 
-#ifdef WATER_FOG
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
-#endif
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 
 void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
 float calcLegacyDistanceAttenuation(float distance, float falloff);
@@ -228,13 +226,6 @@ void main()
 
     color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
 
-    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
-    
-#ifdef WATER_FOG
-    vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0), sunlit_linear);
-    color = temp.rgb;
-#endif
-
     vec3 light = vec3(0);
 
     // Punctual lights
@@ -250,7 +241,11 @@ void main()
 
     color.rgb += light.rgb;
 
+    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
     
+    vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0));
+    color = temp.rgb;
+
     float a = basecolor.a*vertex_color.a;
     
     frag_color = max(vec4(color.rgb,a), vec4(0));
diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
index 5483a4e29c..6446015b03 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
@@ -40,6 +40,8 @@ in vec3 vary_position;
 uniform samplerCube environmentMap;
 
 vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+
 void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
 
 vec3 linear_to_srgb(vec3 c);
@@ -84,6 +86,7 @@ void main()
 
     applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity);
     color.rgb = atmosFragLighting(color.rgb, additive, atten);
+    color = applyWaterFogViewLinear(pos.xyz, color);
 #endif
 
 	color.a = 1.0;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
new file mode 100644
index 0000000000..7b77a2f5fb
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl
@@ -0,0 +1,109 @@
+/**
+ * @file class3/deferred/hazeF.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$
+ */
+
+out vec4 frag_color;
+
+uniform sampler2D normalMap;
+
+// Inputs
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int  sun_up_factor;
+in vec2 vary_fragcoord;
+
+vec3 getNorm(vec2 pos_screen);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+
+float getDepth(vec2 pos_screen);
+
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+uniform vec4 waterPlane;
+
+uniform int cube_snapshot;
+
+uniform float sky_hdr_scale;
+
+void main()
+{
+    vec2  tc           = vary_fragcoord.xy;
+    float depth        = getDepth(tc.xy);
+    vec4  pos          = getPositionWithDepth(tc, depth);
+    vec4  norm         = texture(normalMap, tc);
+    norm.xyz           = getNorm(tc);
+    vec3  light_dir   = (sun_up_factor == 1) ? sun_dir : moon_dir;
+
+    vec3  color = vec3(0);
+    float bloom = 0.0;
+
+    vec3 sunlit;
+    vec3 amblit;
+    vec3 additive;
+    vec3 atten;
+
+    calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
+
+    vec3 sunlit_linear = srgb_to_linear(sunlit);
+    vec3 amblit_linear = amblit;
+
+    bool do_atmospherics = false;
+
+    // mask off atmospherics below water
+    if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
+    {
+        do_atmospherics = true;
+    }
+
+    vec3  irradiance = vec3(0);
+    vec3  radiance  = vec3(0);
+
+    if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+    {
+    }
+    else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+    {
+        //should only be true of WL sky, just port over base color value
+        discard;
+    }
+
+   float alpha = 0.0;
+
+    if (do_atmospherics)
+    {
+        alpha = atten.r;
+        color = srgb_to_linear(additive*2.0);
+        color *= sky_hdr_scale;
+    }
+    else
+    {
+        color = vec3(0,0,0);
+        alpha = 1.0;
+    }
+
+    frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
+    frag_color.a = alpha;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index acff03ec4b..1880f0c870 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -37,9 +37,7 @@
 uniform float emissive_brightness;  // fullbright flag, 1.0 == fullbright, 0.0 otherwise
 uniform int sun_up_factor;
 
-#ifdef WATER_FOG
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
-#endif
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 
 vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten);
 vec3 scaleSoftClipFragLinear(vec3 l);
@@ -386,13 +384,6 @@ void main()
         glare += cur_glare;
     }
 
-    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); 
-
-#ifdef WATER_FOG
-    vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0), sunlit_linear);
-    color = temp.rgb;
-#endif
-
     vec3 npos = normalize(-pos.xyz);
     vec3 light = vec3(0, 0, 0);
 
@@ -408,6 +399,11 @@ void main()
 
     color += light;
 
+    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); 
+
+    vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0));
+    color = temp.rgb;
+
     glare *= 1.0-emissive;
     glare = min(glare, 1.0);
     float al = max(diffcol.a, glare) * vertex_color.a;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 35e99c5bd2..5e8fe9301a 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -83,10 +83,6 @@ uniform vec4 waterPlane;
 
 uniform int cube_snapshot;
 
-#ifdef WATER_FOG
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
-#endif
-
 uniform float sky_hdr_scale;
 
 void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
@@ -167,18 +163,6 @@ void main()
     vec3 sunlit_linear = srgb_to_linear(sunlit);
     vec3 amblit_linear = amblit;
 
-    bool do_atmospherics = false;
-
-#ifndef WATER_FOG
-    // when above water, mask off atmospherics below water
-    if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
-    {
-        do_atmospherics = true;
-    }
-#else
-    do_atmospherics = true;
-#endif
-
     vec3  irradiance = vec3(0);
     vec3  radiance  = vec3(0);
 
@@ -203,11 +187,6 @@ void main()
 
         vec3 v = -normalize(pos.xyz);
         color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
-        
-        if (do_atmospherics)
-        {
-            color = atmosFragLightingLinear(color, additive, atten);
-        }
     }
     else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
     {
@@ -273,21 +252,8 @@ void main()
         {  // add environment map
             applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
         }
-
-        
-        if (do_atmospherics)
-        {
-            color = atmosFragLightingLinear(color, additive, atten);
-        }
    }
 
-    
-
-    #ifdef WATER_FOG
-        vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom));
-        color       = fogged.rgb;
-    #endif
-
     frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
     frag_color.a = 0.0;
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
new file mode 100644
index 0000000000..f63d70cbd7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
@@ -0,0 +1,58 @@
+/**
+ * @file class3/deferred/waterHazeF.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$
+ */
+
+out vec4 frag_color;
+
+// Inputs
+in vec2 vary_fragcoord;
+
+uniform sampler2D normalMap;
+
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
+float getDepth(vec2 pos_screen);
+
+vec4 getWaterFogView(vec3 pos);
+
+void main()
+{
+    vec2  tc           = vary_fragcoord.xy;
+    float depth        = getDepth(tc.xy);
+    vec4  pos          = getPositionWithDepth(tc, depth);
+    vec4  norm         = texture(normalMap, tc);
+
+    if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+    {
+    }
+    else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+    {
+        //should only be true of WL sky, just port over base color value
+        discard;
+    }
+
+    vec4 fogged = getWaterFogView(pos.xyz);
+
+    frag_color.rgb = max(fogged.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
+    frag_color.a = fogged.a;
+}
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index e99ad5b474..924f356f35 100644
--- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -55,7 +55,7 @@ in vec4 littleWave;
 in vec4 view;
 in vec3 vary_position;
 
-vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color, vec3 sunlit);
+vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color);
 
 void main() 
 {
@@ -77,5 +77,5 @@ void main()
     vec4 fb = vec4(waterFogColorLinear, 0.0);
 #endif
     
-	frag_color = max(applyWaterFogViewLinearNoClip(vary_position, fb, vec3(1)), vec4(0));
+	frag_color = max(applyWaterFogViewLinearNoClip(vary_position, fb), vec4(0));
 }
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index ddade462be..af0460fa8b 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -34,7 +34,7 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
 vec3 scaleSoftClipFragLinear(vec3 l);
 vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
 void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
-vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
 
 // PBR interface
 vec2 BRDF(float NoV, float roughness);
@@ -223,7 +223,6 @@ void main()
         refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
     }
 
-    fb = applyWaterFogViewLinear(refPos, fb, sunlit);
 #else
     vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0), sunlit_linear);
 #endif
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 052a1d796a..41dc95a8cb 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -178,27 +178,24 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
 
     fullbright_shader   = 
         (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
-        (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterAlphaProgram : 
         (LLPipeline::sRenderingHUDs) ? &gHUDFullbrightAlphaMaskAlphaProgram :
         &gDeferredFullbrightAlphaMaskAlphaProgram;
     prepare_alpha_shader(fullbright_shader, true, true, water_sign);
 
     simple_shader   = 
         (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
-        (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : 
         (LLPipeline::sRenderingHUDs) ? &gHUDAlphaProgram :
         &gDeferredAlphaProgram;
 
     prepare_alpha_shader(simple_shader, false, true, water_sign); //prime simple shader (loads shadow relevant uniforms)
 
-    LLGLSLShader* materialShader = LLPipeline::sUnderWaterRender ? gDeferredMaterialWaterProgram : gDeferredMaterialProgram;
+    LLGLSLShader* materialShader = gDeferredMaterialProgram;
     for (int i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
     {
         prepare_alpha_shader(&materialShader[i], false, true, water_sign);
     }
 
     pbr_shader = 
-        (LLPipeline::sUnderWaterRender) ? &gDeferredPBRAlphaWaterProgram : 
         (LLPipeline::sRenderingHUDs) ? &gHUDPBRAlphaProgram : 
         &gDeferredPBRAlphaProgram;
 
@@ -727,11 +724,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 
                         llassert(mask < LLMaterial::SHADER_COUNT);
                         target_shader = &(gDeferredMaterialProgram[mask]);
-
-                        if (LLPipeline::sUnderWaterRender)
-                        {
-                            target_shader = &(gDeferredMaterialWaterProgram[mask]);
-                        }
                     }
                     else if (!params.mFullbright)
                     {
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 342b76d93b..7f6409dbde 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -509,14 +509,7 @@ void LLDrawPoolAvatar::beginRigid()
 
 	if (gPipeline.shadersLoaded())
 	{
-		if (LLPipeline::sUnderWaterRender)
-		{
-			sVertexProgram = &gObjectAlphaMaskNoColorWaterProgram;
-		}
-		else
-		{
-			sVertexProgram = &gObjectAlphaMaskNoColorProgram;
-		}
+		sVertexProgram = &gObjectAlphaMaskNoColorProgram;
 		
 		if (sVertexProgram != NULL)
 		{	//eyeballs render with the specular shader
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 6a7e05ac74..c0e4ed38c1 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -82,14 +82,7 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
 	
     U32 idx = shader_idx[pass];
     
-    if (LLPipeline::sUnderWaterRender)
-    {
-        mShader = &(gDeferredMaterialWaterProgram[idx]);
-    }
-    else
-    {
-        mShader = &(gDeferredMaterialProgram[idx]);
-    }
+    mShader = &(gDeferredMaterialProgram[idx]);
     
     if (rigged)
     {
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index a89c9d4561..696618f75b 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -193,10 +193,6 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
     {
         shader = &gHUDFullbrightProgram;
     }
-    else if (LLPipeline::sUnderWaterRender)
-    {
-        shader = &gDeferredFullbrightWaterProgram;
-    }
     else
     {
         shader = &gDeferredFullbrightProgram;
@@ -225,10 +221,6 @@ void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
     {
         shader = &gHUDFullbrightAlphaMaskProgram;
     }
-    else if (LLPipeline::sUnderWaterRender)
-    {
-        shader = &gDeferredFullbrightAlphaMaskWaterProgram;
-    }
     else
     {
         shader = &gDeferredFullbrightAlphaMaskProgram;
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 42587658a6..2f65f3dec3 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -983,7 +983,7 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
 
     LLEnvironment& env = LLEnvironment::instance();
 
-    auto group = LLGLSLShader::SG_WATER;
+    auto group = LLGLSLShader::SG_ANY;
     LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[group];
     
 	{
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index b37f08283d..b926631ebe 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -50,6 +50,7 @@
 #include "llquaternion.h"
 #include "llwindow.h"			// getPixelAspectRatio()
 #include "lltracerecording.h"
+#include "llenvironment.h"
 
 // System includes
 #include <iomanip> // for setprecision
@@ -96,35 +97,37 @@ LLViewerCamera::LLViewerCamera() : LLCamera()
 	gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2));
 }
 
-void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
-											const LLVector3 &up_direction,
-											const LLVector3 &point_of_interest)
+void LLViewerCamera::updateCameraLocation(const LLVector3 &center, const LLVector3 &up_direction, const LLVector3 &point_of_interest)
 {
-	// do not update if avatar didn't move
-	if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate())
-	{
-		return;
-	}
-
-	LLVector3 last_position;
-	LLVector3 last_axis;
-	last_position = getOrigin();
-	last_axis = getAtAxis();
-
-	mLastPointOfInterest = point_of_interest;
-
-	LLViewerRegion * regp = gAgent.getRegion();
-	F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f;
-
-	LLVector3 origin = center;
-	if (origin.mV[2] > water_height)
-	{
-		origin.mV[2] = llmax(origin.mV[2], water_height+0.20f);
-	}
-	else
-	{
-		origin.mV[2] = llmin(origin.mV[2], water_height-0.20f);
-	}
+    // do not update if avatar didn't move
+    if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate())
+    {
+        return;
+    }
+
+    LLVector3 last_position;
+    LLVector3 last_axis;
+    last_position = getOrigin();
+    last_axis     = getAtAxis();
+
+    mLastPointOfInterest = point_of_interest;
+
+    LLViewerRegion *regp         = gAgent.getRegion();
+    F32             water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f;
+
+    LLVector3 origin = center;
+
+    if (LLEnvironment::instance().getCurrentWater()->getFogMod() != 1.f)
+    {
+        if (origin.mV[2] > water_height)
+        {
+            origin.mV[2] = llmax(origin.mV[2], water_height + 0.20f);
+        }
+        else
+        {
+            origin.mV[2] = llmin(origin.mV[2], water_height - 0.20f);
+        }
+    }
 
 	setOriginAndLookAt(origin, up_direction, point_of_interest);
 
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index cdf5e2875f..e6e80e9532 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -99,7 +99,6 @@ LLGLSLShader        gSkinnedObjectFullbrightAlphaMaskProgram;
 LLGLSLShader		gObjectBumpProgram;
 LLGLSLShader        gSkinnedObjectBumpProgram;
 LLGLSLShader		gObjectAlphaMaskNoColorProgram;
-LLGLSLShader		gObjectAlphaMaskNoColorWaterProgram;
 
 //environment shaders
 LLGLSLShader		gWaterProgram;
@@ -138,7 +137,6 @@ LLGLSLShader			gDeferredSkinnedDiffuseProgram;
 LLGLSLShader			gDeferredSkinnedBumpProgram;
 LLGLSLShader			gDeferredBumpProgram;
 LLGLSLShader			gDeferredTerrainProgram;
-LLGLSLShader            gDeferredTerrainWaterProgram;
 LLGLSLShader			gDeferredTreeProgram;
 LLGLSLShader			gDeferredTreeShadowProgram;
 LLGLSLShader            gDeferredSkinnedTreeShadowProgram;
@@ -149,9 +147,10 @@ LLGLSLShader			gDeferredMultiLightProgram[16];
 LLGLSLShader			gDeferredSpotLightProgram;
 LLGLSLShader			gDeferredMultiSpotLightProgram;
 LLGLSLShader			gDeferredSunProgram;
+LLGLSLShader            gHazeProgram;
+LLGLSLShader            gHazeWaterProgram;
 LLGLSLShader			gDeferredBlurLightProgram;
 LLGLSLShader			gDeferredSoftenProgram;
-LLGLSLShader			gDeferredSoftenWaterProgram;
 LLGLSLShader			gDeferredShadowProgram;
 LLGLSLShader            gDeferredSkinnedShadowProgram;
 LLGLSLShader			gDeferredShadowCubeProgram;
@@ -171,8 +170,6 @@ LLGLSLShader			gHUDAlphaProgram;
 LLGLSLShader            gDeferredSkinnedAlphaProgram;
 LLGLSLShader			gDeferredAlphaImpostorProgram;
 LLGLSLShader            gDeferredSkinnedAlphaImpostorProgram;
-LLGLSLShader			gDeferredAlphaWaterProgram;
-LLGLSLShader            gDeferredSkinnedAlphaWaterProgram;
 LLGLSLShader			gDeferredAvatarEyesProgram;
 LLGLSLShader			gDeferredFullbrightProgram;
 LLGLSLShader            gHUDFullbrightProgram;
@@ -180,12 +177,6 @@ LLGLSLShader			gDeferredFullbrightAlphaMaskProgram;
 LLGLSLShader			gHUDFullbrightAlphaMaskProgram;
 LLGLSLShader			gDeferredFullbrightAlphaMaskAlphaProgram;
 LLGLSLShader			gHUDFullbrightAlphaMaskAlphaProgram;
-LLGLSLShader			gDeferredFullbrightWaterProgram;
-LLGLSLShader            gDeferredSkinnedFullbrightWaterProgram;
-LLGLSLShader			gDeferredFullbrightWaterAlphaProgram;
-LLGLSLShader			gDeferredSkinnedFullbrightWaterAlphaProgram;
-LLGLSLShader			gDeferredFullbrightAlphaMaskWaterProgram;
-LLGLSLShader            gDeferredSkinnedFullbrightAlphaMaskWaterProgram;
 LLGLSLShader			gDeferredEmissiveProgram;
 LLGLSLShader            gDeferredSkinnedEmissiveProgram;
 LLGLSLShader			gDeferredPostProgram;
@@ -215,7 +206,6 @@ LLGLSLShader            gDeferredBufferVisualProgram;
 
 // Deferred materials shaders
 LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
-LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
 LLGLSLShader			gHUDPBROpaqueProgram;
 LLGLSLShader            gPBRGlowProgram;
 LLGLSLShader            gPBRGlowSkinnedProgram;
@@ -224,8 +214,6 @@ LLGLSLShader            gDeferredSkinnedPBROpaqueProgram;
 LLGLSLShader            gHUDPBRAlphaProgram;
 LLGLSLShader            gDeferredPBRAlphaProgram;
 LLGLSLShader            gDeferredSkinnedPBRAlphaProgram;
-LLGLSLShader            gDeferredPBRAlphaWaterProgram;
-LLGLSLShader            gDeferredSkinnedPBRAlphaWaterProgram;
 
 //helper for making a rigged variant of a given shader
 bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
@@ -258,30 +246,22 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
     mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram);
 	mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);
-	mShaderList.push_back(&gObjectAlphaMaskNoColorWaterProgram);
 	mShaderList.push_back(&gUnderWaterProgram);
 	mShaderList.push_back(&gDeferredSunProgram);
+    mShaderList.push_back(&gHazeProgram);
+    mShaderList.push_back(&gHazeWaterProgram);
 	mShaderList.push_back(&gDeferredSoftenProgram);
-	mShaderList.push_back(&gDeferredSoftenWaterProgram);
 	mShaderList.push_back(&gDeferredAlphaProgram);
     mShaderList.push_back(&gHUDAlphaProgram);
     mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
 	mShaderList.push_back(&gDeferredAlphaImpostorProgram);
     mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram);
-	mShaderList.push_back(&gDeferredAlphaWaterProgram);
-    mShaderList.push_back(&gDeferredSkinnedAlphaWaterProgram);
 	mShaderList.push_back(&gDeferredFullbrightProgram);
     mShaderList.push_back(&gHUDFullbrightProgram);
 	mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
     mShaderList.push_back(&gHUDFullbrightAlphaMaskProgram);
     mShaderList.push_back(&gDeferredFullbrightAlphaMaskAlphaProgram);
     mShaderList.push_back(&gHUDFullbrightAlphaMaskAlphaProgram);
-	mShaderList.push_back(&gDeferredFullbrightWaterProgram);
-    mShaderList.push_back(&gDeferredSkinnedFullbrightWaterProgram);
-    mShaderList.push_back(&gDeferredFullbrightWaterAlphaProgram);
-    mShaderList.push_back(&gDeferredSkinnedFullbrightWaterAlphaProgram);
-	mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram);
-    mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskWaterProgram);
 	mShaderList.push_back(&gDeferredFullbrightShinyProgram);
     mShaderList.push_back(&gHUDFullbrightShinyProgram);
     mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
@@ -291,17 +271,14 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderList.push_back(&gDeferredEmissiveProgram);
     mShaderList.push_back(&gDeferredSkinnedEmissiveProgram);
 	mShaderList.push_back(&gDeferredAvatarEyesProgram);
-    mShaderList.push_back(&gDeferredTerrainWaterProgram);
-	mShaderList.push_back(&gDeferredAvatarAlphaProgram);
+    mShaderList.push_back(&gDeferredAvatarAlphaProgram);
 	mShaderList.push_back(&gDeferredWLSkyProgram);
 	mShaderList.push_back(&gDeferredWLCloudProgram);
     mShaderList.push_back(&gDeferredWLMoonProgram);
     mShaderList.push_back(&gDeferredWLSunProgram);
     mShaderList.push_back(&gDeferredPBRAlphaProgram);
-    mShaderList.push_back(&gDeferredPBRAlphaWaterProgram);
     mShaderList.push_back(&gHUDPBRAlphaProgram);
     mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram);
-    mShaderList.push_back(&gDeferredSkinnedPBRAlphaWaterProgram);
     mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma
     mShaderList.push_back(&gNoPostGammaCorrectProgram);
     mShaderList.push_back(&gLegacyPostGammaCorrectProgram);
@@ -594,7 +571,6 @@ std::string LLViewerShaderMgr::loadBasicShaders()
 
 	vector< pair<string, S32> > shaders;
 	shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl",       mShaderLevel[SHADER_WINDLIGHT] ) );
-	shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl",  mShaderLevel[SHADER_WINDLIGHT] ) );
 	shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl",    mShaderLevel[SHADER_WINDLIGHT] ) );
 	shaders.push_back( make_pair( "lighting/lightFuncV.glsl",               mShaderLevel[SHADER_LIGHTING] ) );
 	shaders.push_back( make_pair( "lighting/sumLightsV.glsl",               sum_lights_class ) );
@@ -674,7 +650,6 @@ std::string LLViewerShaderMgr::loadBasicShaders()
 
 	std::vector<S32> index_channels;    
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl",      mShaderLevel[SHADER_WINDLIGHT] ) );
-	index_channels.push_back(-1);    shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl",     mShaderLevel[SHADER_WINDLIGHT] ) );
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl",       mShaderLevel[SHADER_WINDLIGHT] ) );
 	index_channels.push_back(-1);    shaders.push_back( make_pair( "windlight/gammaF.glsl",                 mShaderLevel[SHADER_WINDLIGHT]) );
     index_channels.push_back(-1);    shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl",       mShaderLevel[SHADER_WINDLIGHT] ) );
@@ -908,7 +883,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredSkinnedBumpProgram.unload();
 		gDeferredImpostorProgram.unload();
 		gDeferredTerrainProgram.unload();
-		gDeferredTerrainWaterProgram.unload();
 		gDeferredLightProgram.unload();
 		for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i)
 		{
@@ -919,7 +893,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredSunProgram.unload();
 		gDeferredBlurLightProgram.unload();
 		gDeferredSoftenProgram.unload();
-		gDeferredSoftenWaterProgram.unload();
 		gDeferredShadowProgram.unload();
         gDeferredSkinnedShadowProgram.unload();
 		gDeferredShadowCubeProgram.unload();
@@ -937,20 +910,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredAlphaProgram.unload();
         gHUDAlphaProgram.unload();
         gDeferredSkinnedAlphaProgram.unload();
-		gDeferredAlphaWaterProgram.unload();
-        gDeferredSkinnedAlphaWaterProgram.unload();
 		gDeferredFullbrightProgram.unload();
         gHUDFullbrightProgram.unload();
 		gDeferredFullbrightAlphaMaskProgram.unload();
         gHUDFullbrightAlphaMaskProgram.unload();
         gDeferredFullbrightAlphaMaskAlphaProgram.unload();
         gHUDFullbrightAlphaMaskAlphaProgram.unload();
-		gDeferredFullbrightWaterProgram.unload();
-        gDeferredSkinnedFullbrightWaterProgram.unload();
-        gDeferredFullbrightWaterAlphaProgram.unload();
-        gDeferredSkinnedFullbrightWaterAlphaProgram.unload();
-		gDeferredFullbrightAlphaMaskWaterProgram.unload();
-        gDeferredSkinnedFullbrightAlphaMaskWaterProgram.unload();
 		gDeferredEmissiveProgram.unload();
         gDeferredSkinnedEmissiveProgram.unload();
 		gDeferredAvatarEyesProgram.unload();
@@ -984,7 +949,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
 		{
 			gDeferredMaterialProgram[i].unload();
-			gDeferredMaterialWaterProgram[i].unload();
 		}
 
         gHUDPBROpaqueProgram.unload();
@@ -993,8 +957,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredSkinnedPBROpaqueProgram.unload();
         gDeferredPBRAlphaProgram.unload();
         gDeferredSkinnedPBRAlphaProgram.unload();
-        gDeferredPBRAlphaWaterProgram.unload();
-        gDeferredSkinnedPBRAlphaWaterProgram.unload();
 
 		return TRUE;
 	}
@@ -1084,15 +1046,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 	gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
 	gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
 
-	gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
-	gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
-
 	for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
 	{
 		if (success)
@@ -1158,77 +1111,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
             success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
             llassert(success);
 		}
-
-		if (success)
-		{
-            mShaderList.push_back(&gDeferredMaterialWaterProgram[i]);
-
-            gDeferredMaterialWaterProgram[i].mName = llformat("Deferred Underwater Material Shader %d", i);
-
-            U32 alpha_mode = i & 0x3;
-
-            gDeferredMaterialWaterProgram[i].mShaderFiles.clear();
-            gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
-            gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
-            gDeferredMaterialWaterProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-            gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
-
-            gDeferredMaterialWaterProgram[i].clearPermutations();
-
-            bool has_normal_map   = (i & 0x8) > 0;
-            bool has_specular_map = (i & 0x4) > 0;
-
-            if (has_normal_map)
-            {
-                gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", "1");
-            }
-
-            if (has_specular_map)
-            {
-                gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
-            }
-
-            gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
-            if (alpha_mode != 0)
-            {
-                gDeferredMaterialWaterProgram[i].mFeatures.hasAlphaMask = true;
-                gDeferredMaterialWaterProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
-            }
-
-            if (use_sun_shadow)
-            {
-                gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
-            }
-
-            bool has_skin = i & 0x10;
-            if (has_skin)
-            {
-                gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN", "1");
-            }
-            else
-            {
-                gDeferredMaterialWaterProgram[i].mRiggedVariant = &(gDeferredMaterialWaterProgram[i + 0x10]);
-            }
-            gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
-
-            gDeferredMaterialWaterProgram[i].mFeatures.hasReflectionProbes = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.hasWaterFog = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.hasSrgb = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.encodesNormal = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.calculatesAtmospherics = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.hasAtmospherics = true;
-            gDeferredMaterialWaterProgram[i].mFeatures.hasGamma = true;
-
-            gDeferredMaterialWaterProgram[i].mFeatures.hasShadows = use_sun_shadow;
-            
-            if (has_skin)
-            {
-                gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true;
-            }
-
-            success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms);
-            llassert(success);
-		}
 	}
 
 	gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
@@ -1240,15 +1122,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 	gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
 	gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
 
-	gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
-	gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
-
     if (success)
     {
         gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader";
@@ -1356,62 +1229,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         shader->mRiggedVariant->mFeatures.hasLighting = true;
     }
 
-    if (success)
-    {
-        LLGLSLShader* shader = &gDeferredPBRAlphaWaterProgram;
-        shader->mName = "Deferred PBR Alpha Underwater Shader";
-                          
-        shader->mFeatures.calculatesLighting = false;
-        shader->mFeatures.hasLighting = false;
-        shader->mFeatures.isAlphaLighting = true;
-        shader->mFeatures.hasWaterFog = true;
-        shader->mFeatures.hasSrgb = true;
-        shader->mFeatures.encodesNormal = true;
-        shader->mFeatures.calculatesAtmospherics = true;
-        shader->mFeatures.hasAtmospherics = true;
-        shader->mFeatures.hasGamma = true;
-        shader->mFeatures.hasShadows = use_sun_shadow;
-        shader->mFeatures.isDeferred = true; // include deferredUtils
-        shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED];
-
-        shader->mShaderGroup = LLGLSLShader::SG_WATER;
-
-        shader->mShaderFiles.clear();
-        shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
-        shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
-
-        shader->clearPermutations();
-
-        U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
-        shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
-        shader->addPermutation("HAS_NORMAL_MAP", "1");
-        shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness
-        shader->addPermutation("HAS_EMISSIVE_MAP", "1");
-        shader->addPermutation("USE_VERTEX_COLOR", "1");
-        shader->addPermutation("WATER_FOG", "1");
-
-        if (use_sun_shadow)
-        {
-            shader->addPermutation("HAS_SUN_SHADOW", "1");
-        }
-
-        shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-        success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaWaterProgram);
-        if (success)
-        {
-            success = shader->createShader(NULL, NULL);
-        }
-        llassert(success);
-
-        // Alpha Shader Hack
-        // See: LLRender::syncMatrices()
-        shader->mFeatures.calculatesLighting = true;
-        shader->mFeatures.hasLighting = true;
-
-        shader->mRiggedVariant->mFeatures.calculatesLighting = true;
-        shader->mRiggedVariant->mFeatures.hasLighting = true;
-    }
-
     if (success)
     {
         LLGLSLShader* shader = &gHUDPBRAlphaProgram;
@@ -1737,68 +1554,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         }
     }
 
-    if (success)
-    {
-        LLGLSLShader* shader[] = {
-            &gDeferredAlphaWaterProgram,
-            &gDeferredSkinnedAlphaWaterProgram
-        };
-        
-        gDeferredAlphaWaterProgram.mRiggedVariant = &gDeferredSkinnedAlphaWaterProgram;
-		
-        gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader";
-        gDeferredSkinnedAlphaWaterProgram.mName = "Deferred Skinned Alpha Underwater Shader";
-
-        for (int i = 0; i < 2 && success; ++i)
-        {
-            shader[i]->mFeatures.calculatesLighting = false;
-            shader[i]->mFeatures.hasLighting = false;
-            shader[i]->mFeatures.isAlphaLighting = true;
-            shader[i]->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
-            shader[i]->mFeatures.hasWaterFog = true;
-            shader[i]->mFeatures.hasSrgb = true;
-            shader[i]->mFeatures.encodesNormal = true;
-            shader[i]->mFeatures.calculatesAtmospherics = true;
-            shader[i]->mFeatures.hasAtmospherics = true;
-            shader[i]->mFeatures.hasGamma = true;
-            shader[i]->mFeatures.hasShadows = use_sun_shadow;
-            shader[i]->mFeatures.hasReflectionProbes = true;
-            shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-            shader[i]->mShaderGroup = LLGLSLShader::SG_WATER;
-            shader[i]->mShaderFiles.clear();
-            shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
-            shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
-
-            shader[i]->clearPermutations();
-            shader[i]->addPermutation("USE_INDEXED_TEX", "1");
-            shader[i]->addPermutation("WATER_FOG", "1");
-            shader[i]->addPermutation("USE_VERTEX_COLOR", "1");
-            shader[i]->addPermutation("HAS_ALPHA_MASK", "1");
-            if (use_sun_shadow)
-            {
-                shader[i]->addPermutation("HAS_SUN_SHADOW", "1");
-            }
-
-            if (i == 1)
-            { // rigged variant
-                shader[i]->mFeatures.hasObjectSkinning = true;
-                shader[i]->addPermutation("HAS_SKIN", "1");
-            }
-            else
-            {
-                shader[i]->mRiggedVariant = shader[1];
-            }
-            shader[i]->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
-            success = shader[i]->createShader(NULL, NULL);
-            llassert(success);
-
-            // Hack
-            shader[i]->mFeatures.calculatesLighting = true;
-            shader[i]->mFeatures.hasLighting = true;
-        }
-	}
-
 	if (success)
 	{
 		gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader";
@@ -1825,6 +1580,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredFullbrightProgram.mFeatures.hasGamma = true;
 		gDeferredFullbrightProgram.mFeatures.hasAtmospherics = true;
 		gDeferredFullbrightProgram.mFeatures.hasSrgb = true;
+        gDeferredFullbrightProgram.mFeatures.hasWaterFog = true;
 		gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 		gDeferredFullbrightProgram.mShaderFiles.clear();
 		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
@@ -1860,6 +1616,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true;
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;		
+        gDeferredFullbrightAlphaMaskProgram.mFeatures.hasWaterFog = true;
 		gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
 		gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
 		gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
@@ -1933,71 +1690,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         llassert(success);
     }
 
-	if (success)
-	{
-		gDeferredFullbrightWaterProgram.mName = "Deferred Fullbright Underwater Shader";
-		gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true;
-		gDeferredFullbrightWaterProgram.mFeatures.hasAtmospherics = true;
-		gDeferredFullbrightWaterProgram.mFeatures.hasWaterFog = true;
-		gDeferredFullbrightWaterProgram.mFeatures.hasSrgb = true;
-		gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-		gDeferredFullbrightWaterProgram.mShaderFiles.clear();
-		gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
-		gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
-		gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-		gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");
-        success = make_rigged_variant(gDeferredFullbrightWaterProgram, gDeferredSkinnedFullbrightWaterProgram);
-		success = success && gDeferredFullbrightWaterProgram.createShader(NULL, NULL);
-		llassert(success);
-	}
-    
-    if (success)
-    {
-        gDeferredFullbrightWaterAlphaProgram.mName = "Deferred Fullbright Underwater Alpha Shader";
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.calculatesAtmospherics = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.hasGamma = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.hasAtmospherics = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.hasWaterFog = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.hasSrgb = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.isDeferred = true;
-        gDeferredFullbrightWaterAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-        gDeferredFullbrightWaterAlphaProgram.mShaderFiles.clear();
-        gDeferredFullbrightWaterAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
-        gDeferredFullbrightWaterAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
-        gDeferredFullbrightWaterAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-        gDeferredFullbrightWaterAlphaProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-        gDeferredFullbrightWaterAlphaProgram.clearPermutations();
-        gDeferredFullbrightWaterAlphaProgram.addPermutation("WATER_FOG", "1");
-        gDeferredFullbrightWaterAlphaProgram.addPermutation("IS_ALPHA", "1");
-        success = make_rigged_variant(gDeferredFullbrightWaterAlphaProgram, gDeferredSkinnedFullbrightWaterAlphaProgram);
-        success = success && gDeferredFullbrightWaterAlphaProgram.createShader(NULL, NULL);
-        llassert(success);
-    }
-
-	if (success)
-	{
-		gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader";
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true;
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasAtmospherics = true;
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasWaterFog = true;
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasSrgb = true;
-		gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
-		gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear();
-		gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
-		gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
-		gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-		gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		gDeferredFullbrightAlphaMaskWaterProgram.clearPermutations();
-		gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");
-		gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1");
-        success = make_rigged_variant(gDeferredFullbrightAlphaMaskWaterProgram, gDeferredSkinnedFullbrightAlphaMaskWaterProgram);
-		success = success && gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL);
-		llassert(success);
-	}
-
 	if (success)
 	{
 		gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
@@ -2084,40 +1776,53 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		llassert(success);
 	}
 
-	if (success)
-	{
-		gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader";
-		gDeferredSoftenWaterProgram.mShaderFiles.clear();
-		gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
-		gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
-
-        gDeferredSoftenWaterProgram.clearPermutations();
-		gDeferredSoftenWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-		gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1");
-		gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		gDeferredSoftenWaterProgram.mFeatures.hasWaterFog = true;
-		gDeferredSoftenWaterProgram.mFeatures.hasSrgb = true;
-		gDeferredSoftenWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gDeferredSoftenWaterProgram.mFeatures.hasAtmospherics = true;
-		gDeferredSoftenWaterProgram.mFeatures.hasGamma = true;
-        gDeferredSoftenWaterProgram.mFeatures.isDeferred = true;
-        gDeferredSoftenWaterProgram.mFeatures.hasShadows = use_sun_shadow;
-        gDeferredSoftenWaterProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
+    if (success)
+    {
+        gHazeProgram.mName = "Haze Shader";
+        gHazeProgram.mShaderFiles.clear();
+        gHazeProgram.mFeatures.hasSrgb                = true;
+        gHazeProgram.mFeatures.calculatesAtmospherics = true;
+        gHazeProgram.mFeatures.hasAtmospherics        = true;
+        gHazeProgram.mFeatures.hasGamma               = true;
+        gHazeProgram.mFeatures.isDeferred             = true;
+        gHazeProgram.mFeatures.hasShadows             = use_sun_shadow;
+        gHazeProgram.mFeatures.hasReflectionProbes    = mShaderLevel[SHADER_DEFERRED] > 2;
+
+        gHazeProgram.clearPermutations();
+        gHazeProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+        gHazeProgram.mShaderFiles.push_back(make_pair("deferred/hazeF.glsl", GL_FRAGMENT_SHADER));
+
+        gHazeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+        success = gHazeProgram.createShader(NULL, NULL);
+        llassert(success);
+    }
 
-        if (use_sun_shadow)
-        {
-            gDeferredSoftenWaterProgram.addPermutation("HAS_SUN_SHADOW", "1");
-        }
 
-		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
-		{ //if using SSAO, take screen space light map into account as if shadows are enabled
-			gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2);
-            gDeferredSoftenWaterProgram.addPermutation("HAS_SSAO", "1");
-		}
+    if (success)
+    {
+        gHazeWaterProgram.mName = "Water Haze Shader";
+        gHazeWaterProgram.mShaderFiles.clear();
+        gHazeWaterProgram.mShaderGroup           = LLGLSLShader::SG_WATER;
+        gHazeWaterProgram.mFeatures.hasWaterFog            = true;
+        gHazeWaterProgram.mFeatures.hasSrgb                = true;
+        gHazeWaterProgram.mFeatures.calculatesAtmospherics = true;
+        gHazeWaterProgram.mFeatures.hasAtmospherics        = true;
+        gHazeWaterProgram.mFeatures.hasGamma               = true;
+        gHazeWaterProgram.mFeatures.isDeferred             = true;
+        gHazeWaterProgram.mFeatures.hasShadows             = use_sun_shadow;
+        gHazeWaterProgram.mFeatures.hasReflectionProbes    = mShaderLevel[SHADER_DEFERRED] > 2;
+
+        gHazeWaterProgram.clearPermutations();
+        gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+        gHazeWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterHazeF.glsl", GL_FRAGMENT_SHADER));
+
+        gHazeWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+        success = gHazeWaterProgram.createShader(NULL, NULL);
+        llassert(success);
+    }
 
-		success = gDeferredSoftenWaterProgram.createShader(NULL, NULL);
-		llassert(success);
-	}
 
 	if (success)
 	{
@@ -2277,31 +1982,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		llassert(success);
 	}
 
-	if (success)
-	{
-		gDeferredTerrainWaterProgram.mName = "Deferred Terrain Underwater Shader";
-		gDeferredTerrainWaterProgram.mFeatures.encodesNormal = true;
-		gDeferredTerrainWaterProgram.mFeatures.hasSrgb = true;
-		gDeferredTerrainWaterProgram.mFeatures.calculatesLighting = false;
-		gDeferredTerrainWaterProgram.mFeatures.hasLighting = false;
-		gDeferredTerrainWaterProgram.mFeatures.isAlphaLighting = true;
-		gDeferredTerrainWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
-		gDeferredTerrainWaterProgram.mFeatures.hasWaterFog = true;
-		gDeferredTerrainWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gDeferredTerrainWaterProgram.mFeatures.hasAtmospherics = true;
-		gDeferredTerrainWaterProgram.mFeatures.hasGamma = true;
-		
-		gDeferredTerrainWaterProgram.mShaderFiles.clear();
-		gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
-		gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
-		gDeferredTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-		gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		gDeferredTerrainWaterProgram.clearPermutations();
-		gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1");
-		success = gDeferredTerrainWaterProgram.createShader(NULL, NULL);
-        llassert(success);
-	}
-
 	if (success)
 	{
 		gDeferredAvatarProgram.mName = "Deferred Avatar Shader";
@@ -2331,6 +2011,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true;
 		gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true;
         gDeferredAvatarAlphaProgram.mFeatures.hasReflectionProbes = true;
+        gDeferredAvatarAlphaProgram.mFeatures.hasWaterFog = true;
 
 		gDeferredAvatarAlphaProgram.mShaderFiles.clear();
         gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
@@ -2660,24 +2341,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
 	}
 	
-	if (success)
-	{
-		gObjectAlphaMaskNoColorWaterProgram.mName = "No color alpha mask Water Shader";
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.calculatesLighting = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.calculatesAtmospherics = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasWaterFog = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAtmospherics = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasLighting = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.disableTextureIndex = true;
-		gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAlphaMask = true;
-		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.clear();
-		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
-		gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
-		gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
-		gObjectAlphaMaskNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-		success = gObjectAlphaMaskNoColorWaterProgram.createShader(NULL, NULL);
-	}
-
 	if (success)
 	{
 		gImpostorProgram.mName = "Impostor Shader";
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index b0b9719d76..04da7e48ae 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -175,7 +175,6 @@ extern LLGLSLShader        gSkinnedObjectFullbrightAlphaMaskProgram;
 extern LLGLSLShader		gObjectBumpProgram;
 extern LLGLSLShader        gSkinnedObjectBumpProgram;
 extern LLGLSLShader		gObjectAlphaMaskNoColorProgram;
-extern LLGLSLShader		gObjectAlphaMaskNoColorWaterProgram;
 
 //environment shaders
 extern LLGLSLShader			gWaterProgram;
@@ -211,7 +210,6 @@ extern LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
 extern LLGLSLShader			gDeferredNonIndexedDiffuseProgram;
 extern LLGLSLShader			gDeferredBumpProgram;
 extern LLGLSLShader			gDeferredTerrainProgram;
-extern LLGLSLShader			gDeferredTerrainWaterProgram;
 extern LLGLSLShader			gDeferredTreeProgram;
 extern LLGLSLShader			gDeferredTreeShadowProgram;
 extern LLGLSLShader			gDeferredLightProgram;
@@ -219,10 +217,11 @@ extern LLGLSLShader			gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT];
 extern LLGLSLShader			gDeferredSpotLightProgram;
 extern LLGLSLShader			gDeferredMultiSpotLightProgram;
 extern LLGLSLShader			gDeferredSunProgram;
+extern LLGLSLShader         gHazeProgram;
+extern LLGLSLShader         gHazeWaterProgram;
 extern LLGLSLShader			gDeferredBlurLightProgram;
 extern LLGLSLShader			gDeferredAvatarProgram;
 extern LLGLSLShader			gDeferredSoftenProgram;
-extern LLGLSLShader			gDeferredSoftenWaterProgram;
 extern LLGLSLShader			gDeferredShadowProgram;
 extern LLGLSLShader			gDeferredShadowCubeProgram;
 extern LLGLSLShader			gDeferredShadowAlphaMaskProgram;
@@ -251,10 +250,6 @@ extern LLGLSLShader			gDeferredFullbrightAlphaMaskProgram;
 extern LLGLSLShader			gHUDFullbrightAlphaMaskProgram;
 extern LLGLSLShader			gDeferredFullbrightAlphaMaskAlphaProgram;
 extern LLGLSLShader			gHUDFullbrightAlphaMaskAlphaProgram;
-extern LLGLSLShader			gDeferredAlphaWaterProgram;
-extern LLGLSLShader			gDeferredFullbrightWaterProgram;
-extern LLGLSLShader			gDeferredFullbrightWaterAlphaProgram;
-extern LLGLSLShader			gDeferredFullbrightAlphaMaskWaterProgram;
 extern LLGLSLShader			gDeferredEmissiveProgram;
 extern LLGLSLShader			gDeferredAvatarEyesProgram;
 extern LLGLSLShader			gDeferredAvatarAlphaProgram;
@@ -271,12 +266,10 @@ extern LLGLSLShader			gDeferredBufferVisualProgram;
 
 // Deferred materials shaders
 extern LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
-extern LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
 
 extern LLGLSLShader         gHUDPBROpaqueProgram;
 extern LLGLSLShader         gPBRGlowProgram;
 extern LLGLSLShader         gDeferredPBROpaqueProgram;
 extern LLGLSLShader         gDeferredPBRAlphaProgram;
-extern LLGLSLShader         gDeferredPBRAlphaWaterProgram;
 extern LLGLSLShader         gHUDPBRAlphaProgram;
 #endif
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9266c84540..52afe16799 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7875,7 +7875,7 @@ void LLPipeline::renderDeferredLighting()
 
         if (RenderDeferredAtmospheric)
         {  // apply sunlight contribution
-            LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;
+            LLGLSLShader &soften_shader = gDeferredSoftenProgram;
 
             LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - atmospherics");
             LL_PROFILE_GPU_ZONE("atmospherics");
@@ -7904,7 +7904,7 @@ void LLPipeline::renderDeferredLighting()
                 mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
             }
 
-            unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
+            unbindDeferredShader(gDeferredSoftenProgram);
         }
 
         static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
@@ -8056,7 +8056,7 @@ void LLPipeline::renderDeferredLighting()
 
                     LLVector4a center;
                     center.load3(drawablep->getPositionAgent().mV);
-                    const F32 *c = center.getF32ptr();
+                    const F32* c = center.getF32ptr();
                     F32        s = volume->getLightRadius() * 1.5f;
 
                     sVisibleLightCount++;
@@ -8105,8 +8105,8 @@ void LLPipeline::renderDeferredLighting()
                         U32 idx = count - 1;
                         bindDeferredShader(gDeferredMultiLightProgram[idx]);
                         gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
-                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat *) light);
-                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat *) col);
+                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*)light);
+                        gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*)col);
                         gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
                         far_z = 0.f;
                         count = 0;
@@ -8124,11 +8124,11 @@ void LLPipeline::renderDeferredLighting()
 
                 for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
                 {
-                    LLDrawable *drawablep           = *iter;
-                    LLVOVolume *volume              = drawablep->getVOVolume();
-                    LLVector3   center              = drawablep->getPositionAgent();
-                    F32 *       c                   = center.mV;
-                    F32         light_size_final    = volume->getLightRadius() * 1.5f;
+                    LLDrawable* drawablep = *iter;
+                    LLVOVolume* volume = drawablep->getVOVolume();
+                    LLVector3   center = drawablep->getPositionAgent();
+                    F32* c = center.mV;
+                    F32         light_size_final = volume->getLightRadius() * 1.5f;
                     F32         light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF);
 
                     sVisibleLightCount++;
@@ -8154,12 +8154,56 @@ void LLPipeline::renderDeferredLighting()
         }
 
 
+        
+        if (RenderDeferredAtmospheric)
+        {
+            LLGLEnable blend(GL_BLEND);
+            gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA);
+            gGL.setColorMask(true, false);
+
+            for (U32 i = 0; i < 2; ++i)
+            {
+                // apply haze
+                LLGLSLShader &haze_shader = i == 0 ? gHazeProgram : gHazeWaterProgram;
+
+                LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - haze");
+                LL_PROFILE_GPU_ZONE("haze");
+                bindDeferredShader(haze_shader);
+
+                static LLCachedControl<F32> ssao_scale(gSavedSettings, "RenderSSAOIrradianceScale", 0.5f);
+                static LLCachedControl<F32> ssao_max(gSavedSettings, "RenderSSAOIrradianceMax", 0.25f);
+                static LLStaticHashedString ssao_scale_str("ssao_irradiance_scale");
+                static LLStaticHashedString ssao_max_str("ssao_irradiance_max");
+
+                haze_shader.uniform1f(ssao_scale_str, ssao_scale);
+                haze_shader.uniform1f(ssao_max_str, ssao_max);
+
+                LLEnvironment &environment = LLEnvironment::instance();
+                haze_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
+                haze_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
+
+                haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
+
+                {
+                    LLGLDepthTest depth(GL_FALSE);
+
+                    // full screen blit
+                    mScreenTriangleVB->setBuffer();
+                    mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+                }
+
+                unbindDeferredShader(haze_shader);
+            }
+
+            gGL.setSceneBlendType(LLRender::BT_ALPHA);
+        }
+
+
         gGL.setColorMask(true, true);
     }
 
     {  // render non-deferred geometry (alpha, fullbright, glow)
         LLGLDisable blend(GL_BLEND);
-        //LLGLDisable stencil(GL_STENCIL_TEST);
 
         pushRenderTypeMask();
         andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
-- 
cgit v1.2.3