diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
index db130e456ca1e239bb4cbc8585ddcf29f4c61f07..f5d2804c7fb3ed2daba5696f9d3579c3bb467368 100644
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
@@ -23,13 +23,13 @@
  * $/LicenseInfo$
  */
  
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
+out vec4 frag_data[4];
 
 void main() 
 {
-	frag_color = vec4(1,1,1,1);
+    // emissive red PBR material for debugging
+    frag_data[0] = vec4(0, 0, 0, 0);
+    frag_data[1] = vec4(0, 0, 0, 0);
+    frag_data[2] = vec4(1, 0, 0, GBUFFER_FLAG_HAS_PBR);
+    frag_data[3] = vec4(1, 0, 0, 0);
 }
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index cfcb623caf8c310b81d78466a875f63005d93e5b..ddd24b70c63cb0da987ebadc4bb0e7841eb9721b 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 39
+version 40
 // The version number above should be incremented IF AND ONLY IF some
 // change has been made that is sufficiently important to justify
 // resetting the graphics preferences of all users to the recommended
@@ -56,7 +56,7 @@ RenderVBOEnable				1	1
 RenderVBOMappingDisable		1	1
 RenderVolumeLODFactor		1	2.0
 UseStartScreen				1	1
-UseOcclusion				1	1
+UseOcclusion				1	0
 WindLightUseAtmosShaders	1	1
 WLSkyDetail					1	128
 Disregard128DefaultDrawDistance	1	1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 79ce057c300d98face9e1945ab4c7f2c0e2b6a3a..98f498f59d19d214dec36bbfe779852077fc0a15 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 40
+version 41
 // The version number above should be incremented IF AND ONLY IF some
 // change has been made that is sufficiently important to justify
 // resetting the graphics preferences of all users to the recommended
@@ -55,7 +55,7 @@ RenderVBOEnable				1	1
 RenderVBOMappingDisable		1	1
 RenderVolumeLODFactor		1	2.0
 UseStartScreen				1	1
-UseOcclusion				1	1
+UseOcclusion				1	0
 WindLightUseAtmosShaders	1	1
 WLSkyDetail					1	128
 Disregard128DefaultDrawDistance	1	1
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index d02c5861b1f010e49518c0c692d775690f004b5c..96c41416fa34d891bb6eae2173db1decc256c574 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1013,11 +1013,11 @@ class LLOctreeCull : public LLViewerOctreeCull
 	virtual void processGroup(LLViewerOctreeGroup* base_group)
 	{
 		LLSpatialGroup* group = (LLSpatialGroup*)base_group;
-		if (group->needsUpdate() ||
+		/*if (group->needsUpdate() ||
 			group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
 		{
 			group->doOcclusion(mCamera);
-		}
+		}*/
 		gPipeline.markNotCulled(group, *mCamera);
 	}
 };
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 0d2a44867edab7ea035b2145c2241c51b9851bda..5ae7f522f22c2f2e1cdd2d2e91f5d3ccc0eceb96 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -962,7 +962,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			gGL.setColorMask(true, false);
 			if (LLPipeline::sRenderDeferred)
 			{
-				gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
+				gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true);
 			}
 			else
 			{
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index a75eb518f341da52086d17ae63cbe5e3e4b6d89f..1f1616178018e7804a5fa8c71b74c007104ae9a5 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -1169,7 +1169,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
     else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
     {	//check occlusion has been issued for occluded node that has not had a query issued
         assert_states_valid(this);
-        clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+        //clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
         assert_states_valid(this);
     }
 }
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index b8df8bb95f517effb8b9d24039bfa8e40e419e58..c360a7fc63bb77fd90050e9d16d48b14b13ee0e3 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2538,6 +2538,13 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
 		sCull->pushVisibleGroup(group);
 	}
 
+    if (group->needsUpdate() ||
+        group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
+    {
+        // include this group in occlusion groups, not because it is an occluder, but because we want to run
+        // an occlusion query to find out if it's an occluder
+        markOccluder(group);
+    }
 	mNumVisibleNodes++;
 }
 
@@ -4585,12 +4592,14 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
 #endif
 }
 
-void LLPipeline::renderGeomDeferred(LLCamera& camera)
+void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
 {
 	LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
 	LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
     LL_PROFILE_GPU_ZONE("renderGeomDeferred");
 
+    bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
+
 	{
 		LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools"); //LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS);
 
@@ -4630,6 +4639,17 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
 		
 			cur_type = poolp->getType();
 
+            if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
+            {
+                llassert(!gCubeSnapshot); // never do occlusion culling on cube snapshots
+                occlude = false;
+                gGLLastMatrix = NULL;
+                gGL.loadMatrix(gGLModelView);
+                LLGLSLShader::bindNoShader();
+                doOcclusion(camera);
+                gGL.setColorMask(true, false);
+            }
+
 			pool_set_t::iterator iter2 = iter1;
 			if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
 			{
@@ -4686,7 +4706,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
 	} // Tracy ZoneScoped
 }
 
-void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
+void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 {
 	LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS);
     LL_PROFILE_GPU_ZONE("renderGeomPostDeferred");
@@ -4703,7 +4723,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
 	gGL.setColorMask(true, false);
 
 	pool_set_t::iterator iter1 = mPools.begin();
-	bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
 
 	while ( iter1 != mPools.end() )
 	{
@@ -4711,18 +4730,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
 		
 		cur_type = poolp->getType();
 
-		if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
-		{
-            llassert(!gCubeSnapshot); // never do occlusion culling on cube snapshots
-			occlude = false;
-			gGLLastMatrix = NULL;
-			gGL.loadMatrix(gGLModelView);
-			LLGLSLShader::bindNoShader();
-			//doOcclusion(camera, mRT->screen, mRT->occlusionDepth, &mRT->deferredDepth);
-            doOcclusion(camera, mRT->screen, mRT->occlusionDepth);
-			gGL.setColorMask(true, false);
-		}
-
 		pool_set_t::iterator iter2 = iter1;
 		if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
 		{
@@ -4774,16 +4781,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.loadMatrix(gGLModelView);
 
-	if (occlude)
-	{
-		occlude = false;
-		LLGLSLShader::bindNoShader();
-		doOcclusion(camera);
-		gGLLastMatrix = NULL;
-		gGL.matrixMode(LLRender::MM_MODELVIEW);
-		gGL.loadMatrix(gGLModelView);
-	}
-
     if (!gCubeSnapshot)
     {
         // debug displays
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index a31df9c16fe75178e45d972bce0bb3410c3584c5..23ddfb51e53d3cc7e286a88754a6cec407d11bb9 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -290,8 +290,8 @@ class LLPipeline
 
 
 	void renderGeom(LLCamera& camera, bool forceVBOUpdate = false);
-	void renderGeomDeferred(LLCamera& camera);
-	void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true);
+	void renderGeomDeferred(LLCamera& camera, bool do_occlusion = false);
+	void renderGeomPostDeferred(LLCamera& camera);
 	void renderGeomShadow(LLCamera& camera);
 	void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr);
 	void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);