diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index a53b68a50fd4de9a81866f6b019eaa3a29363fd3..bdabd657e108e2850b7cbb6932ca7a700e1f16de 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -41,6 +41,8 @@ namespace tinygltf
     class Model;
 }
 
+class LLTextureEntry;
+
 class LLGLTFMaterial : public LLRefCount
 {
 public:
@@ -193,6 +195,11 @@ class LLGLTFMaterial : public LLRefCount
     // True if setBaseMaterial() was just called
     bool isClearedForBaseMaterial();
 
+    // For local materials, they have to keep track of where
+    // they are assigned to for full updates
+    virtual void addTextureEntry(LLTextureEntry* te) {};
+    virtual void removeTextureEntry(LLTextureEntry* te) {};
+
 private:
     template<typename T>
     void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id);
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 49f67918f8c83f60eb7db971670d32a7abc993b7..a665db378b358dc040a30da9d8311d19a8f1ef34 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -112,7 +112,15 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
 
         mMaterialID = rhs.mMaterialID;
 
+        if (mGLTFMaterial)
+        {
+            mGLTFMaterial->removeTextureEntry(this);
+        }
         mGLTFMaterial = rhs.mGLTFMaterial;
+        if (mGLTFMaterial)
+        {
+            mGLTFMaterial->addTextureEntry(this);
+        }
         
         if (rhs.mGLTFMaterialOverrides.notNull())
         {
@@ -155,6 +163,12 @@ LLTextureEntry::~LLTextureEntry()
 		delete mMediaEntry;
 		mMediaEntry = NULL;
 	}
+
+    if (mGLTFMaterial)
+    {
+        mGLTFMaterial->removeTextureEntry(this);
+        mGLTFMaterial = NULL;
+    }
 }
 
 bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
@@ -524,7 +538,20 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin
         // NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID
         llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial());
 
+        if (mGLTFMaterial)
+        {
+            // Local materials have to keep track
+            // due to update mechanics
+            mGLTFMaterial->removeTextureEntry(this);
+        }
+
         mGLTFMaterial = material;
+
+        if (mGLTFMaterial)
+        {
+            mGLTFMaterial->addTextureEntry(this);
+        }
+
         if (mGLTFMaterial == nullptr)
         {
             setGLTFRenderMaterial(nullptr);
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index 80074cc65533307cea417bb8b47896c0cd10d04a..2e71b4fa87b8a730d6088932c334e835a16f4a77 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -46,6 +46,18 @@ LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial()
     
 }
 
+LLFetchedGLTFMaterial& LLFetchedGLTFMaterial::operator=(const LLFetchedGLTFMaterial& rhs)
+{
+    LLGLTFMaterial::operator =(rhs);
+
+    mBaseColorTexture = rhs.mBaseColorTexture;
+    mNormalTexture = rhs.mNormalTexture;
+    mMetallicRoughnessTexture = rhs.mMetallicRoughnessTexture;
+    mEmissiveTexture = rhs.mEmissiveTexture;
+
+    return *this;
+}
+
 void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
 {
     // glTF 2.0 Specification 3.9.4. Alpha Coverage
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
index 0b51770493624367e60a8e2b7ec9cc9947e72129..166865728146f05a5b9ec4c1d8257eeeca4a7591 100644
--- a/indra/newview/llfetchedgltfmaterial.h
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -39,6 +39,8 @@ class LLFetchedGLTFMaterial: public LLGLTFMaterial
     LLFetchedGLTFMaterial();
     virtual ~LLFetchedGLTFMaterial();
 
+    LLFetchedGLTFMaterial& operator=(const LLFetchedGLTFMaterial& rhs);
+
     // If this material is loaded, fire the given function
     void onMaterialComplete(std::function<void()> material_complete);
 
diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp
index 996b168262b39d83700baa064e8404b061be8307..d464ea05715e3aea58cc54b7d290a3f1115cc852 100644
--- a/indra/newview/lllocalgltfmaterials.cpp
+++ b/indra/newview/lllocalgltfmaterials.cpp
@@ -45,6 +45,7 @@
 #include "llmaterialmgr.h"
 #include "llnotificationsutil.h"
 #include "llscrolllistctrl.h"
+#include "lltextureentry.h"
 #include "lltinygltfhelper.h"
 #include "llviewertexture.h"
 
@@ -118,6 +119,15 @@ S32 LLLocalGLTFMaterial::getIndexInFile() const
     return mMaterialIndex;
 }
 
+void LLLocalGLTFMaterial::addTextureEntry(LLTextureEntry* te)
+{
+    mTextureEntires.insert(te);
+}
+void LLLocalGLTFMaterial::removeTextureEntry(LLTextureEntry* te)
+{
+    mTextureEntires.erase(te);
+}
+
 /* update functions */
 bool LLLocalGLTFMaterial::updateSelf()
 {
@@ -154,6 +164,27 @@ bool LLLocalGLTFMaterial::updateSelf()
                     gGLTFMaterialList.addMaterial(mWorldID, this);
 
                     mUpdateRetries = LL_LOCAL_UPDATE_RETRIES;
+
+                    for (LLTextureEntry* entry : mTextureEntires)
+                    {
+                        // Normally a change in applied material id is supposed to
+                        // drop overrides thus reset material, but local materials
+                        // currently reuse their existing asset id, and purpose is
+                        // to preview how material will work in-world, overrides
+                        // included, so do an override to render update instead.
+                        LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride();
+                        if (override_mat)
+                        {
+                            // do not create a new material, reuse existing pointer
+                            LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial();
+                            if (render_mat)
+                            {
+                                *render_mat = *this;
+                                render_mat->applyOverride(*override_mat);
+                            }
+                        }
+                    }
+
                     updated = true;
                 }
 
diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h
index 6919b9b4b25d25f386ad99b8549c985571d96d7d..1442b83a404d8887420288e2c08cc196495fec47 100644
--- a/indra/newview/lllocalgltfmaterials.h
+++ b/indra/newview/lllocalgltfmaterials.h
@@ -34,6 +34,7 @@
 class LLScrollListCtrl;
 class LLGLTFMaterial;
 class LLViewerObject;
+class LLTextureEntry;
 
 class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial
 {
@@ -48,6 +49,9 @@ class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial
     LLUUID		getWorldID() const;
     S32			getIndexInFile() const;
 
+    void addTextureEntry(LLTextureEntry* te) override;
+    void removeTextureEntry(LLTextureEntry* te) override;
+
 public:
     bool updateSelf();
 
@@ -77,6 +81,7 @@ class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial
     ELinkStatus mLinkStatus;
     S32         mUpdateRetries;
     S32         mMaterialIndex; // Single file can have more than one
+    std::set<LLTextureEntry*> mTextureEntires;
 };
 
 class LLLocalGLTFMaterialTimer : public LLEventTimer
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index cb1694821d12dec8a82a36abf7d98f2ba0846b6a..a3a825c199dd63cea01a4e34974526a3c4673351 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -5368,8 +5368,10 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
 
     LLFetchedGLTFMaterial* src_mat = (LLFetchedGLTFMaterial*) tep->getGLTFMaterial();
 
+    // if override mat exists, we must also have a source mat
     if (!src_mat)
-    { // we can get into this state if an override has arrived before the viewer has
+    {
+        // we can get into this state if an override has arrived before the viewer has
         // received or handled an update, return TEM_CHANGE_NONE to signal to LLGLTFMaterialList that it
         // should queue the update for later
         return retval;
@@ -5383,10 +5385,7 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
 
     tep->setGLTFMaterialOverride(override_mat);
 
-    // if override mat exists, we must also have a source mat
-    llassert(override_mat ? bool(src_mat) : true);
-
-    if (override_mat && src_mat)
+    if (override_mat)
     {
         LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat);
         render_mat->applyOverride(*override_mat);
diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml
index 1c58ea69778062307e00810e1cbbcc85501535c1..a6a401f43ec106167785b48a862b31d3a736e20a 100644
--- a/indra/newview/skins/default/xui/en/floater_material_editor.xml
+++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml
@@ -29,7 +29,6 @@
    color="DkGray2"
    opaque="true"
    tab_stop="true"
-   border="false"
    reserve_scroll_corner="false">
     <panel
      name="panel_material"