diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index 38afd82c8d6f35661805684947010bd219573b07..02b2daf0ac547622b27a56aa97e6c2f98328e1f9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -56,7 +56,7 @@ VARYING vec3 vary_norm;
 VARYING vec4 vertex_color; //vertex color should be treated as sRGB
 #endif
 
-#ifdef FOR_IMPOSTOR
+#ifdef HAS_ALPHA_MASK
 uniform float minimum_alpha;
 #endif
 
@@ -195,7 +195,6 @@ void main()
 #endif
 
     vec4 diffuse_srgb = diffuse_tap;
-    vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_srgb.a);
 
 #ifdef FOR_IMPOSTOR
     vec4 color;
@@ -204,33 +203,37 @@ void main()
 
     float final_alpha = diffuse_srgb.a * vertex_color.a;
     diffuse_srgb.rgb *= vertex_color.rgb;
-    diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb); 
     
     // Insure we don't pollute depth with invis pixels in impostor rendering
     //
-    if (final_alpha <  minimum_alpha)
+    if (final_alpha < minimum_alpha)
     {
         discard;
     }
 
     color.rgb = diffuse_srgb.rgb;
     color.a = final_alpha;
-#else
-    
+
+#else // FOR_IMPOSTOR
+
+    vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_srgb.a);
+
     vec3 light_dir = (sun_up_factor == 1) ? sun_dir: moon_dir;
 
     float final_alpha = diffuse_linear.a;
 
 #ifdef USE_VERTEX_COLOR
-    if (vertex_color.a <= 0.0)
+    final_alpha *= vertex_color.a;
+
+    if (final_alpha < minimum_alpha)
     { // TODO: figure out how to get invisible faces out of 
         // render batches without breaking glow
         discard;
     }
-    final_alpha *= vertex_color.a;
+
     diffuse_srgb.rgb *= vertex_color.rgb;
     diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb);
-#endif
+#endif // USE_VERTEX_COLOR
 
     vec3 sunlit;
     vec3 amblit;
@@ -262,13 +265,13 @@ void main()
 #if !defined(AMBIENT_KILL)
     color.rgb = amblit;
     color.rgb *= ambient;
-#endif
+#endif // !defined(AMBIENT_KILL)
 
 vec3 post_ambient = color.rgb;
 
 #if !defined(SUNLIGHT_KILL)
     color.rgb += sun_contrib;
-#endif
+#endif // !defined(SUNLIGHT_KILL)
 
 vec3 post_sunlight = color.rgb;
 
@@ -300,7 +303,7 @@ vec3 post_atmo = color.rgb;
     // sum local light contrib in linear colorspace
 #if !defined(LOCAL_LIGHT_KILL)
     color.rgb += light.rgb;
-#endif
+#endif // !defined(LOCAL_LIGHT_KILL)
     // back to sRGB as we're going directly to the final RT post-deferred gamma correction
     color.rgb = linear_to_srgb(color.rgb);
 
@@ -319,7 +322,7 @@ vec3 post_atmo = color.rgb;
     color = applyWaterFogView(pos.xyz, color);
 #endif // WATER_FOG
 
-#endif
+#endif // #else // FOR_IMPOSTOR
 
     frag_color = color;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index eb6e56e718cf3da79584bcc5792b972e25f2e2e8..a58cc3d12df4213d1d65976df3811a4f7c8bb1d6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -54,8 +54,7 @@ void main()
 	vec4 norm = texture2D(normalMap,   vary_texcoord0.xy);
 	vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
 
-	col.rgb = linear_to_srgb(col.rgb);
 	frag_data[0] = vec4(col.rgb, 0.0);
 	frag_data[1] = spec;
-	frag_data[2] = vec4(norm.xy,0,0);
+	frag_data[2] = norm;
 }
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index a2b263f34ec343e8cac1141a22d0a41f1e024e01..eebd89f77fd39eadd5386c34aff34e74cf20c97a 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -56,6 +56,11 @@ BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
 
 static BOOL deferred_render = FALSE;
 
+// minimum alpha before discarding a fragment
+static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255
+// minimum alpha before discarding a fragment when rendering impostors
+static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f;
+
 LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
 		LLRenderPass(type), target_shader(NULL),
 		mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF),
@@ -106,11 +111,11 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
 
     if (LLPipeline::sImpostorRender)
     {
-        shader->setMinimumAlpha(0.1f);
+        shader->setMinimumAlpha(MINIMUM_IMPOSTOR_ALPHA);
     }
     else
     {
-        shader->setMinimumAlpha(0.f);
+        shader->setMinimumAlpha(MINIMUM_ALPHA);
     }
     if (textureGamma)
     {
@@ -135,7 +140,7 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
     prepare_alpha_shader(emissive_shader, true, false);
 
     fullbright_shader   = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
-        (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram;
+        (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightAlphaMaskProgram;
     prepare_alpha_shader(fullbright_shader, true, false);
 
     simple_shader   = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
@@ -197,18 +202,18 @@ void LLDrawPoolAlpha::render(S32 pass)
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
 
     simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram :
-        (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram;
+        (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleAlphaMaskProgram;
 
-    fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightProgram :
-        (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram;
+    fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightAlphaMaskProgram :
+        (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightAlphaMaskProgram;
 
     emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram :
         (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
 
-    F32 minimum_alpha = 0.f;
+    F32 minimum_alpha = MINIMUM_ALPHA;
     if (LLPipeline::sImpostorRender)
     {
-        minimum_alpha = 0.1f;
+        minimum_alpha = MINIMUM_IMPOSTOR_ALPHA;
     }
     prepare_forward_shader(fullbright_shader, minimum_alpha);
     prepare_forward_shader(simple_shader, minimum_alpha);
@@ -589,7 +594,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 						const LLTextureEntry* tep = face->getTextureEntry();
 						if(tep)
 						{ // don't render faces that are more than 90% transparent
-							if(tep->getColor().mV[3] < 0.1f)
+							if(tep->getColor().mV[3] < MINIMUM_IMPOSTOR_ALPHA)
 								continue;
 						}
 					}
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index a8e0f576ca382c6a4f6c35e3c077e438705165e7..1cb2c6b9eee1b88c7b83ab47b1a67329d2c88a25 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -1876,6 +1876,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 
             shader->clearPermutations();
             shader->addPermutation("USE_VERTEX_COLOR", "1");
+            shader->addPermutation("HAS_ALPHA_MASK", "1");
             shader->addPermutation("USE_INDEXED_TEX", "1");
             if (use_sun_shadow)
             {
@@ -1952,6 +1953,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
             shader->clearPermutations();
             shader->addPermutation("USE_INDEXED_TEX", "1");
             shader->addPermutation("FOR_IMPOSTOR", "1");
+            shader->addPermutation("HAS_ALPHA_MASK", "1");
             shader->addPermutation("USE_VERTEX_COLOR", "1");
             if (rigged)
             {
@@ -2023,6 +2025,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
             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_SHADOW", "1");
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ccf5b69ea0a9764e03302d0f4b806594685ee26b..20d6fe39e365107eb34e3439892d50fd278236e4 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -361,10 +361,12 @@ static LLCullResult* sCull = NULL;
 
 void validate_framebuffer_object();
 
-
-bool addDeferredAttachments(LLRenderTarget& target)
+// Add color attachments for deferred rendering
+// target -- RenderTarget to add attachments to
+// for_impostor -- whether or not these render targets are for an impostor (if true, avoids implicit sRGB conversions)
+bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false)
 {
-	return target.addColorAttachment(GL_SRGB8_ALPHA8) && //specular
+	return target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) && //specular
 			target.addColorAttachment(GL_RGB10_A2); //normal+z
 }
 
@@ -10974,14 +10976,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
 
 		if (!avatar->mImpostor.isComplete())
 		{
+            avatar->mImpostor.allocate(resX, resY, GL_RGBA, TRUE, FALSE);
+
 			if (LLPipeline::sRenderDeferred)
 			{
-				avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE);
-				addDeferredAttachments(avatar->mImpostor);
-			}
-			else
-			{
-				avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+				addDeferredAttachments(avatar->mImpostor, true);
 			}
 		
 			gGL.getTexUnit(0)->bind(&avatar->mImpostor);