diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 633ef44ce8892a608529c4a0f8002a7cf4f5960e..2e1c206d405596f6dced43bff31823888209a257 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -697,6 +697,18 @@ void teardown_texture_matrix(LLDrawInfo& params)
     }
 }
 
+void LLRenderPass::pushGLTFBatches(U32 type, bool textured)
+{
+    if (textured)
+    {
+        pushGLTFBatches(type);
+    }
+    else
+    {
+        pushRiggedGLTFBatches(type);
+    }
+}
+
 void LLRenderPass::pushGLTFBatches(U32 type)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
@@ -712,6 +724,21 @@ void LLRenderPass::pushGLTFBatches(U32 type)
     }
 }
 
+void LLRenderPass::pushUntexturedGLTFBatches(U32 type)
+{
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+    auto* begin = gPipeline.beginRenderMap(type);
+    auto* end = gPipeline.endRenderMap(type);
+    for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+    {
+        LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushGLTFBatch");
+        LLDrawInfo& params = **i;
+        LLCullResult::increment_iterator(i, end);
+
+        pushUntexturedGLTFBatch(params);
+    }
+}
+
 void LLRenderPass::pushGLTFBatch(LLDrawInfo& params)
 {
     auto& mat = params.mGLTFMaterial;
@@ -730,6 +757,30 @@ void LLRenderPass::pushGLTFBatch(LLDrawInfo& params)
     teardown_texture_matrix(params);
 }
 
+void LLRenderPass::pushUntexturedGLTFBatch(LLDrawInfo& params)
+{
+    auto& mat = params.mGLTFMaterial;
+
+    LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
+
+    applyModelMatrix(params);
+
+    params.mVertexBuffer->setBuffer();
+    params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+}
+
+void LLRenderPass::pushRiggedGLTFBatches(U32 type, bool textured)
+{
+    if (textured)
+    {
+        pushRiggedGLTFBatches(type);
+    }
+    else
+    {
+        pushUntexturedRiggedGLTFBatches(type);
+    }
+}
+
 void LLRenderPass::pushRiggedGLTFBatches(U32 type)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
@@ -748,6 +799,25 @@ void LLRenderPass::pushRiggedGLTFBatches(U32 type)
     }
 }
 
+void LLRenderPass::pushUntexturedRiggedGLTFBatches(U32 type)
+{
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+    LLVOAvatar* lastAvatar = nullptr;
+    U64 lastMeshId = 0;
+
+    auto* begin = gPipeline.beginRenderMap(type);
+    auto* end = gPipeline.endRenderMap(type);
+    for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+    {
+        LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushRiggedGLTFBatch");
+        LLDrawInfo& params = **i;
+        LLCullResult::increment_iterator(i, end);
+
+        pushUntexturedRiggedGLTFBatch(params, lastAvatar, lastMeshId);
+    }
+}
+
+
 void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId)
 {
     if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
@@ -760,3 +830,15 @@ void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvat
     pushGLTFBatch(params);
 }
 
+void LLRenderPass::pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId)
+{
+    if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
+    {
+        uploadMatrixPalette(params);
+        lastAvatar = params.mAvatar;
+        lastMeshId = params.mSkinInfo->mHash;
+    }
+
+    pushUntexturedGLTFBatch(params);
+}
+
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index d5ef734c4b9e9ad2eb632d406cd4873eefb3d3cc..5414dba6bf5a32318814b73a2197e5504ec2ebad 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -356,10 +356,29 @@ class LLRenderPass : public LLDrawPool
 
     void pushRiggedBatches(U32 type, bool texture = true, bool batch_textures = false);
     void pushUntexturedRiggedBatches(U32 type);
+
+    // push full GLTF batches
+    // assumes draw infos of given type have valid GLTF materials
     void pushGLTFBatches(U32 type);
-    void pushGLTFBatch(LLDrawInfo& params);
+
+    // like pushGLTFBatches, but will not bind textures or set up texture transforms
+    void pushUntexturedGLTFBatches(U32 type);
+
+    // helper function for dispatching to textured or untextured pass based on bool
+    void pushGLTFBatches(U32 type, bool textured);
+
+
+    // rigged variants of above
     void pushRiggedGLTFBatches(U32 type);
+    void pushRiggedGLTFBatches(U32 type, bool textured);
+    void pushUntexturedRiggedGLTFBatches(U32 type);
+
+    // push a single GLTF draw call
+    void pushGLTFBatch(LLDrawInfo& params);
     void pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId);
+    void pushUntexturedGLTFBatch(LLDrawInfo& params);
+    void pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId);
+
 	void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false);
     void pushRiggedMaskBatches(U32 type, bool texture = true, bool batch_textures = false);
 	void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 25f24525e2a6967891c52d31ced1991deac85236..35e19b5ca0fdff3c2b03f3035066c98c2b481a26 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -514,6 +514,7 @@ void LLDrawPoolAlpha::renderPbrEmissives(std::vector<LLDrawInfo*>& emissives)
     for (LLDrawInfo* draw : emissives)
     {
         llassert(draw->mGLTFMaterial);
+        LLGLDisable cull_face(draw->mGLTFMaterial->mDoubleSided ? GL_CULL_FACE : 0);
         draw->mGLTFMaterial->bind(draw->mTexture);
         draw->mVertexBuffer->setBuffer();
         draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
@@ -569,6 +570,7 @@ void LLDrawPoolAlpha::renderRiggedPbrEmissives(std::vector<LLDrawInfo*>& emissiv
             lastMeshId = draw->mSkinInfo->mHash;
         }
 
+        LLGLDisable cull_face(draw->mGLTFMaterial->mDoubleSided ? GL_CULL_FACE : 0);
         draw->mGLTFMaterial->bind(draw->mTexture);
         draw->mVertexBuffer->setBuffer();
         draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index db962febdaaa97fdbdb3aaad958444faca86e7aa..45203f48cfb7dba63824349f93079bc55337773e 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -819,7 +819,7 @@ const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
 
 const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb");
 const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("651510b8-5f4d-8991-1592-e7eeab2a5a06");
-const LLUUID LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY("6c83e853-e7f8-cad7-8ee6-5f31c453721c");
+const LLUUID LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY("cef49723-0292-af49-9b14-9598a616b8a3");
 const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("084e26cd-a900-28e8-08d0-64a9de5c15e2");
 const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("8a01b97a-cb20-c1ea-ac63-f7ea84ad0090");
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 175e559569b102c61990a82e947762811648d0ef..41821e671870c84d6d91da66107a8d673b0bfd45 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6627,6 +6627,25 @@ void LLPipeline::renderObjects(U32 type, bool texture, bool batch_texture, bool
 	gGLLastMatrix = NULL;		
 }
 
+void LLPipeline::renderGLTFObjects(U32 type, bool texture, bool rigged)
+{
+    assertInitialized();
+    gGL.loadMatrix(gGLModelView);
+    gGLLastMatrix = NULL;
+
+    if (rigged)
+    {
+        mSimplePool->pushRiggedGLTFBatches(type + 1, texture);
+    }
+    else
+    {
+        mSimplePool->pushGLTFBatches(type, texture);
+    }
+
+    gGL.loadMatrix(gGLModelView);
+    gGLLastMatrix = NULL;
+}
+
 // Currently only used for shadows -Cosmic,2023-04-19
 void LLPipeline::renderAlphaObjects(bool rigged)
 {
@@ -8691,8 +8710,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
         LLRenderPass::PASS_NORMMAP,
         LLRenderPass::PASS_NORMMAP_EMISSIVE,
         LLRenderPass::PASS_NORMSPEC,
-        LLRenderPass::PASS_NORMSPEC_EMISSIVE,
-        LLRenderPass::PASS_GLTF_PBR
+        LLRenderPass::PASS_NORMSPEC_EMISSIVE
     };
 
     LLGLEnable cull(GL_CULL_FACE);
@@ -8755,6 +8773,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
             renderObjects(type, false, false, rigged);
         }
 
+        renderGLTFObjects(LLRenderPass::PASS_GLTF_PBR, false, rigged);
+
         gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
     }
 
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index ee6ab5c1757d21d73032a9d5d9a7f410b15e334a..a1023e1899854c2a741f8bf285017763c369ea2e 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -263,7 +263,8 @@ class LLPipeline
 	void forAllVisibleDrawables(void (*func)(LLDrawable*));
 
     void renderObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
-
+    void renderGLTFObjects(U32 type, bool texture = true, bool rigged = false);
+    
     void renderAlphaObjects(bool rigged = false);
 	void renderMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
     void renderFullbrightMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);