diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index b4299fc2f5ab0d1cdc031f028a8ae2e41cbed6a6..c2b390d2eb4376a59c30c4f15b40e9b2845dab5d 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -1049,7 +1049,6 @@ BOOL LLAvatarAppearance::loadSkeletonNode ()
 	mRoot->addChild(mMeshLOD[MESH_ID_UPPER_BODY]);
 	mRoot->addChild(mMeshLOD[MESH_ID_LOWER_BODY]);
 	mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]);
-	mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
 
 	LLAvatarJoint *skull = (LLAvatarJoint*)mRoot->findJoint("mSkull");
 	if (skull)
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 5c1cb9e159714f0ae9dd1b153e7319034726b985..5381664e4fbf6bd991c90c85cebe27cf4d78dc3f 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -168,8 +168,8 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
 	is_deferred_render = true;
 	
 	if (LLPipeline::sImpostorRender)
-	{ //impostor pass does not have rigid or impostor rendering
-		pass += 2;
+	{ //impostor pass does not have impostor rendering
+		++pass;
 	}
 
 	switch (pass)
@@ -195,7 +195,7 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)
 
 	if (LLPipeline::sImpostorRender)
 	{
-		pass += 2;
+		++pass;
 	}
 
 	switch (pass)
@@ -415,7 +415,7 @@ void LLDrawPoolAvatar::render(S32 pass)
     LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
 	if (LLPipeline::sImpostorRender)
 	{
-		renderAvatars(NULL, pass+2);
+		renderAvatars(NULL, ++pass);
 		return;
 	}
 
@@ -430,7 +430,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
 
 	if (LLPipeline::sImpostorRender)
 	{ //impostor render does not have impostors or rigid rendering
-		pass += 2;
+		++pass;
 	}
 
 	switch (pass)
@@ -458,7 +458,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
 
 	if (LLPipeline::sImpostorRender)
 	{
-		pass += 2;		
+		++pass;
 	}
 
 	switch (pass)
diff --git a/indra/newview/llfloatertexturepicker.cpp b/indra/newview/llfloatertexturepicker.cpp
index bcf6c80749a59a24da5e159223c0311c4eafb1f2..eee705907215c4b48efe0ba53b6e8e915e9646c4 100644
--- a/indra/newview/llfloatertexturepicker.cpp
+++ b/indra/newview/llfloatertexturepicker.cpp
@@ -147,12 +147,20 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti
 				mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO);
 			}
 		}
-		
-
-		
 	}
 }
 
+void LLFloaterTexturePicker::setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection)
+{
+    LLUUID asset_id = itemp->getAssetUUID();
+    if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL && asset_id.isNull())
+    {
+        // If an inventory item has a null asset, consider it a valid blank material(gltf)
+        asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+    }
+    setImageID(asset_id, set_selection);
+}
+
 void LLFloaterTexturePicker::setActive( BOOL active )					
 {
 	if (!active && getChild<LLUICtrl>("Pipette")->getValue().asBoolean())
@@ -303,7 +311,7 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
 		{
 			if (drop)
 			{
-				setImageID( item->getAssetUUID() );
+                setImageIDFromItem(item);
 				commitIfImmediateSet();
 			}
 
@@ -492,6 +500,7 @@ void LLFloaterTexturePicker::draw()
             if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
             {
                 mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID);
+                llassert(mGLTFMaterial == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr);
             }
             else
             {
@@ -604,6 +613,11 @@ void LLFloaterTexturePicker::draw()
 
 const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library)
 {
+	if (asset_id.isNull())
+	{
+		return LLUUID::null;
+	}
+
 	LLViewerInventoryCategory::cat_array_t cats;
 	LLViewerInventoryItem::item_array_t items;
 	LLAssetIDMatches asset_id_matches(asset_id);
@@ -800,7 +814,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
 			{
 				mNoCopyTextureSelected = TRUE;
 			}
-			setImageID(itemp->getAssetUUID(),false);
+            setImageIDFromItem(itemp, false);
 			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
 
 			if(!mPreviewSettingChanged)
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 8bbff470e01382918fbb711375d4fd97c7ea6c0f..b102b5acde73969a78a9baad0d6e0728f5442ef5 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -964,7 +964,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
 		BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
 
         bool has_pbr_material;
-        updateUIGLTF(objectp, has_pbr_material, force_set_values);
+        bool has_faces_without_pbr;
+        updateUIGLTF(objectp, has_pbr_material, has_faces_without_pbr, force_set_values);
 
         const bool has_material = !has_pbr_material;
 
@@ -1489,7 +1490,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
 			getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)(fullbright_flag != 0));
 			getChildView("checkbox fullbright")->setEnabled(editable && !has_pbr_material);
 			getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);
-            getChild<LLComboBox>("combobox matmedia")->setEnabledByValue("Materials", !has_pbr_material);
+            mComboMatMedia->setEnabledByValue("Materials", !has_pbr_material);
 		}
 		
 		// Repeats per meter
@@ -1746,7 +1747,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
 	}
 }
 
-void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool force_set_values)
+void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool& has_faces_without_pbr, bool force_set_values)
 {
     has_pbr_material = false;
 
@@ -1759,9 +1760,7 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
     {
         LLUUID pbr_id;
         bool identical_pbr;
-        LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr);
-
-        has_pbr_material = pbr_id.notNull();
+        LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr, has_pbr_material, has_faces_without_pbr);
 
         pbr_ctrl->setTentative(identical_pbr ? FALSE : TRUE);
         pbr_ctrl->setEnabled(editable && has_pbr_capabilities);
@@ -1769,13 +1768,13 @@ void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material,
     }
 
     getChildView("pbr_from_inventory")->setEnabled(editable && has_pbr_capabilities);
-    getChildView("edit_selected_pbr")->setEnabled(editable && has_pbr_material && has_pbr_capabilities);
-    getChildView("save_selected_pbr")->setEnabled(objectp->permCopy() && has_pbr_material && has_pbr_capabilities);
+    getChildView("edit_selected_pbr")->setEnabled(editable && has_pbr_material && !has_faces_without_pbr && has_pbr_capabilities);
+    getChildView("save_selected_pbr")->setEnabled(objectp->permCopy() && has_pbr_material && !has_faces_without_pbr && has_pbr_capabilities);
 
     const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled();
     if (show_pbr)
     {
-        const bool new_state = has_pbr_capabilities && has_pbr_material;
+        const bool new_state = has_pbr_capabilities && has_pbr_material && !has_faces_without_pbr;
 
         LLUICtrl* gltfCtrlTextureScaleU = getChild<LLUICtrl>("gltfTextureScaleU");
         LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV");
@@ -4964,16 +4963,34 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)
 	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
 }
 
-void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical)
+void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical, bool& has_faces_with_pbr, bool& has_faces_without_pbr)
 {
     struct LLSelectedTEGetmatId : public LLSelectedTEGetFunctor<LLUUID>
     {
+        LLSelectedTEGetmatId()
+            : mHasFacesWithoutPBR(false)
+            , mHasFacesWithPBR(false)
+        {
+        }
         LLUUID get(LLViewerObject* object, S32 te_index)
         {
-            return object->getRenderMaterialID(te_index);
+            LLUUID pbr_id = object->getRenderMaterialID(te_index);
+            if (pbr_id.isNull())
+            {
+                mHasFacesWithoutPBR = true;
+            }
+            else
+            {
+                mHasFacesWithPBR = true;
+            }
+            return pbr_id;
         }
+        bool mHasFacesWithoutPBR;
+        bool mHasFacesWithPBR;
     } func;
     identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, id);
+    has_faces_with_pbr = func.mHasFacesWithPBR;
+    has_faces_without_pbr = func.mHasFacesWithoutPBR;
 }
 
 void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material)
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index b6d77b237416c84b393695b9e1226af1df478fd4..eaf82a26be01ca3b9216b11f17de2ff936bdf93a 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -476,7 +476,7 @@ class LLPanelFace : public LLPanel
     void onTextureSelectionChanged(LLInventoryItem* itemp);
     void onPbrSelectionChanged(LLInventoryItem* itemp);
 
-    void updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool force_set_values);
+    void updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool& has_faces_without_pbr, bool force_set_values);
     void updateVisibilityGLTF();
 
     void updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func);
@@ -619,7 +619,7 @@ class LLPanelFace : public LLPanel
 		static void getFace(class LLFace*& face_to_return, bool& identical_face);
 		static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face);
 		static void getTexId(LLUUID& id, bool& identical);
-        static void getPbrMaterialId(LLUUID& id, bool& identical);
+        static void getPbrMaterialId(LLUUID& id, bool& identical, bool& has_pbr, bool& has_faces_without_pbr);
 		static void getObjectScaleS(F32& scale_s, bool& identical);
 		static void getObjectScaleT(F32& scale_t, bool& identical);
 		static void getMaxDiffuseRepeats(F32& repeats, bool& identical);
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index b2ad2bf55b022995269f12475ec28cede80dfcb1..7b77d4a0791cee2acd966bbcd6373c4510be277e 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -222,12 +222,20 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti
 				mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO);
 			}
 		}
-		
-
-		
 	}
 }
 
+void LLFloaterTexturePicker::setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection)
+{
+    LLUUID asset_id = itemp->getAssetUUID();
+    if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL && asset_id.isNull())
+    {
+        // If an inventory item has a null asset, consider it a valid blank material(gltf)
+        asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+    }
+    setImageID(asset_id, set_selection);
+}
+
 void LLFloaterTexturePicker::setActive( BOOL active )					
 {
 	if (!active && getChild<LLUICtrl>("Pipette")->getValue().asBoolean())
@@ -378,7 +386,7 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
 		{
 			if (drop)
 			{
-				setImageID( item->getAssetUUID() );
+                setImageIDFromItem(item);
 				commitIfImmediateSet();
 			}
 
@@ -675,6 +683,11 @@ void LLFloaterTexturePicker::draw()
 
 const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library)
 {
+	if (asset_id.isNull())
+	{
+		return LLUUID::null;
+	}
+
 	LLViewerInventoryCategory::cat_array_t cats;
 	LLViewerInventoryItem::item_array_t items;
 	LLAssetIDMatches asset_id_matches(asset_id);
@@ -850,7 +863,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
 			{
 				mNoCopyTextureSelected = TRUE;
 			}
-			setImageID(itemp->getAssetUUID(),false);
+            setImageIDFromItem(itemp, false);
 			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
 
 			if(!mPreviewSettingChanged)
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index cf51be6b4393806e21f3181d2b1d13e16fdf6896..9d1ff3d53afd58ab781db346c11f5c15eddd68dd 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -2915,7 +2915,12 @@ bool enable_object_inspect()
 
 struct LLSelectedTEGetmatIdAndPermissions : public LLSelectedTEFunctor
 {
-    LLSelectedTEGetmatIdAndPermissions() : mCanCopy(true), mCanModify(true), mCanTransfer(true) {}
+    LLSelectedTEGetmatIdAndPermissions()
+        : mCanCopy(true)
+        , mCanModify(true)
+        , mCanTransfer(true)
+        , mHasNonPbrFaces(false)
+    {}
     bool apply(LLViewerObject* objectp, S32 te_index)
     {
         mCanCopy &= (bool)objectp->permCopy();
@@ -2926,11 +2931,16 @@ struct LLSelectedTEGetmatIdAndPermissions : public LLSelectedTEFunctor
         {
             mMaterialId = mat_id;
         }
+        else
+        {
+            mHasNonPbrFaces = true;
+        }
         return true;
     }
     bool mCanCopy;
     bool mCanModify;
     bool mCanTransfer;
+    bool mHasNonPbrFaces;
     LLUUID mMaterialId;
 };
 
@@ -2943,7 +2953,7 @@ bool enable_object_edit_gltf_material()
 
     LLSelectedTEGetmatIdAndPermissions func;
     LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
-    return func.mCanModify && func.mMaterialId.notNull();
+    return func.mCanModify && !func.mHasNonPbrFaces;
 }
 
 bool enable_object_open()
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index d362f52db6af617b3939ecc5678bd7ff8ea0a517..1f9a54668a755b3667fbc85a5886bbaab620e197 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -627,13 +627,17 @@ void LLViewerOctreeGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntr
 //virtual 
 void LLViewerOctreeGroup::handleDestruction(const TreeNode* node)
 {
+    if (isDead())
+    {
+        return;
+    }
+    setState(DEAD);
 	for (OctreeNode::element_iter i = mOctreeNode->getDataBegin(), i_end = mOctreeNode->getDataEnd(); i != i_end; ++i)
 	{
 		LLViewerOctreeEntry* obj = *i;
 		if (obj && obj->getGroup() == this)
 		{
 			obj->nullGroup();
-			//obj->setGroup(NULL);
 		}
 	}
 	mOctreeNode = NULL;
@@ -724,8 +728,7 @@ bool LLViewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4
 		newMin = minMax[0];
 		newMax = minMax[1];
 
-		OctreeNode::const_element_iter i_end = node->getDataEnd();
-		for (++i; i != i_end; ++i)
+		for (++i; i != node->getDataEnd(); ++i)
 		{
 			entry = *i;
 			minMax = entry->getSpatialExtents();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 1fad7d8ec2cd5d5e2930579914e451ddd2caa0ad..56f8967c3c5b2f0f8ccca0d6bc98a042127e3a5f 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5432,11 +5432,6 @@ U32 LLVOAvatar::renderRigid()
 	{
 		return 0;
 	}
-	
-	if (!mIsBuilt)
-	{
-		return 0;
-	}
 
 	if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
 	{
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 92af626c313b98062d79672435ae00f1fca94a88..554f3b72f769173e236354f9a5b52880c0fe74a8 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2621,8 +2621,11 @@ void LLPipeline::doOcclusion(LLCamera& camera)
 		for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
 		{
 			LLSpatialGroup* group = *iter;
-			group->doOcclusion(&camera);
-			group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
+            if (!group->isDead())
+            {
+                group->doOcclusion(&camera);
+                group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
+            }
 		}
 	
 		//apply occlusion culling to object cache tree
@@ -3051,6 +3054,10 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
 	for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(), iter_end = sCull->endDrawableGroups(); iter != iter_end; ++iter)
 	{
 		LLSpatialGroup* group = *iter;
+        if (group->isDead())
+        {
+            continue;
+        }
 		group->checkOcclusion();
 		if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED))
 		{
@@ -3110,6 +3117,10 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
 	for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(), iter_end = sCull->endVisibleGroups(); iter != iter_end; ++iter)
 	{
 		LLSpatialGroup* group = *iter;
+        if (group->isDead())
+        {
+            continue;
+        }
 		group->checkOcclusion();
 		if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED))
 		{
@@ -3271,7 +3282,12 @@ void forAllDrawables(LLCullResult::sg_iterator begin,
 {
 	for (LLCullResult::sg_iterator i = begin; i != end; ++i)
 	{
-		for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(), j_end = (*i)->getDataEnd(); j != j_end; ++j)
+        LLSpatialGroup* group = *i;
+        if (group->isDead())
+        {
+            continue;
+        }
+		for (LLSpatialGroup::element_iter j = group->getDataBegin(); j != group->getDataEnd(); ++j)
 		{
 			if((*j)->hasDrawable())
 			{
@@ -3480,6 +3496,10 @@ void LLPipeline::postSort(LLCamera &camera)
         for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
         {
             LLSpatialGroup *group = *i;
+            if (group->isDead())
+            {
+                continue;
+            }
             if (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
             {
                 group->rebuildGeom();
@@ -3498,6 +3518,12 @@ void LLPipeline::postSort(LLCamera &camera)
     for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
     {
         LLSpatialGroup *group = *i;
+
+        if (group->isDead())
+        {
+            continue;
+        }
+
         if ((sUseOcclusion && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) ||
             (RenderAutoHideSurfaceAreaLimit > 0.f &&
              group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit * llmax(group->mObjectBoxSize, 10.f)))