From 577f6a46f02ecfa4efabc0b379e44e4f53a0b391 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Thu, 9 Feb 2023 17:00:36 -0600
Subject: [PATCH] SL-19181 Modulate "glow" by PBR emissive.

---
 .../shaders/class1/deferred/pbrglowF.glsl     | 67 +++++++++++++
 .../shaders/class1/deferred/pbrglowV.glsl     | 70 +++++++++++++
 indra/newview/lldrawpool.h                    |  2 +
 indra/newview/lldrawpoolalpha.cpp             | 97 ++++++++++++++++---
 indra/newview/lldrawpoolalpha.h               |  9 +-
 indra/newview/lldrawpoolpbropaque.cpp         | 25 +++--
 indra/newview/llfetchedgltfmaterial.cpp       |  4 +-
 indra/newview/llviewershadermgr.cpp           | 22 +++++
 indra/newview/llviewershadermgr.h             |  1 +
 indra/newview/llvovolume.cpp                  | 14 ++-
 indra/newview/pipeline.cpp                    |  2 +
 indra/newview/pipeline.h                      |  2 +
 12 files changed, 290 insertions(+), 25 deletions(-)
 create mode 100644 indra/newview/app_settings/shaders/class1/deferred/pbrglowF.glsl
 create mode 100644 indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl

diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrglowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrglowF.glsl
new file mode 100644
index 00000000000..8dc9e02f7a9
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrglowF.glsl
@@ -0,0 +1,67 @@
+/** 
+ * @file pbrglowF.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, 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$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+// forward fullbright implementation for HUDs
+
+uniform sampler2D diffuseMap;  //always in sRGB space
+
+uniform vec3 emissiveColor;
+uniform sampler2D emissiveMap;
+
+out vec4 frag_color;
+
+in vec3 vary_position;
+in vec4 vertex_emissive;
+
+in vec2 basecolor_texcoord;
+in vec2 emissive_texcoord;
+
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+void main()
+{
+    vec4 basecolor = texture2D(diffuseMap, basecolor_texcoord.xy).rgba;
+
+    if (basecolor.a < minimum_alpha)
+    {
+        discard;
+    }
+
+    vec3 emissive = emissiveColor;
+    emissive *= srgb_to_linear(texture2D(emissiveMap, emissive_texcoord.xy).rgb);
+
+    float lum = max(max(emissive.r, emissive.g), emissive.b);
+    lum *= vertex_emissive.a;
+
+    // HUDs are rendered after gamma correction, output in sRGB space
+    frag_color.rgb = vec3(0);
+    frag_color.a = lum;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl
new file mode 100644
index 00000000000..75b24336c54
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl
@@ -0,0 +1,70 @@
+/** 
+ * @file pbgglowV.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, 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$
+ */
+
+
+#ifdef HAS_SKIN
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
+uniform mat4 modelview_projection_matrix;
+#endif
+
+uniform mat4 texture_matrix0;
+
+uniform mat3 texture_basecolor_matrix;
+uniform mat3 texture_emissive_matrix;
+
+in vec3 position;
+in vec4 emissive;
+
+in vec2 texcoord0;
+
+out vec2 basecolor_texcoord;
+out vec2 emissive_texcoord;
+ 
+out vec4 vertex_emissive;
+
+void main()
+{
+#ifdef HAS_SKIN
+    mat4 mat = getObjectSkinnedTransform();
+
+    mat = modelview_matrix * mat;
+
+    vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+
+    gl_Position = projection_matrix*vec4(pos,1.0);
+#else
+    //transform vertex
+    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); 
+#endif
+
+    basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy;
+    emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy;
+
+    vertex_emissive = emissive;
+}
+
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index a60d09c1546..2c5e31f579e 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -184,6 +184,8 @@ class LLRenderPass : public LLDrawPool
         PASS_NORMSPEC_EMISSIVE_RIGGED,
 		PASS_GLOW,
         PASS_GLOW_RIGGED,
+        PASS_GLTF_GLOW,
+        PASS_GLTF_GLOW_RIGGED,
 		PASS_ALPHA,
         PASS_ALPHA_RIGGED,
 		PASS_ALPHA_MASK,
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 3dda24595e8..f4b426c5ab4 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -175,9 +175,12 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
     llassert(LLPipeline::sRenderDeferred);
 
     emissive_shader = &gDeferredEmissiveProgram;
-                      
     prepare_alpha_shader(emissive_shader, true, false, water_sign);
 
+    pbr_emissive_shader = &gPBRGlowProgram;
+    prepare_alpha_shader(pbr_emissive_shader, true, false, water_sign);
+
+
     fullbright_shader   = 
         (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
         (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterAlphaProgram : 
@@ -482,7 +485,7 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)
 	}
 }
 
-void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)
+void LLDrawPoolAlpha::drawEmissive(LLDrawInfo* draw)
 {
     LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
     draw->mVertexBuffer->setBuffer();
@@ -490,7 +493,7 @@ void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)
 }
 
 
-void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
+void LLDrawPoolAlpha::renderEmissives(std::vector<LLDrawInfo*>& emissives)
 {
     emissive_shader->bind();
     emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
@@ -498,12 +501,25 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi
     for (LLDrawInfo* draw : emissives)
     {
         bool tex_setup = TexSetup(draw, false);
-        drawEmissive(mask, draw);
+        drawEmissive(draw);
         RestoreTexSetup(tex_setup);
     }
 }
 
-void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
+void LLDrawPoolAlpha::renderPbrEmissives(std::vector<LLDrawInfo*>& emissives)
+{
+    pbr_emissive_shader->bind();
+
+    for (LLDrawInfo* draw : emissives)
+    {
+        llassert(draw->mGLTFMaterial);
+        draw->mGLTFMaterial->bind(draw->mTexture);
+        draw->mVertexBuffer->setBuffer();
+        draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+    }
+}
+
+void LLDrawPoolAlpha::renderRiggedEmissives(std::vector<LLDrawInfo*>& emissives)
 {
     LLGLDepthTest depth(GL_TRUE, GL_FALSE); //disable depth writes since "emissive" is additive so sorting doesn't matter
     LLGLSLShader* shader = emissive_shader->mRiggedVariant;
@@ -513,8 +529,6 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&
     LLVOAvatar* lastAvatar = nullptr;
     U64 lastMeshId = 0;
 
-    mask |= LLVertexBuffer::MAP_WEIGHT4;
-
     for (LLDrawInfo* draw : emissives)
     {
         bool tex_setup = TexSetup(draw, false);
@@ -527,11 +541,37 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&
             lastAvatar = draw->mAvatar;
             lastMeshId = draw->mSkinInfo->mHash;
         }
-        drawEmissive(mask, draw);
+        drawEmissive(draw);
         RestoreTexSetup(tex_setup);
     }
 }
 
+void LLDrawPoolAlpha::renderRiggedPbrEmissives(std::vector<LLDrawInfo*>& emissives)
+{
+    LLGLDepthTest depth(GL_TRUE, GL_FALSE); //disable depth writes since "emissive" is additive so sorting doesn't matter
+    pbr_emissive_shader->bind(true);
+    
+    LLVOAvatar* lastAvatar = nullptr;
+    U64 lastMeshId = 0;
+
+    for (LLDrawInfo* draw : emissives)
+    {
+        if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash)
+        {
+            if (!uploadMatrixPalette(*draw))
+            { // failed to upload matrix palette, skip rendering
+                continue;
+            }
+            lastAvatar = draw->mAvatar;
+            lastMeshId = draw->mSkinInfo->mHash;
+        }
+
+        draw->mGLTFMaterial->bind(draw->mTexture);
+        draw->mVertexBuffer->setBuffer();
+        draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+    }
+}
+
 void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
@@ -600,8 +640,13 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 
             static std::vector<LLDrawInfo*> emissives;
             static std::vector<LLDrawInfo*> rigged_emissives;
+            static std::vector<LLDrawInfo*> pbr_emissives;
+            static std::vector<LLDrawInfo*> pbr_rigged_emissives;
+
             emissives.resize(0);
             rigged_emissives.resize(0);
+            pbr_emissives.resize(0);
+            pbr_rigged_emissives.resize(0);
 
 			bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
 													  || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
@@ -787,11 +832,25 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 				{
                     if (params.mAvatar != nullptr)
                     {
-                        rigged_emissives.push_back(&params);
+                        if (params.mGLTFMaterial.isNull())
+                        {
+                            rigged_emissives.push_back(&params);
+                        }
+                        else
+                        {
+                            pbr_rigged_emissives.push_back(&params);
+                        }
                     }
                     else
                     {
-                        emissives.push_back(&params);
+                        if (params.mGLTFMaterial.isNull())
+                        {
+                            emissives.push_back(&params);
+                        }
+                        else
+                        {
+                            pbr_emissives.push_back(&params);
+                        }
                     }
 				}
 			
@@ -818,14 +877,28 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
                 if (!emissives.empty())
                 {
                     light_enabled = true;
-                    renderEmissives(mask, emissives);
+                    renderEmissives(emissives);
+                    rebind = true;
+                }
+
+                if (!pbr_emissives.empty())
+                {
+                    light_enabled = true;
+                    renderPbrEmissives(pbr_emissives);
                     rebind = true;
                 }
 
                 if (!rigged_emissives.empty())
                 {
                     light_enabled = true;
-                    renderRiggedEmissives(mask, rigged_emissives);
+                    renderRiggedEmissives(rigged_emissives);
+                    rebind = true;
+                }
+
+                if (!pbr_rigged_emissives.empty())
+                {
+                    light_enabled = true;
+                    renderRiggedPbrEmissives(pbr_rigged_emissives);
                     rebind = true;
                 }
 
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index 1e10bb55663..f2f802d85e0 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -77,11 +77,14 @@ class LLDrawPoolAlpha final: public LLRenderPass
     LLGLSLShader* simple_shader = nullptr;
     LLGLSLShader* fullbright_shader = nullptr;
     LLGLSLShader* emissive_shader = nullptr;
+    LLGLSLShader* pbr_emissive_shader = nullptr;
     LLGLSLShader* pbr_shader = nullptr;
 
-    void drawEmissive(U32 mask, LLDrawInfo* draw);
-    void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);
-    void renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);
+    void drawEmissive(LLDrawInfo* draw);
+    void renderEmissives(std::vector<LLDrawInfo*>& emissives);
+    void renderRiggedEmissives(std::vector<LLDrawInfo*>& emissives);
+    void renderPbrEmissives(std::vector<LLDrawInfo*>& emissives);
+    void renderRiggedPbrEmissives(std::vector<LLDrawInfo*>& emissives);
     bool TexSetup(LLDrawInfo* draw, bool use_material);
     void RestoreTexSetup(bool tex_setup);
 
diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp
index c5413a068a9..d30fc22393f 100644
--- a/indra/newview/lldrawpoolpbropaque.cpp
+++ b/indra/newview/lldrawpoolpbropaque.cpp
@@ -59,18 +59,29 @@ void LLDrawPoolGLTFPBR::renderDeferred(S32 pass)
 
 S32 LLDrawPoolGLTFPBR::getNumPostDeferredPasses()
 {
-    return LLPipeline::sRenderingHUDs ? 1 : 0;
+    return 1;
 }
 
 void LLDrawPoolGLTFPBR::renderPostDeferred(S32 pass)
 {
-    // only HUD rendering should execute this pass
-    llassert(LLPipeline::sRenderingHUDs);
-
-    gHUDPBROpaqueProgram.bind();
-    for (U32 type : gltf_render_types)
+    if (LLPipeline::sRenderingHUDs)
     {
-        pushGLTFBatches(type);
+        gHUDPBROpaqueProgram.bind();
+        for (U32 type : gltf_render_types)
+        {
+            pushGLTFBatches(type);
+        }
+    }
+    else
+    {
+        gGL.setColorMask(false, true);
+        gPBRGlowProgram.bind();
+        pushGLTFBatches(LLRenderPass::PASS_GLTF_GLOW);
+
+        gPBRGlowProgram.bind(true);
+        pushRiggedGLTFBatches(LLRenderPass::PASS_GLTF_GLOW_RIGGED);
+
+        gGL.setColorMask(true, false);
     }
 }
 
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index 003b373e50c..f3583daa0a9 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -60,7 +60,9 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
 
     if (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
     {
-        min_alpha = mAlphaCutoff;
+        // dividing the alpha cutoff by transparency here allows the shader to compare against
+        // the alpha value of the texture without needing the transparency value
+        min_alpha = mAlphaCutoff/mBaseColor.mV[3];
     }
     shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha);
 
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index ccb2a861284..2775a988695 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -206,6 +206,8 @@ LLGLSLShader            gDeferredGenBrdfLutProgram;
 LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
 LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
 LLGLSLShader			gHUDPBROpaqueProgram;
+LLGLSLShader            gPBRGlowProgram;
+LLGLSLShader            gPBRGlowSkinnedProgram;
 LLGLSLShader			gDeferredPBROpaqueProgram;
 LLGLSLShader            gDeferredSkinnedPBROpaqueProgram;
 LLGLSLShader            gHUDPBRAlphaProgram;
@@ -1016,6 +1018,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		}
 
         gHUDPBROpaqueProgram.unload();
+        gPBRGlowProgram.unload();
         gDeferredPBROpaqueProgram.unload();
         gDeferredSkinnedPBROpaqueProgram.unload();
         gDeferredPBRAlphaProgram.unload();
@@ -1325,6 +1328,23 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         llassert(success);
     }
 
+    if (success)
+    {
+        gPBRGlowProgram.mName = " PBR Glow Shader";
+        gPBRGlowProgram.mFeatures.hasSrgb = true;
+        gPBRGlowProgram.mShaderFiles.clear();
+        gPBRGlowProgram.mShaderFiles.push_back(make_pair("deferred/pbrglowV.glsl", GL_VERTEX_SHADER));
+        gPBRGlowProgram.mShaderFiles.push_back(make_pair("deferred/pbrglowF.glsl", GL_FRAGMENT_SHADER));
+        gPBRGlowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+        success = make_rigged_variant(gPBRGlowProgram, gPBRGlowSkinnedProgram);
+        if (success)
+        {
+            success = gPBRGlowProgram.createShader(NULL, NULL);
+        }
+        llassert(success);
+    }
+
     if (success)
     {
         gHUDPBROpaqueProgram.mName = "HUD PBR Opaque Shader";
@@ -1341,6 +1361,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
         llassert(success);
     }
 
+    
+
 	if (success)
 	{
         LLGLSLShader* shader = &gDeferredPBRAlphaProgram;
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 027dea6f8de..9bd01dbdf50 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -268,6 +268,7 @@ extern LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
 extern LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
 
 extern LLGLSLShader         gHUDPBROpaqueProgram;
+extern LLGLSLShader         gPBRGlowProgram;
 extern LLGLSLShader         gDeferredPBROpaqueProgram;
 extern LLGLSLShader         gDeferredPBRAlphaProgram;
 extern LLGLSLShader         gHUDPBRAlphaProgram;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 0c5aac4d0f7..9f51509f969 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -5201,8 +5201,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		(type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) ||
 		(facep->getTextureEntry()->getFullbright());
 	
-	if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL))
+	if (!fullbright && 
+        type != LLRenderPass::PASS_GLOW && 
+        !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL))
 	{
+        llassert(false);
 		LL_WARNS() << "Non fullbright face has no normals!" << LL_ENDL;
 		return;
 	}
@@ -6798,7 +6801,14 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 
 			if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f)
 			{
-				registerFace(group, facep, LLRenderPass::PASS_GLOW);
+                if (gltf_mat)
+                {
+                    registerFace(group, facep, LLRenderPass::PASS_GLTF_GLOW);
+                }
+                else
+                {
+                    registerFace(group, facep, LLRenderPass::PASS_GLOW);
+                }
 			}
 						
 			++face_iter;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 039ad9cf8f1..65d9d4e0605 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -8443,6 +8443,7 @@ void LLPipeline::renderDeferredLighting()
                           LLPipeline::RENDER_TYPE_VOLUME,
                           LLPipeline::RENDER_TYPE_GLOW,
                           LLPipeline::RENDER_TYPE_BUMP,
+                          LLPipeline::RENDER_TYPE_GLTF_PBR,
                           LLPipeline::RENDER_TYPE_PASS_SIMPLE,
                           LLPipeline::RENDER_TYPE_PASS_ALPHA,
                           LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
@@ -8452,6 +8453,7 @@ void LLPipeline::renderDeferredLighting()
                           LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
                           LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
                           LLPipeline::RENDER_TYPE_PASS_GLOW,
+                          LLPipeline::RENDER_TYPE_PASS_GLTF_GLOW,
                           LLPipeline::RENDER_TYPE_PASS_GRASS,
                           LLPipeline::RENDER_TYPE_PASS_SHINY,
                           LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 37d5dbd9c68..282f28e736a 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -492,6 +492,8 @@ class LLPipeline
         RENDER_TYPE_PASS_POST_BUMP_RIGGED = LLRenderPass::PASS_POST_BUMP_RIGGED,
 		RENDER_TYPE_PASS_GLOW					= LLRenderPass::PASS_GLOW,
         RENDER_TYPE_PASS_GLOW_RIGGED = LLRenderPass::PASS_GLOW_RIGGED,
+        RENDER_TYPE_PASS_GLTF_GLOW = LLRenderPass::PASS_GLTF_GLOW,
+        RENDER_TYPE_PASS_GLTF_GLOW_RIGGED = LLRenderPass::PASS_GLTF_GLOW_RIGGED,
 		RENDER_TYPE_PASS_ALPHA					= LLRenderPass::PASS_ALPHA,
 		RENDER_TYPE_PASS_ALPHA_MASK				= LLRenderPass::PASS_ALPHA_MASK,
         RENDER_TYPE_PASS_ALPHA_MASK_RIGGED = LLRenderPass::PASS_ALPHA_MASK_RIGGED,
-- 
GitLab