diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index e4bfcdffa390abf3fadbc1bb00e6901dcfb93a84..6557c2b3513744ab0d9f67209c0343ece8f5fe81 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -1265,6 +1265,8 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
         }
     }
 
+    gPipeline.mReflectionMapManager.reset();
+
     if (!mSignalEnvChanged.empty())
         mSignalEnvChanged(env, env_version);
 }
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
index 261aa51d62bfcf249ed56c73b0a9574aef0588df..624fbd1758fdc6468c161380914907fa29139fab 100644
--- a/indra/newview/llreflectionmap.cpp
+++ b/indra/newview/llreflectionmap.cpp
@@ -169,7 +169,6 @@ void LLReflectionMap::autoAdjustOrigin()
 
 bool LLReflectionMap::intersects(LLReflectionMap* other)
 {
-    // TODO: incorporate getBox
     LLVector4a delta;
     delta.setSub(other->mOrigin, mOrigin);
 
@@ -239,11 +238,13 @@ bool LLReflectionMap::getBox(LLMatrix4& box)
                 scale.set_scale(glh::vec3f(s.mV));
                 if (vobjp->mDrawable != nullptr)
                 {
+                    // object to agent space (no scale)
                     glh::matrix4f rm((F32*)vobjp->mDrawable->getWorldMatrix().mMatrix);
 
-                    glh::matrix4f rt((F32*)vobjp->getRelativeXform().mMatrix);
+                    // construct object to camera space (with scale)
+                    mv = mv * rm * scale;
 
-                    mv = mv * rm * scale; // *rt;
+                    // inverse is camera space to object unit cube 
                     mv = mv.inverse();
 
                     box = LLMatrix4(mv.m);
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index dc84b0b10e65862a985ae6e3bbc3f6a6a0e56ae9..fd809364967522a3dac27ae6b71a13cc51e0970d 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -75,6 +75,23 @@ struct CompareProbeDistance
     }
 };
 
+// return true if a is higher priority for an update than b
+static bool check_priority(LLReflectionMap* a, LLReflectionMap* b)
+{
+    if (!a->mComplete && !b->mComplete)
+    { //neither probe is complete, use distance
+        return a->mDistance < b->mDistance;
+    }
+    else if (a->mComplete && b->mComplete)
+    { //both probes are complete, use combination of distance and last update time
+        return (a->mDistance - (gFrameTimeSeconds - a->mLastUpdateTime)) <
+            (b->mDistance - (gFrameTimeSeconds - b->mLastUpdateTime));
+    }
+
+    // one of these probes is not complete, if b is complete, a is higher priority
+    return b->mComplete;
+}
+
 // helper class to seed octree with probes
 void LLReflectionMapManager::update()
 {
@@ -181,6 +198,12 @@ void LLReflectionMapManager::update()
 
         LLVector4a d;
 
+        if (probe != mDefaultProbe)
+        {
+            d.setSub(camera_pos, probe->mOrigin);
+            probe->mDistance = d.getLength3().getF32() - probe->mRadius;
+        }
+
         if (probe->mComplete)
         {
             probe->mFadeIn = llmin((F32) (probe->mFadeIn + gFrameIntervalSeconds), 1.f);
@@ -201,7 +224,7 @@ void LLReflectionMapManager::update()
             if (!did_update &&
                 i < mReflectionProbeCount &&
                 (oldestProbe == nullptr ||
-                    probe->mLastUpdateTime < oldestProbe->mLastUpdateTime))
+                    check_priority(probe, oldestProbe)))
             {
                oldestProbe = probe;
             }
@@ -214,12 +237,6 @@ void LLReflectionMapManager::update()
         {
             closestDynamic = probe;
         }
-
-        if (probe != mDefaultProbe)
-        {
-            d.setSub(camera_pos, probe->mOrigin);
-            probe->mDistance = d.getLength3().getF32() - probe->mRadius;
-        }
     }
 
     if (realtime && closestDynamic != nullptr)
@@ -702,12 +719,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
     }
 }
 
-void LLReflectionMapManager::rebuild()
+void LLReflectionMapManager::reset()
 {
-    for (auto& probe : mProbes)
-    {
-        probe->mLastUpdateTime = 0.f;
-    }
+    mReset = true;
 }
 
 void LLReflectionMapManager::shift(const LLVector4a& offset)
@@ -950,12 +964,30 @@ void renderReflectionProbe(LLReflectionMap* probe)
     gGL.begin(gGL.LINES);
     for (auto& neighbor : probe->mNeighbors)
     {
+        if (probe->mViewerObject && neighbor->mViewerObject)
+        {
+            continue;
+        }
+        
         gGL.vertex3fv(po);
         gGL.vertex3fv(neighbor->mOrigin.getF32ptr());
     }
     gGL.end();
     gGL.flush();
 
+    gGL.diffuseColor4f(1, 1, 0, 1);
+    gGL.begin(gGL.LINES);
+    for (auto& neighbor : probe->mNeighbors)
+    {
+        if (probe->mViewerObject && neighbor->mViewerObject)
+        {
+            gGL.vertex3fv(po);
+            gGL.vertex3fv(neighbor->mOrigin.getF32ptr());
+        }
+    }
+    gGL.end();
+    gGL.flush();
+
 #if 0
     LLSpatialGroup* group = probe->mGroup;
     if (group)
@@ -1022,8 +1054,9 @@ void LLReflectionMapManager::initReflectionMaps()
 
     U32 count = llclamp((S32) probe_count, 1, LL_MAX_REFLECTION_PROBE_COUNT);
 
-    if (mTexture.isNull() || mReflectionProbeCount != count)
+    if (mTexture.isNull() || mReflectionProbeCount != count || mReset)
     {
+        mReset = false;
         mReflectionProbeCount = count;
         mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512));
         mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1
@@ -1045,6 +1078,7 @@ void LLReflectionMapManager::initReflectionMaps()
 
         for (auto& probe : mProbes)
         {
+            probe->mLastUpdateTime = 0.f;
             probe->mComplete = false;
             probe->mProbeIndex = -1;
             probe->mCubeArray = nullptr;
diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h
index 9a46af58b35fe4b87d2b15b2158883ee92dc979b..066b1e380fb8551ae06af1243718b041ea2de093 100644
--- a/indra/newview/llreflectionmapmanager.h
+++ b/indra/newview/llreflectionmapmanager.h
@@ -80,8 +80,8 @@ class alignas(16) LLReflectionMapManager
     // Guaranteed to not return null
     LLReflectionMap* registerViewerObject(LLViewerObject* vobj);
 
-    // force an update of all probes
-    void rebuild();
+    // reset all state on the next update
+    void reset();
 
     // called on region crossing to "shift" probes into new coordinate frame
     void shift(const LLVector4a& offset);
@@ -190,5 +190,8 @@ class alignas(16) LLReflectionMapManager
 
     // amount to scale local lights during an irradiance map update (set during updateProbeFace and used by LLPipeline)
     F32 mLightScale = 1.f;
+
+    // if true, reset all probe render state on the next update (for teleports and sky changes)
+    bool mReset = false;
 };
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 3a8206ad262b5366a90f5c67276cab5952fc7bd7..89538b3bd5d897527eb111f43335958ccbd324bb 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -8451,12 +8451,6 @@ void handle_cache_clear_immediately()
 	LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately);
 }
 
-void handle_rebuild_reflection_probes()
-{
-    gPipeline.mReflectionMapManager.rebuild();
-}
-
-
 void handle_web_content_test(const LLSD& param)
 {
 	std::string url = param.asString();
@@ -9550,9 +9544,7 @@ void initialize_menus()
 	
 	//Develop (clear cache immediately)
 	commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
-    //Develop (override environment map)
-    commit.add("Develop.RebuildReflectionProbes", boost::bind(&handle_rebuild_reflection_probes));
-
+    
 	// Admin >Object
 	view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
 	view_listener_t::addMenu(new LLAdminHandleObjectOwnerSelf(), "Admin.HandleObjectOwnerSelf");
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index b8515cb096ff3080ea403b81cd54c487736a633a..d77415877c345ea26fb301c0d8fdc42667682db7 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -3238,13 +3238,6 @@ function="World.EnvPreset"
                  function="Advanced.HandleAttachedLightParticles"
                  parameter="RenderAttachedParticles" />
             </menu_item_check>
-            <menu_item_call
-              enabled="true"
-              label="Rebuild Reflection Probes"
-              name="Rebuild Reflection Probes">
-              <menu_item_call.on_click
-               function="Develop.RebuildReflectionProbes" />
-            </menu_item_call>
           <menu_item_separator />
           
           <menu_item_call