diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 2c743d596e8f13539bf6c919076964d9d06dcb00..8b335d57d70be036e5d35672714c2f73e7af8bd9 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -1441,6 +1441,11 @@ BOOL LLPanelRegionTerrainInfo::postBuild()
 	mAskedTextureHeights = false;
 	mConfirmedTextureHeights = false;
 
+    if (!mRegionChangedSlot.connected())
+    {
+        mRegionChangedSlot = gAgent.addRegionChangedCallback(boost::bind(&LLPanelRegionTerrainInfo::onRegionChanged,this));
+    }
+
     refresh();
 
 	return LLPanelRegionInfo::postBuild();
@@ -1449,8 +1454,7 @@ BOOL LLPanelRegionTerrainInfo::postBuild()
 // virtual
 void LLPanelRegionTerrainInfo::refresh()
 {
-    // For simplicity, require restart
-    static BOOL feature_pbr_terrain_enabled = gSavedSettings.getBOOL("RenderTerrainPBREnabled");
+    static LLCachedControl<bool> feature_pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
 
     LLTextBox* texture_text = getChild<LLTextBox>("detail_texture_text");
     if (texture_text) { texture_text->setVisible(!feature_pbr_terrain_enabled); }
@@ -1512,6 +1516,27 @@ void LLPanelRegionTerrainInfo::onSelectMaterialType()
     }
 }
 
+void LLPanelRegionTerrainInfo::onRegionChanged()
+{
+    LLViewerRegion *region = gAgent.getRegion();
+    if (!region) { return; }
+
+    if (region->simulatorFeaturesReceived())
+    {
+        onSimulatorFeaturesReceived(region->getRegionID(), region);
+    }
+    else
+    {
+        // See "RenderTerrainPBREnabled" in LLViewerRegion::setSimulatorFeatures
+        region->setSimulatorFeaturesReceivedCallback(boost::bind(&LLPanelRegionTerrainInfo::onSimulatorFeaturesReceived,this,_1, _2));
+    }
+}
+
+void LLPanelRegionTerrainInfo::onSimulatorFeaturesReceived(const LLUUID& region_id, LLViewerRegion* regionp)
+{
+    refresh();
+}
+
 // virtual
 bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region)
 {
@@ -1568,6 +1593,9 @@ bool LLPanelRegionTerrainInfo::refreshFromRegion(LLViewerRegion* region)
 		LL_DEBUGS() << "no region set" << LL_ENDL;
 		getChild<LLUICtrl>("region_text")->setValue(LLSD(""));
 	}
+    
+    // Update visibility of terrain swatches, etc
+    refresh();
 
 	getChildView("download_raw_btn")->setEnabled(owner_or_god);
 	getChildView("upload_raw_btn")->setEnabled(owner_or_god);
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index 91fd54fcf990cdd4b0c27f6c7b0fe10664730265..91e1f5b0580d3dc9843df80413cfba8bae439771 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -248,6 +248,8 @@ class LLPanelRegionTerrainInfo : public LLPanelRegionInfo
 	
 	BOOL postBuild() override;
 	
+    void onRegionChanged();
+    void onSimulatorFeaturesReceived(const LLUUID& region_id, LLViewerRegion* regionp);
     bool refreshFromRegion(LLViewerRegion* region) override;                // refresh local settings from region update from simulator
 	void setEnvControls(bool available);									// Whether environment settings are available for this region
 
@@ -271,6 +273,7 @@ class LLPanelRegionTerrainInfo : public LLPanelRegionInfo
 private:
 	bool mConfirmedTextureHeights;
 	bool mAskedTextureHeights;
+    boost::signals2::connection mRegionChangedSlot;
 };
 
 /////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index da7b1131a382349fab08dbbbf0e3e446e93aded2..981984db6ae24469d62804e1296a4ad72610eb9b 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -9506,10 +9506,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
 	view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark");
 	view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache");
-    if (gSavedSettings.get<bool>("RenderTerrainPBREnabled"))
-    {
-        view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain");
-    }
+    view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain");
 
 	#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
 	view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode");
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 5b51267cbee6d542f32ee6e958114ce763c7a186..d887a579e432f7b773571d008788523925649293 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1610,8 +1610,8 @@ void LLViewerRegion::idleUpdate(F32 max_update_time)
 
 	mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame();
 
-    static bool pbr_terrain_enabled = gSavedSettings.get<bool>("RenderTerrainPBREnabled");
-    static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE);
+    static LLCachedControl<bool> pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
+    static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false);
     bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR);
     bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals;
 
@@ -1925,8 +1925,8 @@ void LLViewerRegion::forceUpdate()
 {
 	constexpr F32 max_update_time = 0.f;
 
-	static bool pbr_terrain_enabled = gSavedSettings.get<BOOL>("RenderTerrainPBREnabled");
-	static LLCachedControl<BOOL> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", FALSE);
+    static LLCachedControl<bool> pbr_terrain_enabled(gSavedSettings, "RenderTerrainPBREnabled", false);
+    static LLCachedControl<bool> pbr_terrain_experimental_normals(gSavedSettings, "RenderTerrainPBRNormalsEnabled", false);
 	bool pbr_material = mImpl->mCompositionp && (mImpl->mCompositionp->getMaterialType() == LLTerrainMaterials::Type::PBR);
 	bool pbr_land = pbr_material && pbr_terrain_enabled && pbr_terrain_experimental_normals;
 
@@ -2460,6 +2460,16 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
 
     gSavedSettings.setBOOL("RenderMirrors", mirrors_enabled);
 
+    if (mSimulatorFeatures.has("PBRTerrainEnabled"))
+    {
+        bool enabled = mSimulatorFeatures["PBRTerrainEnabled"];
+        gSavedSettings.setBOOL("RenderTerrainPBREnabled", enabled);
+    }
+    else
+    {
+        gSavedSettings.setBOOL("RenderTerrainPBREnabled", false);
+    }
+
     if (mSimulatorFeatures.has("PBRMaterialSwatchEnabled"))
     {
         bool enabled = mSimulatorFeatures["PBRMaterialSwatchEnabled"];
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index c092eb82f3432c8e7653dfd4acb9f10d411d72c2..09b21e4e0addfd87981b52b21252a2663425331f 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -159,7 +159,7 @@ bool LLTerrainMaterials::materialsReady(bool boost, bool strict)
     }
 
 #if 1
-    static bool sRenderTerrainPBREnabled = gSavedSettings.get<bool>("RenderTerrainPBREnabled");
+    static LLCachedControl<bool> sRenderTerrainPBREnabled(gSavedSettings, "RenderTerrainPBREnabled", false);
     static LLCachedControl<bool> sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false);
     if (sRenderTerrainPBREnabled && sRenderTerrainPBRForce)
     {