diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index fda2fc960bb248e1f972bdde664c22f3f4eab0c0..061470316c9b19f0c2f0b30e69b09ddfce8a6e94 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -296,6 +296,7 @@ set(viewer_SOURCE_FILES
     llfloatermyscripts.cpp
     llfloatermyenvironment.cpp
     llfloaternamedesc.cpp
+    llfloaternewfeaturenotification.cpp
     llfloaternewlocalinventory.cpp
     llfloaternotificationsconsole.cpp
     llfloaternotificationstabbed.cpp
@@ -1019,6 +1020,7 @@ set(viewer_HEADER_FILES
     llfloatermyscripts.h
     llfloatermyenvironment.h
     llfloaternamedesc.h
+    llfloaternewfeaturenotification.h
     llfloaternewlocalinventory.h
     llfloaternotificationsconsole.h
     llfloaternotificationstabbed.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index b72c1e28d236d70d123556a26d667d6e90de1a6b..2ffd2133cbda0250edbe5cc65dae70b2c923a33d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5919,6 +5919,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>LastUIFeatureVersion</key>
+    <map>
+        <key>Comment</key>
+        <string>UI Feature Version number for tracking feature notification between viewer builds</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>LLSD</string>
+        <key>Value</key>
+        <string></string>
+    </map>
     <key>LastFindPanel</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index dd239f3990f36eeadd3c2b798b9e3e1fa3cb9be0..719c6e824eb9aac7410a028d4aaa281af733c028 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -128,6 +128,11 @@ const F64 CHAT_AGE_FAST_RATE = 3.0;
 const F32 MIN_FIDGET_TIME = 8.f; // seconds
 const F32 MAX_FIDGET_TIME = 20.f; // seconds
 
+const S32 UI_FEATURE_VERSION = 1;
+// For version 1: 1 - inventory, 2 - gltf
+// Will need to change to 3 once either inventory or gltf releases and cause a conflict
+const S32 UI_FEATURE_FLAGS = 2;
+
 // The agent instance.
 LLAgent gAgent;
 
@@ -389,7 +394,7 @@ LLAgent::LLAgent() :
 	mHideGroupTitle(FALSE),
 	mGroupID(),
 
-	mInitialized(FALSE),
+	mInitialized(false),
 	mListener(),
 
 	mDoubleTapRunTimer(),
@@ -469,7 +474,7 @@ LLAgent::LLAgent() :
 
 	mNextFidgetTime(0.f),
 	mCurrentFidget(0),
-	mFirstLogin(FALSE),
+	mFirstLogin(false),
 	mOutfitChosen(FALSE),
     mCrouch(false),
 	mVoiceConnected(false),
@@ -531,7 +536,7 @@ void LLAgent::init()
 
 	mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_AGENT);
 
-	mInitialized = TRUE;
+	mInitialized = true;
 }
 
 //-----------------------------------------------------------------------------
@@ -586,6 +591,93 @@ void LLAgent::onAppFocusGained()
 //	}
 }
 
+void LLAgent::setFirstLogin(bool b)
+{
+    mFirstLogin = b;
+
+    if (mFirstLogin)
+    {
+        // Don't notify new users about new features
+        if (getFeatureVersion() <= UI_FEATURE_VERSION)
+        {
+            setFeatureVersion(UI_FEATURE_VERSION, UI_FEATURE_FLAGS);
+        }
+    }
+}
+
+void LLAgent::setFeatureVersion(S32 version, S32 flags)
+{
+    LLSD updated_version;
+    updated_version["version"] = version;
+    updated_version["flags"] = flags;
+    gSavedSettings.setLLSD("LastUIFeatureVersion", updated_version);
+}
+
+S32 LLAgent::getFeatureVersion()
+{
+    S32 version;
+    S32 flags;
+    getFeatureVersionAndFlags(version, flags);
+    return version;
+}
+
+void LLAgent::getFeatureVersionAndFlags(S32& version, S32& flags)
+{
+    version = 0;
+    flags = 0;
+    LLSD feature_version = gSavedSettings.getLLSD("LastUIFeatureVersion");
+    if (feature_version.isInteger())
+    {
+        version = feature_version.asInteger();
+        flags = 1; // inventory flag
+    }
+    else if (feature_version.isMap())
+    {
+        version = feature_version["version"];
+        flags = feature_version["flags"];
+    }
+    else if (!feature_version.isString() && !feature_version.isUndefined())
+    {
+        // is something newer inside?
+        version = UI_FEATURE_VERSION;
+        flags = UI_FEATURE_FLAGS;
+    }
+}
+
+void LLAgent::showLatestFeatureNotification(const std::string key)
+{
+    S32 version;
+    S32 flags; // a single release can have multiple new features
+    getFeatureVersionAndFlags(version, flags);
+    if (version <= UI_FEATURE_VERSION && (flags & UI_FEATURE_FLAGS) != UI_FEATURE_FLAGS)
+    {
+        S32 flag = 0;
+
+        if (key == "inventory")
+        {
+            // Notify user about new thumbnail support
+            flag = 1;
+        }
+
+        if (key == "gltf")
+        {
+            flag = 2;
+        }
+
+        if ((flags & flag) == 0)
+        {
+            // Need to open on top even if called from onOpen,
+            // do on idle to make sure it's on top
+            LLSD floater_key(key);
+            doOnIdleOneTime([floater_key]()
+                            {
+                                LLFloaterReg::showInstance("new_feature_notification", floater_key);
+                            });
+
+            setFeatureVersion(UI_FEATURE_VERSION, flags | flag);
+        }
+    }
+}
 
 void LLAgent::ageChat()
 {
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 5a354a3ef3f246ef93711776d5ca151771bc64ed..26cceaffca4623528a4233c330a0c67189cc99b3 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -117,15 +117,20 @@ class LLAgent final : public LLOldEvents::LLObservable
 	//--------------------------------------------------------------------
 public:
 	void			onAppFocusGained();
-	void			setFirstLogin(BOOL b) 	{ mFirstLogin = b; }
+	void			setFirstLogin(bool b);
 	// Return TRUE if the database reported this login as the first for this particular user.
-	BOOL 			isFirstLogin() const 	{ return mFirstLogin; }
-	BOOL 			isInitialized() const 	{ return mInitialized; }
+	bool 			isFirstLogin() const 	{ return mFirstLogin; }
+	bool 			isInitialized() const 	{ return mInitialized; }
+
+    void            setFeatureVersion(S32 version, S32 flags);
+    S32             getFeatureVersion();
+    void            getFeatureVersionAndFlags(S32 &version, S32 &flags);
+    void            showLatestFeatureNotification(const std::string key);
 public:
 	std::string		mMOTD; 					// Message of the day
 private:
-	BOOL			mInitialized;
-	BOOL			mFirstLogin;
+	bool			mInitialized;
+	bool			mFirstLogin;
 	std::shared_ptr<LLAgentListener> mListener;
 
 	//--------------------------------------------------------------------
diff --git a/indra/newview/llfloaternewfeaturenotification.cpp b/indra/newview/llfloaternewfeaturenotification.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1e5002496744298a6afdda57d09e95bf958886ae
--- /dev/null
+++ b/indra/newview/llfloaternewfeaturenotification.cpp
@@ -0,0 +1,83 @@
+/** 
+ * @file llfloaternewfeaturenotification.cpp
+ * @brief LLFloaterNewFeatureNotification class implementation
+ *
+ * $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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaternewfeaturenotification.h"
+
+
+LLFloaterNewFeatureNotification::LLFloaterNewFeatureNotification(const LLSD& key)
+  : LLFloater(key)
+{
+}
+
+LLFloaterNewFeatureNotification::~LLFloaterNewFeatureNotification()
+{
+}
+
+BOOL LLFloaterNewFeatureNotification::postBuild()
+{
+    setCanDrag(FALSE);
+    getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloaterNewFeatureNotification::onCloseBtn, this));
+
+    const std::string title_txt = "title_txt";
+    const std::string dsc_txt = "description_txt";
+    std::string feature = "_" + getKey().asString();
+    
+    getChild<LLUICtrl>(title_txt)->setValue(getString(title_txt + feature));
+    getChild<LLUICtrl>(dsc_txt)->setValue(getString(dsc_txt + feature));
+
+    if (getKey().asString() == "gltf")
+    {
+        LLRect rect = getRect();
+        // make automatic?
+        reshape(rect.getWidth() + 90, rect.getHeight() + 45);
+    }
+
+    return TRUE;
+}
+
+void LLFloaterNewFeatureNotification::onOpen(const LLSD& key)
+{
+    centerOnScreen();
+}
+
+void LLFloaterNewFeatureNotification::onCloseBtn()
+{
+    closeFloater();
+}
+
+void LLFloaterNewFeatureNotification::centerOnScreen()
+{
+    LLVector2 window_size = LLUI::getInstance()->getWindowSize();
+    centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY])));
+    LLFloaterView* parent = dynamic_cast<LLFloaterView*>(getParent());
+    if (parent)
+    {
+        parent->bringToFront(this);
+    }
+}
+
diff --git a/indra/newview/llfloaternewfeaturenotification.h b/indra/newview/llfloaternewfeaturenotification.h
new file mode 100644
index 0000000000000000000000000000000000000000..95501451dc51c3f8b9b96051c9fe13d0b4ddb0c6
--- /dev/null
+++ b/indra/newview/llfloaternewfeaturenotification.h
@@ -0,0 +1,49 @@
+/** 
+ * @file llfloaternewfeaturenotification.h
+ * @brief LLFloaterNewFeatureNotification class definition
+ *
+ * $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$
+ */
+
+#ifndef LL_FLOATER_NEW_FEATURE_NOTOFICATION_H
+#define LL_FLOATER_NEW_FEATURE_NOTOFICATION_H
+
+#include "llfloater.h"
+
+class LLFloaterNewFeatureNotification:
+    public LLFloater
+{
+    friend class LLFloaterReg;
+public:
+    BOOL postBuild() override;
+    void onOpen(const LLSD& key) override;
+
+private:
+    LLFloaterNewFeatureNotification(const LLSD& key);
+    /*virtual*/	~LLFloaterNewFeatureNotification();
+
+    void centerOnScreen();
+
+    void onCloseBtn();	
+};
+
+#endif
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 1e4591c8c2041948c24715912064a00065bcd324..d092d16cfc2fb5575590a190129a0add215af37e 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1828,7 +1828,12 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<Pe
         return false;
     }
 
+    // func.mIsOverride=true is used for the singleton material editor floater
+    // associated with the build floater. This flag also excludes objects from
+    // the selection that do not satisfy PERM_MODIFY.
+    llassert(func.mIsOverride);
     LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/);
+
     LLViewerObject* selected_object = func.mObject;
     if (!selected_object)
     {
@@ -1929,7 +1934,7 @@ bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<Pe
 
 bool LLMaterialEditor::canModifyObjectsMaterial()
 {
-    LLSelectedTEGetMatData func(false);
+    LLSelectedTEGetMatData func(true);
     LLPermissions permissions;
     LLViewerInventoryItem* item_out;
     return can_use_objects_material(func, std::vector({PERM_MODIFY}), permissions, item_out);
@@ -1937,7 +1942,7 @@ bool LLMaterialEditor::canModifyObjectsMaterial()
 
 bool LLMaterialEditor::canSaveObjectsMaterial()
 {
-    LLSelectedTEGetMatData func(false);
+    LLSelectedTEGetMatData func(true);
     LLPermissions permissions;
     LLViewerInventoryItem* item_out;
     return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions, item_out);
@@ -1945,7 +1950,7 @@ bool LLMaterialEditor::canSaveObjectsMaterial()
 
 void LLMaterialEditor::saveObjectsMaterialAs()
 {
-    LLSelectedTEGetMatData func(false);
+    LLSelectedTEGetMatData func(true);
     LLPermissions permissions;
     LLViewerInventoryItem* item = nullptr;
     bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions, item);
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index a721000b4ef0c8d2db2886aa8532756267089164..39dba3e3444c75874f91f3e22e0f75bff22fd3d7 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -478,6 +478,15 @@ LLPanelFace::~LLPanelFace()
     unloadMedia();
 }
 
+void LLPanelFace::onVisibilityChange(BOOL new_visibility)
+{
+    if (new_visibility)
+    {
+        gAgent.showLatestFeatureNotification("gltf");
+    }
+    LLPanel::onVisibilityChange(new_visibility);
+}
+
 void LLPanelFace::draw()
 {
     updateCopyTexButton();
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index fdb393690322394e24f930099aa2257c43e633f6..a572a39f172c42d4bfe4d024e9d35cfab7ab0be3 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -110,6 +110,7 @@ class LLPanelFace : public LLPanel
 
     static void onMaterialOverrideReceived(const LLUUID& object_id, S32 side);
 
+    /*virtual*/ void onVisibilityChange(BOOL new_visibility);
     /*virtual*/ void draw();
 
 	LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 0181e0879912b98c817da1512ae963f62de3a363..37451dff1b50bb9339823df01ed0bf3f604f781f 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -3738,7 +3738,7 @@ bool process_login_success_response(U32& first_sim_size_x, U32& first_sim_size_y
 		std::string flag = login_flags["ever_logged_in"];
 		if(!flag.empty())
 		{
-			gAgent.setFirstLogin((flag == "N") ? TRUE : FALSE);
+			gAgent.setFirstLogin(flag == "N");
 		}
 
 		/*  Flag is currently ignored by the viewer.
@@ -3829,7 +3829,7 @@ bool process_login_success_response(U32& first_sim_size_x, U32& first_sim_size_y
 	std::string fake_initial_outfit_name = gSavedSettings.getString("FakeInitialOutfitName");
 	if (!fake_initial_outfit_name.empty())
 	{
-		gAgent.setFirstLogin(TRUE);
+		gAgent.setFirstLogin(true);
 		sInitialOutfit = fake_initial_outfit_name;
 		if (sInitialOutfitGender.empty())
 		{
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index d2739e117bccc668c8def21e66c0f07e482bdb1a..685066506be8c3f681a9c2c433bd1399c0570fe1 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -191,11 +191,15 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
 // an item.
 BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
+    BOOL pick_reflection_probe = gSavedSettings.getBOOL("SelectReflectionProbes");
+
 	// don't pick transparent so users can't "pay" transparent objects
 	mPick = gViewerWindow->pickImmediate(x, y,
                                          /*BOOL pick_transparent*/ FALSE,
                                          /*BOOL pick_rigged*/ TRUE,
-                                         /*BOOL pick_particle*/ TRUE);
+                                         /*BOOL pick_particle*/ TRUE,
+                                         /*BOOL pick_unselectable*/ TRUE, 
+                                         pick_reflection_probe);
 	mPick.mKeyMask = mask;
 
 	// claim not handled so UI focus stays same
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 84f0b8075474a181515712203a24e3788ca8b451..0403135416e6eef23b070405988c06c1c2bee8aa 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -117,6 +117,7 @@
 #include "llfloatermyscripts.h"
 #include "llfloatermyenvironment.h"
 #include "llfloaternamedesc.h"
+#include "llfloaternewfeaturenotification.h"
 #include "llfloaternewlocalinventory.h"
 #include "llfloaternotificationsconsole.h"
 #include "llfloaternotificationstabbed.h"
@@ -257,6 +258,7 @@ class LLFloaterOpenHandler : public LLCommandHandler
                 "avatar_picker",
                 "camera",
                 "camera_presets",
+                "change_item_thumbnail"
                 "classified",
                 "add_landmark",
                 "delete_pref_preset",
@@ -275,6 +277,7 @@ class LLFloaterOpenHandler : public LLCommandHandler
                 "message_critical", // Modal!!! Login specific. If this is in use elsewhere, better to create a non modal variant
                 "message_tos", // Modal!!! Login specific.
                 "mute_object_by_name",
+                "new_feature_notification",
                 "publish_classified",
                 "save_pref_preset",
                 "save_camera_preset",
@@ -427,6 +430,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);
 	LLFloaterReg::add("mute_object_by_name", "floater_mute_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGetBlockedObjectName>);
 	LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>);
+    LLFloaterReg::add("new_feature_notification", "floater_new_feature_notification.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNewFeatureNotification>);
 
 	LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
 	
diff --git a/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml b/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c8726d36b44d2b8e81590561ba4bf31bdfd4594d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="130"
+ width="300"
+ layout="topleft"
+ name="floater_new_feature_notification"
+ title="NEW FEATURE"
+ show_title="false"
+ header_height="0"
+ bg_opaque_image="Window_NoTitle_Foreground"
+ bg_alpha_image="Window_NoTitle_Background"
+ can_resize="false"
+ can_drag_on_left="false"
+ can_minimize="false"
+ can_close="false">
+    <floater.string name="title_txt_inventory">
+New inventory features
+    </floater.string>
+    <floater.string name="description_txt_inventory">
+You can now add preview images to inventory items and view a folder in its own window.
+Learn more in this [https://community.secondlife.com/blogs/entry/13637-new-features-inventory-item-preview-and-single-folder-view/ blogpost]
+    </floater.string>
+    <floater.string name="title_txt_gltf">
+New GLTF PBR materials support
+    </floater.string>
+    <floater.string name="description_txt_gltf">
+You can now use expanded material support with the ability to import and edit GLTF Physically Based Rendering (PBR) Materials.
+In order to support the addition of the GLTF format, some areas in the viewer may appear darker than usual.
+
+Learn more about [https://wiki.secondlife.com/wiki/PBR_Materials Physically Based Rendering (PBR)]
+    </floater.string>
+  <text
+   type="string"
+   length="1"
+   follows="top|left|right"
+   font="SansSerifLargeBold"
+   text_color="White"
+   layout="topleft"
+   left="10"
+   height="14"
+   top="10"
+   right="-10"
+   name="title_txt">
+New feature
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="top|left|right|bottom"
+   text_color="White"
+   layout="topleft"
+   left="10"
+   height="40"
+   top_pad="14"
+   right="-10"
+   word_wrap="true"
+   name="description_txt">
+Feature description
+  </text>
+  <button
+   follows="bottom|left|right"
+   layout="topleft"
+   height="24"
+   label="Got it!"
+   left="104"
+   bottom="-10"
+   name="close_btn"
+   width="90"/>
+</floater>