diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d6af39f97ebff2d8abc2aaf5c37a94ae545d4c99..5ffd610fbafc1c58b678eca821f3b0651ab8c5e4 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10367,7 +10367,7 @@
     <key>Type</key>
     <string>U32</string>
     <key>Value</key>
-    <real>1</real>
+    <real>2</real>
   </map>
   <key>RenderExposure</key>
   <map>
@@ -10403,18 +10403,17 @@
     <key>Value</key>
     <real>0</real>
   </map>
-  <key>RenderReflectionProbeTextureHackID</key>
+  <key>RenderAutomaticReflectionProbes</key>
   <map>
     <key>Comment</key>
-    <string>HACK -- Any object with a diffuse texture with this ID will be treated as a user override reflection probe. (default is "Violet Info Hub" photo from Library)</string>
+    <string>Automatic reflection probes control.  0 - disable, 1 - Terrain/water only, 2- Terrain/water + objects.  Requires restart.</string>
     <key>Persist</key>
     <integer>1</integer>
     <key>Type</key>
-    <string>String</string>
+    <string>S32</string>
     <key>Value</key>
-    <string>6b186931-05da-eafa-a3ed-a012a33bbfb6</string>
+    <integer>2</integer>
   </map>
-  
   <key>RenderReflectionRes</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
index 689929fe38f5252d22baa18c8a6d69a07af873f5..861b78c961733bdfb86790d99256c97c7515dd66 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
@@ -36,17 +36,16 @@ uniform sampler2D exposureMap;
 uniform float dt;
 uniform vec2 noiseVec;
 
-// calculate luminance the same way LLColor4::calcHSL does
+
 float lum(vec3 col)
 {
-    float mx = max(max(col.r, col.g), col.b);
-    float mn = min(min(col.r, col.g), col.b);
-    return (mx + mn) * 0.5;
+    vec3 l = vec3(0.2126, 0.7152, 0.0722);
+    return dot(l, col);
 }
 
 void main() 
 {
-    float step = 1.0/32.0;
+    float step = 1.0/16.0;
 
     float start = step;
     float end = 1.0-step;
@@ -55,13 +54,13 @@ void main()
 
     vec3 col;
 
-    vec2 nz = noiseVec * step * 0.5;
+    //vec2 nz = noiseVec * step * 0.5;
 
     for (float x = start; x <= end; x += step)
     {
         for (float y = start; y <= end; y += step)
         {
-            vec2 tc = vec2(x,y) + nz;
+            vec2 tc = vec2(x,y); // + nz;
             vec3 c = texture(diffuseRect, tc).rgb + texture(emissiveRect, tc).rgb;
             float L = max(lum(c), 0.25);
 
@@ -82,11 +81,13 @@ void main()
 
     float L = lum(col);
 
-    float s = clamp(0.1/L, 0.5, 4.0);
+    float s = clamp(0.175/L, 0.125, 1.3);
+
 
     float prev = texture(exposureMap, vec2(0.5,0.5)).r;
-    s = mix(prev, s, min(dt*2.0, 0.04));
 
+    s = mix(prev, s, min(dt*2.0*abs(prev-s), 0.04));
+    
     frag_color = vec4(s, s, s, dt);
 }
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index 4ac1ff936813536f14093e359402e4da19097d33..221de0b0954a9dfca8362cce464b72fa955e293a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -125,7 +125,6 @@ vec3 toneMap(vec3 color)
     // this factor is based on the exposure correction of Krzysztof Narkowicz in his
     // implemetation of ACES tone mapping
     color *= 1.0/0.6;
-    //color /= 0.6;
     color = toneMapACES_Hill(color);
 #endif
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index fc6291d4381364f071a6af1906d912592c40afa3..0090155e5cd61d7585e25ac52e54e8449e471903 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -91,7 +91,7 @@ void main()
     vary_LightNormPosDot = rel_pos_lightnorm_dot;
 
     // Initialize temp variables
-    vec3 sunlight = (sun_up_factor == 1) ? sunlight_color*2.0 : moonlight_color*0.75;
+    vec3 sunlight = (sun_up_factor == 1) ? sunlight_color*2.0 : moonlight_color;
     
     // Sunlight attenuation effect (hue and brightness) due to atmosphere
     // this is used later for sunlight modulation at various altitudes
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl
index 0d3dbf85e2dc10ba29124e59ce20fa7782721dad..c2527db218fbe0c70e46bbd1cb917b71ecd842b8 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl
@@ -62,8 +62,10 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
 
     vec3  rel_pos_norm = normalize(rel_pos);
     float rel_pos_len  = length(rel_pos);
-    float scale = 2.0;
-    vec3  sunlight     = (sun_up_factor == 1) ? sunlight_color * scale: moonlight_color*0.75;
+    
+    float scale = sun_up_factor + 1;
+    vec3  sunlight     = (sun_up_factor == 1) ? sunlight_color: moonlight_color;
+    sunlight *= scale;
 
     // sunlight attenuation effect (hue and brightness) due to atmosphere
     // this is used later for sunlight modulation at various altitudes
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 7a5676e0ababaf94069360109efd085800813067..677d83a1fedcae01b872fd7bf0ec0b8fb96a2457 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -35,6 +35,8 @@ uniform sampler2D sceneMap;
 uniform int cube_snapshot;
 uniform float max_probe_lod;
 
+#define MAX_REFMAP_COUNT 256  // must match LL_MAX_REFLECTION_PROBE_COUNT
+
 layout (std140) uniform ReflectionProbes
 {
     // list of OBBs for user override probes
@@ -42,18 +44,18 @@ layout (std140) uniform ReflectionProbes
     // for each box refBox[i]...
     /// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation
     //  box[3][0..2] - plane thickness
-    mat4 refBox[REFMAP_COUNT];
+    mat4 refBox[MAX_REFMAP_COUNT];
     // list of bounding spheres for reflection probes sorted by distance to camera (closest first)
-    vec4 refSphere[REFMAP_COUNT];
+    vec4 refSphere[MAX_REFMAP_COUNT];
     // extra parameters (currently only .x used for probe ambiance)
-    vec4 refParams[REFMAP_COUNT];
+    vec4 refParams[MAX_REFMAP_COUNT];
     // index  of cube map in reflectionProbes for a corresponding reflection probe
     // e.g. cube map channel of refSphere[2] is stored in refIndex[2]
     // refIndex.x - cubemap channel in reflectionProbes
     // refIndex.y - index in refNeighbor of neighbor list (index is ivec4 index, not int index)
     // refIndex.z - number of neighbors
     // refIndex.w - priority, if negative, this probe has a box influence
-    ivec4 refIndex[REFMAP_COUNT];
+    ivec4 refIndex[MAX_REFMAP_COUNT];
 
     // neighbor list data (refSphere indices, not cubemap array layer)
     ivec4 refNeighbor[1024];
@@ -674,7 +676,7 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
     sampleReflectionProbes(ambenv, glossenv, tc, pos, norm, glossiness);
 
     // fudge factor to get PBR water at a similar luminance ot legacy water
-    glossenv *= 0.25;
+    glossenv *= 0.4;
 }
 
 void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)
diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h
index 6eff607ea5faaee8b8e01d881f53dda70b354219..d639f6a54c5eec7295d9bba0186df151775a9089 100644
--- a/indra/newview/llreflectionmap.h
+++ b/indra/newview/llreflectionmap.h
@@ -90,6 +90,12 @@ class alignas(16) LLReflectionMap : public LLRefCount
     // cube map used to sample this environment map
     LLPointer<LLCubeMapArray> mCubeArray;
     S32 mCubeIndex = -1; // index into cube map array or -1 if not currently stored in cube map array
+    
+    // probe has had at least one full update and is ready to render
+    bool mComplete = false;
+
+    // fade in parameter for this probe
+    F32 mFadeIn = 0.f;
 
     // index into array packed by LLReflectionMapManager::getReflectionMaps
     // WARNING -- only valid immediately after call to getReflectionMaps
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 58ce571505fabeb9e737c404a409d180331146ec..09ac7e57a4e307166ff07f530290e43dea564f62 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -181,7 +181,11 @@ void LLReflectionMapManager::update()
 
         LLVector4a d;
 
-        if (probe->mOccluded)
+        if (probe->mComplete)
+        {
+            probe->mFadeIn = llmin((F32) (probe->mFadeIn + gFrameIntervalSeconds), 1.f);
+        }
+        if (probe->mOccluded && probe->mComplete)
         {
             if (oldestOccluded == nullptr)
             {
@@ -300,7 +304,7 @@ void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& ma
         mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested
         if (mProbes[i]->mCubeIndex != -1)
         {
-            if (!mProbes[i]->mOccluded)
+            if (!mProbes[i]->mOccluded && mProbes[i]->mComplete)
             {
                 mProbes[i]->mProbeIndex = count;
                 maps[count++] = mProbes[i];
@@ -328,29 +332,20 @@ void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& ma
 
 LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group)
 {
-#if 1
-    if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)
+    static LLCachedControl<S32> automatic_probes(gSavedSettings, "RenderAutomaticReflectionProbes", 2);
+    if (automatic_probes > 1)
     {
-        OctreeNode* node = group->getOctreeNode();
-        F32 size = node->getSize().getF32ptr()[0];
-        if (size >= 15.f && size <= 17.f)
+        if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)
         {
-            return addProbe(group);
+            OctreeNode* node = group->getOctreeNode();
+            F32 size = node->getSize().getF32ptr()[0];
+            if (size >= 15.f && size <= 17.f)
+            {
+                return addProbe(group);
+            }
         }
     }
-#endif
 
-#if 0
-    if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_TERRAIN)
-    {
-        OctreeNode* node = group->getOctreeNode();
-        F32 size = node->getSize().getF32ptr()[0];
-        if (size >= 15.f && size <= 17.f)
-        {
-            return addProbe(group);
-        }
-    }
-#endif
     return nullptr;
 }
 
@@ -394,6 +389,7 @@ S32 LLReflectionMapManager::allocateCubeIndex()
             S32 ret = mProbes[i]->mCubeIndex;
             mProbes[i]->mCubeIndex = -1;
             mProbes[i]->mCubeArray = nullptr;
+            mProbes[i]->mComplete = false;
             return ret;
         }
     }
@@ -444,6 +440,7 @@ void LLReflectionMapManager::doProbeUpdate()
         mUpdatingFace = 0;
         if (isRadiancePass())
         {
+            mUpdatingProbe->mComplete = true;
             mUpdatingProbe = nullptr;
             mRadiancePass = false;
         }
@@ -777,7 +774,10 @@ void LLReflectionMapManager::updateUniforms()
         // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space
         LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT]; 
 
-        // extra parameters (currently only ambiance in .x)
+        // extra parameters 
+        //  x - irradiance scale
+        //  y - radiance scale
+        //  z - fade in
         LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT];
 
         // indices used by probe:
@@ -852,7 +852,7 @@ void LLReflectionMapManager::updateUniforms()
             rpd.refIndex[count][3] = -rpd.refIndex[count][3];
         }
 
-        rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, radscale, 0.f, 0.f);
+        rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, radscale, refmap->mFadeIn, 0.f);
 
         S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors
         {
@@ -1006,11 +1006,15 @@ void LLReflectionMapManager::renderDebug()
 
 void LLReflectionMapManager::initReflectionMaps()
 {
-    if (mTexture.isNull())
+    static LLCachedControl<S32> probe_count(gSavedSettings, "RenderReflectionProbeCount", LL_MAX_REFLECTION_PROBE_COUNT);
+
+    U32 count = llclamp((S32) probe_count, 1, LL_MAX_REFLECTION_PROBE_COUNT);
+
+    if (mTexture.isNull() || mReflectionProbeCount != count)
     {
+        mReflectionProbeCount = count;
         mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512));
         mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1
-        mReflectionProbeCount = llclamp(gSavedSettings.getS32("RenderReflectionProbeCount"), 1, LL_MAX_REFLECTION_PROBE_COUNT);
 
         mTexture = new LLCubeMapArray();
 
@@ -1019,6 +1023,28 @@ void LLReflectionMapManager::initReflectionMaps()
 
         mIrradianceMaps = new LLCubeMapArray();
         mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE);
+
+        // reset probe state
+        mUpdatingFace = 0;
+        mUpdatingProbe = nullptr;
+        mRadiancePass = false;
+        mRealtimeRadiancePass = false;
+        mDefaultProbe = nullptr;
+
+        for (auto& probe : mProbes)
+        {
+            probe->mComplete = false;
+            probe->mProbeIndex = -1;
+            probe->mCubeArray = nullptr;
+            probe->mCubeIndex = -1;
+        }
+
+        for (bool& is_free : mCubeFree)
+        {
+            is_free = true;
+        }
+
+        mCubeFree[0] = false;
     }
 
     if (mVertexBuffer.isNull())
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 8570c0cd5d49c71c20e21b1ef97d15292b99b73f..969f0a35949a3a2ba0cd7614d39dac97126d8be3 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -79,6 +79,8 @@
 #include <boost/bind.hpp>	// for SkinFolder listener
 #include <boost/signals2.hpp>
 
+// *TODO: Consider enabling mipmaps (they have been disabled for a long time). Likely has a significant performance impact for tiled/high texture repeat media. Mip generation in a shader may also be an option if necessary.
+constexpr BOOL USE_MIPMAPS = FALSE;
 
 void init_threaded_picker_load_dialog(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple)
 {
@@ -1564,7 +1566,8 @@ LLViewerMediaImpl::LLViewerMediaImpl(	  const LLUUID& texture_id,
 
 	// connect this media_impl to the media texture, creating it if it doesn't exist.0
 	// This is necessary because we need to be able to use getMaxVirtualSize() even if the media plugin is not loaded.
-	LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture(mTextureId);
+    // *TODO: Consider enabling mipmaps (they have been disabled for a long time). Likely has a significant performance impact for tiled/high texture repeat media. Mip generation in a shader may also be an option if necessary.
+	LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture(mTextureId, USE_MIPMAPS);
 	if(media_tex)
 	{
 		media_tex->setMediaImpl();
@@ -1658,13 +1661,14 @@ void LLViewerMediaImpl::destroyMediaSource()
 
 	cancelMimeTypeProbe();
 
-    mLock.lock();   // Delay tear-down while bg thread is updating
-	if(mMediaSource)
-	{
-		mMediaSource->setDeleteOK(true) ;
-		mMediaSource = NULL; // shared pointer
-	}
-    mLock.unlock();
+    {
+        LLMutexLock lock(&mLock); // Delay tear-down while bg thread is updating
+        if(mMediaSource)
+        {
+            mMediaSource->setDeleteOK(true) ;
+            mMediaSource = NULL; // shared pointer
+        }
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -2959,14 +2963,17 @@ bool LLViewerMediaImpl::preMediaTexUpdate(LLViewerMediaTexture*& media_tex, U8*&
 void LLViewerMediaImpl::doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* data, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool sync)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
-    mLock.lock();   // don't allow media source tear-down during update
+    LLMutexLock lock(&mLock); // don't allow media source tear-down during update
+
+    const LLGLuint tex_name = media_tex->getGLTexture() ? media_tex->getGLTexture()->getTexName() : (LLGLuint)0;
+    if (!tex_name)
+    {
+        llassert(false);
+        return;
+    }
 
     // wrap "data" in an LLImageRaw but do NOT make a copy
     LLPointer<LLImageRaw> raw = new LLImageRaw(data, media_tex->getWidth(), media_tex->getHeight(), media_tex->getComponents(), true);
-        
-    // Allocate GL texture based on LLImageRaw but do NOT copy to GL
-    LLGLuint tex_name = 0;
-    media_tex->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER, true, &tex_name);
 
     // copy just the subimage covered by the image raw to GL
     media_tex->setSubImage(data, data_width, data_height, x_pos, y_pos, width, height, tex_name);
@@ -2983,8 +2990,6 @@ void LLViewerMediaImpl::doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* da
     // release the data pointer before freeing raw so LLImageRaw destructor doesn't
     // free memory at data pointer
     raw->releaseData();
-
-    mLock.unlock();
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -3002,10 +3007,10 @@ LLViewerMediaTexture* LLViewerMediaImpl::updateMediaImage()
     }
 
     llassert(!mTextureId.isNull());
-    LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture( mTextureId );
+    // *TODO: Consider enabling mipmaps (they have been disabled for a long time). Likely has a significant performance impact for tiled/high texture repeat media. Mip generation in a shader may also be an option if necessary.
+    LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture( mTextureId, USE_MIPMAPS );
  
     if ( mNeedsNewTexture
-        || media_tex->getUseMipMaps()
         || (media_tex->getWidth() != mMediaSource->getTextureWidth())
         || (media_tex->getHeight() != mMediaSource->getTextureHeight())
         || (mTextureUsedWidth != mMediaSource->getWidth())
@@ -3021,8 +3026,6 @@ LLViewerMediaTexture* LLViewerMediaImpl::updateMediaImage()
 
         // MEDIAOPT: check to see if size actually changed before doing work
         media_tex->destroyGLTexture();
-        // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work?
-        media_tex->reinit(FALSE);	// probably not needed
 
         // MEDIAOPT: seems insane that we actually have to make an imageraw then
         // immediately discard it
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index dd4ff50259f7766107f00b2623f255a8cdd90759..192a96a408929201a5a805bcd10eb272d92ab673 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1255,43 +1255,45 @@ U32 LLViewerRegion::getNumOfVisibleGroups() const
 
 void LLViewerRegion::updateReflectionProbes()
 {
-#if 1
-    const F32 probe_spacing = 32.f;
-    const F32 probe_radius = sqrtf((probe_spacing * 0.5f) * (probe_spacing * 0.5f) * 3.f);
-    const F32 hover_height = 2.f;
+    static LLCachedControl<S32> automatic_probes(gSavedSettings, "RenderAutomaticReflectionProbes", 2);
+    if (automatic_probes > 0)
+    {
+        const F32 probe_spacing = 32.f;
+        const F32 probe_radius = sqrtf((probe_spacing * 0.5f) * (probe_spacing * 0.5f) * 3.f);
+        const F32 hover_height = 2.f;
 
-    F32 start = probe_spacing * 0.5f;
+        F32 start = probe_spacing * 0.5f;
 
-    U32 grid_width = REGION_WIDTH_METERS / probe_spacing;
+        U32 grid_width = REGION_WIDTH_METERS / probe_spacing;
 
-    mReflectionMaps.resize(grid_width * grid_width);
+        mReflectionMaps.resize(grid_width * grid_width);
 
-    F32 water_height = getWaterHeight();
-    LLVector3 origin = getOriginAgent();
+        F32 water_height = getWaterHeight();
+        LLVector3 origin = getOriginAgent();
 
-    for (U32 i = 0; i < grid_width; ++i)
-    {
-        F32 x = i * probe_spacing + start;
-        for (U32 j = 0; j < grid_width; ++j)
+        for (U32 i = 0; i < grid_width; ++i)
         {
-            F32 y = j * probe_spacing + start;
+            F32 x = i * probe_spacing + start;
+            for (U32 j = 0; j < grid_width; ++j)
+            {
+                F32 y = j * probe_spacing + start;
 
-            U32 idx = i * grid_width + j;
+                U32 idx = i * grid_width + j;
 
-            if (mReflectionMaps[idx].isNull())
-            {
-                mReflectionMaps[idx] = gPipeline.mReflectionMapManager.addProbe();
-            }
+                if (mReflectionMaps[idx].isNull())
+                {
+                    mReflectionMaps[idx] = gPipeline.mReflectionMapManager.addProbe();
+                }
 
-            LLVector3 probe_origin = LLVector3(x,y, llmax(water_height, mImpl->mLandp->resolveHeightRegion(x,y)));
-            probe_origin.mV[2] += hover_height;
-            probe_origin += origin;
+                LLVector3 probe_origin = LLVector3(x, y, llmax(water_height, mImpl->mLandp->resolveHeightRegion(x, y)));
+                probe_origin.mV[2] += hover_height;
+                probe_origin += origin;
 
-            mReflectionMaps[idx]->mOrigin.load3(probe_origin.mV);
-            mReflectionMaps[idx]->mRadius = probe_radius;
+                mReflectionMaps[idx]->mOrigin.load3(probe_origin.mV);
+                mReflectionMaps[idx]->mRadius = probe_radius;
+            }
         }
     }
-#endif
 }
 
 void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 93f4d22ff8c3908a8d3a558502e47ded2b276d89..d1f6392eae41b4c0bdf0e99e37d618be2ca332f0 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -401,30 +401,16 @@ void LLViewerShaderMgr::setShaders()
 
     llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10));
 
-    //bool canRenderDeferred = true; // DEPRECATED -- LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
-    //bool hasWindLightShaders = true; // DEPRECATED -- LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");
-    bool doingWindLight = true; //DEPRECATED -- hasWindLightShaders&& gSavedSettings.getBOOL("WindLightUseAtmosShaders");
-
+    
     S32 light_class = 3;
     S32 interface_class = 2;
     S32 env_class = 2;
     S32 obj_class = 2;
     S32 effect_class = 2;
-    S32 wl_class = 1;
+    S32 wl_class = 2;
     S32 water_class = 3;
     S32 deferred_class = 3;
 
-    if (doingWindLight)
-    {
-        // user has disabled WindLight in their settings, downgrade
-        // windlight shaders to stub versions.
-        wl_class = 2;
-    }
-    else
-    {
-        light_class = 2;
-    }
-
     // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders
     if (!wl_class || (mShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()))
     {
@@ -670,7 +656,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()
 
 	bool has_reflection_probes = gSavedSettings.getBOOL("RenderReflectionsEnabled") && gGLManager.mGLVersion > 3.99f;
 
-	S32 probe_count = gSavedSettings.getS32("RenderReflectionProbeCount");
+	S32 probe_count = llclamp(gSavedSettings.getS32("RenderReflectionProbeCount"), 1, LL_MAX_REFLECTION_PROBE_COUNT);
 
     if (ambient_kill)
     {