diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 9b298b120a87468a878bbdac8df3ccef69571a8f..cecdefd7e838ebb7d7219785af5478d8206ecc44 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -80,213 +80,162 @@ void LLDrawPoolAlpha::prerender()
 
 S32 LLDrawPoolAlpha::getNumPostDeferredPasses() 
 { 
-	if (LLPipeline::sImpostorRender)
-	{ //skip depth buffer filling pass when rendering impostors
-		return 1;
-	}
-	else if (gSavedSettings.getBOOL("RenderDepthOfField"))
-	{
-		return 2; 
-	}
-	else
-	{
-		return 1;
-	}
+    return 1;
 }
 
-void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) 
-{ 
-    LL_PROFILE_ZONE_SCOPED;
-
-    F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+// set some common parameters on the given shader to prepare for alpha rendering
+static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma)
+{
+    static LLCachedControl<F32> displayGamma(gSavedSettings, "RenderDeferredDisplayGamma");
+    F32 gamma = displayGamma;
 
-    emissive_shader[0] = (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
-    emissive_shader[1] = emissive_shader[0]->mRiggedVariant;
+    shader->bind();
+    shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
+    shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
 
-    for (int i = 0; i < 2; ++i)
+    if (LLPipeline::sImpostorRender)
     {
-        emissive_shader[i]->bind();
-        emissive_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
-        emissive_shader[i]->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-        emissive_shader[i]->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+        shader->setMinimumAlpha(0.5f);
+    }
+    else
+    {
+        shader->setMinimumAlpha(0.f);
+    }
+    if (textureGamma)
+    {
+        shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
     }
 
-	if (pass == 0)
-	{
-        fullbright_shader[0] = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram :
-                (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram;
-        fullbright_shader[1] = fullbright_shader[0]->mRiggedVariant;
- 
-        for (int i = 0; i < 2; ++i)
-        {
-            fullbright_shader[i]->bind();
-            fullbright_shader[i]->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-            fullbright_shader[i]->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
-            fullbright_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
-            fullbright_shader[i]->unbind();
-        }
-
-        simple_shader[0] = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
-                (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
-        simple_shader[1] = simple_shader[0]->mRiggedVariant;
-
-		//prime simple shader (loads shadow relevant uniforms)
-        for (int i = 0; i < 2; ++i)
-        {
-            gPipeline.bindDeferredShader(*simple_shader[i]);
-            simple_shader[i]->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
-            simple_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
-        }
-	}
-	else if (!LLPipeline::sImpostorRender)
-	{
-		//update depth buffer sampler
-		gPipeline.mScreen.flush();
-		gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
-							0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	
-		gPipeline.mDeferredDepth.bindTarget();
-		simple_shader[0] = fullbright_shader[0] = &gObjectFullbrightAlphaMaskProgram;
-        simple_shader[1] = fullbright_shader[1] = simple_shader[0]->mRiggedVariant;
-        
-        for (int i = 0; i < 2; ++i)
-        {
-            simple_shader[i]->bind();
-            simple_shader[i]->setMinimumAlpha(0.33f);
-        }
-	}
-
-	deferred_render = TRUE;
-	if (mShaderLevel > 0)
-	{
-		// Start out with no shaders.
-		target_shader = NULL;
-	}
-	gPipeline.enableLightsDynamic();
+    //also prepare rigged variant
+    if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
+    { 
+        prepare_alpha_shader(shader->mRiggedVariant, textureGamma);
+    }
 }
 
-void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) 
+void LLDrawPoolAlpha::renderPostDeferred(S32 pass) 
 { 
     LL_PROFILE_ZONE_SCOPED;
+    deferred_render = TRUE;
 
-	if (pass == 1 && !LLPipeline::sImpostorRender)
-	{
-		gPipeline.mDeferredDepth.flush();
-		gPipeline.mScreen.bindTarget();
-		LLGLSLShader::sCurBoundShaderPtr->unbind();
-	}
+    // first pass, regular forward alpha rendering
+    {
+        emissive_shader = (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+        prepare_alpha_shader(emissive_shader, true);
 
-	deferred_render = FALSE;
-	endRenderPass(pass);
+        fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram :
+            (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram;
+        prepare_alpha_shader(fullbright_shader, true);
+
+        simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
+            (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
+        prepare_alpha_shader(simple_shader, false);
+        
+        forwardRender();
+    }
+
+    // second pass, render to depth for depth of field effects
+    if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField"))
+    { 
+        //update depth buffer sampler
+        gPipeline.mScreen.flush();
+        gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
+            0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+        gPipeline.mDeferredDepth.bindTarget();
+        simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
+
+        simple_shader->bind();
+        simple_shader->setMinimumAlpha(0.33f);
+
+        // mask off color buffer writes as we're only writing to depth buffer
+        gGL.setColorMask(false, false);
+
+        // If the face is more than 90% transparent, then don't update the Depth buffer for Dof
+        // We don't want the nearly invisible objects to cause of DoF effects
+        renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, 
+            true); // <--- discard mostly transparent faces
+
+        gPipeline.mDeferredDepth.flush();
+        gPipeline.mScreen.bindTarget();
+        gGL.setColorMask(true, false);
+    }
+
+    renderDebugAlpha();
+
+    deferred_render = FALSE;
 }
 
-void LLDrawPoolAlpha::renderPostDeferred(S32 pass) 
-{ 
-    LL_PROFILE_ZONE_SCOPED;
-	render(pass); 
+//set some generic parameters for forward (non-deferred) rendering
+static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha)
+{
+    shader->bind();
+    shader->setMinimumAlpha(minimum_alpha);
+    shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+
+    //also prepare rigged variant
+    if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
+    {
+        prepare_forward_shader(shader->mRiggedVariant, minimum_alpha);
+    }
 }
 
-void LLDrawPoolAlpha::beginRenderPass(S32 pass)
+void LLDrawPoolAlpha::render(S32 pass)
 {
-    LL_PROFILE_ZONE_SCOPED;
-	
-    simple_shader[0]     = (LLPipeline::sImpostorRender)   ? &gObjectSimpleImpostorProgram  :
-                        (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram     : &gObjectSimpleProgram;
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
 
-    fullbright_shader[0] = (LLPipeline::sImpostorRender)   ? &gObjectFullbrightProgram      :
-                        (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram;
+    simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram :
+        (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram;
 
-    emissive_shader[0]   = (LLPipeline::sImpostorRender)   ? &gObjectEmissiveProgram        :
-                        (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram   : &gObjectEmissiveProgram;
+    fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightProgram :
+        (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram;
 
-    simple_shader[1] = simple_shader[0]->mRiggedVariant;
-    fullbright_shader[1] = fullbright_shader[0]->mRiggedVariant;
-    emissive_shader[1] = emissive_shader[0]->mRiggedVariant;
+    emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram :
+        (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
 
+    F32 minimum_alpha = 0.f;
     if (LLPipeline::sImpostorRender)
-	{
-        for (int i = 0; i < 2; ++i)
-        {
-            fullbright_shader[i]->bind();
-            fullbright_shader[i]->setMinimumAlpha(0.5f);
-            fullbright_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
-            simple_shader[i]->bind();
-            simple_shader[i]->setMinimumAlpha(0.5f);
-            simple_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
-        }
-	}
-    else
-	{
-        for (int i = 0; i < 2; ++i)
-        {
-            fullbright_shader[i]->bind();
-            fullbright_shader[i]->setMinimumAlpha(0.f);
-            fullbright_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
-            simple_shader[i]->bind();
-            simple_shader[i]->setMinimumAlpha(0.f);
-            simple_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
-        }
+    {
+        minimum_alpha = 0.5f;
     }
-	gPipeline.enableLightsDynamic();
+    prepare_forward_shader(fullbright_shader, minimum_alpha);
+    prepare_forward_shader(simple_shader, minimum_alpha);
 
-    LLGLSLShader::bindNoShader();
-}
-
-void LLDrawPoolAlpha::endRenderPass( S32 pass )
-{
-    LL_PROFILE_ZONE_SCOPED;
-	LLRenderPass::endRenderPass(pass);
+    forwardRender();
 
-	if(gPipeline.canUseWindLightShaders()) 
-	{
-		LLGLSLShader::bindNoShader();
-	}
+    renderDebugAlpha();
 }
 
-void LLDrawPoolAlpha::render(S32 pass)
+void LLDrawPoolAlpha::forwardRender()
 {
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
+    gPipeline.enableLightsDynamic();
 
-	LLGLSPipelineAlpha gls_pipeline_alpha;
+    LLGLSPipelineAlpha gls_pipeline_alpha;
 
-	if (deferred_render && pass == 1)
-	{ //depth only
-		gGL.setColorMask(false, false);
-	}
-	else
-	{
-		gGL.setColorMask(true, true);
-	}
-	
-	bool write_depth = LLDrawPoolWater::sSkipScreenCopy
-						 || (deferred_render && pass == 1)
-						 // we want depth written so that rendered alpha will
-						 // contribute to the alpha mask used for impostors
-						 || LLPipeline::sImpostorRenderAlphaDepthPass;
+    //enable writing to alpha for emissive effects
+    gGL.setColorMask(true, true);
 
-	LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
+    bool write_depth = LLDrawPoolWater::sSkipScreenCopy
+        // we want depth written so that rendered alpha will
+        // contribute to the alpha mask used for impostors
+        || LLPipeline::sImpostorRenderAlphaDepthPass;
 
-	if (deferred_render && pass == 1)
-	{
-		gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
-	}
-	else
-	{
-		mColorSFactor = LLRender::BF_SOURCE_ALPHA;           // } regular alpha blend
-		mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
-		mAlphaSFactor = LLRender::BF_ZERO;                         // } glow suppression
-		mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;       // }
-		gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-	}
+    LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
 
-	renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
+    mColorSFactor = LLRender::BF_SOURCE_ALPHA;           // } regular alpha blend
+    mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
+    mAlphaSFactor = LLRender::BF_ZERO;                         // } glow suppression
+    mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;       // }
+    gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
 
-	gGL.setColorMask(true, false);
+    // If the face is more than 90% transparent, then don't update the Depth buffer for Dof
+    // We don't want the nearly invisible objects to cause of DoF effects
+    renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);
 
-	if (deferred_render && pass == 1)
-	{
-		gGL.setSceneBlendType(LLRender::BT_ALPHA);
-	}
+    gGL.setColorMask(true, false);
+}
 
+void LLDrawPoolAlpha::renderDebugAlpha()
+{
 	if (sShowDebugAlpha)
 	{
 		gHighlightProgram.bind();
@@ -403,7 +352,7 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material)
 			current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
 		} 
     }
-    else if (current_shader == simple_shader[0] || current_shader == simple_shader[1])
+    else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant)
     {
         current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
 	    current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
@@ -470,14 +419,8 @@ void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)
 
 void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
 {
-    emissive_shader[0]->bind();
-    emissive_shader[0]->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
-
-    gPipeline.enableLightsDynamic();
-
-    // install glow-accumulating blend mode
-    // don't touch color, add to alpha (glow)
-    gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);
+    emissive_shader->bind();
+    emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
 
     for (LLDrawInfo* draw : emissives)
     {
@@ -485,24 +428,13 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi
         drawEmissive(mask, draw);
         RestoreTexSetup(tex_setup);
     }
-
-    // restore our alpha blend mode
-    gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
-    emissive_shader[0]->unbind();
 }
 
 void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
 {
-    emissive_shader[1]->bind();
-    emissive_shader[1]->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
-
-    gPipeline.enableLightsDynamic();
-
-    mask |= LLVertexBuffer::MAP_WEIGHT4;
-    // install glow-accumulating blend mode
-    // don't touch color, add to alpha (glow)
-    gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);
+    LLGLSLShader* shader = emissive_shader->mRiggedVariant;
+    shader->bind();
+    shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
 
     LLVOAvatar* lastAvatar = nullptr;
     U64 lastMeshId = 0;
@@ -522,14 +454,9 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&
         drawEmissive(mask, draw);
         RestoreTexSetup(tex_setup);
     }
-
-    // restore our alpha blend mode
-    gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
-    emissive_shader[1]->unbind();
 }
 
-void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
+void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only)
 {
     LL_PROFILE_ZONE_SCOPED;
     BOOL initialized_lighting = FALSE;
@@ -577,17 +504,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
 					continue;
 				}
 
-				// Fix for bug - NORSPEC-271
-				// If the face is more than 90% transparent, then don't update the Depth buffer for Dof
-				// We don't want the nearly invisible objects to cause of DoF effects
-				if(pass == 1 && !LLPipeline::sImpostorRender)
+				if(depth_only)
 				{
+                    // when updating depth buffer, discard faces that are more than 90% transparent
 					LLFace*	face = params.mFace;
 					if(face)
 					{
 						const LLTextureEntry* tep = face->getTextureEntry();
 						if(tep)
-						{
+						{ // don't render faces that are more than 90% transparent
 							if(tep->getColor().mV[3] < 0.1f)
 								continue;
 						}
@@ -609,7 +534,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
 					if (light_enabled || !initialized_lighting)
 					{
 						initialized_lighting = TRUE;
-						target_shader = fullbright_shader[0];
+						target_shader = fullbright_shader;
 
 						light_enabled = FALSE;
 					}
@@ -618,7 +543,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
 				else if (!light_enabled || !initialized_lighting)
 				{
 					initialized_lighting = TRUE;
-					target_shader = simple_shader[0];
+					target_shader = simple_shader;
 					light_enabled = TRUE;
 				}
 
@@ -647,11 +572,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
 				}
 				else if (!params.mFullbright)
 				{
-					target_shader = simple_shader[0];
+					target_shader = simple_shader;
 				}
 				else
 				{
-					target_shader = fullbright_shader[0];
+					target_shader = fullbright_shader;
 				}
 				
                 if (params.mAvatar != nullptr)
@@ -748,7 +673,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
 				}
 			}
 
+            // render emissive faces into alpha channel for bloom effects
+            if (!depth_only)
             {
+                gPipeline.enableLightsDynamic();
+
+                // install glow-accumulating blend mode
+                // don't touch color, add to alpha (glow)
+                gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);
+
                 bool rebind = false;
                 LLGLSLShader* lastShader = current_shader;
                 if (!emissives.empty())
@@ -765,6 +698,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
                     rebind = true;
                 }
 
+                // restore our alpha blend mode
+                gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+
                 if (lastShader && rebind)
                 {
                     lastShader->bind();
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index 64c17c3fefb86d8dd664209255a0637ff89393cd..1f6909e28221481c008bce33a664aa296446267a 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -51,19 +51,17 @@ class LLDrawPoolAlpha: public LLRenderPass
 	/*virtual*/ ~LLDrawPoolAlpha();
 
 	/*virtual*/ S32 getNumPostDeferredPasses();
-	/*virtual*/ void beginPostDeferredPass(S32 pass);
-	/*virtual*/ void endPostDeferredPass(S32 pass);
 	/*virtual*/ void renderPostDeferred(S32 pass);
-
-	/*virtual*/ void beginRenderPass(S32 pass = 0);
-	/*virtual*/ void endRenderPass( S32 pass );
 	/*virtual*/ S32	 getNumPasses() { return 1; }
 
 	virtual void render(S32 pass = 0);
+    void forwardRender();
 	/*virtual*/ void prerender();
 
+    void renderDebugAlpha();
+
 	void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
-	void renderAlpha(U32 mask, S32 pass);
+	void renderAlpha(U32 mask, bool depth_only = false);
 	void renderAlphaHighlight(U32 mask);
     bool uploadMatrixPalette(const LLDrawInfo& params);
 
@@ -73,9 +71,9 @@ class LLDrawPoolAlpha: public LLRenderPass
 	LLGLSLShader* target_shader;
 
     // setup by beginFooPass, [0] is static variant, [1] is rigged variant
-    LLGLSLShader* simple_shader[2] = { nullptr };
-	LLGLSLShader* fullbright_shader[2] = { nullptr };
-	LLGLSLShader* emissive_shader[2] = { nullptr };
+    LLGLSLShader* simple_shader = nullptr;
+    LLGLSLShader* fullbright_shader = nullptr;
+    LLGLSLShader* emissive_shader = nullptr;
 
     void drawEmissive(U32 mask, LLDrawInfo* draw);
     void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index dc52fc76803dd8ecad0d002292a30a0b40d5c7f7..b01450bba92cf8ce9128779e93eee1784146a8e3 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -200,21 +200,7 @@ void LLDrawPoolBump::prerender()
 // static
 S32 LLDrawPoolBump::numBumpPasses()
 {
-	if (gSavedSettings.getBOOL("RenderObjectBump"))
-	{
-		if (mShaderLevel > 1)
-		{
-			return 6;
-		}
-		else
-		{
-			return 4;
-		}
-	}
-    else
-	{
-		return 0;
-	}
+    return 1;
 }
 
 S32 LLDrawPoolBump::getNumPasses()
@@ -222,108 +208,49 @@ S32 LLDrawPoolBump::getNumPasses()
 	return numBumpPasses();
 }
 
-void LLDrawPoolBump::beginRenderPass(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
-    mRigged = ((pass % 2) == 1);
-    pass /= 2;
-	switch( pass )
-	{
-		case 0:
-			beginShiny();
-			break;
-		case 1:
-			if (mShaderLevel > 1)
-			{
-				beginFullbrightShiny();
-			}
-			else 
-			{
-				beginBump();
-			}
-			break;
-		case 2:
-			beginBump();
-			break;
-		default:
-			llassert(0);
-			break;
-	}
-}
-
 void LLDrawPoolBump::render(S32 pass)
 {
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
-	
-	if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE))
-	{
-		return;
-	}
-    pass /= 2;
-	switch( pass )
-	{
-		case 0:
-			renderShiny();
-			break;
-		case 1:
-			if (mShaderLevel > 1)
-			{
-				renderFullbrightShiny();
-			}
-			else 
-			{
-				renderBump(); 
-			}
-			break;
-		case 2:
-			renderBump();
-			break;
-		default:
-			llassert(0);
-			break;
-	}
-}
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
 
-void LLDrawPoolBump::endRenderPass(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
-    pass /= 2;
-	switch( pass )
-	{
-		case 0:
-			endShiny();
-			break;
-		case 1:
-			if (mShaderLevel > 1)
-			{
-				endFullbrightShiny();
-			}
-			else 
-			{
-				endBump();
-			}
-			break;
-		case 2:
-			endBump();
-			break;
-		default:
-			llassert(0);
-			break;
-	}
+    if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE))
+    {
+        return;
+    }
+
+    for (int i = 0; i < 2; ++i)
+    {
+        mRigged = i == 1;
+
+        // first pass -- shiny
+        beginShiny();
+        renderShiny();
+        endShiny();
+
+        //second pass -- fullbright shiny
+        if (mShaderLevel > 1)
+        {
+            beginFullbrightShiny();
+            renderFullbrightShiny();
+            endFullbrightShiny();
+        }
 
-	//to cleanup texture channels
-	LLRenderPass::endRenderPass(pass);
+        //third pass -- bump
+        beginBump();
+        renderBump(LLRenderPass::PASS_BUMP);
+        endBump();
+    }
 }
 
+
 //static
-void LLDrawPoolBump::beginShiny(bool invisible)
+void LLDrawPoolBump::beginShiny()
 {
 	LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
 	
 	mShiny = TRUE;
 	sVertexMask = VERTEX_MASK_SHINY;
 	// Second pass: environment map
-	if (!invisible && mShaderLevel > 1)
+	if (mShaderLevel > 1)
 	{
 		sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
 	}
@@ -353,7 +280,7 @@ void LLDrawPoolBump::beginShiny(bool invisible)
         shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
     }
 
-	bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);
+	bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel);
 
 	if (mShaderLevel > 1)
 	{ //indexed texture rendering, channel 0 is always diffuse
@@ -362,12 +289,12 @@ void LLDrawPoolBump::beginShiny(bool invisible)
 }
 
 //static
-void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible)
+void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel)
 {
 	LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
 	if( cube_map )
 	{
-		if (!invisible && shader )
+		if (shader )
 		{
 			LLMatrix4 mat;
 			mat.initRows(LLVector4(gGLModelView+0),
@@ -405,14 +332,14 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di
 	}
 }
 
-void LLDrawPoolBump::renderShiny(bool invisible)
+void LLDrawPoolBump::renderShiny()
 {
 	LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
 	
 	if( gSky.mVOSkyp->getCubeMap() )
 	{
 		LLGLEnable blend_enable(GL_BLEND);
-		if (!invisible && mShaderLevel > 1)
+		if (mShaderLevel > 1)
 		{
             if (mRigged)
             {
@@ -423,7 +350,7 @@ void LLDrawPoolBump::renderShiny(bool invisible)
                 LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
             }
 		}
-		else if (!invisible)
+		else
 		{
             if (mRigged)
             {
@@ -438,12 +365,12 @@ void LLDrawPoolBump::renderShiny(bool invisible)
 }
 
 //static
-void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible)
+void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel)
 {
 	LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
 	if( cube_map )
 	{
-		if (!invisible && shader_level > 1)
+		if (shader_level > 1)
 		{
 			shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
 					
@@ -461,11 +388,11 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
 	}
 }
 
-void LLDrawPoolBump::endShiny(bool invisible)
+void LLDrawPoolBump::endShiny()
 {
 	LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
 
-	unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);
+	unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel);
 	if (shader)
 	{
 		shader->unbind();
@@ -737,7 +664,7 @@ S32 LLDrawPoolBump::getNumDeferredPasses()
 { 
 	if (gSavedSettings.getBOOL("RenderObjectBump"))
 	{
-		return 2;
+		return 1;
 	}
 	else
 	{
@@ -745,122 +672,81 @@ S32 LLDrawPoolBump::getNumDeferredPasses()
 	}
 }
 
-void LLDrawPoolBump::beginDeferredPass(S32 pass)
-{
-	if (!gPipeline.hasRenderBatches( pass == 0 ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_BUMP_RIGGED))
-	{
-		return;
-	}
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
-	mShiny = TRUE;
-	gDeferredBumpProgram.bind(pass == 1);
-	diffuse_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-	bump_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::BUMP_MAP);
-	gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
-	gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE);
-}
-
-void LLDrawPoolBump::endDeferredPass(S32 pass)
-{
-	if (!gPipeline.hasRenderBatches(pass == 0 ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_BUMP_RIGGED))
-	{
-		return;
-	}
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
-	mShiny = FALSE;
-    LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-    LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::BUMP_MAP);
-    LLGLSLShader::sCurBoundShaderPtr->unbind();
-	gGL.getTexUnit(0)->activate();
-}
-
 void LLDrawPoolBump::renderDeferred(S32 pass)
 {
-    if (!gPipeline.hasRenderBatches(pass == 0 ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_BUMP_RIGGED))
-	{
-		return;
-	}
 	LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
 
-    bool rigged = pass == 1;
-    U32 type = rigged ? LLRenderPass::PASS_BUMP_RIGGED : LLRenderPass::PASS_BUMP;
-    LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
-    LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
+    mShiny = TRUE;
+    for (int i = 0; i < 2; ++i)
+    {
+        bool rigged = i == 1;
+        gDeferredBumpProgram.bind(rigged);
+        diffuse_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+        bump_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+        gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
+        gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE);
 
-    U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
+        U32 type = rigged ? LLRenderPass::PASS_BUMP_RIGGED : LLRenderPass::PASS_BUMP;
+        LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+        LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
 
-    LLVOAvatar* avatar = nullptr;
-    U64 skin = 0;
-
-    for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
-    {
-        LLDrawInfo& params = **i;
+        U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
 
-        LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
-        LLDrawPoolBump::bindBumpMap(params, bump_channel);
+        LLVOAvatar* avatar = nullptr;
+        U64 skin = 0;
 
-        if (rigged)
+        for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
         {
-            if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash)
+            LLDrawInfo& params = **i;
+
+            LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
+            LLDrawPoolBump::bindBumpMap(params, bump_channel);
+
+            if (rigged)
             {
-                uploadMatrixPalette(params);
-                avatar = params.mAvatar;
-                skin = params.mSkinInfo->mHash;
+                if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash)
+                {
+                    uploadMatrixPalette(params);
+                    avatar = params.mAvatar;
+                    skin = params.mSkinInfo->mHash;
+                }
+                pushBatch(params, mask | LLVertexBuffer::MAP_WEIGHT4, TRUE, FALSE);
+            }
+            else
+            {
+                pushBatch(params, mask, TRUE, FALSE);
             }
-            pushBatch(params, mask | LLVertexBuffer::MAP_WEIGHT4, TRUE, FALSE);
-        }
-        else
-        {
-            pushBatch(params, mask, TRUE, FALSE);
         }
+
+        LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+        LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::BUMP_MAP);
+        LLGLSLShader::sCurBoundShaderPtr->unbind();
+        gGL.getTexUnit(0)->activate();
     }
-}
 
-void LLDrawPoolBump::beginPostDeferredPass(S32 pass)
-{
-    mRigged = ((pass % 2) == 1);
-    pass /= 2;
-	switch (pass)
-	{
-	case 0:
-		beginFullbrightShiny();
-		break;
-	case 1:
-		beginBump();
-		break;
-	}
+    mShiny = FALSE;
 }
 
-void LLDrawPoolBump::endPostDeferredPass(S32 pass)
-{
-	switch (pass)
-	{
-	case 0:
-		endFullbrightShiny();
-		break;
-	case 1:
-		endBump(LLRenderPass::PASS_POST_BUMP);
-		break;
-	}
-
-	//to disable texture channels
-	LLRenderPass::endRenderPass(pass);
-}
 
 void LLDrawPoolBump::renderPostDeferred(S32 pass)
 {
-    pass /= 2;
-	switch (pass)
-	{
-	case 0:
-		renderFullbrightShiny();
-		break;
-	case 1:
-		renderBump(LLRenderPass::PASS_POST_BUMP);
-		break;
-	}
+    for (int i = 0; i < 2; ++i)
+    { // two passes -- static and rigged
+        mRigged = (i == 1);
+
+        // render shiny
+        beginFullbrightShiny();
+        renderFullbrightShiny();
+        endFullbrightShiny();
+
+        //render bump
+        beginBump();
+        renderBump(LLRenderPass::PASS_POST_BUMP);
+        endBump();
+    }
 }
 
+
 ////////////////////////////////////////////////////////////////
 // List of bump-maps created from other textures.
 
@@ -1526,44 +1412,4 @@ void LLDrawPoolInvisible::render(S32 pass)
 	{
 		gOcclusionProgram.unbind();
 	}
-
-	if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))
-	{
-		beginShiny(true);
-		renderShiny(true);
-		endShiny(true);
-	}
-}
-
-void LLDrawPoolInvisible::beginDeferredPass(S32 pass)
-{
-	beginRenderPass(pass);
-}
-
-void LLDrawPoolInvisible::endDeferredPass( S32 pass )
-{
-	endRenderPass(pass);
-}
-
-void LLDrawPoolInvisible::renderDeferred( S32 pass )
-{ //render invisiprims; this doesn't work becaue it also blocks all the post-deferred stuff
-#if 0 
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE);
-  
-	U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
-	glStencilMask(0);
-	glStencilOp(GL_ZERO, GL_KEEP, GL_REPLACE);
-	gGL.setColorMask(false, false);
-	pushBatches(LLRenderPass::PASS_INVISIBLE, invisi_mask, FALSE);
-	gGL.setColorMask(true, true);
-	glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
-	glStencilMask(0xFFFFFFFF);
-	
-	if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))
-	{
-		beginShiny(true);
-		renderShiny(true);
-		endShiny(true);
-	}
-#endif
 }
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index 624dbe3034a868f0136d67f1533e11cd8121211f..38744a7d98c40f25ede335bf1249f040cd298bfe 100644
--- a/indra/newview/lldrawpoolbump.h
+++ b/indra/newview/lldrawpoolbump.h
@@ -53,8 +53,6 @@ protected :
 	LLDrawPoolBump();
 
 	virtual void render(S32 pass = 0) override;
-	virtual void beginRenderPass( S32 pass ) override;
-	virtual void endRenderPass( S32 pass ) override;
 	virtual S32	 getNumPasses() override;
 	/*virtual*/ void prerender() override;
 	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE) override;
@@ -64,9 +62,9 @@ protected :
 		
 	S32 numBumpPasses();
 	
-	void beginShiny(bool invisible = false);
-	void renderShiny(bool invisible = false);
-	void endShiny(bool invisible = false);
+	void beginShiny();
+	void renderShiny();
+	void endShiny();
 	
 	void beginFullbrightShiny();
 	void renderFullbrightShiny();
@@ -76,17 +74,13 @@ protected :
 	void renderBump(U32 pass = LLRenderPass::PASS_BUMP);
 	void endBump(U32 pass = LLRenderPass::PASS_BUMP);
 
-	static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible);
-	static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible);
+	static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel);
+	static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel);
 
 	virtual S32 getNumDeferredPasses() override;
-	/*virtual*/ void beginDeferredPass(S32 pass) override;
-	/*virtual*/ void endDeferredPass(S32 pass) override;
 	/*virtual*/ void renderDeferred(S32 pass) override;
 
-    virtual S32 getNumPostDeferredPasses() override { return 4; }
-	/*virtual*/ void beginPostDeferredPass(S32 pass) override;
-	/*virtual*/ void endPostDeferredPass(S32 pass) override;
+    virtual S32 getNumPostDeferredPasses() override { return 1; }
 	/*virtual*/ void renderPostDeferred(S32 pass) override;
 
 	static BOOL bindBumpMap(LLDrawInfo& params, S32 channel = -2);
@@ -171,10 +165,10 @@ class LLBumpImageList
 
 extern LLBumpImageList gBumpImageList;
 
-class LLDrawPoolInvisible : public LLDrawPoolBump
+class LLDrawPoolInvisible : public LLRenderPass
 {
 public:
-	LLDrawPoolInvisible() : LLDrawPoolBump(LLDrawPool::POOL_INVISIBLE) { }
+	LLDrawPoolInvisible() : LLRenderPass(LLDrawPool::POOL_INVISIBLE) { }
 
 	enum
 	{
@@ -189,11 +183,6 @@ class LLDrawPoolInvisible : public LLDrawPoolBump
 	virtual void beginRenderPass( S32 pass ) { }
 	virtual void endRenderPass( S32 pass ) { }
 	virtual S32	 getNumPasses() {return 1;}
-
-	virtual S32 getNumDeferredPasses() { return 1; }
-	/*virtual*/ void beginDeferredPass(S32 pass);
-	/*virtual*/ void endDeferredPass(S32 pass);
-	/*virtual*/ void renderDeferred(S32 pass);
 };
 
 
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index a1d769bc8358b97819564d3d1c2344aec95fc44f..4ada753355f316f533cd5614aa29bbbeb3531ee4 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -38,83 +38,54 @@
 #include "llrender.h"
 
 static LLGLSLShader* simple_shader = NULL;
-static LLGLSLShader* fullbright_shader = NULL;
 
 static LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple");
 static LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS_DEFERRED("Deferred Grass");
 
-void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)
+
+static void setup_simple_shader(LLGLSLShader* shader)
 {
-    if (pass == 0)
+    shader->bind();
+
+    if (LLPipeline::sRenderingHUDs)
     {
-        gDeferredEmissiveProgram.bind();
+        shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
     }
     else
     {
-        llassert(gDeferredEmissiveProgram.mRiggedVariant);
-        gDeferredEmissiveProgram.mRiggedVariant->bind();
+        shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
     }
-
-	LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-    if (LLPipeline::sRenderingHUDs)
-	{
-        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);
-	}
-	else
-	{
-        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);
-	}
 }
 
-void LLDrawPoolGlow::renderPostDeferred(S32 pass)
+static void setup_glow_shader(LLGLSLShader* shader)
 {
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
-	LLGLEnable blend(GL_BLEND);
-	LLGLDisable test(GL_ALPHA_TEST);
-	gGL.flush();
-	/// Get rid of z-fighting with non-glow pass.
-	LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
-	glPolygonOffset(-1.0f, -1.0f);
-	gGL.setSceneBlendType(LLRender::BT_ADD);
-	
-	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-	gGL.setColorMask(false, true);
-
-    if (pass == 0)
+    setup_simple_shader(shader);
+    if (LLPipeline::sRenderDeferred && !LLPipeline::sRenderingHUDs)
     {
-        pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+        shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
     }
     else
     {
-        pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+        shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
     }
-	
-	gGL.setColorMask(true, false);
-	gGL.setSceneBlendType(LLRender::BT_ALPHA);	
 }
 
-void LLDrawPoolGlow::endPostDeferredPass(S32 pass)
+static void setup_fullbright_shader(LLGLSLShader* shader)
 {
-    LLGLSLShader::sCurBoundShaderPtr->unbind();
-
-	LLRenderPass::endRenderPass(pass);
+    setup_glow_shader(shader);
+    shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
 }
 
-S32 LLDrawPoolGlow::getNumPasses()
+
+void LLDrawPoolGlow::renderPostDeferred(S32 pass)
 {
-	if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
-	{
-		return 2;
-	}
-	else
-	{
-		return 0;
-	}
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
+    render(&gDeferredEmissiveProgram);
 }
 
-void LLDrawPoolGlow::render(S32 pass)
+void LLDrawPoolGlow::render(LLGLSLShader* shader)
 {
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
 	LLGLEnable blend(GL_BLEND);
 	LLGLDisable test(GL_ALPHA_TEST);
 	gGL.flush();
@@ -123,55 +94,32 @@ void LLDrawPoolGlow::render(S32 pass)
 	glPolygonOffset(-1.0f, -1.0f);
 	gGL.setSceneBlendType(LLRender::BT_ADD);
 	
-	U32 shader_level = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
-
-	//should never get here without basic shaders enabled
-	llassert(shader_level > 0);
-	
-	LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
-    if (pass == 1)
-    {
-        llassert(shader->mRiggedVariant);
-        shader = shader->mRiggedVariant;
-    }
-	shader->bind();
-	if (LLPipeline::sRenderDeferred)
-	{
-		shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-	}
-	else
-	{
-		shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
-	}
-
-    if (LLPipeline::sRenderingHUDs)
-	{
-		shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
-	}
-	else
-	{
-		shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
-	}
-
 	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
 	gGL.setColorMask(false, true);
 
-    if (pass == 0)
-    {
-        pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-    }
-    else
-    {
-        pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-    }
-	
-	gGL.setColorMask(true, false);
-	gGL.setSceneBlendType(LLRender::BT_ALPHA);
-	
-	if (shader_level > 0 && fullbright_shader)
-	{
-		shader->unbind();
-	}
+    //first pass -- static objects
+    setup_glow_shader(shader);
+    pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+        
+    // second pass -- rigged objects
+    shader = shader->mRiggedVariant;
+    setup_glow_shader(shader);
+    pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ 
+    gGL.setColorMask(true, false);
+    gGL.setSceneBlendType(LLRender::BT_ALPHA);	
+}
+
+S32 LLDrawPoolGlow::getNumPasses()
+{
+    return 1;
+}
+
+void LLDrawPoolGlow::render(S32 pass)
+{
+    LL_PROFILE_ZONE_SCOPED;
+    LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+    render(shader);
 }
 
 LLDrawPoolSimple::LLDrawPoolSimple() :
@@ -186,65 +134,38 @@ void LLDrawPoolSimple::prerender()
 
 S32 LLDrawPoolSimple::getNumPasses()
 {
-    return 2;
+    return 1;
 }
 
-void LLDrawPoolSimple::beginRenderPass(S32 pass)
+void LLDrawPoolSimple::render(S32 pass)
 {
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
 
+	LLGLDisable blend(GL_BLEND);
+	
+    LLGLSLShader* shader = nullptr;
     if (LLPipeline::sImpostorRender)
     {
-        simple_shader = &gObjectSimpleImpostorProgram;
+        shader = &gObjectSimpleImpostorProgram;
     }
     else if (LLPipeline::sUnderWaterRender)
     {
-        simple_shader = &gObjectSimpleWaterProgram;
+        shader = &gObjectSimpleWaterProgram;
     }
     else
     {
-        simple_shader = &gObjectSimpleProgram;
-    }
- 
-    if (pass == 1)
-    {
-        llassert(simple_shader->mRiggedVariant);
-        simple_shader = simple_shader->mRiggedVariant;
+        shader = &gObjectSimpleProgram;
     }
 
-	simple_shader->bind();
-
-    if (LLPipeline::sRenderingHUDs)
-	{
-		simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
-	}
-	else
-	{
-		simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
-	}
-}
-
-void LLDrawPoolSimple::endRenderPass(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
-	stop_glerror();
-	LLRenderPass::endRenderPass(pass);
-	stop_glerror();
-	simple_shader->unbind();
-}
-
-void LLDrawPoolSimple::render(S32 pass)
-{
-	LLGLDisable blend(GL_BLEND);
-	
 	{ //render simple
-		LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
+	
 		gPipeline.enableLightsDynamic();
 
 		U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX;
 
-        if (pass == 0)
+        // first pass -- static objects
         {
+            setup_simple_shader(shader);
             pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE);
 
             if (LLPipeline::sRenderDeferred)
@@ -257,8 +178,11 @@ void LLDrawPoolSimple::render(S32 pass)
                 pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE);
             }
         }
-        else
+        
+        //second pass, rigged
         {
+            shader = shader->mRiggedVariant;
+            setup_simple_shader(shader);
             pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, mask, TRUE, TRUE);
 
             if (LLPipeline::sRenderDeferred)
@@ -275,9 +199,6 @@ void LLDrawPoolSimple::render(S32 pass)
 }
 
 
-
-
-
 static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK("Alpha Mask");
 
 LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
@@ -290,84 +211,36 @@ void LLDrawPoolAlphaMask::prerender()
 	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
 }
 
-void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
+void LLDrawPoolAlphaMask::render(S32 pass)
 {
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
-
+	LLGLDisable blend(GL_BLEND);
+    LL_PROFILE_ZONE_SCOPED;
+	
+    LLGLSLShader* shader = nullptr;
     if (LLPipeline::sUnderWaterRender)
     {
-        simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
+        shader = &gObjectSimpleWaterAlphaMaskProgram;
     }
     else
     {
-        simple_shader = &gObjectSimpleAlphaMaskProgram;
+        shader = &gObjectSimpleAlphaMaskProgram;
     }
 
-    if (pass == 1)
-    {
-        llassert(simple_shader->mRiggedVariant);
-        simple_shader = simple_shader->mRiggedVariant;
-    }
-
-    simple_shader->bind();
-
-    if (LLPipeline::sRenderingHUDs)
-    {
-	    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
-    }
-    else
-    {
-	    simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
-    }
-}
-
-void LLDrawPoolAlphaMask::endRenderPass(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
-	stop_glerror();
-	LLRenderPass::endRenderPass(pass);
-	stop_glerror();
-	if (mShaderLevel > 0)
-	{
-		simple_shader->unbind();
-	}
-}
-
-void LLDrawPoolAlphaMask::render(S32 pass)
-{
-	LLGLDisable blend(GL_BLEND);
-    LL_PROFILE_ZONE_SCOPED;
-	
-	
-
-	simple_shader->bind();
-	simple_shader->setMinimumAlpha(0.33f);
-
-    if (LLPipeline::sRenderingHUDs)
-	{
-		simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
-	}
-	else
-	{
-		simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
-	}
+    // render static
+    setup_simple_shader(shader);
+    pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+	pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+	pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+	pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+	pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
 
-    if (pass == 0)
-    {
-		pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-		pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-		pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-		pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-		pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-	}
-	else
-	{
-        pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-        pushRiggedMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-        pushRiggedMaskBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-        pushRiggedMaskBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-        pushRiggedMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-	}
+    // render rigged
+    setup_simple_shader(shader->mRiggedVariant);
+    pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+    pushRiggedMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+    pushRiggedMaskBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+    pushRiggedMaskBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+    pushRiggedMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
 }
 
 LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() :
@@ -380,61 +253,27 @@ void LLDrawPoolFullbrightAlphaMask::prerender()
 	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
 }
 
-void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
-
-    bool rigged = (pass == 1);
-	if (LLPipeline::sUnderWaterRender)
-	{
-        gObjectFullbrightWaterAlphaMaskProgram.bind(rigged);
-	}
-	else
-	{
-		gObjectFullbrightAlphaMaskProgram.bind(rigged);
-	}
-
-    if (LLPipeline::sRenderingHUDs)
-	{
-		LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);
-        LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
-	}
-	else
-	{
-        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);
-        if (LLPipeline::sRenderDeferred)
-        {
-            LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-        }
-        else
-        {
-            LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
-        }
-	}
-}
-
-void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
-	stop_glerror();
-	LLRenderPass::endRenderPass(pass);
-	stop_glerror();
-    LLGLSLShader::sCurBoundShaderPtr->unbind();
-}
-
 void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
 {
 	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
 
-    if (pass == 0)
+    LLGLSLShader* shader = nullptr;
+    if (LLPipeline::sUnderWaterRender)
     {
-        pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+        shader = &gObjectFullbrightWaterAlphaMaskProgram;
     }
     else
     {
-        pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+        shader = &gObjectFullbrightAlphaMaskProgram;
     }
-	
+
+    // render static
+    setup_fullbright_shader(shader);
+    pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+
+    // render rigged
+    setup_fullbright_shader(shader->mRiggedVariant);
+    pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
 }
 
 //===============================
@@ -443,112 +282,41 @@ void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
 
 S32 LLDrawPoolSimple::getNumDeferredPasses()
 {
-    if (LLPipeline::sRenderingHUDs)
-    {
-        return 1;
-    }
-    else
-    {
-        return 2;
-    }
-}
-void LLDrawPoolSimple::beginDeferredPass(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
-
-    mShader = &gDeferredDiffuseProgram;
-    
-    if (pass == 1)
-    {
-        llassert(mShader->mRiggedVariant != nullptr);
-        mShader = mShader->mRiggedVariant;
-    }
-    
-
-    mShader->bind();
-
-    if (LLPipeline::sRenderingHUDs)
-	{
-		mShader->uniform1i(LLShaderMgr::NO_ATMO, 1);
-	}
-	else
-	{
-		mShader->uniform1i(LLShaderMgr::NO_ATMO, 0);
-	}
-}
-
-void LLDrawPoolSimple::endDeferredPass(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
-	LLRenderPass::endRenderPass(pass);
-
-	mShader->unbind();
+    return 1;
 }
 
 void LLDrawPoolSimple::renderDeferred(S32 pass)
 {
-    LL_PROFILE_ZONE_SCOPED;
+    LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
 	LLGLDisable blend(GL_BLEND);
 	LLGLDisable alpha_test(GL_ALPHA_TEST);
 
-    if (pass == 0)
-	{ //render simple
-		LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
-		pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-	}
-    else
-    {
-        //render simple rigged
-        pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-    }
+	//render static
+    setup_simple_shader(&gDeferredDiffuseProgram);
+	pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+	
+    //render rigged
+    setup_simple_shader(gDeferredDiffuseProgram.mRiggedVariant);
+    pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
 }
 
 static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask");
 
-void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass)
-{
-    if (pass == 0)
-    {
-        gDeferredDiffuseAlphaMaskProgram.bind();
-    }
-    else
-    {
-        llassert(gDeferredDiffuseAlphaMaskProgram.mRiggedVariant);
-        gDeferredDiffuseAlphaMaskProgram.mRiggedVariant->bind();
-    }
-
-}
-
-void LLDrawPoolAlphaMask::endDeferredPass(S32 pass)
-{
-    LLGLSLShader::sCurBoundShaderPtr->unbind();
-}
 
 void LLDrawPoolAlphaMask::renderDeferred(S32 pass)
 {
 	LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_DEFERRED);
-	LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.33f);
+    LLGLSLShader* shader = &gDeferredDiffuseAlphaMaskProgram;
 
-    if (LLPipeline::sRenderingHUDs)
-	{
-        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);
-	}
-	else
-	{
-        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);
-	}
+    //render static
+    setup_simple_shader(shader);
+    pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
 
-    if (pass == 0)
-    {
-        pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-    }
-    else
-    {
-        pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-    }
+    //render rigged
+    setup_simple_shader(shader->mRiggedVariant);
+    pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
 }
 
-
 // grass drawpool
 LLDrawPoolGrass::LLDrawPoolGrass() :
  LLRenderPass(POOL_GRASS)
@@ -667,83 +435,31 @@ void LLDrawPoolFullbright::prerender()
 	mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
 }
 
-void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
-{
-    bool rigged = (pass == 1);
-	if (LLPipeline::sUnderWaterRender)
-	{
-		gDeferredFullbrightWaterProgram.bind(rigged);
-	}
-	else
-	{
-		gDeferredFullbrightProgram.bind(rigged);
-
-        if (LLPipeline::sRenderingHUDs)
-	    {
-            LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);
-	    }
-	    else
-	    {
-            LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);
-	    }
-	}
-}
 
 void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
 {
 	LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
-	
-	gGL.setSceneBlendType(LLRender::BT_ALPHA);
-	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
-    if (pass == 0)
+
+    LLGLSLShader* shader = nullptr;
+    if (LLPipeline::sUnderWaterRender)
     {
-        pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
+        shader = &gDeferredFullbrightWaterProgram;
     }
     else
     {
-        pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE);
+        shader = &gDeferredFullbrightProgram;
     }
-}
 
-void LLDrawPoolFullbright::endPostDeferredPass(S32 pass)
-{
-    LLGLSLShader::sCurBoundShaderPtr->unbind();
-	LLRenderPass::endRenderPass(pass);
-}
-
-void LLDrawPoolFullbright::beginRenderPass(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
-	
-	if (LLPipeline::sUnderWaterRender)
-	{
-		fullbright_shader = &gObjectFullbrightWaterProgram;
-	}
-	else
-	{
-		fullbright_shader = &gObjectFullbrightProgram;
-	}
-
-    if (pass == 1)
-    {
-        llassert(fullbright_shader->mRiggedVariant);
-        fullbright_shader = fullbright_shader->mRiggedVariant;
-    }
-}
-
-void LLDrawPoolFullbright::endRenderPass(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
-	LLRenderPass::endRenderPass(pass);
-
-	stop_glerror();
-
-	if (mShaderLevel > 0)
-	{
-		fullbright_shader->unbind();
-	}
-
-	stop_glerror();
+	gGL.setSceneBlendType(LLRender::BT_ALPHA);
+	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
+    
+    // render static
+    setup_fullbright_shader(shader);
+    pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
+    
+    // render rigged
+    setup_fullbright_shader(shader->mRiggedVariant);
+    pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE);
 }
 
 void LLDrawPoolFullbright::render(S32 pass)
@@ -752,102 +468,75 @@ void LLDrawPoolFullbright::render(S32 pass)
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
 	stop_glerror();
+    LLGLSLShader* shader = nullptr;
+    if (LLPipeline::sUnderWaterRender)
+    {
+        shader = &gObjectFullbrightWaterProgram;
+    }
+    else
+    {
+        shader = &gObjectFullbrightProgram;
+    }
 
-	if (mShaderLevel > 0)
-	{
-		fullbright_shader->bind();
-		fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
-		fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f);
-
-        if (LLPipeline::sRenderingHUDs)
-	    {
-		    fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
-	    }
-	    else
-	    {
-		    fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
-	    }
-
-		U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
 
-        if (pass == 0)
-        {
-            pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
-            pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE);
-            pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
-            pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
-            pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask, TRUE, TRUE);
-        }
-        else
-        {
-            pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE);
-            pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE);
-            pushRiggedBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE);
-            pushRiggedBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE);
-            pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE);
-        }
-	}
+	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
 
-	stop_glerror();
+    // render static
+    setup_fullbright_shader(shader);
+    pushBatches(LLRenderPass::PASS_FULLBRIGHT, mask, TRUE, TRUE);
+    pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, mask, TRUE, TRUE);
+    pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, mask, TRUE, TRUE);
+    pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, mask, TRUE, TRUE);
+    pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, mask, TRUE, TRUE);
+ 
+    // render rigged
+    setup_fullbright_shader(shader->mRiggedVariant);
+    pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, mask, TRUE, TRUE);
+    pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, mask, TRUE, TRUE);
+    pushRiggedBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE);
+    pushRiggedBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE);
+    pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, mask, TRUE, TRUE);
 }
 
 S32 LLDrawPoolFullbright::getNumPasses()
 { 
-	return 2;
+	return 1;
 }
 
-
-void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
+void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
 {
-    bool rigged = (pass == 1);
+	LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
+    
+    LLGLSLShader* shader = nullptr;
     if (LLPipeline::sRenderingHUDs)
     {
-        gObjectFullbrightAlphaMaskProgram.bind(rigged);
-		LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
-        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);
+        shader = &gObjectFullbrightAlphaMaskProgram;
     }
-	else if (LLPipeline::sRenderDeferred)
-	{
+    else if (LLPipeline::sRenderDeferred)
+    {
         if (LLPipeline::sUnderWaterRender)
-		{
-            gDeferredFullbrightAlphaMaskWaterProgram.bind(rigged);
-            LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-            LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1);
-		}
-		else
-		{
-			gDeferredFullbrightAlphaMaskProgram.bind(rigged);
-            LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-            LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);
-		}
+        {
+            shader = &gDeferredFullbrightAlphaMaskWaterProgram;
+        }
+        else
+        {
+            shader = &gDeferredFullbrightAlphaMaskProgram;
+        }
     }
     else
     {
-		gObjectFullbrightAlphaMaskProgram.bind(rigged);
-        LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
-        LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0);
-	}
-}
+        shader = &gObjectFullbrightAlphaMaskProgram;
+    }
 
-void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
-{
-	LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
 	LLGLDisable blend(GL_BLEND);
 	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
-    if (pass == 0)
-    {
-        pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE);
-    }
-    else
-    {
-        pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, fullbright_mask, TRUE, TRUE);
-    }
-}
-
-void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
-{
-    LLGLSLShader::sCurBoundShaderPtr->unbind();
-	LLRenderPass::endRenderPass(pass);
+    
+    // render static
+    setup_fullbright_shader(shader);
+    pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE);
+    
+    // render rigged
+    setup_fullbright_shader(shader->mRiggedVariant);
+    pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, fullbright_mask, TRUE, TRUE);
 }
 
-
diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h
index d6fecdd23c14eb7f4d0bec84bb583ab5b2fd9f0f..cccbe5e495515aa5d1184f20e0a6936d251994f5 100644
--- a/indra/newview/lldrawpoolsimple.h
+++ b/indra/newview/lldrawpoolsimple.h
@@ -46,18 +46,12 @@ class LLDrawPoolSimple : public LLRenderPass
 	LLDrawPoolSimple();
 	
     S32 getNumDeferredPasses() override;
-	void beginDeferredPass(S32 pass) override;
-	void endDeferredPass(S32 pass) override;
 	void renderDeferred(S32 pass) override;
 
-	void beginRenderPass(S32 pass) override;
-	void endRenderPass(S32 pass) override;
 	/// We need two passes so we can handle emissive materials separately.
     S32	 getNumPasses() override;
 	void render(S32 pass = 0) override;
 	void prerender() override;
-
-    LLGLSLShader* mShader = nullptr;
 };
 
 class LLDrawPoolGrass : public LLRenderPass
@@ -101,14 +95,10 @@ class LLDrawPoolAlphaMask : public LLRenderPass
 
 	LLDrawPoolAlphaMask();
 
-	/*virtual*/ S32 getNumDeferredPasses() { return 2; }
-	/*virtual*/ void beginDeferredPass(S32 pass);
-	/*virtual*/ void endDeferredPass(S32 pass);
+	/*virtual*/ S32 getNumDeferredPasses() { return 1; }
 	/*virtual*/ void renderDeferred(S32 pass);
 
-	/*virtual*/ S32	 getNumPasses() { return 2; }
-	/*virtual*/ void beginRenderPass(S32 pass);
-	/*virtual*/ void endRenderPass(S32 pass);
+	/*virtual*/ S32	 getNumPasses() { return 1; }
 	/*virtual*/ void render(S32 pass = 0);
 	/*virtual*/ void prerender();
 
@@ -127,14 +117,10 @@ class LLDrawPoolFullbrightAlphaMask : public LLRenderPass
 
 	LLDrawPoolFullbrightAlphaMask();
 	
-	/*virtual*/ S32 getNumPostDeferredPasses() { return 2; }
-	/*virtual*/ void beginPostDeferredPass(S32 pass);
-	/*virtual*/ void endPostDeferredPass(S32 pass);
+	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
 	/*virtual*/ void renderPostDeferred(S32 pass);
 
-	/*virtual*/ S32	 getNumPasses() { return 2; }
-	/*virtual*/ void beginRenderPass(S32 pass);
-	/*virtual*/ void endRenderPass(S32 pass);
+	/*virtual*/ S32	 getNumPasses() { return 1; }
 	/*virtual*/ void render(S32 pass = 0);
 	/*virtual*/ void prerender();
 };
@@ -153,13 +139,9 @@ class LLDrawPoolFullbright : public LLRenderPass
 
 	LLDrawPoolFullbright();
 	
-	/*virtual*/ S32 getNumPostDeferredPasses() { return 2; }
-	/*virtual*/ void beginPostDeferredPass(S32 pass);
-	/*virtual*/ void endPostDeferredPass(S32 pass);
+	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
 	/*virtual*/ void renderPostDeferred(S32 pass);
 
-	/*virtual*/ void beginRenderPass(S32 pass);
-	/*virtual*/ void endRenderPass(S32 pass);
 	/*virtual*/ S32	 getNumPasses();
 	/*virtual*/ void render(S32 pass = 0);
 	/*virtual*/ void prerender();
@@ -182,11 +164,11 @@ class LLDrawPoolGlow : public LLRenderPass
 
 	virtual void prerender() { }
 
-	/*virtual*/ S32 getNumPostDeferredPasses() { return 2; }
-	/*virtual*/ void beginPostDeferredPass(S32 pass); 
-	/*virtual*/ void endPostDeferredPass(S32 pass);
+	/*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
 	/*virtual*/ void renderPostDeferred(S32 pass);
 
+    void render(LLGLSLShader* shader);
+
 	/*virtual*/ S32 getNumPasses();
 
 	void render(S32 pass = 0);