diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
index 9a6453ea482e9ecc97fd8fa027551e65b4be1443..f9de0c792959f9f0a4c2ad6247fdc62ae8c22f1b 100644
--- a/indra/llcommon/llpointer.h
+++ b/indra/llcommon/llpointer.h
@@ -340,4 +340,28 @@ class LLCopyOnWritePointer : public LLPointer<Type>
 	bool mStayUnique;
 };
 
+
+// boost hash adapter
+template <class Type>
+struct boost::hash<LLPointer<Type>>
+{
+    typedef LLPointer<Type> argument_type;
+    typedef std::size_t result_type;
+    result_type operator()(argument_type const& s) const
+    {
+        return (std::size_t) s.get();
+    }
+};
+
+// Adapt boost hash to std hash
+namespace std
+{
+    template<class Type> struct hash<LLPointer<Type>>
+    {
+        std::size_t operator()(LLPointer<Type> const& s) const noexcept
+        {
+            return boost::hash<LLPointer<Type>>()(s);
+        }
+    };
+}
 #endif
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 2a0f4c93ac40f1b9ab8f4ddd68d218e87d11b93f..cdd8ae88bb93b980abcfd6e73ba0aa3da1998fcd 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -42,6 +42,7 @@
 #include "llrect.h"
 #include "llappviewer.h" // for gFrameTimeSeconds
 #include "llvieweroctree.h"
+#include <unordered_set>
 
 class LLCamera;
 class LLDrawPool;
@@ -223,7 +224,8 @@ class LLDrawable
 	friend class LLDrawPool;
 	friend class LLSpatialBridge;
 	
-	typedef std::set<LLPointer<LLDrawable> > drawable_set_t;
+	typedef std::unordered_set<LLPointer<LLDrawable> > drawable_set_t;
+    typedef std::set<LLPointer<LLDrawable> > ordered_drawable_set_t;
 	typedef std::vector<LLPointer<LLDrawable> > drawable_vector_t;
 	typedef std::list<LLPointer<LLDrawable> > drawable_list_t;
 	typedef std::queue<LLPointer<LLDrawable> > drawable_queue_t;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index aebeeb21acf6119ce00d11d60a3accf4efde84ed..251af1b46e4d80b5a1ef09f282cc3c0f0e2692da 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -7234,22 +7234,11 @@ void LLViewerObject::setRenderMaterialIDs(const LLRenderMaterialParams* material
 {
     if (!local_origin)
     {
-        const S32 num_tes = llmin((S32)getNumTEs(), (S32)getNumFaces()); // avatars have TEs but no faces
-        for (S32 te = 0; te < num_tes; ++te)
+        for (S32 te = 0; te < getNumTEs(); ++te)
         {
             const LLUUID& id = material_params ? material_params->getMaterial(te) : LLUUID::null;
-            if (id.notNull())
-            {
-                getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id));
-                setHasRenderMaterialParams(true);
-            }
-            else
-            {
-                getTE(te)->setGLTFMaterial(nullptr);
-            }
+            setRenderMaterialID(te, id, false);
         }
-        faceMappingChanged();
-        gPipeline.markTextured(mDrawable);
     }
 }
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index b60b64ed1fbeff1fa90fa60fa69630b6b4ba96bc..a0fec90f87a0ff587b854a81a85c8497e96c1f63 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6150,7 +6150,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 				
 		// FIND NEW LIGHTS THAT ARE IN RANGE
 		light_set_t new_nearby_lights;
-		for (LLDrawable::drawable_set_t::iterator iter = mLights.begin();
+		for (LLDrawable::ordered_drawable_set_t::iterator iter = mLights.begin();
 			 iter != mLights.end(); ++iter)
 		{
 			LLDrawable* drawable = *iter;
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 59858cfcfc801c8c35ef9daf563e251a8697f6f9..3b41d603565e199eaa7b0220f43884883f22d118 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -798,7 +798,7 @@ class LLPipeline
 	};
 	typedef std::set< Light, Light::compare > light_set_t;
 	
-	LLDrawable::drawable_set_t		mLights;
+	LLDrawable::ordered_drawable_set_t	mLights;
 	light_set_t						mNearbyLights; // lights near camera
 	LLColor4						mHWLightColors[8];