From 8ec39da3468f53af85d0cd4d4d9c54a72d6b8152 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Fri, 29 Jul 2011 17:46:16 -0500
Subject: SH-2181 Fix for alpha flickering when basic shaders enabled (don't
 use glAlphaFunc when shaders are available).

Reviewed by Leslie
---
 indra/llrender/llgl.cpp                            |  11 ++
 indra/llrender/llglslshader.cpp                    |  13 +-
 indra/llrender/llglslshader.h                      |   5 +
 indra/llrender/llrender.cpp                        |  29 ++++
 indra/llrender/llshadermgr.cpp                     | 106 ++++++++++--
 .../shaders/class1/deferred/diffuseAlphaMaskF.glsl |  30 ++++
 .../class1/deferred/diffuseAlphaMaskIndexedF.glsl  |  26 +++
 .../shaders/class1/deferred/shadowAlphaMaskF.glsl  |  27 ++++
 .../shaders/class1/deferred/shadowAlphaMaskV.glsl  |  23 +++
 .../shaders/class1/deferred/shadowF.glsl           |   4 +-
 .../shaders/class1/deferred/shadowV.glsl           |   3 -
 .../shaders/class2/lighting/lightAlphaMaskF.glsl   |  30 ++++
 .../class2/lighting/lightAlphaMaskNonIndexedF.glsl |  33 ++++
 .../class2/lighting/lightFullbrightAlphaMaskF.glsl |  29 ++++
 .../lightFullbrightNonIndexedAlphaMaskF.glsl       |  31 ++++
 .../lighting/lightFullbrightWaterAlphaMaskF.glsl   |  29 ++++
 .../lightFullbrightWaterNonIndexedAlphaMaskF.glsl  |  29 ++++
 .../class2/lighting/lightWaterAlphaMaskF.glsl      |  27 ++++
 .../lighting/lightWaterAlphaMaskNonIndexedF.glsl   |  31 ++++
 indra/newview/lldrawpoolalpha.cpp                  |  69 +++++---
 indra/newview/lldrawpoolavatar.cpp                 |  17 +-
 indra/newview/lldrawpoolsimple.cpp                 |  27 ++--
 indra/newview/lldrawpooltree.cpp                   |  36 +++--
 indra/newview/lldrawpoolwlsky.cpp                  |   3 +-
 indra/newview/llselectmgr.cpp                      |   2 -
 indra/newview/llviewerprecompiledheaders.h         |   4 +-
 indra/newview/llviewershadermgr.cpp                | 177 +++++++++++++++++++++
 indra/newview/llviewershadermgr.h                  |   9 ++
 indra/newview/llvoavatar.cpp                       |  14 +-
 indra/newview/pipeline.cpp                         |  13 +-
 30 files changed, 787 insertions(+), 100 deletions(-)
 create mode 100644 indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
 create mode 100644 indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskNonIndexedF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class2/lighting/lightFullbrightAlphaMaskF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterAlphaMaskF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskNonIndexedF.glsl

(limited to 'indra')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 8937726209..2f6ef2b663 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -48,6 +48,7 @@
 #include "llstacktrace.h"
 
 #include "llglheaders.h"
+#include "llglslshader.h"
 
 #ifdef _DEBUG
 //#define GL_STATE_VERIFY
@@ -1781,6 +1782,16 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
 LLGLState::LLGLState(LLGLenum state, S32 enabled) :
 	mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
 {
+	if (LLGLSLShader::sNoFixedFunction)
+	{ //always disable state that's deprecated post GL 3.0
+		switch (state)
+		{
+			case GL_ALPHA_TEST:
+				enabled = 0;
+				break;
+		}
+	}
+
 	stop_glerror();
 	if (state)
 	{
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 80c93bb0d2..f51d83abe4 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -49,6 +49,7 @@ using std::make_pair;
 using std::string;
 
 GLhandleARB LLGLSLShader::sCurBoundShader = 0;
+LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
 bool LLGLSLShader::sNoFixedFunction = false;
 
 //UI shader -- declared here so llui_libtest will link properly
@@ -63,7 +64,8 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
 LLShaderFeatures::LLShaderFeatures()
 : calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
 hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false),
-hasGamma(false), hasLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false)
+hasGamma(false), hasLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false),
+hasAlphaMask(false)
 {
 }
 
@@ -386,6 +388,7 @@ void LLGLSLShader::bind()
 	{
 		glUseProgramObjectARB(mProgramObject);
 		sCurBoundShader = mProgramObject;
+		sCurBoundShaderPtr = this;
 		if (mUniformsDirty)
 		{
 			LLShaderMgr::instance()->updateShaderUniforms(this);
@@ -410,6 +413,7 @@ void LLGLSLShader::unbind()
 		}
 		glUseProgramObjectARB(0);
 		sCurBoundShader = 0;
+		sCurBoundShaderPtr = NULL;
 		stop_glerror();
 	}
 }
@@ -418,6 +422,7 @@ void LLGLSLShader::bindNoShader(void)
 {
 	glUseProgramObjectARB(0);
 	sCurBoundShader = 0;
+	sCurBoundShaderPtr = NULL;
 }
 
 S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
@@ -979,3 +984,9 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
 		glVertexAttrib4fvARB(mAttribute[index], v);
 	}
 }
+
+void LLGLSLShader::setAlphaRange(F32 minimum, F32 maximum)
+{
+	uniform1f("minimum_alpha", minimum);
+	uniform1f("maximum_alpha", maximum);
+}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 621e0b82ee..558ea66b50 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -47,6 +47,7 @@ public:
 	bool hasGamma;
 	S32 mIndexedTextureChannels;
 	bool disableTextureIndex;
+	bool hasAlphaMask;
 
 	// char numLights;
 	
@@ -67,6 +68,8 @@ public:
 	LLGLSLShader();
 
 	static GLhandleARB sCurBoundShader;
+	static LLGLSLShader* sCurBoundShaderPtr;
+
 	static bool sNoFixedFunction;
 
 	void unload();
@@ -105,6 +108,8 @@ public:
 	void uniformMatrix3fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
 	void uniformMatrix4fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
 
+	void setAlphaRange(F32 minimum, F32 maximum);
+
 	void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
 	void vertexAttrib4fv(U32 index, GLfloat* v);
 	
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 70df1dd1d1..d72918b15d 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1168,6 +1168,11 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
 {
 	flush();
 
+	if (LLGLSLShader::sNoFixedFunction)
+	{ //glAlphaFunc is deprecated in OpenGL 3.3
+		return;
+	}
+
 	if (mCurrAlphaFunc != func ||
 		mCurrAlphaFuncVal != value)
 	{
@@ -1182,6 +1187,30 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
 			glAlphaFunc(sGLCompareFunc[func], value);
 		}
 	}
+
+	if (gDebugGL)
+	{ //make sure cached state is correct
+		GLint cur_func = 0;
+		glGetIntegerv(GL_ALPHA_TEST_FUNC, &cur_func);
+
+		if (func == CF_DEFAULT)
+		{
+			func = CF_GREATER;
+		}
+
+		if (cur_func != sGLCompareFunc[func])
+		{
+			llerrs << "Alpha test function corrupted!" << llendl;
+		}
+
+		F32 ref = 0.f;
+		glGetFloatv(GL_ALPHA_TEST_REF, &ref);
+
+		if (ref != value)
+		{
+			llerrs << "Alpha test value corrupted!" << llendl;
+		}
+	}
 }
 
 void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 751b250d96..986c1f2774 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -206,21 +206,40 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 	
 	if (features->hasLighting)
 	{
-	
 		if (features->hasWaterFog)
 		{
 			if (features->disableTextureIndex)
 			{
-				if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl"))
+				if (features->hasAlphaMask)
 				{
-					return FALSE;
+					if (!shader->attachObject("lighting/lightWaterAlphaMaskNonIndexedF.glsl"))
+					{
+						return FALSE;
+					}
+				}
+				else
+				{
+					if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl"))
+					{
+						return FALSE;
+					}
 				}
 			}
 			else 
 			{
-				if (!shader->attachObject("lighting/lightWaterF.glsl"))
+				if (features->hasAlphaMask)
 				{
-					return FALSE;
+					if (!shader->attachObject("lighting/lightWaterAlphaMaskF.glsl"))
+					{
+						return FALSE;
+					}
+				}
+				else
+				{
+					if (!shader->attachObject("lighting/lightWaterF.glsl"))
+					{
+						return FALSE;
+					}
 				}
 				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
 			}
@@ -230,16 +249,36 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 		{
 			if (features->disableTextureIndex)
 			{
-				if (!shader->attachObject("lighting/lightNonIndexedF.glsl"))
+				if (features->hasAlphaMask)
 				{
-					return FALSE;
+					if (!shader->attachObject("lighting/lightAlphaMaskNonIndexedF.glsl"))
+					{
+						return FALSE;
+					}
+				}
+				else
+				{
+					if (!shader->attachObject("lighting/lightNonIndexedF.glsl"))
+					{
+						return FALSE;
+					}
 				}
 			}
 			else 
 			{
-				if (!shader->attachObject("lighting/lightF.glsl"))
+				if (features->hasAlphaMask)
 				{
-					return FALSE;
+					if (!shader->attachObject("lighting/lightAlphaMaskF.glsl"))
+					{
+						return FALSE;
+					}
+				}
+				else
+				{
+					if (!shader->attachObject("lighting/lightF.glsl"))
+					{
+						return FALSE;
+					}
 				}
 				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
 			}
@@ -272,14 +311,28 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 		{
 			if (features->disableTextureIndex)
 			{
-				if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl"))
+				if (features->hasAlphaMask)
+				{
+					if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl"))
+					{
+						return FALSE;
+					}
+				}
+				else if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl"))
 				{
 					return FALSE;
 				}
 			}
 			else 
 			{
-				if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
+				if (features->hasAlphaMask)
+				{
+					if (!shader->attachObject("lighting/lightFullbrightWaterAlphaMaskF.glsl"))
+					{
+						return FALSE;
+					}
+				}
+				else if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
 				{
 					return FALSE;
 				}
@@ -310,16 +363,37 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
 		{
 			if (features->disableTextureIndex)
 			{
-				if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl"))
+
+				if (features->hasAlphaMask)
 				{
-					return FALSE;
+					if (!shader->attachObject("lighting/lightFullbrightNonIndexedAlphaMaskF.glsl"))
+					{
+						return FALSE;
+					}
+				}
+				else
+				{
+					if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl"))
+					{
+						return FALSE;
+					}
 				}
 			}
 			else 
 			{
-				if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
+				if (features->hasAlphaMask)
 				{
-					return FALSE;
+					if (!shader->attachObject("lighting/lightFullbrightAlphaMaskF.glsl"))
+					{
+						return FALSE;
+					}
+				}
+				else
+				{
+					if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
+					{
+						return FALSE;
+					}
 				}
 				shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
 			}
@@ -406,7 +480,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
 			LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
 		}
 	}
-}
+ }
 
 GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
 {
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
new file mode 100644
index 0000000000..338d0ebb2b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -0,0 +1,30 @@
+/** 
+ * @file diffuseF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+uniform sampler2D diffuseMap;
+
+varying vec3 vary_normal;
+
+void main() 
+{
+	vec4 col = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color;
+	
+	if (col.a < minimum_alpha || col.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	gl_FragData[0] = vec4(col.rgb, 0.0);
+	gl_FragData[1] = vec4(0,0,0,0); // spec
+	vec3 nvn = normalize(vary_normal);
+	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
new file mode 100644
index 0000000000..0671cb94bd
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -0,0 +1,26 @@
+/** 
+ * @file diffuseAlphaMaskIndexedF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+varying vec3 vary_normal;
+
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+void main() 
+{
+	vec4 col = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+	
+	if (col.a < minimum_alpha || col.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	gl_FragData[0] = vec4(col.rgb, 0.0);
+	gl_FragData[1] = vec4(0,0,0,0);
+	vec3 nvn = normalize(vary_normal);
+	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
new file mode 100644
index 0000000000..e24d0b666e
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
@@ -0,0 +1,27 @@
+/** 
+ * @file shadowAlphaMaskF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+uniform sampler2D diffuseMap;
+
+varying vec4 post_pos;
+
+void main() 
+{
+	float alpha = texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a;
+
+	if (alpha < minimum_alpha || alpha > maximum_alpha)
+	{
+		discard;
+	}
+
+	gl_FragColor = vec4(1,1,1,1);
+	
+	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
new file mode 100644
index 0000000000..58e9bcec58
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
@@ -0,0 +1,23 @@
+/** 
+ * @file shadowAlphaMaskV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+
+
+varying vec4 post_pos;
+
+void main()
+{
+	//transform vertex
+	vec4 pos = gl_ModelViewProjectionMatrix*gl_Vertex;
+	
+	post_pos = pos;
+	
+	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+	
+	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
+	gl_FrontColor = gl_Color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
index e0c5406483..0bfe74ce42 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
@@ -7,13 +7,11 @@
  
 
 
-uniform sampler2D diffuseMap;
-
 varying vec4 post_pos;
 
 void main() 
 {
-	gl_FragColor = vec4(1,1,1,texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a);
+	gl_FragColor = vec4(1,1,1,1);
 	
 	gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
index 9271a5115c..d40c2d9f78 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
@@ -17,7 +17,4 @@ void main()
 	post_pos = pos;
 	
 	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-	
-	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
-	gl_FrontColor = gl_Color;
 }
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskF.glsl
new file mode 100644
index 0000000000..1211ad7a89
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskF.glsl
@@ -0,0 +1,30 @@
+/** 
+ * @file lightAlphaMaskF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+vec3 atmosLighting(vec3 light);
+vec3 scaleSoftClip(vec3 light);
+
+void default_lighting() 
+{
+	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+	
+	if (color.a < minimum_alpha || color.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	color.rgb = atmosLighting(color.rgb);
+
+	color.rgb = scaleSoftClip(color.rgb);
+
+	gl_FragColor = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskNonIndexedF.glsl
new file mode 100644
index 0000000000..1a7d67b943
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/lighting/lightAlphaMaskNonIndexedF.glsl
@@ -0,0 +1,33 @@
+/** 
+ * @file lightAlphaMaskNonIndexedF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+
+uniform sampler2D diffuseMap;
+
+vec3 atmosLighting(vec3 light);
+vec3 scaleSoftClip(vec3 light);
+
+void default_lighting() 
+{
+	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
+
+	if (color.a < minimum_alpha || color.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	color.rgb = atmosLighting(color.rgb);
+
+	color.rgb = scaleSoftClip(color.rgb);
+
+	gl_FragColor = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightAlphaMaskF.glsl
new file mode 100644
index 0000000000..73e885a7e9
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightAlphaMaskF.glsl
@@ -0,0 +1,29 @@
+/** 
+ * @file lightFullbrightAlphaMaskF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+vec3 fullbrightAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+void fullbright_lighting()
+{
+	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+	
+	if (color.a < minimum_alpha || color.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	color.rgb = fullbrightAtmosTransport(color.rgb);
+	
+	color.rgb = fullbrightScaleSoftClip(color.rgb);
+
+	gl_FragColor = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
new file mode 100644
index 0000000000..55dfe9b166
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
@@ -0,0 +1,31 @@
+/** 
+ * @file lightFullbrightNonIndexedAlphaMaskF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+vec3 fullbrightAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+uniform sampler2D diffuseMap;
+
+void fullbright_lighting()
+{
+	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
+	
+	if (color.a < minimum_alpha || color.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	color.rgb = fullbrightAtmosTransport(color.rgb);
+	
+	color.rgb = fullbrightScaleSoftClip(color.rgb);
+
+	gl_FragColor = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterAlphaMaskF.glsl
new file mode 100644
index 0000000000..e4cea077f9
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterAlphaMaskF.glsl
@@ -0,0 +1,29 @@
+/** 
+ * @file lightFullbrightWaterAlphaMaskF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+vec4 diffuseLookup(vec2 texcoord);
+
+vec3 fullbrightAtmosTransport(vec3 light);
+vec4 applyWaterFog(vec4 color);
+
+void fullbright_lighting_water()
+{
+	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+
+	if (color.a < minimum_alpha || color.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	color.rgb = fullbrightAtmosTransport(color.rgb);
+	
+	gl_FragColor = applyWaterFog(color);
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
new file mode 100644
index 0000000000..e8533f94a7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
@@ -0,0 +1,29 @@
+/** 
+ * @file lightFullbrightWaterNonIndexedAlphaMaskF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+uniform sampler2D diffuseMap;
+
+vec3 fullbrightAtmosTransport(vec3 light);
+vec4 applyWaterFog(vec4 color);
+
+void fullbright_lighting_water()
+{
+	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color;
+
+	if (color.a < minimum_alpha || color.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	color.rgb = fullbrightAtmosTransport(color.rgb);
+	
+	gl_FragColor = applyWaterFog(color);
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskF.glsl
new file mode 100644
index 0000000000..7b3c20f092
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskF.glsl
@@ -0,0 +1,27 @@
+/** 
+ * @file lightWaterAlphaMaskF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+vec3 atmosLighting(vec3 light);
+vec4 applyWaterFog(vec4 color);
+
+void default_lighting_water()
+{
+	vec4 color = diffuseLookup(gl_TexCoord[0].xy) * gl_Color;
+
+	if (color.a < minimum_alpha || color.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	color.rgb = atmosLighting(color.rgb);
+
+	gl_FragColor = applyWaterFog(color);
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskNonIndexedF.glsl
new file mode 100644
index 0000000000..907140effd
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/lighting/lightWaterAlphaMaskNonIndexedF.glsl
@@ -0,0 +1,31 @@
+/** 
+ * @file lightWaterAlphaMaskNonIndexedF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $/LicenseInfo$
+ */
+ 
+uniform float minimum_alpha;
+uniform float maximum_alpha;
+
+uniform sampler2D diffuseMap;
+
+vec3 atmosLighting(vec3 light);
+vec4 applyWaterFog(vec4 color);
+
+void default_lighting_water()
+{
+	vec4 color = texture2D(diffuseMap,gl_TexCoord[0].xy) * gl_Color;
+
+	if (color.a < minimum_alpha || color.a > maximum_alpha)
+	{
+		discard;
+	}
+
+	color.rgb = atmosLighting(color.rgb);
+
+	color = applyWaterFog(color);
+	
+	gl_FragColor = color;
+}
+
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index ddcf42e523..9719140a37 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -88,16 +88,13 @@ void LLDrawPoolAlpha::endDeferredPass(S32 pass)
 
 void LLDrawPoolAlpha::renderDeferred(S32 pass)
 {
-	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
-	{
-		LLFastTimer t(FTM_RENDER_GRASS);
-		gDeferredTreeProgram.bind();
-		LLGLEnable test(GL_ALPHA_TEST);
-		//render alpha masked objects
-		LLRenderPass::renderTexture(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
-		gDeferredTreeProgram.unbind();
-	}			
-	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+	LLFastTimer t(FTM_RENDER_GRASS);
+	gDeferredDiffuseAlphaMaskProgram.bind();
+	gDeferredDiffuseAlphaMaskProgram.setAlphaRange(0.33f, 1.f);
+
+	//render alpha masked objects
+	LLRenderPass::pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+	gDeferredDiffuseAlphaMaskProgram.unbind();			
 }
 
 
@@ -124,7 +121,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
 	if (pass == 0)
 	{
 		simple_shader = &gDeferredAlphaProgram;
-		fullbright_shader = &gObjectFullbrightProgram;
+		fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
 
 		//prime simple shader (loads shadow relevant uniforms)
 		gPipeline.bindDeferredShader(*simple_shader);
@@ -138,7 +135,8 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
 		gPipeline.mDeferredDepth.bindTarget();
 		simple_shader = NULL;
 		fullbright_shader = NULL;
-		gObjectFullbrightProgram.bind();
+		gObjectFullbrightAlphaMaskProgram.bind();
+		gObjectFullbrightAlphaMaskProgram.setAlphaRange(0.33f, 1.f);
 	}
 
 	deferred_render = TRUE;
@@ -157,7 +155,7 @@ void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
 	{
 		gPipeline.mDeferredDepth.flush();
 		gPipeline.mScreen.bindTarget();
-		gObjectFullbrightProgram.unbind();
+		gObjectFullbrightAlphaMaskProgram.unbind();
 	}
 
 	deferred_render = FALSE;
@@ -175,13 +173,13 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
 	
 	if (LLPipeline::sUnderWaterRender)
 	{
-		simple_shader = &gObjectSimpleWaterProgram;
-		fullbright_shader = &gObjectFullbrightWaterProgram;
+		simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
+		fullbright_shader = &gObjectFullbrightWaterAlphaMaskProgram;
 	}
 	else
 	{
-		simple_shader = &gObjectSimpleProgram;
-		fullbright_shader = &gObjectFullbrightProgram;
+		simple_shader = &gObjectSimpleAlphaMaskProgram;
+		fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
 	}
 
 	if (mVertexShaderLevel > 0)
@@ -227,29 +225,32 @@ void LLDrawPoolAlpha::render(S32 pass)
 		mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds
 		gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
 
-		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f);
 		if (mVertexShaderLevel > 0)
 		{
-			if (!LLPipeline::sRenderDeferred)
+			if (!LLPipeline::sRenderDeferred || !deferred_render)
 			{
 				simple_shader->bind();
+				simple_shader->setAlphaRange(0.33f, 1.f);
+
 				pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
 			}
 			if (fullbright_shader)
 			{
 				fullbright_shader->bind();
+				fullbright_shader->setAlphaRange(0.33f, 1.f);
 			}
 			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
 			//LLGLSLShader::bindNoShader();
 		}
 		else
 		{
+			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); //OK
 			gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
 			pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask());
 			gPipeline.enableLightsDynamic();
 			pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
+			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
 		}
-		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 	}
 
 	LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy || 
@@ -257,7 +258,6 @@ void LLDrawPoolAlpha::render(S32 pass)
 
 	if (deferred_render && pass == 1)
 	{
-		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f);
 		gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
 	}
 	else
@@ -268,13 +268,33 @@ void LLDrawPoolAlpha::render(S32 pass)
 		mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;       // }
 		gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
 
-		if (LLPipeline::sImpostorRender)
+		if (mVertexShaderLevel > 0)
 		{
-			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
+			if (LLPipeline::sImpostorRender)
+			{
+				fullbright_shader->bind();
+				fullbright_shader->setAlphaRange(0.5f, 1.f);
+				simple_shader->bind();
+				simple_shader->setAlphaRange(0.5f, 1.f);
+			}				
+			else
+			{
+				fullbright_shader->bind();
+				fullbright_shader->setAlphaRange(0.f, 1.f);
+				simple_shader->bind();
+				simple_shader->setAlphaRange(0.f, 1.f);
+			}
 		}
 		else
 		{
-			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+			if (LLPipeline::sImpostorRender)
+			{
+				gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK
+			}
+			else
+			{
+				gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
+			}
 		}
 	}
 
@@ -291,7 +311,6 @@ void LLDrawPoolAlpha::render(S32 pass)
 
 	if (deferred_render && pass == 1)
 	{
-		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 		gGL.setSceneBlendType(LLRender::BT_ALPHA);
 	}
 
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 9f790d03fe..694b7dcedd 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -258,7 +258,6 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()
 	sSkipOpaque = TRUE;
 	sShaderLevel = mVertexShaderLevel;
 	sVertexProgram = &gDeferredAvatarAlphaProgram;
-
 	sRenderingSkinned = TRUE;
 
 	gPipeline.bindDeferredShader(*sVertexProgram);
@@ -361,7 +360,7 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
 		{
 			gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX];
 		}
-		gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.2f);
+		//gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.2f);
 		
 		glColor4f(1,1,1,1);
 
@@ -605,16 +604,17 @@ void LLDrawPoolAvatar::beginRigid()
 	{
 		if (LLPipeline::sUnderWaterRender)
 		{
-			sVertexProgram = &gObjectSimpleNonIndexedWaterProgram;
+			sVertexProgram = &gObjectAlphaMaskNonIndexedWaterProgram;
 		}
 		else
 		{
-			sVertexProgram = &gObjectSimpleNonIndexedProgram;
+			sVertexProgram = &gObjectAlphaMaskNonIndexedProgram;
 		}
 		
 		if (sVertexProgram != NULL)
 		{	//eyeballs render with the specular shader
 			sVertexProgram->bind();
+			sVertexProgram->setAlphaRange(0.2f, 1.f);
 		}
 	}
 	else
@@ -692,11 +692,11 @@ void LLDrawPoolAvatar::beginSkinned()
 	{
 		if (LLPipeline::sUnderWaterRender)
 		{
-			sVertexProgram = &gObjectSimpleNonIndexedWaterProgram;
+			sVertexProgram = &gObjectAlphaMaskNonIndexedWaterProgram;
 		}
 		else
 		{
-			sVertexProgram = &gObjectSimpleNonIndexedProgram;
+			sVertexProgram = &gObjectAlphaMaskNonIndexedProgram;
 		}
 	}
 	
@@ -728,6 +728,11 @@ void LLDrawPoolAvatar::beginSkinned()
 			sVertexProgram->bind();
 		}
 	}
+
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		sVertexProgram->setAlphaRange(0.2f, 1.f);
+	}
 }
 
 void LLDrawPoolAvatar::endSkinned()
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index 224f149c6b..eec4ee6bac 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -182,7 +182,6 @@ void LLDrawPoolSimple::endRenderPass(S32 pass)
 void LLDrawPoolSimple::render(S32 pass)
 {
 	LLGLDisable blend(GL_BLEND);
-	LLGLDisable alpha_test(GL_ALPHA_TEST);
 	
 	{ //render simple
 		LLFastTimer t(FTM_RENDER_SIMPLE);
@@ -202,6 +201,7 @@ void LLDrawPoolSimple::render(S32 pass)
 		}
 		else
 		{
+			LLGLDisable alpha_test(GL_ALPHA_TEST);
 			renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());
 		}
 		
@@ -256,19 +256,21 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass)
 
 	if (LLPipeline::sUnderWaterRender)
 	{
-		simple_shader = &gObjectSimpleNonIndexedWaterProgram;
+		simple_shader = &gObjectAlphaMaskNonIndexedWaterProgram;
 	}
 	else
 	{
-		simple_shader = &gObjectSimpleNonIndexedProgram;
+		simple_shader = &gObjectAlphaMaskNonIndexedProgram;
 	}
 
 	if (mVertexShaderLevel > 0)
 	{
 		simple_shader->bind();
+		simple_shader->setAlphaRange(0.5f, 1.f);
 	}
 	else 
 	{
+		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
 		// don't use shaders!
 		if (gGLManager.mHasShaderObjects)
 		{
@@ -286,22 +288,23 @@ void LLDrawPoolGrass::endRenderPass(S32 pass)
 	{
 		simple_shader->unbind();
 	}
+	else
+	{
+		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+	}
 }
 
 void LLDrawPoolGrass::render(S32 pass)
 {
 	LLGLDisable blend(GL_BLEND);
-	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
-
+	
 	{
 		LLFastTimer t(FTM_RENDER_GRASS);
 		LLGLEnable test(GL_ALPHA_TEST);
 		gGL.setSceneBlendType(LLRender::BT_ALPHA);
 		//render grass
 		LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask());
-	}			
-
-	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+	}
 }
 
 void LLDrawPoolGrass::beginDeferredPass(S32 pass)
@@ -316,17 +319,13 @@ void LLDrawPoolGrass::endDeferredPass(S32 pass)
 
 void LLDrawPoolGrass::renderDeferred(S32 pass)
 {
-	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
-
 	{
 		LLFastTimer t(FTM_RENDER_GRASS_DEFERRED);
-		gDeferredTreeProgram.bind();
-		LLGLEnable test(GL_ALPHA_TEST);
+		gDeferredNonIndexedDiffuseAlphaMaskProgram.bind();
+		gDeferredNonIndexedDiffuseAlphaMaskProgram.setAlphaRange(0.5f, 1.f);
 		//render grass
 		LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask());
 	}			
-
-	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 }
 
 
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index 429e06b227..a6e0151114 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -62,24 +62,25 @@ void LLDrawPoolTree::prerender()
 void LLDrawPoolTree::beginRenderPass(S32 pass)
 {
 	LLFastTimer t(FTM_RENDER_TREES);
-	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
-	
+		
 	if (LLPipeline::sUnderWaterRender)
 	{
-		shader = &gObjectSimpleNonIndexedWaterProgram;
+		shader = &gObjectAlphaMaskNonIndexedWaterProgram;
 	}
 	else
 	{
-		shader = &gObjectSimpleNonIndexedProgram;
+		shader = &gObjectAlphaMaskNonIndexedProgram;
 	}
 
 	if (gPipeline.canUseVertexShaders())
 	{
 		shader->bind();
+		shader->setAlphaRange(0.5f, 1.f);
 	}
 	else
 	{
 		gPipeline.enableLightsDynamic();
+		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
 	}
 }
 
@@ -92,7 +93,7 @@ void LLDrawPoolTree::render(S32 pass)
 		return;
 	}
 
-	LLGLEnable test(GL_ALPHA_TEST);
+	LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1);
 	LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);
 
 	if (gSavedSettings.getBOOL("RenderAnimateTrees"))
@@ -121,12 +122,16 @@ void LLDrawPoolTree::render(S32 pass)
 void LLDrawPoolTree::endRenderPass(S32 pass)
 {
 	LLFastTimer t(FTM_RENDER_TREES);
-	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
-	
+		
 	if (gPipeline.canUseWindLightShadersOnObjects())
 	{
 		shader->unbind();
 	}
+	
+	if (mVertexShaderLevel <= 0)
+	{
+		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+	}
 }
 
 //============================================
@@ -135,10 +140,10 @@ void LLDrawPoolTree::endRenderPass(S32 pass)
 void LLDrawPoolTree::beginDeferredPass(S32 pass)
 {
 	LLFastTimer t(FTM_RENDER_TREES);
-	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
 		
-	shader = &gDeferredTreeProgram;
+	shader = &gDeferredNonIndexedDiffuseAlphaMaskProgram;
 	shader->bind();
+	shader->setAlphaRange(0.5f, 1.f);
 }
 
 void LLDrawPoolTree::renderDeferred(S32 pass)
@@ -149,8 +154,7 @@ void LLDrawPoolTree::renderDeferred(S32 pass)
 void LLDrawPoolTree::endDeferredPass(S32 pass)
 {
 	LLFastTimer t(FTM_RENDER_TREES);
-	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
-	
+		
 	shader->unbind();
 }
 
@@ -160,11 +164,12 @@ void LLDrawPoolTree::endDeferredPass(S32 pass)
 void LLDrawPoolTree::beginShadowPass(S32 pass)
 {
 	LLFastTimer t(FTM_SHADOW_TREE);
-	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
+	
 	glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"),
 					gSavedSettings.getF32("RenderDeferredTreeShadowBias"));
 
-	gDeferredShadowProgram.bind();
+	gDeferredShadowAlphaMaskProgram.bind();
+	gDeferredShadowAlphaMaskProgram.setAlphaRange(0.5f, 1.f);
 }
 
 void LLDrawPoolTree::renderShadow(S32 pass)
@@ -175,12 +180,9 @@ void LLDrawPoolTree::renderShadow(S32 pass)
 void LLDrawPoolTree::endShadowPass(S32 pass)
 {
 	LLFastTimer t(FTM_SHADOW_TREE);
-	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
-
+	
 	glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"),
 						gSavedSettings.getF32("RenderDeferredSpotShadowBias"));
-
-	//gDeferredShadowProgram.unbind();
 }
 
 
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index a219386b53..79a835fd14 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -233,8 +233,7 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const
 	{
 		LLGLEnable blend(GL_BLEND);
 		gGL.setSceneBlendType(LLRender::BT_ALPHA);
-		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
-
+		
 		gGL.getTexUnit(0)->bind(sCloudNoiseTexture);
 
 		cloud_shader->bind();
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 8fa4065fa6..26b2b0f5c3 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -5123,7 +5123,6 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 
 	gGL.getTexUnit(0)->bind(mSilhouetteImagep);
 	LLGLSPipelineSelection gls_select;
-	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
 	LLGLEnable blend(GL_BLEND);
 	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
 
@@ -5250,7 +5249,6 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 	}
 
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 }
 
 void LLSelectMgr::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point)
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index 252183b6d7..12f6a0dd1c 100644
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -120,8 +120,8 @@
 
 // Library includes from llvfs
 #include "lldir.h"
-
-// Library includes from llmessage project
+
+// Library includes from llmessage project
 #include "llcachename.h"
 
 #endif
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 62d83b516f..fa8d43e0b2 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -70,8 +70,12 @@ LLGLSLShader	gTwoTextureAddProgram;
 //object shaders
 LLGLSLShader		gObjectSimpleProgram;
 LLGLSLShader		gObjectSimpleWaterProgram;
+LLGLSLShader		gObjectSimpleAlphaMaskProgram;
+LLGLSLShader		gObjectSimpleWaterAlphaMaskProgram;
 LLGLSLShader		gObjectFullbrightProgram;
 LLGLSLShader		gObjectFullbrightWaterProgram;
+LLGLSLShader		gObjectFullbrightAlphaMaskProgram;
+LLGLSLShader		gObjectFullbrightWaterAlphaMaskProgram;
 LLGLSLShader		gObjectFullbrightShinyProgram;
 LLGLSLShader		gObjectFullbrightShinyWaterProgram;
 LLGLSLShader		gObjectShinyProgram;
@@ -80,6 +84,8 @@ LLGLSLShader		gObjectBumpProgram;
 
 LLGLSLShader		gObjectSimpleNonIndexedProgram;
 LLGLSLShader		gObjectSimpleNonIndexedWaterProgram;
+LLGLSLShader		gObjectAlphaMaskNonIndexedProgram;
+LLGLSLShader		gObjectAlphaMaskNonIndexedWaterProgram;
 LLGLSLShader		gObjectFullbrightNonIndexedProgram;
 LLGLSLShader		gObjectFullbrightNonIndexedWaterProgram;
 LLGLSLShader		gObjectFullbrightShinyNonIndexedProgram;
@@ -128,7 +134,9 @@ LLGLSLShader			gDeferredImpostorProgram;
 LLGLSLShader			gDeferredEdgeProgram;
 LLGLSLShader			gDeferredWaterProgram;
 LLGLSLShader			gDeferredDiffuseProgram;
+LLGLSLShader			gDeferredDiffuseAlphaMaskProgram;
 LLGLSLShader			gDeferredNonIndexedDiffuseProgram;
+LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskProgram;
 LLGLSLShader			gDeferredSkinnedDiffuseProgram;
 LLGLSLShader			gDeferredSkinnedBumpProgram;
 LLGLSLShader			gDeferredSkinnedAlphaProgram;
@@ -145,6 +153,7 @@ LLGLSLShader			gDeferredSunProgram;
 LLGLSLShader			gDeferredBlurLightProgram;
 LLGLSLShader			gDeferredSoftenProgram;
 LLGLSLShader			gDeferredShadowProgram;
+LLGLSLShader			gDeferredShadowAlphaMaskProgram;
 LLGLSLShader			gDeferredAvatarShadowProgram;
 LLGLSLShader			gDeferredAttachmentShadowProgram;
 LLGLSLShader			gDeferredAlphaProgram;
@@ -177,6 +186,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderList.push_back(&gWaterProgram);
 	mShaderList.push_back(&gAvatarEyeballProgram); 
 	mShaderList.push_back(&gObjectSimpleProgram);
+	mShaderList.push_back(&gObjectSimpleAlphaMaskProgram);
 	mShaderList.push_back(&gObjectBumpProgram);
 	mShaderList.push_back(&gUIProgram);
 	mShaderList.push_back(&gCustomAlphaProgram);
@@ -185,10 +195,13 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderList.push_back(&gSolidColorProgram);
 	mShaderList.push_back(&gOcclusionProgram);
 	mShaderList.push_back(&gObjectFullbrightProgram);
+	mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
 	mShaderList.push_back(&gObjectFullbrightShinyProgram);
 	mShaderList.push_back(&gObjectFullbrightShinyWaterProgram);
 	mShaderList.push_back(&gObjectSimpleNonIndexedProgram);
 	mShaderList.push_back(&gObjectSimpleNonIndexedWaterProgram);
+	mShaderList.push_back(&gObjectAlphaMaskNonIndexedProgram);
+	mShaderList.push_back(&gObjectAlphaMaskNonIndexedWaterProgram);
 	mShaderList.push_back(&gObjectFullbrightNonIndexedProgram);
 	mShaderList.push_back(&gObjectFullbrightNonIndexedWaterProgram);
 	mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram);
@@ -205,6 +218,8 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
 	mShaderList.push_back(&gTerrainWaterProgram);
 	mShaderList.push_back(&gObjectSimpleWaterProgram);
 	mShaderList.push_back(&gObjectFullbrightWaterProgram);
+	mShaderList.push_back(&gObjectSimpleWaterAlphaMaskProgram);
+	mShaderList.push_back(&gObjectFullbrightWaterAlphaMaskProgram);
 	mShaderList.push_back(&gAvatarWaterProgram);
 	mShaderList.push_back(&gObjectShinyWaterProgram);
 	mShaderList.push_back(&gObjectShinyNonIndexedWaterProgram);
@@ -623,10 +638,14 @@ void LLViewerShaderMgr::unloadShaders()
 	gSolidColorProgram.unload();
 
 	gObjectSimpleProgram.unload();
+	gObjectSimpleAlphaMaskProgram.unload();
 	gObjectBumpProgram.unload();
 	gObjectSimpleWaterProgram.unload();
+	gObjectSimpleWaterAlphaMaskProgram.unload();
 	gObjectFullbrightProgram.unload();
 	gObjectFullbrightWaterProgram.unload();
+	gObjectFullbrightAlphaMaskProgram.unload();
+	gObjectFullbrightWaterAlphaMaskProgram.unload();
 
 	gObjectShinyProgram.unload();
 	gObjectFullbrightShinyProgram.unload();
@@ -635,6 +654,8 @@ void LLViewerShaderMgr::unloadShaders()
 
 	gObjectSimpleNonIndexedProgram.unload();
 	gObjectSimpleNonIndexedWaterProgram.unload();
+	gObjectAlphaMaskNonIndexedProgram.unload();
+	gObjectAlphaMaskNonIndexedWaterProgram.unload();
 	gObjectFullbrightNonIndexedProgram.unload();
 	gObjectFullbrightNonIndexedWaterProgram.unload();
 
@@ -673,6 +694,8 @@ void LLViewerShaderMgr::unloadShaders()
 	gPostNightVisionProgram.unload();
 
 	gDeferredDiffuseProgram.unload();
+	gDeferredDiffuseAlphaMaskProgram.unload();
+	gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
 	gDeferredNonIndexedDiffuseProgram.unload();
 	gDeferredSkinnedDiffuseProgram.unload();
 	gDeferredSkinnedBumpProgram.unload();
@@ -766,17 +789,25 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/transportF.glsl",				mVertexShaderLevel[SHADER_WINDLIGHT] ) );	
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "environment/waterFogF.glsl",				mVertexShaderLevel[SHADER_WATER] ) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) );
+	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) );
+	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedAlphaMaskF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) );
+	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskNonIndexedF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) );
+	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(-1);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) );
+	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl",					mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) );
+	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightAlphaMaskF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightWaterF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) );
+	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) );
+	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightWaterAlphaMaskF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightShinyF.glsl",				mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl",	mVertexShaderLevel[SHADER_LIGHTING] ) );
 	index_channels.push_back(ch);	 shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl",			mVertexShaderLevel[SHADER_LIGHTING] ) );
@@ -1022,6 +1053,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 	{
 		gDeferredTreeProgram.unload();
 		gDeferredDiffuseProgram.unload();
+		gDeferredDiffuseAlphaMaskProgram.unload();
+		gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
 		gDeferredNonIndexedDiffuseProgram.unload();
 		gDeferredSkinnedDiffuseProgram.unload();
 		gDeferredSkinnedBumpProgram.unload();
@@ -1037,6 +1070,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredBlurLightProgram.unload();
 		gDeferredSoftenProgram.unload();
 		gDeferredShadowProgram.unload();
+		gDeferredShadowAlphaMaskProgram.unload();
 		gDeferredAvatarShadowProgram.unload();
 		gDeferredAttachmentShadowProgram.unload();
 		gDeferredAvatarProgram.unload();
@@ -1075,6 +1109,27 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		success = gDeferredDiffuseProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader";
+		gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear();
+		gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits;
+		gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+		success = gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
+		gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear();
+		gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+		success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader";
@@ -1399,6 +1454,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		success = gDeferredShadowProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
+		gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();
+		gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredShadowAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+		success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader";
@@ -1613,16 +1678,22 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		gObjectFullbrightShinyWaterProgram.unload();
 		gObjectShinyWaterProgram.unload();
 		gObjectSimpleProgram.unload();
+		gObjectSimpleAlphaMaskProgram.unload();
 		gObjectBumpProgram.unload();
 		gObjectSimpleWaterProgram.unload();
+		gObjectSimpleWaterAlphaMaskProgram.unload();
 		gObjectFullbrightProgram.unload();
+		gObjectFullbrightAlphaMaskProgram.unload();
 		gObjectFullbrightWaterProgram.unload();
+		gObjectFullbrightWaterAlphaMaskProgram.unload();
 		gObjectShinyNonIndexedProgram.unload();
 		gObjectFullbrightShinyNonIndexedProgram.unload();
 		gObjectFullbrightShinyNonIndexedWaterProgram.unload();
 		gObjectShinyNonIndexedWaterProgram.unload();
 		gObjectSimpleNonIndexedProgram.unload();
 		gObjectSimpleNonIndexedWaterProgram.unload();
+		gObjectAlphaMaskNonIndexedProgram.unload();
+		gObjectAlphaMaskNonIndexedWaterProgram.unload();
 		gObjectFullbrightNonIndexedProgram.unload();
 		gObjectFullbrightNonIndexedWaterProgram.unload();
 		gSkinnedObjectSimpleProgram.unload();
@@ -1670,6 +1741,41 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gObjectAlphaMaskNonIndexedProgram.mName = "Non indexed alpha mask Shader";
+		gObjectAlphaMaskNonIndexedProgram.mFeatures.calculatesLighting = true;
+		gObjectAlphaMaskNonIndexedProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectAlphaMaskNonIndexedProgram.mFeatures.hasGamma = true;
+		gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAtmospherics = true;
+		gObjectAlphaMaskNonIndexedProgram.mFeatures.hasLighting = true;
+		gObjectAlphaMaskNonIndexedProgram.mFeatures.disableTextureIndex = true;
+		gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAlphaMask = true;
+		gObjectAlphaMaskNonIndexedProgram.mShaderFiles.clear();
+		gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectAlphaMaskNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gObjectAlphaMaskNonIndexedProgram.createShader(NULL, NULL);
+	}
+	
+	if (success)
+	{
+		gObjectAlphaMaskNonIndexedWaterProgram.mName = "Non indexed alpha mask Water Shader";
+		gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.calculatesLighting = true;
+		gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasWaterFog = true;
+		gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAtmospherics = true;
+		gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasLighting = true;
+		gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
+		gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAlphaMask = true;
+		gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.clear();
+		gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectAlphaMaskNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		gObjectAlphaMaskNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+		success = gObjectAlphaMaskNonIndexedWaterProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gObjectFullbrightNonIndexedProgram.mName = "Non Indexed Fullbright Shader";
@@ -1783,6 +1889,23 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		gObjectSimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
 		success = gObjectSimpleProgram.createShader(NULL, NULL);
 	}
+
+	if (success)
+	{
+		gObjectSimpleAlphaMaskProgram.mName = "Simple Alpha Mask Shader";
+		gObjectSimpleAlphaMaskProgram.mFeatures.calculatesLighting = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.hasGamma = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.hasAtmospherics = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.hasLighting = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.hasAlphaMask = true;
+		gObjectSimpleAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
+		gObjectSimpleAlphaMaskProgram.mShaderFiles.clear();
+		gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectSimpleAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);
+	}
 	
 	if (success)
 	{
@@ -1817,6 +1940,24 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		success = gObjectSimpleWaterProgram.createShader(NULL, NULL);
 	}
 	
+	if (success)
+	{
+		gObjectSimpleWaterAlphaMaskProgram.mName = "Simple Water Alpha Mask Shader";
+		gObjectSimpleWaterAlphaMaskProgram.mFeatures.calculatesLighting = true;
+		gObjectSimpleWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasWaterFog = true;
+		gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasAtmospherics = true;
+		gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasLighting = true;
+		gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true;
+		gObjectSimpleWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
+		gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.clear();
+		gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+		success = gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gObjectFullbrightProgram.mName = "Fullbright Shader";
@@ -1848,6 +1989,39 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		success = gObjectFullbrightWaterProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gObjectFullbrightAlphaMaskProgram.mName = "Fullbright Alpha Mask Shader";
+		gObjectFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
+		gObjectFullbrightAlphaMaskProgram.mFeatures.hasTransport = true;
+		gObjectFullbrightAlphaMaskProgram.mFeatures.isFullbright = true;
+		gObjectFullbrightAlphaMaskProgram.mFeatures.hasAlphaMask = true;
+		gObjectFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
+		gObjectFullbrightAlphaMaskProgram.mShaderFiles.clear();
+		gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectFullbrightAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		success = gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+	}
+
+	if (success)
+	{
+		gObjectFullbrightWaterAlphaMaskProgram.mName = "Fullbright Water Shader";
+		gObjectFullbrightWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+		gObjectFullbrightWaterAlphaMaskProgram.mFeatures.isFullbright = true;
+		gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasWaterFog = true;		
+		gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasTransport = true;
+		gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true;
+		gObjectFullbrightWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
+		gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.clear();
+		gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
+		gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+		gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+		success = gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gObjectShinyProgram.mName = "Shiny Shader";
@@ -2092,6 +2266,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
 		gAvatarProgram.mFeatures.hasGamma = true;
 		gAvatarProgram.mFeatures.hasAtmospherics = true;
 		gAvatarProgram.mFeatures.hasLighting = true;
+		gAvatarProgram.mFeatures.hasAlphaMask = true;
 		gAvatarProgram.mFeatures.disableTextureIndex = true;
 		gAvatarProgram.mShaderFiles.clear();
 		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2108,6 +2283,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
 			gAvatarWaterProgram.mFeatures.hasWaterFog = true;
 			gAvatarWaterProgram.mFeatures.hasAtmospherics = true;
 			gAvatarWaterProgram.mFeatures.hasLighting = true;
+			gAvatarWaterProgram.mFeatures.hasAlphaMask = true;
 			gAvatarWaterProgram.mFeatures.disableTextureIndex = true;
 			gAvatarWaterProgram.mShaderFiles.clear();
 			gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2146,6 +2322,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
 		gAvatarEyeballProgram.mFeatures.hasGamma = true;
 		gAvatarEyeballProgram.mFeatures.hasAtmospherics = true;
 		gAvatarEyeballProgram.mFeatures.hasLighting = true;
+		gAvatarEyeballProgram.mFeatures.hasAlphaMask = true;
 		gAvatarEyeballProgram.mFeatures.disableTextureIndex = true;
 		gAvatarEyeballProgram.mShaderFiles.clear();
 		gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB));
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 93a0ecc4f0..629ef32adb 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -297,11 +297,17 @@ extern LLGLSLShader			gTwoTextureAddProgram;
 								
 //object shaders
 extern LLGLSLShader			gObjectSimpleProgram;
+extern LLGLSLShader			gObjectSimpleAlphaMaskProgram;
 extern LLGLSLShader			gObjectSimpleWaterProgram;
+extern LLGLSLShader			gObjectSimpleWaterAlphaMaskProgram;
 extern LLGLSLShader			gObjectSimpleNonIndexedProgram;
 extern LLGLSLShader			gObjectSimpleNonIndexedWaterProgram;
+extern LLGLSLShader			gObjectAlphaMaskNonIndexedProgram;
+extern LLGLSLShader			gObjectAlphaMaskNonIndexedWaterProgram;
 extern LLGLSLShader			gObjectFullbrightProgram;
 extern LLGLSLShader			gObjectFullbrightWaterProgram;
+extern LLGLSLShader			gObjectFullbrightAlphaMaskProgram;
+extern LLGLSLShader			gObjectFullbrightWaterAlphaMaskProgram;
 extern LLGLSLShader			gObjectFullbrightNonIndexedProgram;
 extern LLGLSLShader			gObjectFullbrightNonIndexedWaterProgram;
 extern LLGLSLShader			gObjectBumpProgram;
@@ -359,6 +365,8 @@ extern LLGLSLShader			gDeferredImpostorProgram;
 extern LLGLSLShader			gDeferredEdgeProgram;
 extern LLGLSLShader			gDeferredWaterProgram;
 extern LLGLSLShader			gDeferredDiffuseProgram;
+extern LLGLSLShader			gDeferredDiffuseAlphaMaskProgram;
+extern LLGLSLShader			gDeferredNonIndexedDiffuseAlphaMaskProgram;
 extern LLGLSLShader			gDeferredNonIndexedDiffuseProgram;
 extern LLGLSLShader			gDeferredSkinnedDiffuseProgram;
 extern LLGLSLShader			gDeferredSkinnedBumpProgram;
@@ -377,6 +385,7 @@ extern LLGLSLShader			gDeferredBlurLightProgram;
 extern LLGLSLShader			gDeferredAvatarProgram;
 extern LLGLSLShader			gDeferredSoftenProgram;
 extern LLGLSLShader			gDeferredShadowProgram;
+extern LLGLSLShader			gDeferredShadowAlphaMaskProgram;
 extern LLGLSLShader			gDeferredPostGIProgram;
 extern LLGLSLShader			gDeferredPostProgram;
 extern LLGLSLShader			gDeferredPostNoDoFProgram;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 3f98df9eb9..2a4a5d7c47 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -4219,7 +4219,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 		bool should_alpha_mask = shouldAlphaMask();
 		LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
 		
-		if (should_alpha_mask)
+		if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
 		{
 			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
 		}
@@ -4248,7 +4248,10 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 			}
 		}
 
-		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+		if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
+		{
+			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+		}
 
 		if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender)
 		{
@@ -4331,7 +4334,7 @@ U32 LLVOAvatar::renderRigid()
 	bool should_alpha_mask = shouldAlphaMask();
 	LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
 
-	if (should_alpha_mask)
+	if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
 	{
 		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
 	}
@@ -4342,7 +4345,10 @@ U32 LLVOAvatar::renderRigid()
 		num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
 	}
 
-	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+	if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
+	{
+		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+	}
 	
 	return num_indices;
 }
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index dfcc7396ba..c3a90a4c62 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -3669,6 +3669,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 				occlude = FALSE;
 				gGLLastMatrix = NULL;
 				glLoadMatrixd(gGLModelView);
+				LLGLSLShader::bindNoShader();
 				doOcclusion(camera);
 			}
 
@@ -3734,6 +3735,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 			occlude = FALSE;
 			gGLLastMatrix = NULL;
 			glLoadMatrixd(gGLModelView);
+			LLGLSLShader::bindNoShader();
 			doOcclusion(camera);
 		}
 	}
@@ -3931,6 +3933,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 			occlude = FALSE;
 			gGLLastMatrix = NULL;
 			glLoadMatrixd(gGLModelView);
+			LLGLSLShader::bindNoShader();
 			doOcclusion(camera);
 			gGL.setColorMask(true, false);
 		}
@@ -3996,6 +3999,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 		occlude = FALSE;
 		gGLLastMatrix = NULL;
 		glLoadMatrixd(gGLModelView);
+		LLGLSLShader::bindNoShader();
 		doOcclusion(camera);
 		gGLLastMatrix = NULL;
 		glLoadMatrixd(gGLModelView);
@@ -6236,7 +6240,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 		gGlowExtractProgram.uniform1f("warmthAmount", warmthAmount);
 		LLGLEnable blend_on(GL_BLEND);
 		LLGLEnable test(GL_ALPHA_TEST);
-		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+		
 		gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
 		
 		mScreen.bindTexture(0, 0);
@@ -8306,7 +8310,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 			gOcclusionProgram.bind();
 		}
 		LLFastTimer ftm(FTM_SHADOW_SIMPLE);
-		LLGLDisable test(GL_ALPHA_TEST);
 		gGL.getTexUnit(0)->disable();
 		for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i)
 		{
@@ -8332,12 +8335,11 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 
 	{
 		LLFastTimer ftm(FTM_SHADOW_ALPHA);
-		LLGLEnable test(GL_ALPHA_TEST);
-		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f);
+		gDeferredShadowAlphaMaskProgram.bind();
+		gDeferredShadowAlphaMaskProgram.setAlphaRange(0.6f, 1.f);
 		renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE);
 		glColor4f(1,1,1,1);
 		renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
-		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 	}
 
 	//glCullFace(GL_BACK);
@@ -8822,6 +8824,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 					LLPipeline::RENDER_TYPE_WATER,
 					LLPipeline::RENDER_TYPE_VOIDWATER,
 					LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW,
+					LLPipeline::RENDER_TYPE_PASS_GRASS,
 					LLPipeline::RENDER_TYPE_PASS_SIMPLE,
 					LLPipeline::RENDER_TYPE_PASS_BUMP,
 					LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
-- 
cgit v1.2.3