diff --git a/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl
index dd850ff97cb31c2dfa0052e4b18176014c21df41..95abd4d9329499132bae75a45dca2a7b39e175a2 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/reflectionProbeF.glsl
@@ -38,6 +38,12 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
         pos, norm, glossiness, false);
 }
 
+vec4 sampleReflectionProbesDebug(vec3 pos)
+{
+    //output green to debug display
+    return vec4(0, 1, 0, 0.5);
+}
+
 void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, 
         vec3 pos, vec3 norm, float glossiness, float envIntensity)
 {
diff --git a/indra/newview/app_settings/shaders/class1/interface/reflectionprobeF.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionprobeF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..e2e0a2002bfcf0e3d557bd02aee16d55931e7d6a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/reflectionprobeF.glsl
@@ -0,0 +1,32 @@
+/** 
+ * @file reflectionprobeF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+// debug stub
+out vec4 frag_color;
+
+void main() 
+{
+	frag_color = vec4(0,1,0,0.5);
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/reflectionprobeV.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionprobeV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..0efbd639445547597680b0846a253a47ba11ef5c
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/reflectionprobeV.glsl
@@ -0,0 +1,34 @@
+/** 
+ * @file reflectionprobeV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+ // Debug stub
+
+ATTRIBUTE vec3 position;
+
+void main()
+{
+    gl_Position = vec4(position, 1.0); 
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
index eb261434381e69db94bcd0b705b23e4f5c44929f..af43c7b4e3e7cf7c3ded1b0a657127bde94bbbb7 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
@@ -50,6 +50,12 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
         pos, norm, glossiness, false);
 }
 
+vec4 sampleReflectionProbesDebug(vec3 pos)
+{
+    // show nothing in debug display
+    return vec4(0, 0, 0, 0);
+}
+
 void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, 
         vec3 pos, vec3 norm, float glossiness, float envIntensity)
 {
diff --git a/indra/newview/app_settings/shaders/class2/interface/reflectionprobeF.glsl b/indra/newview/app_settings/shaders/class2/interface/reflectionprobeF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..986b233e0beadc735fcc5e121831a49ba2ef538d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/interface/reflectionprobeF.glsl
@@ -0,0 +1,42 @@
+/** 
+ * @file reflectionprobeF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+out vec4 frag_color;
+
+in vec2 vary_fragcoord;
+
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
+float getDepth(vec2 pos_screen);
+
+vec4 sampleReflectionProbesDebug(vec3 pos);
+
+void main()
+{
+    vec2  tc           = vary_fragcoord.xy;
+    float depth        = getDepth(tc.xy);
+    vec4  pos          = getPositionWithDepth(tc, depth);
+
+    frag_color = sampleReflectionProbesDebug(pos.xyz);
+}
diff --git a/indra/newview/app_settings/shaders/class2/interface/reflectionprobeV.glsl b/indra/newview/app_settings/shaders/class2/interface/reflectionprobeV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..e45b1c288b11333267970c3bb3a66ec57167ccee
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/interface/reflectionprobeV.glsl
@@ -0,0 +1,38 @@
+/** 
+ * @file reflectionprobeV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+ 
+in vec3 position;
+
+out vec2 vary_fragcoord;
+
+void main()
+{
+    //transform vertex
+    vec4 pos = vec4(position.xyz, 1.0);
+    gl_Position = pos; 
+
+    vary_fragcoord = (pos.xy*0.5+0.5);
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index ca436033f1974aa5891fa11d299ae1d8146caf83..977b2e6b24817b4242ff9ee4d3a7ddffcfb3e578 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -518,6 +518,13 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
     glossenv = sampleProbes(pos, normalize(refnormpersp), lod, errorCorrect);
 }
 
+vec4 sampleReflectionProbesDebug(vec3 pos)
+{
+    preProbeSample(pos);
+
+    return vec4(probeInfluences*0.25, 0, 0, probeInfluences*0.25);
+}
+
 void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
     vec3 pos, vec3 norm, float glossiness)
 {
@@ -525,6 +532,7 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
         pos, norm, glossiness, false);
 }
 
+
 void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
         vec3 pos, vec3 norm, float glossiness, float envIntensity)
 {
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 408e60595cec8bc918a08e2f25c4d4bdf783d642..b7e2fd4cb4a997a17be51a14d07003cbc68e4649 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -92,8 +92,7 @@ LLGLSLShader	gDownsampleDepthProgram;
 LLGLSLShader	gDownsampleDepthRectProgram;
 LLGLSLShader	gAlphaMaskProgram;
 LLGLSLShader	gBenchmarkProgram;
-LLGLSLShader    gScreenSpaceReflectionProgram;
-
+LLGLSLShader    gReflectionProbeDisplayProgram;
 
 //object shaders
 LLGLSLShader		gObjectSimpleProgram;
@@ -694,6 +693,7 @@ void LLViewerShaderMgr::unloadShaders()
 	gDownsampleDepthProgram.unload();
 	gDownsampleDepthRectProgram.unload();
 	gBenchmarkProgram.unload();
+    gReflectionProbeDisplayProgram.unload();
 	gAlphaMaskProgram.unload();
 	gUIProgram.unload();
 	gPathfindingProgram.unload();
@@ -710,7 +710,6 @@ void LLViewerShaderMgr::unloadShaders()
 	gOneTextureFilterProgram.unload();
 	gOneTextureNoColorProgram.unload();
 	gSolidColorProgram.unload();
-    gScreenSpaceReflectionProgram.unload();
 
 	gObjectFullbrightNoColorProgram.unload();
 	gObjectFullbrightNoColorWaterProgram.unload();
@@ -3888,6 +3887,18 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		success = gBenchmarkProgram.createShader(NULL, NULL);
 	}
 
+    if (success)
+    {
+        gReflectionProbeDisplayProgram.mName = "Reflection Probe Display Shader";
+        gReflectionProbeDisplayProgram.mFeatures.hasReflectionProbes = true;
+        gReflectionProbeDisplayProgram.mShaderFiles.clear();
+        gReflectionProbeDisplayProgram.mShaderFiles.push_back(make_pair("interface/reflectionprobeV.glsl", GL_VERTEX_SHADER));
+        gReflectionProbeDisplayProgram.mShaderFiles.push_back(make_pair("interface/reflectionprobeF.glsl", GL_FRAGMENT_SHADER));
+        gReflectionProbeDisplayProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+        success = gReflectionProbeDisplayProgram.createShader(NULL, NULL);
+    }
+
+    
 	if (success)
 	{
 		gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader";
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index a53706e96aee91cdfca3f9487af59b809b763d2b..d26750f230fce8cac1b8ac019521fe81a62af3c4 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -163,6 +163,7 @@ extern LLGLSLShader			gClipProgram;
 extern LLGLSLShader			gDownsampleDepthProgram;
 extern LLGLSLShader			gDownsampleDepthRectProgram;
 extern LLGLSLShader			gBenchmarkProgram;
+extern LLGLSLShader         gReflectionProbeDisplayProgram;
 
 //output tex0[tc0] + tex1[tc1]
 extern LLGLSLShader			gTwoTextureAddProgram;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 5c3a8303225b2f682e1326176f31ccf4b3764482..9d792d08010e865d5ceef07d871c8e45eb91c9da 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -338,6 +338,18 @@ static LLCullResult* sCull = NULL;
 
 void validate_framebuffer_object();
 
+// override the projection_matrix uniform on the given shader to that which would be set by the main camera
+void set_camera_projection_matrix(LLGLSLShader& shader)
+{
+    auto          camProj = LLViewerCamera::getInstance()->getProjection();
+    glh::matrix4f projection = get_current_projection();
+    projection.set_row(0, glh::vec4f(camProj.mMatrix[0][0], camProj.mMatrix[0][1], camProj.mMatrix[0][2], camProj.mMatrix[0][3]));
+    projection.set_row(0, glh::vec4f(camProj.mMatrix[1][0], camProj.mMatrix[1][1], camProj.mMatrix[1][2], camProj.mMatrix[1][3]));
+    projection.set_row(0, glh::vec4f(camProj.mMatrix[2][0], camProj.mMatrix[2][1], camProj.mMatrix[2][2], camProj.mMatrix[2][3]));
+    projection.set_row(0, glh::vec4f(camProj.mMatrix[3][0], camProj.mMatrix[3][1], camProj.mMatrix[3][2], camProj.mMatrix[3][3]));
+    shader.uniformMatrix4fv(LLShaderMgr::PROJECTION_MATRIX, 1, FALSE, projection.m);
+}
+
 // Add color attachments for deferred rendering
 // target -- RenderTarget to add attachments to
 bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false)
@@ -491,7 +503,21 @@ void LLPipeline::init()
 
 	mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
 	mDeferredVB->allocateBuffer(8, 0, true);
-	setLightingDetail(-1);
+
+    {
+        mScreenTriangleVB = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
+        mScreenTriangleVB->allocateBuffer(3, 0, true);
+        LLStrider<LLVector3> vert;
+        mScreenTriangleVB->getVertexStrider(vert);
+
+        vert[0].set(-1, 1, 0);
+        vert[1].set(-1, -3, 0);
+        vert[2].set(3, 1, 0);
+
+        mScreenTriangleVB->flush();
+    }
+
+    setLightingDetail(-1);
 	
 	//
 	// Update all settings to trigger a cached settings refresh
@@ -659,6 +685,7 @@ void LLPipeline::cleanup()
 	mInitialized = false;
 
 	mDeferredVB = NULL;
+    mScreenTriangleVB = nullptr;
 
 	mCubeVB = NULL;
 
@@ -5210,6 +5237,21 @@ void LLPipeline::renderDebug()
     if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_REFLECTION_PROBES) && !hud_only)
     {
         mReflectionMapManager.renderDebug();
+
+        LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("probe debug display");
+
+        bindDeferredShader(gReflectionProbeDisplayProgram, NULL);
+        mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+        // Provide our projection matrix.
+        set_camera_projection_matrix(gReflectionProbeDisplayProgram);
+
+        LLGLEnable blend(GL_BLEND);
+        LLGLDepthTest depth(GL_FALSE);
+
+        mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+        unbindDeferredShader(gReflectionProbeDisplayProgram);
     }
 
 	gUIProgram.bind();
@@ -7513,31 +7555,18 @@ void LLPipeline::renderFinalize()
 
     if (!gCubeSnapshot)
     {
+        LLRenderTarget* screen_target = &mRT->screen;
+        screen_target->bindTarget();
+
         if (RenderScreenSpaceReflections)
         {
             LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - screen space reflections");
             LL_PROFILE_GPU_ZONE("screen space reflections");
-            LLStrider<LLVector3> vert;
-            mDeferredVB->getVertexStrider(vert);
-
-            vert[0].set(-1, 1, 0);
-            vert[1].set(-1, -3, 0);
-            vert[2].set(3, 1, 0);
-
-            // Make sure the deferred VB is a full screen triangle.
-            mDeferredVB->getVertexStrider(vert);
 
             bindDeferredShader(gPostScreenSpaceReflectionProgram, NULL);
-            mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+            mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 
-            // Provide our projection matrix.
-            auto          camProj    = LLViewerCamera::getInstance()->getProjection();
-            glh::matrix4f projection = get_current_projection();
-            projection.set_row(0, glh::vec4f(camProj.mMatrix[0][0], camProj.mMatrix[0][1], camProj.mMatrix[0][2], camProj.mMatrix[0][3]));
-            projection.set_row(0, glh::vec4f(camProj.mMatrix[1][0], camProj.mMatrix[1][1], camProj.mMatrix[1][2], camProj.mMatrix[1][3]));
-            projection.set_row(0, glh::vec4f(camProj.mMatrix[2][0], camProj.mMatrix[2][1], camProj.mMatrix[2][2], camProj.mMatrix[2][3]));
-            projection.set_row(0, glh::vec4f(camProj.mMatrix[3][0], camProj.mMatrix[3][1], camProj.mMatrix[3][2], camProj.mMatrix[3][3]));
-            gPostScreenSpaceReflectionProgram.uniformMatrix4fv(LLShaderMgr::PROJECTION_MATRIX, 1, FALSE, projection.m);
+            set_camera_projection_matrix(gPostScreenSpaceReflectionProgram);
 
             // We need linear depth.
             static LLStaticHashedString zfar("zFar");
@@ -7547,14 +7576,10 @@ void LLPipeline::renderFinalize()
             gPostScreenSpaceReflectionProgram.uniform1f(zfar, farClip);
             gPostScreenSpaceReflectionProgram.uniform1f(znear, nearClip);
 
-            LLRenderTarget *screen_target = &mRT->screen;
-
-            screen_target->bindTarget();
             S32 channel = gPostScreenSpaceReflectionProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP, screen_target->getUsage());
             if (channel > -1)
             {
                 screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
-				
             }
 
             {
@@ -7567,23 +7592,17 @@ void LLPipeline::renderFinalize()
             }
 
             unbindDeferredShader(gPostScreenSpaceReflectionProgram);
-
-            screen_target->flush();
         }
 
         // gamma correct lighting
-
         {
             LL_PROFILE_GPU_ZONE("gamma correct");
 
             LLGLDepthTest depth(GL_FALSE, GL_FALSE);
 
-            LLRenderTarget* screen_target = &mRT->screen;
-
             LLVector2 tc1(0, 0);
             LLVector2 tc2((F32)screen_target->getWidth() * 2, (F32)screen_target->getHeight() * 2);
 
-            screen_target->bindTarget();
             // Apply gamma correction to the frame here.
             gDeferredPostGammaCorrectProgram.bind();
             // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
@@ -7614,9 +7633,10 @@ void LLPipeline::renderFinalize()
 
             gGL.getTexUnit(channel)->unbind(screen_target->getUsage());
             gDeferredPostGammaCorrectProgram.unbind();
-            screen_target->flush();
         }
 
+        screen_target->flush();
+
         LLVertexBuffer::unbind();
     }
 
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index c0add04cca6089d665e7164fe78437d6a1d475c5..7661cd1b4210615c87b92394e5bdb8cdd82b69c4 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -693,9 +693,12 @@ class LLPipeline
     LLCullResult            mReflectedObjects;
     LLCullResult            mRefractedObjects;
 
-	//utility buffer for rendering post effects, gets abused by renderDeferredLighting
+	//utility buffers for rendering post effects
 	LLPointer<LLVertexBuffer> mDeferredVB;
 
+    // a single triangle that covers the whole screen
+    LLPointer<LLVertexBuffer> mScreenTriangleVB;
+
 	//utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]
 	LLPointer<LLVertexBuffer> mCubeVB;