diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 4304db36bea26b30380a85184f47cc5f45dbd8f7..22d6bae0eb4718de60bc87458ef902efa36cea94 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -70,35 +70,38 @@ LLAssetDictionary::LLAssetDictionary()
 {
 	//       												   DESCRIPTION			TYPE NAME	HUMAN NAME			CAN LINK?   CAN FETCH?  CAN KNOW?	
 	//      												  |--------------------|-----------|-------------------|-----------|-----------|---------|
-	addEntry(LLAssetType::AT_TEXTURE, 			new AssetEntry("TEXTURE",			"texture",	"texture",			true,		false,		true));
-	addEntry(LLAssetType::AT_SOUND, 			new AssetEntry("SOUND",				"sound",	"sound",			true,		true,		true));
-	addEntry(LLAssetType::AT_CALLINGCARD, 		new AssetEntry("CALLINGCARD",		"callcard",	"calling card",		true,		false,		false));
-	addEntry(LLAssetType::AT_LANDMARK, 			new AssetEntry("LANDMARK",			"landmark",	"landmark",			true,		true,		true));
-	addEntry(LLAssetType::AT_SCRIPT, 			new AssetEntry("SCRIPT",			"script",	"legacy script",	true,		false,		false));
-	addEntry(LLAssetType::AT_CLOTHING, 			new AssetEntry("CLOTHING",			"clothing",	"clothing",			true,		true,		true));
-	addEntry(LLAssetType::AT_OBJECT, 			new AssetEntry("OBJECT",			"object",	"object",			true,		false,		false));
-	addEntry(LLAssetType::AT_NOTECARD, 			new AssetEntry("NOTECARD",			"notecard",	"note card",		true,		false,		true));
-	addEntry(LLAssetType::AT_CATEGORY, 			new AssetEntry("CATEGORY",			"category",	"folder",			true,		false,		false));
-	addEntry(LLAssetType::AT_LSL_TEXT, 			new AssetEntry("LSL_TEXT",			"lsltext",	"lsl2 script",		true,		false,		false));
-	addEntry(LLAssetType::AT_LSL_BYTECODE, 		new AssetEntry("LSL_BYTECODE",		"lslbyte",	"lsl bytecode",		true,		false,		false));
-	addEntry(LLAssetType::AT_TEXTURE_TGA, 		new AssetEntry("TEXTURE_TGA",		"txtr_tga",	"tga texture",		true,		false,		false));
-	addEntry(LLAssetType::AT_BODYPART, 			new AssetEntry("BODYPART",			"bodypart",	"body part",		true,		true,		true));
-	addEntry(LLAssetType::AT_SOUND_WAV, 		new AssetEntry("SOUND_WAV",			"snd_wav",	"sound",			true,		false,		false));
-	addEntry(LLAssetType::AT_IMAGE_TGA, 		new AssetEntry("IMAGE_TGA",			"img_tga",	"targa image",		true,		false,		false));
-	addEntry(LLAssetType::AT_IMAGE_JPEG, 		new AssetEntry("IMAGE_JPEG",		"jpeg",		"jpeg image",		true,		false,		false));
-	addEntry(LLAssetType::AT_ANIMATION, 		new AssetEntry("ANIMATION",			"animatn",	"animation",		true,		true,		true));
-	addEntry(LLAssetType::AT_GESTURE, 			new AssetEntry("GESTURE",			"gesture",	"gesture",			true,		true,		true));
-	addEntry(LLAssetType::AT_SIMSTATE, 			new AssetEntry("SIMSTATE",			"simstate",	"simstate",			false,		false,		false));
-
-	addEntry(LLAssetType::AT_LINK, 				new AssetEntry("LINK",				"link",		"sym link",			false,		false,		true));
-	addEntry(LLAssetType::AT_LINK_FOLDER, 		new AssetEntry("FOLDER_LINK",		"link_f", 	"sym folder link",	false,		false,		true));
-	addEntry(LLAssetType::AT_MESH,              new AssetEntry("MESH",              "mesh",     "mesh",             false,      false,      false));
-	addEntry(LLAssetType::AT_WIDGET,            new AssetEntry("WIDGET",            "widget",   "widget",           false,      false,      false));
-	addEntry(LLAssetType::AT_PERSON,            new AssetEntry("PERSON",            "person",   "person",           false,      false,      false));
-	addEntry(LLAssetType::AT_NONE, 				new AssetEntry("NONE",				"-1",		NULL,		  		FALSE,		FALSE,		FALSE));
+    addEntry(LLAssetType::AT_TEXTURE,           new AssetEntry("TEXTURE",           "texture",  "texture",			true,		false,		true));
+    addEntry(LLAssetType::AT_SOUND,             new AssetEntry("SOUND",             "sound",    "sound",			true,		true,		true));
+    addEntry(LLAssetType::AT_CALLINGCARD,       new AssetEntry("CALLINGCARD",       "callcard", "calling card",		true,		false,		false));
+    addEntry(LLAssetType::AT_LANDMARK,          new AssetEntry("LANDMARK",          "landmark", "landmark",			true,		true,		true));
+    addEntry(LLAssetType::AT_SCRIPT,            new AssetEntry("SCRIPT",            "script",   "legacy script",	true,		false,		false));
+    addEntry(LLAssetType::AT_CLOTHING,          new AssetEntry("CLOTHING",          "clothing", "clothing",			true,		true,		true));
+    addEntry(LLAssetType::AT_OBJECT,            new AssetEntry("OBJECT",            "object",   "object",			true,		false,		false));
+    addEntry(LLAssetType::AT_NOTECARD,          new AssetEntry("NOTECARD",          "notecard", "note card",		true,		false,		true));
+    addEntry(LLAssetType::AT_CATEGORY,          new AssetEntry("CATEGORY",          "category", "folder",			true,		false,		false));
+    addEntry(LLAssetType::AT_LSL_TEXT,          new AssetEntry("LSL_TEXT",          "lsltext",  "lsl2 script",		true,		false,		false));
+    addEntry(LLAssetType::AT_LSL_BYTECODE,      new AssetEntry("LSL_BYTECODE",      "lslbyte",  "lsl bytecode",		true,		false,		false));
+    addEntry(LLAssetType::AT_TEXTURE_TGA,       new AssetEntry("TEXTURE_TGA",       "txtr_tga", "tga texture",		true,		false,		false));
+    addEntry(LLAssetType::AT_BODYPART,          new AssetEntry("BODYPART",          "bodypart", "body part",		true,		true,		true));
+    addEntry(LLAssetType::AT_SOUND_WAV,         new AssetEntry("SOUND_WAV",         "snd_wav",  "sound",			true,		false,		false));
+    addEntry(LLAssetType::AT_IMAGE_TGA,         new AssetEntry("IMAGE_TGA",         "img_tga",  "targa image",		true,		false,		false));
+    addEntry(LLAssetType::AT_IMAGE_JPEG,        new AssetEntry("IMAGE_JPEG",        "jpeg",     "jpeg image",		true,		false,		false));
+    addEntry(LLAssetType::AT_ANIMATION,         new AssetEntry("ANIMATION",         "animatn",  "animation",		true,		true,		true));
+    addEntry(LLAssetType::AT_GESTURE,           new AssetEntry("GESTURE",			"gesture",  "gesture",			true,		true,		true));
+    addEntry(LLAssetType::AT_SIMSTATE, 		    new AssetEntry("SIMSTATE",			"simstate", "simstate",			false,		false,		false));
+
+    addEntry(LLAssetType::AT_LINK, 			    new AssetEntry("LINK",              "link",     "sym link",			false,		false,		true));
+    addEntry(LLAssetType::AT_LINK_FOLDER, 		new AssetEntry("FOLDER_LINK",       "link_f",   "sym folder link",	false,		false,		true));
+    addEntry(LLAssetType::AT_MESH,              new AssetEntry("MESH",              "mesh",     "mesh",             false,      false,      false));
+    addEntry(LLAssetType::AT_WIDGET,            new AssetEntry("WIDGET",            "widget",   "widget",           false,      false,      false));
+    addEntry(LLAssetType::AT_PERSON,            new AssetEntry("PERSON",            "person",   "person",           false,      false,      false));
+    addEntry(LLAssetType::AT_SETTINGS,          new AssetEntry("SETTINGS",          "settings", "settings blob",    false,      true,       true));
+    addEntry(LLAssetType::AT_NONE,              new AssetEntry("NONE",              "-1",		NULL,		  		FALSE,		FALSE,		FALSE));
 
 };
 
+const std::string LLAssetType::BADLOOKUP("llassettype_bad_lookup");
+
 // static
 LLAssetType::EType LLAssetType::getType(const std::string& desc_name)
 {
@@ -117,7 +120,7 @@ const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type)
 	}
 	else
 	{
-		return badLookup();
+		return BADLOOKUP;
 	}
 }
 
@@ -132,7 +135,7 @@ const char *LLAssetType::lookup(LLAssetType::EType asset_type)
 	}
 	else
 	{
-		return badLookup().c_str();
+		return BADLOOKUP.c_str();
 	}
 }
 
@@ -170,7 +173,7 @@ const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type)
 	}
 	else
 	{
-		return badLookup().c_str();
+		return BADLOOKUP.c_str();
 	}
 }
 
@@ -220,14 +223,6 @@ bool LLAssetType::lookupIsLinkType(EType asset_type)
 	return false;
 }
 
-// static
-const std::string &LLAssetType::badLookup()
-{
-	static const std::string sBadLookup = "llassettype_bad_lookup";
-	return sBadLookup;
-
-}
-
 // static
 bool LLAssetType::lookupIsAssetFetchByIDAllowed(EType asset_type)
 {
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index b849be9f16ad3a02474c7334631cf418f2b286e2..3a660496e3b72d132ed6e90fc1e6a36b02f80b9f 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -116,10 +116,18 @@ class LL_COMMON_API LLAssetType
 		AT_PERSON = 45,
 			// A user uuid  which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop.
 
-		AT_MESH = 49,
-			// Mesh data in our proprietary SLM format
-		
-		AT_COUNT = 50,
+        AT_MESH = 49,
+        // Mesh data in our proprietary SLM format
+
+        AT_RESERVED_1 = 50,
+        AT_RESERVED_2 = 51,
+        AT_RESERVED_3 = 52,
+        AT_RESERVED_4 = 53,
+        AT_RESERVED_5 = 54,
+
+        AT_SETTINGS = 55,   // Collection of settings
+            
+		AT_COUNT = 56,
 
 			// +*********************************************************+
 			// |  TO ADD AN ELEMENT TO THIS ENUM:                        |
@@ -153,7 +161,7 @@ class LL_COMMON_API LLAssetType
 	static bool 				lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download
 	static bool 				lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer
 
-	static const std::string&	badLookup(); // error string when a lookup fails
+    static const std::string    BADLOOKUP;
 
 protected:
 	LLAssetType() {}
diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp
index b0daf639fad2c054e77f45b21584fa795f1fc585..2c8c82a62b190ec8fc86e2fa0daa88c23bc4d8ce 100644
--- a/indra/llinventory/llfoldertype.cpp
+++ b/indra/llinventory/llfoldertype.cpp
@@ -147,7 +147,7 @@ bool LLFolderType::lookupIsEnsembleType(EType folder_type)
 // static
 LLAssetType::EType LLFolderType::folderTypeToAssetType(LLFolderType::EType folder_type)
 {
-	if (LLAssetType::lookup(LLAssetType::EType(folder_type)) == LLAssetType::badLookup())
+	if (LLAssetType::lookup(LLAssetType::EType(folder_type)) == LLAssetType::BADLOOKUP)
 	{
 		LL_WARNS() << "Converting to unknown asset type " << folder_type << LL_ENDL;
 	}
diff --git a/indra/llinventory/llinventorydefines.h b/indra/llinventory/llinventorydefines.h
index 3881fb1fd72d22d9c1e8ff9b18b36b8f5d4c556f..b420e98ecb10ab7dc144159c7fa7d991dacd33fc 100644
--- a/indra/llinventory/llinventorydefines.h
+++ b/indra/llinventory/llinventorydefines.h
@@ -84,6 +84,10 @@ class LLInventoryItemFlags
 		II_FLAGS_WEARABLES_MASK = 0xff,
 			// Wearables use the low order byte of flags to store the
 			// LLWearableType::EType enumeration found in newview/llwearable.h
+			// 
+        II_FLAGS_SETTINGS_MASK                      = 0x0000ff,
+            // Settings (like wearables) use the low order byte of flags to store 
+            // the settings type 
 
 		II_FLAGS_PERM_OVERWRITE_MASK = 				(II_FLAGS_OBJECT_SLAM_PERM |
 													 II_FLAGS_OBJECT_SLAM_SALE |
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index d1e6807f52138a3fa5fd2ed6a64b5433d6a337b9..20c0a12d9e2f49a25f61d3a60dd36b542286eb41 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -85,6 +85,7 @@ LLInventoryDictionary::LLInventoryDictionary()
 	addEntry(LLInventoryType::IT_MESH,                new InventoryEntry("mesh",      "mesh",          1, LLAssetType::AT_MESH));
 	addEntry(LLInventoryType::IT_WIDGET,              new InventoryEntry("widget",    "widget",        1, LLAssetType::AT_WIDGET));
 	addEntry(LLInventoryType::IT_PERSON,              new InventoryEntry("person",    "person",        1, LLAssetType::AT_PERSON));
+    addEntry(LLInventoryType::IT_SETTINGS,            new InventoryEntry("settings",  "settings",      1, LLAssetType::AT_SETTINGS));
 }
 
 
@@ -145,6 +146,14 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
 	LLInventoryType::IT_NONE,			// 47	AT_NONE
 	LLInventoryType::IT_NONE,			// 48	AT_NONE
 	LLInventoryType::IT_MESH,			// 49	AT_MESH
+
+    LLInventoryType::IT_NONE,   		// 50   AT_RESERVED_1
+    LLInventoryType::IT_NONE,	    	// 51   AT_RESERVED_2
+    LLInventoryType::IT_NONE,		    // 52   AT_RESERVED_3
+    LLInventoryType::IT_NONE,			// 53   AT_RESERVED_4
+    LLInventoryType::IT_NONE,			// 54   AT_RESERVED_5
+
+    LLInventoryType::IT_SETTINGS,       // 55   AT_SETTINGS
 };
 
 // static
@@ -194,6 +203,7 @@ bool LLInventoryType::cannotRestrictPermissions(LLInventoryType::EType type)
 	{
 		case IT_CALLINGCARD:
 		case IT_LANDMARK:
+        case IT_SETTINGS:
 			return true;
 		default:
 			return false;
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index fc3c78cf5062c7c0333a68585733ab2aa1320c1e..a45bcc364eabc023fba24efaff09df34654088fc 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -64,7 +64,8 @@ class LLInventoryType
 		IT_MESH = 22,
 		IT_WIDGET = 23,
 		IT_PERSON = 24,
-		IT_COUNT = 25,
+        IT_SETTINGS = 25,
+		IT_COUNT = 26,
 
 		IT_NONE = -1
 	};
@@ -110,6 +111,9 @@ class LLInventoryType
 		ICONNAME_LINKFOLDER,
 		ICONNAME_MESH,
 
+        ICONNAME_SETTINGS_SKY,
+        ICONNAME_SETTINGS_WATER,
+
 		ICONNAME_INVALID,
 		ICONNAME_COUNT,
 		ICONNAME_NONE = -1
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 4c8bcdac917eb856022ac9626e33dc0cb74ce0bc..61d13c0b1cd8bef2b2c7e2a35a175cf8e531620f 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -87,6 +87,7 @@ set(llmath_HEADER_FILES
     raytrace.h
     v2math.h
     v3color.h
+    v3colorutil.h
     v3dmath.h
     v3math.h
     v4color.h
diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp
index 47374c287f2d4c1b008534b726fe5647dd9b3bc0..dcef2b345eac9de9c7da63211d477d67d57633f4 100644
--- a/indra/llmath/llquaternion.cpp
+++ b/indra/llmath/llquaternion.cpp
@@ -103,6 +103,10 @@ LLQuaternion::LLQuaternion(const LLVector3 &x_axis,
 	*this = mat.quaternion();
 	normalize();
 }
+LLQuaternion::LLQuaternion(const LLSD &sd)
+{
+    setValue(sd);
+}
 
 // Quatizations
 void	LLQuaternion::quantize16(F32 lower, F32 upper)
diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h
index aa0b1752f4e0a56883ff4abaa27e885311a8c760..11b6abf80052d06c10f995ba8831b10f2f452200 100644
--- a/indra/llmath/llquaternion.h
+++ b/indra/llmath/llquaternion.h
@@ -28,6 +28,7 @@
 #define LLQUATERNION_H
 
 #include <iostream>
+#include "llsd.h"
 
 #ifndef LLMATH_H //enforce specific include order to avoid tangling inline dependencies
 #error "Please include llmath.h first."
@@ -63,6 +64,10 @@ class LLQuaternion
 	LLQuaternion(const LLVector3 &x_axis,
 				 const LLVector3 &y_axis,
 				 const LLVector3 &z_axis);			// Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis]
+    explicit LLQuaternion(const LLSD &sd);          // Initializes Quaternion from LLSD array.
+
+    LLSD getValue() const;
+    void setValue(const LLSD& sd);
 
 	BOOL isIdentity() const;
 	BOOL isNotIdentity() const;
@@ -166,6 +171,25 @@ class LLQuaternion
 	//static U32 mMultCount;
 };
 
+inline LLSD LLQuaternion::getValue() const
+{
+    LLSD ret;
+    ret[0] = mQ[0];
+    ret[1] = mQ[1];
+    ret[2] = mQ[2];
+    ret[3] = mQ[3];
+    return ret;
+}
+
+inline void LLQuaternion::setValue(const LLSD& sd)
+{
+    mQ[0] = sd[0].asReal();
+    mQ[1] = sd[1].asReal();
+    mQ[2] = sd[2].asReal();
+    mQ[3] = sd[3].asReal();
+}
+
+
 // checker
 inline BOOL	LLQuaternion::isFinite() const
 {
diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp
index a0cd6428538b61c197dcf7aa29b4fd57163298b0..a24571f2c82ea53af1c0b9438c69cc0fadbb637f 100644
--- a/indra/llmath/v2math.cpp
+++ b/indra/llmath/v2math.cpp
@@ -118,7 +118,7 @@ LLSD LLVector2::getValue() const
 	return ret;
 }
 
-void LLVector2::setValue(LLSD& sd)
+void LLVector2::setValue(const LLSD& sd)
 {
 	mV[0] = (F32) sd[0].asReal();
 	mV[1] = (F32) sd[1].asReal();
diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h
index 8d5db96f5e295633531865c8254960526b970037..2335a2e3273b8991b8405ed6ddd13874b911e2ef 100644
--- a/indra/llmath/v2math.h
+++ b/indra/llmath/v2math.h
@@ -49,6 +49,7 @@ class LLVector2
 		LLVector2(F32 x, F32 y);			      // Initializes LLVector2 to (x. y)
 		LLVector2(const F32 *vec);				  // Initializes LLVector2 to (vec[0]. vec[1])
         explicit LLVector2(const LLVector3 &vec); // Initializes LLVector2 to (vec[0]. vec[1])
+        explicit LLVector2(const LLSD &sd);
 		
 		// Clears LLVector2 to (0, 0).  DEPRECATED - prefer zeroVec.
 		void	clear();
@@ -61,7 +62,7 @@ class LLVector2
 		void	set(const F32 *vec);			// Sets LLVector2 to vec
 
 		LLSD	getValue() const;
-		void	setValue(LLSD& sd);
+		void	setValue(const LLSD& sd);
 
 		void	setVec(F32 x, F32 y);	        // deprecated
 		void	setVec(const LLVector2 &vec);	// deprecated
@@ -145,6 +146,10 @@ inline LLVector2::LLVector2(const LLVector3 &vec)
 	mV[VY] = vec.mV[VY];
 }
 
+inline LLVector2::LLVector2(const LLSD &sd)
+{
+    setValue(sd);
+}
 
 // Clear and Assignment Functions
 
diff --git a/indra/llmath/v3colorutil.h b/indra/llmath/v3colorutil.h
new file mode 100644
index 0000000000000000000000000000000000000000..00b36132d8db07a84c5e41537177782c1ddcc79d
--- /dev/null
+++ b/indra/llmath/v3colorutil.h
@@ -0,0 +1,95 @@
+/** 
+ * @file v3color.h
+ * @brief LLColor3 class header file.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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_V3COLORUTIL_H
+#define LL_V3COLORUTIL_H
+
+#include "v3color.h"
+
+inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right)
+{
+    return LLColor3(left.mV[0] / right.mV[0],
+        left.mV[1] / right.mV[1],
+        left.mV[2] / right.mV[2]);
+}
+
+
+inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right)
+{
+    return LLColor3(left.mV[0] * right.mV[0],
+        left.mV[1] * right.mV[1],
+        left.mV[2] * right.mV[2]);
+}
+
+
+inline LLColor3 componentExp(LLColor3 const &v)
+{
+    return LLColor3(exp(v.mV[0]),
+        exp(v.mV[1]),
+        exp(v.mV[2]));
+}
+
+inline LLColor3 componentPow(LLColor3 const &v, F32 exponent)
+{
+    return LLColor3(pow(v.mV[0], exponent),
+        pow(v.mV[1], exponent),
+        pow(v.mV[2], exponent));
+}
+
+inline LLColor3 componentSaturate(LLColor3 const &v)
+{
+    return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f),
+        std::max(std::min(v.mV[1], 1.f), 0.f),
+        std::max(std::min(v.mV[2], 1.f), 0.f));
+}
+
+
+inline LLColor3 componentSqrt(LLColor3 const &v)
+{
+    return LLColor3(sqrt(v.mV[0]),
+        sqrt(v.mV[1]),
+        sqrt(v.mV[2]));
+}
+
+inline void componentMultBy(LLColor3 & left, LLColor3 const & right)
+{
+    left.mV[0] *= right.mV[0];
+    left.mV[1] *= right.mV[1];
+    left.mV[2] *= right.mV[2];
+}
+
+inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
+{
+    return (left + ((right - left) * amount));
+}
+
+inline LLColor3 smear(F32 val)
+{
+    return LLColor3(val, val, val);
+}
+
+
+#endif
diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h
index 623c8b200353bb60bd5f052213a2b3a8f86cc7e8..293005a6278ccce79c54a3e283e4c509f62a1b1c 100644
--- a/indra/llmath/v4math.h
+++ b/indra/llmath/v4math.h
@@ -48,6 +48,7 @@ class LLVector4
 		explicit LLVector4(const F64 *vec);			// Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]);
 		explicit LLVector4(const LLVector3 &vec);			// Initializes LLVector4 to (vec, 1)
 		explicit LLVector4(const LLVector3 &vec, F32 w);	// Initializes LLVector4 to (vec, w)
+        explicit LLVector4(const LLSD &sd);
 		LLVector4(F32 x, F32 y, F32 z);		// Initializes LLVector4 to (x. y, z, 1)
 		LLVector4(F32 x, F32 y, F32 z, F32 w);
 
@@ -61,6 +62,15 @@ class LLVector4
 			return ret;
 		}
 
+        void setValue(const LLSD& sd)
+        {
+            mV[0] = sd[0].asReal();
+            mV[1] = sd[1].asReal();
+            mV[2] = sd[2].asReal();
+            mV[3] = sd[3].asReal();
+        }
+
+
 		inline BOOL isFinite() const;									// checks to see if all values of LLVector3 are finite
 
 		inline void	clear();		// Clears LLVector4 to (0, 0, 0, 1)
@@ -191,6 +201,11 @@ inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)
 	mV[VW] = w;
 }
 
+inline LLVector4::LLVector4(const LLSD &sd)
+{
+    setValue(sd);
+}
+
 
 inline BOOL LLVector4::isFinite() const
 {
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f353109debb2da964f0428c472a504e6159233ca..f3811fffe76abe305504d244de5a2bceb128ecab 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -533,6 +533,8 @@ set(viewer_SOURCE_FILES
     llsecapi.cpp
     llsechandler_basic.cpp
     llselectmgr.cpp
+    llsettingsbase.cpp
+    llsettingssky.cpp
     llshareavatarhandler.cpp
     llsidepanelappearance.cpp
     llsidepanelinventory.cpp
@@ -1145,6 +1147,8 @@ set(viewer_HEADER_FILES
     llsecapi.h
     llsechandler_basic.h
     llselectmgr.h
+    llsettingsbase.h
+    llsettingssky.h
     llsidepanelappearance.h
     llsidepanelinventory.h
     llsidepanelinventorysubpanel.h
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 495180f087a50097dfb5ba052085baf71a1e5938..64b48228f68fee3ff859222863c11cff0483567f 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -92,6 +92,9 @@ LLIconDictionary::LLIconDictionary()
 	addEntry(LLInventoryType::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkFolder"));
 	addEntry(LLInventoryType::ICONNAME_MESH,	 				new IconEntry("Inv_Mesh"));
 
+    addEntry(LLInventoryType::ICONNAME_SETTINGS_SKY,            new IconEntry("Inv_SettingSky"));
+    addEntry(LLInventoryType::ICONNAME_SETTINGS_WATER,          new IconEntry("Inv_SettingWater"));
+
 	addEntry(LLInventoryType::ICONNAME_INVALID, 				new IconEntry("Inv_Invalid"));
 
 	addEntry(LLInventoryType::ICONNAME_NONE, 					new IconEntry("NONE"));
@@ -166,6 +169,11 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
 			break;
 		case LLAssetType::AT_MESH:
 			idx = LLInventoryType::ICONNAME_MESH;
+            break;
+        case LLAssetType::AT_SETTINGS:
+            // TODO: distinguish between Sky and Water settings.
+            idx = LLInventoryType::ICONNAME_SETTINGS_SKY;
+            break;
 		default:
 			break;
 	}
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index e5fd126d53c0a2a98e93222b57b37170c64e5125..c26f2f07ce425cb67968973aa895932b12c0a8fe 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1801,7 +1801,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
 		// For example, there is a known backwards compatibility issue in some viewer prototypes prior to when 
 		// the AT_LINK enum changed from 23 to 24.
 		if ((item->getType() == LLAssetType::AT_NONE)
-		    || LLAssetType::lookup(item->getType()) == LLAssetType::badLookup())
+		    || LLAssetType::lookup(item->getType()) == LLAssetType::BADLOOKUP)
 		{
 			LL_WARNS(LOG_INV) << "Got bad asset type for item [ name: " << item->getName()
 							  << " type: " << item->getType()
diff --git a/indra/newview/llsettingsbase.cpp b/indra/newview/llsettingsbase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1aafacae458054c557161bb2e89c71ef02f8d65e
--- /dev/null
+++ b/indra/newview/llsettingsbase.cpp
@@ -0,0 +1,246 @@
+/**
+* @file llsettingsbase.cpp
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $LicenseInfo:2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2017, 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 "llsettingsbase.h"
+
+#include "llmath.h"
+#include <algorithm>
+
+#include "llsdserialize.h"
+
+namespace
+{
+    const F32 BREAK_POINT = 0.5;
+}
+
+//=========================================================================
+LLSettingsBase::LLSettingsBase():
+    mSettings(LLSD::emptyMap()),
+    mDirty(true)
+{
+}
+
+LLSettingsBase::LLSettingsBase(const LLSD setting) :
+    mSettings(setting),
+    mDirty(true)
+{
+}
+
+//=========================================================================
+void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F32 mix) 
+{
+    mSettings = interpolateSDMap(mSettings, other.mSettings, mix);
+    setDirtyFlag(true);
+}
+
+LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) const
+{
+    LLSD newSettings;
+
+    for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it)
+    {
+        std::string key_name = (*it).first;
+        LLSD value = (*it).second;
+
+        LLSD::Type setting_type = value.type();
+        switch (setting_type)
+        {
+        case LLSD::TypeMap:
+            newSettings[key_name] = combineSDMaps(value, LLSD());
+            break;
+        case LLSD::TypeArray:
+            newSettings[key_name] = LLSD::emptyArray();
+            for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
+            {
+                newSettings[key_name].append(*ita);
+            }
+            break;
+        default:
+            newSettings[key_name] = value;
+            break;
+        }
+    }
+
+    if (!other.isUndefined())
+    {
+        for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
+        {
+            std::string key_name = (*it).first;
+            LLSD value = (*it).second;
+
+            LLSD::Type setting_type = value.type();
+            switch (setting_type)
+            {
+            case LLSD::TypeMap:
+                newSettings[key_name] = combineSDMaps(value, LLSD());
+                break;
+            case LLSD::TypeArray:
+                newSettings[key_name] = LLSD::emptyArray();
+                for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
+                {
+                    newSettings[key_name].append(*ita);
+                }
+                break;
+            default:
+                newSettings[key_name] = value;
+                break;
+            }
+        }
+    }
+
+    return newSettings;
+}
+
+LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, F32 mix) const
+{
+    LLSD newSettings;
+
+    stringset_t skip = getSkipInterpolateKeys();
+    stringset_t slerps = getSlerpKeys();
+
+    for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it)
+    {
+        std::string key_name = (*it).first;
+        LLSD value = (*it).second;
+
+        if (skip.find(key_name) != skip.end())
+            continue;
+
+        if (!other.has(key_name))
+        {   // The other does not contain this setting, keep the original value 
+            // TODO: Should I blend this out instead?
+            newSettings[key_name] = value;
+            continue;
+        }
+        LLSD::Type setting_type = value.type();
+        LLSD other_value = other[key_name];
+        
+        if (other_value.type() != setting_type)
+        {   
+            // The data type mismatched between this and other. Hard switch when we pass the break point
+            // but issue a warning.
+            LL_WARNS("SETTINGS") << "Setting lerp between mismatched types for '" << key_name << "'." << LL_ENDL;
+            newSettings[key_name] = (mix > BREAK_POINT) ? other_value : value;
+            continue;
+        }
+
+        switch (setting_type)
+        {
+        case LLSD::TypeInteger:
+            // lerp between the two values rounding the result to the nearest integer. 
+            newSettings[key_name] = LLSD::Integer(llroundf(lerp(value.asReal(), other_value.asReal(), mix)));
+            break;
+        case LLSD::TypeReal:
+            // lerp between the two values.
+            newSettings[key_name] = LLSD::Real(lerp(value.asReal(), other_value.asReal(), mix));
+            break;
+        case LLSD::TypeMap:
+            // deep copy.
+            newSettings[key_name] = interpolateSDMap(value, other_value, mix);
+            break;
+
+        case LLSD::TypeArray:
+            {
+                LLSD newvalue(LLSD::emptyArray());
+
+                if (slerps.find(key_name) != slerps.end())
+                {
+                    LLQuaternion q = slerp(mix, LLQuaternion(value), LLQuaternion(other_value));
+                    newvalue = q.getValue();
+                }
+                else
+                {   // TODO: We could expand this to inspect the type and do a deep lerp based on type. 
+                    // for now assume a heterogeneous array of reals. 
+                    size_t len = std::max(value.size(), other_value.size());
+
+                    for (size_t i = 0; i < len; ++i)
+                    {
+
+                        newvalue[i] = lerp(value[i].asReal(), other_value[i].asReal(), mix);
+                    }
+                }
+                
+                newSettings[key_name] = newvalue;
+            }
+
+            break;
+
+//      case LLSD::TypeBoolean:
+//      case LLSD::TypeString:
+//      case LLSD::TypeUUID:
+//      case LLSD::TypeURI:
+//      case LLSD::TypeBinary:
+//      case LLSD::TypeDate:
+        default:
+            // atomic or unknown data types. Lerping between them does not make sense so switch at the break.
+            newSettings[key_name] = (mix > BREAK_POINT) ? other_value : value;
+            break;
+        }
+    }
+
+    // Now add anything that is in other but not in the settings
+    for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
+    {
+        // TODO: Should I blend this in instead?
+        if (skip.find((*it).first) == skip.end())
+            continue;
+
+        if (!settings.has((*it).first))
+            continue;
+    
+        newSettings[(*it).first] = (*it).second;
+    }
+
+    return newSettings;
+}
+
+
+void LLSettingsBase::exportSettings(std::string name) const
+{
+    LLSD exprt = LLSDMap("type", LLSD::String(getSettingType()))
+        ("name", LLSD::String(name))
+        ("settings", mSettings);
+
+    std::string path_name = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, name + ".settings");
+
+    // write to file
+    llofstream presetsXML(path_name.c_str());
+    if (presetsXML.is_open())
+    {
+        LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+        formatter->format(exprt, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
+        presetsXML.close();
+
+        LL_DEBUGS() << "saved preset '" << name << "'; " << mSettings.size() << " settings" << LL_ENDL;
+
+    }
+    else
+    {
+        LL_WARNS("Presets") << "Cannot open for output preset file " << path_name << LL_ENDL;
+    }
+}
diff --git a/indra/newview/llsettingsbase.h b/indra/newview/llsettingsbase.h
new file mode 100644
index 0000000000000000000000000000000000000000..01a19c8734534a849522a32c64809661932d9e85
--- /dev/null
+++ b/indra/newview/llsettingsbase.h
@@ -0,0 +1,155 @@
+/**
+* @file llsettingsbase.h
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $LicenseInfo:2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2017, 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_SETTINGS_BASE_H
+#define LL_SETTINGS_BASE_H
+
+#include <string>
+#include <map>
+#include <vector>
+
+#include "llsd.h"
+#include "llsdutil.h"
+#include "v2math.h"
+#include "v3math.h"
+#include "v4math.h"
+#include "llquaternion.h"
+#include "v4color.h"
+
+class LLSettingsBase: private boost::noncopyable
+{
+    friend class LLEnvironment;
+
+public:
+    typedef boost::shared_ptr<LLSettingsBase> ptr_t;
+
+    virtual ~LLSettingsBase() { };
+
+    //---------------------------------------------------------------------
+    virtual std::string getSettingType() const = 0;
+
+    //---------------------------------------------------------------------
+    // Settings status 
+    inline bool hasSetting(const std::string &param) const { return mSettings.has(param); }
+    inline bool isDirty() const { return mDirty; }
+    inline void setDirtyFlag(bool dirty) { mDirty = dirty; }
+
+    //---------------------------------------------------------------------
+    // 
+    inline void setValue(const std::string &name, const LLSD &value)
+    {
+        mSettings[name] = value;
+        mDirty = true;
+    }
+
+    inline LLSD getValue(const std::string &name, const LLSD &deflt = LLSD())
+    {
+        if (!mSettings.has(name))
+            return deflt;
+        return mSettings[name];
+    }
+
+    inline void setValue(const std::string &name, const LLVector2 &value)
+    {
+        setValue(name, value.getValue());
+    }
+
+    inline void setValue(const std::string &name, const LLVector3 &value)
+    {
+        setValue(name, value.getValue());
+    }
+
+    inline void setValue(const std::string &name, const LLVector4 &value)
+    {
+        setValue(name, value.getValue());
+    }
+
+    inline void setValue(const std::string &name, const LLQuaternion &value)
+    {
+        setValue(name, value.getValue());
+    }
+
+    inline void setValue(const std::string &name, const LLColor3 &value)
+    {
+        setValue(name, value.getValue());
+    }
+
+    inline void setValue(const std::string &name, const LLColor4 &value)
+    {
+        setValue(name, value.getValue());
+    }
+
+    // Note this method is marked const but may modify the settings object.
+    // (note the internal const cast).  This is so that it may be called without
+    // special consideration from getters.
+    inline void update() const
+    {
+        if (!mDirty)
+            return;
+        (const_cast<LLSettingsBase *>(this))->updateSettings();
+    }
+
+    // TODO: This is temporary 
+    virtual void exportSettings(std::string name) const;
+
+protected:
+    LLSettingsBase();
+    LLSettingsBase(const LLSD setting);
+
+    typedef std::set<std::string>   stringset_t;
+
+    // combining settings objects. Customize for specific setting types
+    virtual void lerpSettings(const LLSettingsBase &other, F32 mix);
+
+    /// when lerping between settings, some may require special handling.  
+    /// Get a list of these key to be skipped by the default settings lerp.
+    /// (handling should be performed in the override of lerpSettings.
+    virtual stringset_t getSkipInterpolateKeys() const { return stringset_t(); }  
+
+    // A list of settings that represent quaternions and should be slerped 
+    // rather than lerped.
+    virtual stringset_t getSlerpKeys() const { return stringset_t(); }
+
+    // Calculate any custom settings that may need to be cached.
+    virtual void updateSettings() { mDirty = false; };
+
+    virtual stringset_t getSkipApplyKeys() const { return stringset_t(); }
+    // Apply any settings that need special handling. 
+    virtual void applySpecial(void *) { };
+
+    LLSD    mSettings;
+
+private:
+    bool    mDirty;
+
+    LLSD    combineSDMaps(const LLSD &first, const LLSD &other) const;
+    LLSD    interpolateSDMap(const LLSD &settings, const LLSD &other, F32 mix) const;
+
+};
+
+
+#endif
diff --git a/indra/newview/llsettingssky.cpp b/indra/newview/llsettingssky.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..364c2113440126ee820b4ad839948d4cfed28eb3
--- /dev/null
+++ b/indra/newview/llsettingssky.cpp
@@ -0,0 +1,513 @@
+/**
+* @file llsettingssky.cpp
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $LicenseInfo:2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2017, 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 "llviewercontrol.h"
+#include "llsettingssky.h"
+#include <algorithm>
+#include <boost/make_shared.hpp>
+#include "lltrace.h"
+#include "llfasttimer.h"
+#include "v3colorutil.h"
+
+#include "llglslshader.h"
+#include "llviewershadermgr.h"
+
+#include "llsky.h"
+
+//=========================================================================
+namespace
+{
+    const LLVector3 DUE_EAST(-1.0f, 0.0f, 0.0);
+
+    LLTrace::BlockTimerStatHandle FTM_BLEND_ENVIRONMENT("Blending Environment Params");
+    LLTrace::BlockTimerStatHandle FTM_UPDATE_ENVIRONMENT("Update Environment Params");
+
+}
+
+//=========================================================================
+const std::string LLSettingsSky::SETTING_AMBIENT("ambient");
+const std::string LLSettingsSky::SETTING_BLOOM_TEXTUREID("bloom_id");
+const std::string LLSettingsSky::SETTING_BLUE_DENSITY("blue_density");
+const std::string LLSettingsSky::SETTING_BLUE_HORIZON("blue_horizon");
+const std::string LLSettingsSky::SETTING_CLOUD_COLOR("cloud_color");
+const std::string LLSettingsSky::SETTING_CLOUD_POS_DENSITY1("cloud_pos_density1");
+const std::string LLSettingsSky::SETTING_CLOUD_POS_DENSITY2("cloud_pos_density2");
+const std::string LLSettingsSky::SETTING_CLOUD_SCALE("cloud_scale");
+const std::string LLSettingsSky::SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate");
+const std::string LLSettingsSky::SETTING_CLOUD_SHADOW("cloud_shadow");
+const std::string LLSettingsSky::SETTING_CLOUD_TEXTUREID("cloud_id");
+const std::string LLSettingsSky::SETTING_DENSITY_MULTIPLIER("density_multiplier");
+const std::string LLSettingsSky::SETTING_DISTANCE_MULTIPLIER("distance_multiplier");
+const std::string LLSettingsSky::SETTING_DOME_OFFSET("dome_offset");
+const std::string LLSettingsSky::SETTING_DOME_RADIUS("dome_radius");
+const std::string LLSettingsSky::SETTING_GAMMA("gamma");
+const std::string LLSettingsSky::SETTING_GLOW("glow");
+const std::string LLSettingsSky::SETTING_HAZE_DENSITY("haze_density");
+const std::string LLSettingsSky::SETTING_HAZE_HORIZON("haze_horizon");
+const std::string LLSettingsSky::SETTING_LIGHT_NORMAL("lightnorm");
+const std::string LLSettingsSky::SETTING_MAX_Y("max_y");
+const std::string LLSettingsSky::SETTING_MOON_ROTATION("moon_rotation");
+const std::string LLSettingsSky::SETTING_MOON_TEXTUREID("moon_id");
+const std::string LLSettingsSky::SETTING_NAME("name");
+const std::string LLSettingsSky::SETTING_STAR_BRIGHTNESS("star_brightness");
+const std::string LLSettingsSky::SETTING_SUNLIGHT_COLOR("sunlight_color");
+const std::string LLSettingsSky::SETTING_SUN_ROTATION("sun_rotation");
+const std::string LLSettingsSky::SETTING_SUN_TEXUTUREID("sun_id");
+
+const std::string LLSettingsSky::SETTING_LEGACY_EAST_ANGLE("east_angle");
+const std::string LLSettingsSky::SETTING_LEGACY_ENABLE_CLOUD_SCROLL("enable_cloud_scroll");
+const std::string LLSettingsSky::SETTING_LEGACY_SUN_ANGLE("sun_angle");
+
+
+//=========================================================================
+LLSettingsSky::LLSettingsSky(const LLSD &data) :
+    LLSettingsBase(data)
+{
+}
+
+LLSettingsSky::LLSettingsSky():
+    LLSettingsBase()
+{
+}
+
+LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const 
+{ 
+    static stringset_t slepSet;
+
+    if (slepSet.empty())
+    {
+        slepSet.insert(SETTING_SUN_ROTATION);
+        slepSet.insert(SETTING_MOON_ROTATION);
+    }
+
+    return slepSet;
+}
+
+
+LLSettingsSky::ptr_t LLSettingsSky::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings)
+{
+    LLSD newsettings(LLSD::emptyMap());
+
+    newsettings[SETTING_NAME] = name;
+
+    if (oldsettings.has(SETTING_AMBIENT))
+    {
+        newsettings[SETTING_AMBIENT] = LLColor3(oldsettings[SETTING_AMBIENT]).getValue();
+    }
+
+    if (oldsettings.has(SETTING_BLUE_DENSITY))
+    {
+        newsettings[SETTING_BLUE_DENSITY] = LLColor3(oldsettings[SETTING_BLUE_DENSITY]).getValue();
+    }
+
+    if (oldsettings.has(SETTING_BLUE_HORIZON))
+    {
+        newsettings[SETTING_BLUE_HORIZON] = LLColor3(oldsettings[SETTING_BLUE_HORIZON]).getValue();
+    }
+
+    if (oldsettings.has(SETTING_CLOUD_COLOR))
+    {
+        newsettings[SETTING_CLOUD_COLOR] = LLColor4(oldsettings[SETTING_CLOUD_COLOR]).getValue();
+    }
+    if (oldsettings.has(SETTING_SUNLIGHT_COLOR))
+    {
+        newsettings[SETTING_SUNLIGHT_COLOR] = LLColor4(oldsettings[SETTING_SUNLIGHT_COLOR]).getValue();
+    }
+    if (oldsettings.has(SETTING_CLOUD_SHADOW))
+    {
+        newsettings[SETTING_CLOUD_SHADOW] = LLSD::Real(oldsettings[SETTING_CLOUD_SHADOW][0].asReal());
+    }
+
+    if (oldsettings.has(SETTING_CLOUD_POS_DENSITY1))
+    {
+        newsettings[SETTING_CLOUD_POS_DENSITY1] = LLColor4(oldsettings[SETTING_CLOUD_POS_DENSITY1]).getValue();
+    }
+    if (oldsettings.has(SETTING_CLOUD_POS_DENSITY2))
+    {
+        newsettings[SETTING_CLOUD_POS_DENSITY2] = LLColor4(oldsettings[SETTING_CLOUD_POS_DENSITY2]).getValue();
+    }
+    if (oldsettings.has(SETTING_LIGHT_NORMAL))
+    {
+        newsettings[SETTING_LIGHT_NORMAL] = LLVector4(oldsettings[SETTING_LIGHT_NORMAL]).getValue();
+    }
+
+    if (oldsettings.has(SETTING_CLOUD_SCALE))
+    {
+        newsettings[SETTING_CLOUD_SCALE] = LLSD::Real(oldsettings[SETTING_CLOUD_SCALE][0].asReal());
+    }
+
+    if (oldsettings.has(SETTING_DENSITY_MULTIPLIER))
+    {
+        newsettings[SETTING_DENSITY_MULTIPLIER] = LLSD::Real(oldsettings[SETTING_DENSITY_MULTIPLIER][0].asReal());
+    }
+    if (oldsettings.has(SETTING_DISTANCE_MULTIPLIER))
+    {
+        newsettings[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(oldsettings[SETTING_DISTANCE_MULTIPLIER][0].asReal());
+    }
+    if (oldsettings.has(SETTING_HAZE_DENSITY))
+    {
+        newsettings[SETTING_HAZE_DENSITY] = LLSD::Real(oldsettings[SETTING_HAZE_DENSITY][0].asReal());
+    }
+    if (oldsettings.has(SETTING_HAZE_HORIZON))
+    {
+        newsettings[SETTING_HAZE_HORIZON] = LLSD::Real(oldsettings[SETTING_HAZE_HORIZON][0].asReal());
+    }
+    if (oldsettings.has(SETTING_MAX_Y))
+    {
+        newsettings[SETTING_MAX_Y] = LLSD::Real(oldsettings[SETTING_MAX_Y][0].asReal());
+    }
+    if (oldsettings.has(SETTING_STAR_BRIGHTNESS))
+    {
+        newsettings[SETTING_STAR_BRIGHTNESS] = LLSD::Real(oldsettings[SETTING_STAR_BRIGHTNESS].asReal());
+    }
+
+    if (oldsettings.has(SETTING_GLOW))
+    {
+        newsettings[SETTING_GLOW] = LLColor3(oldsettings[SETTING_GLOW]).getValue();
+    }
+
+    if (oldsettings.has(SETTING_GAMMA))
+    {
+        newsettings[SETTING_GAMMA] = LLSD::Real(oldsettings[SETTING_GAMMA][0].asReal());
+    }
+
+    if (oldsettings.has(SETTING_CLOUD_SCROLL_RATE))
+    {
+        LLVector2 cloud_scroll(oldsettings[SETTING_CLOUD_SCROLL_RATE]);
+
+        if (oldsettings.has(SETTING_LEGACY_ENABLE_CLOUD_SCROLL))
+        {
+            LLSD enabled = oldsettings[SETTING_LEGACY_ENABLE_CLOUD_SCROLL];
+            if (!enabled[0].asBoolean())
+                cloud_scroll.mV[0] = 0.0f;
+            if (!enabled[1].asBoolean())
+                cloud_scroll.mV[1] = 0.0f;
+        }
+
+        newsettings[SETTING_CLOUD_SCROLL_RATE] = cloud_scroll.getValue();
+    }
+
+
+    if (oldsettings.has(SETTING_LEGACY_EAST_ANGLE) && oldsettings.has(SETTING_LEGACY_SUN_ANGLE))
+    {   // convert the east and sun angles into a quaternion.
+        F32 east = oldsettings[SETTING_LEGACY_EAST_ANGLE].asReal();
+        F32 azimuth = oldsettings[SETTING_LEGACY_SUN_ANGLE].asReal();
+
+        LLQuaternion sunquat;
+        sunquat.setEulerAngles(azimuth, 0.0, east);
+//         // set the sun direction from SunAngle and EastAngle
+//         F32 sinTheta = sin(east);
+//         F32 cosTheta = cos(east);
+// 
+//         F32 sinPhi = sin(azimuth);
+//         F32 cosPhi = cos(azimuth);
+// 
+//         LLVector4 sunDir;
+//         sunDir.mV[0] = -sinTheta * cosPhi;
+//         sunDir.mV[1] = sinPhi;
+//         sunDir.mV[2] = cosTheta * cosPhi;
+//         sunDir.mV[3] = 0;
+// 
+//         LLQuaternion sunquat = LLQuaternion(0.1, sunDir);   // small rotation around axis
+        LLQuaternion moonquat = ~sunquat;
+
+        newsettings[SETTING_SUN_ROTATION] = sunquat.getValue();
+        newsettings[SETTING_MOON_ROTATION] = moonquat.getValue();
+    }
+
+    LLSettingsSky::ptr_t skyp = boost::make_shared<LLSettingsSky>(newsettings);
+    skyp->update();
+
+    return skyp;    
+}
+
+LLSettingsSky::ptr_t LLSettingsSky::buildDefaultSky()
+{
+    LLSD settings = LLSettingsSky::defaults();
+
+    LLSettingsSky::ptr_t skyp = boost::make_shared<LLSettingsSky>(settings);
+    skyp->update();
+
+    return skyp;
+}
+
+
+// Settings status 
+
+LLSettingsSky::ptr_t LLSettingsSky::blend(const LLSettingsSky::ptr_t &other, F32 mix) const
+{
+    LL_RECORD_BLOCK_TIME(FTM_BLEND_ENVIRONMENT);
+    LL_INFOS("WINDLIGHT", "SKY", "EEP") << "Blending new sky settings object." << LL_ENDL;
+
+    LLSettingsSky::ptr_t skyp = boost::make_shared<LLSettingsSky>(mSettings);
+    // the settings in the initial constructor are references tho this' settings block.  
+    // They will be replaced in the following lerp
+    skyp->lerpSettings(*other, mix);
+
+    return skyp;
+}
+
+
+LLSD LLSettingsSky::defaults()
+{
+    LLSD dfltsetting;
+
+    
+    LLQuaternion sunquat;
+    sunquat.setEulerAngles(1.39626, 0.0, 0.0); // 80deg Azumith/0deg East
+    LLQuaternion moonquat = ~sunquat;
+
+    // Magic constants copied form dfltsetting.xml 
+    dfltsetting[SETTING_AMBIENT]            = LLColor3::white.getValue();
+    dfltsetting[SETTING_BLUE_DENSITY]       = LLColor3(0.2447, 0.4487, 0.7599).getValue();
+    dfltsetting[SETTING_BLUE_HORIZON]       = LLColor3(0.4954, 0.4954, 0.6399).getValue();
+    dfltsetting[SETTING_CLOUD_COLOR]        = LLColor3(0.4099, 0.4099, 0.4099).getValue();
+    dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor3(1.0000, 0.5260, 1.0000).getValue();
+    dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor3(1.0000, 0.5260, 1.0000).getValue();
+    dfltsetting[SETTING_CLOUD_SCALE]        = LLSD::Real(0.4199);
+    dfltsetting[SETTING_CLOUD_SCROLL_RATE]  = LLSDArray(10.1999)(10.0109);
+    dfltsetting[SETTING_CLOUD_SHADOW]       = LLColor3(0.2699, 0.0000, 0.0000).getValue();
+    dfltsetting[SETTING_DENSITY_MULTIPLIER] = LLSD::Real(0.0001);
+    dfltsetting[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(0.8000);
+    dfltsetting[SETTING_DOME_OFFSET]        = LLSD::Real(1.0);
+    dfltsetting[SETTING_DOME_RADIUS]        = LLSD::Real(0.0);
+    dfltsetting[SETTING_GAMMA]              = LLSD::Real(1.0000);
+    dfltsetting[SETTING_GLOW]               = LLColor3(5.000, 0.0010, -0.4799).getValue();   // *RIDER: This is really weird for a color... TODO: check if right.
+    dfltsetting[SETTING_HAZE_DENSITY]       = LLSD::Real(0.6999);
+    dfltsetting[SETTING_HAZE_HORIZON]       = LLSD::Real(0.1899);
+    dfltsetting[SETTING_LIGHT_NORMAL]       = LLVector4(0.0000, 0.9126, -0.4086, 0.0000).getValue();
+    dfltsetting[SETTING_MAX_Y]              = LLSD::Real(1605);
+    dfltsetting[SETTING_MOON_ROTATION]      = moonquat.getValue();
+    dfltsetting[SETTING_NAME]               = std::string("_default_");
+    dfltsetting[SETTING_STAR_BRIGHTNESS]    = LLSD::Real(0.0000);
+    dfltsetting[SETTING_SUNLIGHT_COLOR]     = LLColor3(0.7342, 0.7815, 0.8999).getValue();
+    dfltsetting[SETTING_SUN_ROTATION]       = sunquat.getValue();
+
+    dfltsetting[SETTING_BLOOM_TEXTUREID]    = LLUUID::null;
+    dfltsetting[SETTING_CLOUD_TEXTUREID]    = LLUUID::null;
+    dfltsetting[SETTING_MOON_TEXTUREID]     = IMG_SUN; // gMoonTextureID;   // These two are returned by the login... wow!
+    dfltsetting[SETTING_SUN_TEXUTUREID]     = IMG_MOON; // gSunTextureID;
+
+    return dfltsetting;
+}
+
+void LLSettingsSky::updateSettings()
+{
+    LL_RECORD_BLOCK_TIME(FTM_UPDATE_ENVIRONMENT);
+    LL_INFOS("WINDLIGHT", "SKY", "EEP") << "WL Parameters are dirty.  Reticulating Splines..." << LL_ENDL;
+
+    // base class clears dirty flag so as to not trigger recursive update
+    LLSettingsBase::updateSettings();
+
+    calculateHeavnlyBodyPositions();
+    calculateLightSettings();
+}
+
+void LLSettingsSky::calculateHeavnlyBodyPositions()
+{
+    mSunDirection = DUE_EAST * getSunRotation();
+    mSunDirection.normalize();
+    mMoonDirection = DUE_EAST * getMoonRotation();
+    mMoonDirection.normalize();
+
+
+    // is the normal from the sun or the moon
+    if (mSunDirection.mV[1] >= 0.0)
+    {
+        mLightDirection = mSunDirection;
+    }
+    else if (mSunDirection.mV[1] < 0.0 && mSunDirection.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS)
+    {
+        // clamp v1 to 0 so sun never points up and causes weirdness on some machines
+        LLVector3 vec(mSunDirection);
+        vec.mV[1] = 0.0;
+        vec.normVec();
+        mLightDirection = vec;
+    }
+    else
+    {
+        mLightDirection = mMoonDirection;
+    }
+
+    // calculate the clamp lightnorm for sky (to prevent ugly banding in sky
+    // when haze goes below the horizon
+    mLightDirectionClamped = mSunDirection;
+
+    if (mLightDirectionClamped.mV[1] < -0.1f)
+    {
+        mLightDirectionClamped.mV[1] = -0.1f;
+    }
+}
+
+void LLSettingsSky::calculateLightSettings()
+{
+    LLColor3 vary_HazeColor;
+    LLColor3 vary_SunlightColor;
+    LLColor3 vary_AmbientColor;
+    {
+        // Initialize temp variables
+        LLColor3 sunlight = getSunlightColor();
+
+        // Fetch these once...
+        F32 haze_density = getHazeDensity();
+        F32 haze_horizon = getHazeHorizon();
+        F32 density_multiplier = getDensityMultiplier();
+        F32 max_y = getMaxY();
+        F32 gamma = getGama();
+        F32 cloud_shadow = getCloudShadow();
+        LLColor3 blue_density = getBlueDensity();
+        LLColor3 blue_horizon = getBlueHorizon();
+        LLColor3 ambient = getAmbientColor();
+
+
+        // Sunlight attenuation effect (hue and brightness) due to atmosphere
+        // this is used later for sunlight modulation at various altitudes
+        LLColor3 light_atten =  
+            (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y);
+
+        // Calculate relative weights
+        LLColor3 temp2(0.f, 0.f, 0.f);
+        LLColor3 temp1 = blue_density + smear(haze_density);
+        LLColor3 blue_weight = componentDiv(blue_density, temp1);
+        LLColor3 haze_weight = componentDiv(smear(haze_density), temp1);
+
+        // Compute sunlight from P & lightnorm (for long rays like sky)
+        /// USE only lightnorm.
+        // temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] );
+
+        // and vary_sunlight will work properly with moon light
+        F32 lighty = mLightDirection[1];
+        if (lighty < LLSky::NIGHTTIME_ELEVATION_COS)
+        {
+            lighty = -lighty;
+        }
+
+        temp2.mV[1] = llmax(0.f, lighty);
+        if (temp2.mV[1] > 0.f)
+        {
+            temp2.mV[1] = 1.f / temp2.mV[1];
+        }
+        componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
+
+        // Distance
+        temp2.mV[2] = density_multiplier;
+
+        // Transparency (-> temp1)
+        temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]);
+
+        // vary_AtmosAttenuation = temp1; 
+
+        //increase ambient when there are more clouds
+        LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f;
+
+        //haze color
+        vary_HazeColor =
+            (blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient)
+            + componentMult(haze_horizon * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient)
+            );
+
+        //brightness of surface both sunlight and ambient
+        vary_SunlightColor = componentMult(sunlight, temp1) * 1.f;
+        vary_SunlightColor.clamp();
+        vary_SunlightColor = smear(1.0f) - vary_SunlightColor;
+        vary_SunlightColor = componentPow(vary_SunlightColor, gamma);
+        vary_SunlightColor = smear(1.0f) - vary_SunlightColor;
+        vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5;
+        vary_AmbientColor.clamp();
+        vary_AmbientColor = smear(1.0f) - vary_AmbientColor;
+        vary_AmbientColor = componentPow(vary_AmbientColor, gamma);
+        vary_AmbientColor = smear(1.0f) - vary_AmbientColor;
+
+        componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1);
+
+    }
+
+    float dp = getSunDirection() * LLVector3(0, 0, 1.f); // a dot b
+    if (dp < 0)
+    {
+        dp = 0;
+    }
+
+    // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio
+    // between sunlight and point lights in windlight to normalize point lights.
+    F32 sun_dynamic_range = std::max(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f);
+    
+    mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp);
+
+    mSunDiffuse = vary_SunlightColor;
+    mSunAmbient = vary_AmbientColor;
+    mMoonDiffuse = vary_SunlightColor;
+    mMoonAmbient = vary_AmbientColor;
+
+    mTotalAmbient = vary_AmbientColor;
+    mTotalAmbient.setAlpha(1);
+
+    mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f;
+    mFadeColor.setAlpha(0);
+
+}
+
+
+LLSettingsSky::stringset_t LLSettingsSky::getSkipApplyKeys() const
+{
+
+    static stringset_t skip_apply_set;
+
+    if (skip_apply_set.empty())
+    {
+        skip_apply_set.insert(SETTING_GAMMA);
+        skip_apply_set.insert(SETTING_MOON_ROTATION);
+        skip_apply_set.insert(SETTING_SUN_ROTATION);
+        skip_apply_set.insert(SETTING_NAME);
+        skip_apply_set.insert(SETTING_STAR_BRIGHTNESS);
+        skip_apply_set.insert(SETTING_CLOUD_SCROLL_RATE);
+        skip_apply_set.insert(SETTING_LIGHT_NORMAL);
+        skip_apply_set.insert(SETTING_CLOUD_POS_DENSITY1);
+    }
+
+    return skip_apply_set;
+}
+
+void LLSettingsSky::applySpecial(void *ptarget)
+{
+    LLGLSLShader *shader = (LLGLSLShader *)ptarget;
+
+    if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
+    {
+        shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mLightDirectionClamped.mV);
+    }
+
+    shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
+    
+    shader->uniform4f(LLShaderMgr::GAMMA, getGama(), 0.0, 0.0, 1.0);
+}
+
+//-------------------------------------------------------------------------
+// const std::string LLSettingsSky::SETTING_DENSITY_MULTIPLIER("density_multiplier");
+// const std::string LLSettingsSky::SETTING_LIGHT_NORMAL("lightnorm");
+// const std::string LLSettingsSky::SETTING_NAME("name");
diff --git a/indra/newview/llsettingssky.h b/indra/newview/llsettingssky.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b8691fa8b59c19ddf7973e7f75443fc4875c4f1
--- /dev/null
+++ b/indra/newview/llsettingssky.h
@@ -0,0 +1,314 @@
+/**
+* @file llsettingssky.h
+* @author optional
+* @brief A base class for asset based settings groups.
+*
+* $LicenseInfo:2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2017, 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_SETTINGS_SKY_H
+#define LL_SETTINGS_SKY_H
+
+#include "llsettingsbase.h"
+
+class LLSettingsSky: public LLSettingsBase
+{
+public:
+    static const std::string SETTING_AMBIENT;
+    static const std::string SETTING_BLOOM_TEXTUREID;
+    static const std::string SETTING_BLUE_DENSITY;
+    static const std::string SETTING_BLUE_HORIZON;
+    static const std::string SETTING_CLOUD_COLOR;
+    static const std::string SETTING_CLOUD_POS_DENSITY1;
+    static const std::string SETTING_CLOUD_POS_DENSITY2;
+    static const std::string SETTING_CLOUD_SCALE;
+    static const std::string SETTING_CLOUD_SCROLL_RATE;
+    static const std::string SETTING_CLOUD_SHADOW;
+    static const std::string SETTING_CLOUD_TEXTUREID;
+    static const std::string SETTING_DENSITY_MULTIPLIER;
+    static const std::string SETTING_DISTANCE_MULTIPLIER;
+    static const std::string SETTING_DOME_OFFSET;
+    static const std::string SETTING_DOME_RADIUS;
+    static const std::string SETTING_GAMMA;
+    static const std::string SETTING_GLOW;
+    static const std::string SETTING_HAZE_DENSITY;
+    static const std::string SETTING_HAZE_HORIZON;
+    static const std::string SETTING_LIGHT_NORMAL;
+    static const std::string SETTING_MAX_Y;
+    static const std::string SETTING_MOON_ROTATION;
+    static const std::string SETTING_MOON_TEXTUREID;
+    static const std::string SETTING_NAME;
+    static const std::string SETTING_STAR_BRIGHTNESS;
+    static const std::string SETTING_SUNLIGHT_COLOR;
+    static const std::string SETTING_SUN_ROTATION;
+    static const std::string SETTING_SUN_TEXUTUREID;
+
+    static const std::string SETTING_LEGACY_EAST_ANGLE;
+    static const std::string SETTING_LEGACY_ENABLE_CLOUD_SCROLL;
+    static const std::string SETTING_LEGACY_SUN_ANGLE;
+
+    typedef boost::shared_ptr<LLSettingsSky> ptr_t;
+
+    //---------------------------------------------------------------------
+    LLSettingsSky(const LLSD &data);
+    virtual ~LLSettingsSky() { };
+
+    static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings);
+    static ptr_t buildDefaultSky();
+
+    //---------------------------------------------------------------------
+    virtual std::string getSettingType() const { return std::string("sky"); }
+
+    // Settings status 
+    ptr_t blend(const ptr_t &other, F32 mix) const;
+    
+    static LLSD defaults();
+
+    //---------------------------------------------------------------------
+    LLColor3 getAmbientColor() const
+    {
+        return LLColor3(mSettings[SETTING_AMBIENT]);
+    }
+
+    LLUUID getBloomTextureId() const
+    {
+        return mSettings[SETTING_BLOOM_TEXTUREID].asUUID();
+    }
+
+    LLColor3 getBlueDensity() const
+    {
+        return LLColor3(mSettings[SETTING_BLUE_DENSITY]);
+    }
+
+    LLColor3 getBlueHorizon() const
+    {
+        return LLColor3(mSettings[SETTING_BLUE_HORIZON]);
+    }
+
+    LLColor3 getCloudColor() const
+    {
+        return mSettings[SETTING_CLOUD_COLOR].asReal();
+    }
+
+    LLUUID getCloudNoiseTextureId() const
+    {
+        return mSettings[SETTING_CLOUD_TEXTUREID].asUUID();
+    }
+
+    LLColor3 getCloudPosDensity1() const
+    {
+        return mSettings[SETTING_CLOUD_POS_DENSITY1].asReal();
+    }
+
+    LLColor3 getCloudPosDensity2() const
+    {
+        return mSettings[SETTING_CLOUD_POS_DENSITY2].asReal();
+    }
+
+    F32 getCloudScale() const
+    {
+        return mSettings[SETTING_CLOUD_SCALE].asReal();
+    }
+
+    LLVector2 getCloudScrollRate() const
+    {
+        return LLVector2(mSettings[SETTING_CLOUD_SCROLL_RATE]);
+    }
+
+    F32 getCloudShadow() const
+    {
+        return mSettings[SETTING_CLOUD_SHADOW].asReal();
+    }
+
+    F32 getDensityMultiplier() const
+    {
+        return mSettings[SETTING_DENSITY_MULTIPLIER].asReal();
+    }
+
+    F32 getDistanceMultiplier() const
+    {
+        return mSettings[SETTING_DISTANCE_MULTIPLIER].asReal();
+    }
+
+    F32 getDomeOffset() const
+    {
+        return mSettings[SETTING_DOME_OFFSET].asReal();
+    }
+
+    F32 getDomeRadius() const
+    {
+        return mSettings[SETTING_DOME_RADIUS].asReal();
+    }
+
+    F32 getGama() const
+    {
+        return mSettings[SETTING_GAMMA].asReal();
+    }
+
+    LLColor3 getGlow() const
+    {
+        return mSettings[SETTING_GLOW].asReal();
+    }
+
+    F32 getHazeDensity() const
+    {
+        return mSettings[SETTING_HAZE_DENSITY].asReal();
+    }
+
+    F32 getHazeHorizon() const
+    {
+        return mSettings[SETTING_HAZE_HORIZON].asReal();
+    }
+
+    F32 getMaxY() const
+    {
+        return mSettings[SETTING_MAX_Y].asReal();
+    }
+
+    LLQuaternion getMoonRotation() const
+    {
+        return LLQuaternion(mSettings[SETTING_MOON_ROTATION]);
+    }
+
+    LLUUID getMoonTextureId() const
+    {
+        return mSettings[SETTING_MOON_TEXTUREID].asUUID();
+    }
+
+    F32 getStarBrightness() const
+    {
+        return mSettings[SETTING_STAR_BRIGHTNESS].asReal();
+    }
+
+    LLColor3 getSunlightColor() const
+    {
+        return LLColor3(mSettings[SETTING_SUNLIGHT_COLOR]);
+    }
+
+    LLQuaternion getSunRotation() const
+    {
+        return LLQuaternion(mSettings[SETTING_SUN_ROTATION]);
+    }
+
+    LLUUID getSunTextureId() const
+    {
+        return mSettings[SETTING_SUN_TEXUTUREID].asUUID();
+    }
+
+
+    // Internal/calculated settings
+    LLVector3 getLightDirection() const
+    {
+        update();
+        return mLightDirection;
+    };
+
+    LLVector3 getLightDirectionClamped() const
+    {
+        update();
+        return mLightDirectionClamped;
+    };
+
+    F32 getSceneLightStrength() const
+    {
+        update();
+        return mSceneLightStrength;
+    }
+
+    LLVector3   getSunDirection() const
+    {
+        update();
+        return mSunDirection;
+    }
+
+    LLVector3   getMoonDirection() const
+    {
+        update();
+        return mMoonDirection;
+    }
+
+    LLColor3    getSunDiffuse() const
+    {
+        update();
+        return mSunDiffuse;
+    }
+
+    LLColor3    getSunAmbient() const
+    {
+        update();
+        return mSunAmbient;
+    }
+
+    LLColor3    getMoonDiffuse() const
+    {
+        update();
+        return mMoonDiffuse;
+    }
+
+    LLColor3    getMoonAmbient() const
+    {
+        update();
+        return mMoonAmbient;
+    }
+
+    LLColor4    getTotalAmbient() const
+    {
+        update();
+        return mTotalAmbient;
+    }
+
+    LLColor4    getFadeColor() const
+    {
+        update();
+        return mFadeColor;
+    }
+
+protected:
+    LLSettingsSky();
+
+    virtual stringset_t getSlerpKeys() const;
+
+    virtual void        updateSettings();
+
+    virtual stringset_t getSkipApplyKeys() const;
+    virtual void        applySpecial(void *);
+
+private:
+    void        calculateHeavnlyBodyPositions();
+    void        calculateLightSettings();
+
+    LLVector3   mSunDirection;
+    LLVector3   mMoonDirection;
+    F32         mSceneLightStrength;
+    LLVector3   mLightDirection;
+    LLVector3   mLightDirectionClamped;
+
+    LLColor3    mSunDiffuse;
+    LLColor3    mSunAmbient;
+    LLColor3    mMoonDiffuse;
+    LLColor3    mMoonAmbient;        
+    
+    LLColor4    mTotalAmbient;
+    LLColor4    mFadeColor;
+};
+
+#endif
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 3e0cec0f0999e7fb19b05ae4141f28bd03789070..8adc86b423392182d43173af4465c2a9133c441e 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -3429,6 +3429,7 @@ std::string LLViewerShaderMgr::getShaderDirPrefix(void)
 
 void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
 {
+    //*LAPRAS*/
 	LLWLParamManager::getInstance()->updateShaderUniforms(shader);
 	LLWaterParamManager::getInstance()->updateShaderUniforms(shader);
 }
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 6b4a450e6fe202537a3f4c79495ae488700de155..03dfdf92fae11184c908a91793ffe85e3c1f003f 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -50,6 +50,7 @@
 #include "lldrawpoolwlsky.h"
 #include "llwlparammanager.h"
 #include "llwaterparammanager.h"
+#include "v3colorutil.h"
 
 #undef min
 #undef max
@@ -560,68 +561,6 @@ void LLVOSky::createSkyTexture(const S32 side, const S32 tile)
 	}
 }
 
-static inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right)
-{
-	return LLColor3(left.mV[0]/right.mV[0],
-					 left.mV[1]/right.mV[1],
-					 left.mV[2]/right.mV[2]);
-}
-
-
-static inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right)
-{
-	return LLColor3(left.mV[0]*right.mV[0],
-					 left.mV[1]*right.mV[1],
-					 left.mV[2]*right.mV[2]);
-}
-
-
-static inline LLColor3 componentExp(LLColor3 const &v)
-{
-	return LLColor3(exp(v.mV[0]),
-					 exp(v.mV[1]),
-					 exp(v.mV[2]));
-}
-
-static inline LLColor3 componentPow(LLColor3 const &v, F32 exponent)
-{
-	return LLColor3(pow(v.mV[0], exponent),
-					pow(v.mV[1], exponent),
-					pow(v.mV[2], exponent));
-}
-
-static inline LLColor3 componentSaturate(LLColor3 const &v)
-{
-	return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f),
-					 std::max(std::min(v.mV[1], 1.f), 0.f),
-					 std::max(std::min(v.mV[2], 1.f), 0.f));
-}
-
-
-static inline LLColor3 componentSqrt(LLColor3 const &v)
-{
-	return LLColor3(sqrt(v.mV[0]),
-					 sqrt(v.mV[1]),
-					 sqrt(v.mV[2]));
-}
-
-static inline void componentMultBy(LLColor3 & left, LLColor3 const & right)
-{
-	left.mV[0] *= right.mV[0];
-	left.mV[1] *= right.mV[1];
-	left.mV[2] *= right.mV[2];
-}
-
-static inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
-{
-	return (left + ((right - left) * amount));
-}
-
-static inline LLColor3 smear(F32 val)
-{
-	return LLColor3(val, val, val);
-}
-
 void LLVOSky::initAtmospherics(void)
 {	
 	bool error;
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index 4b4393b07b9996341347af02dde54f58cc2b73f5..980fe96c2b765b97f5a96293d55a2eff426e79f7 100644
--- a/indra/newview/llwlparammanager.cpp
+++ b/indra/newview/llwlparammanager.cpp
@@ -317,6 +317,10 @@ bool LLWLParamManager::loadPreset(const std::string& path)
 		addParamSet(key, params_data);
 	}
 
+    //*RIDER temp code testing conversion old preset to new settings.
+    //LLSettingsSky::ptr_t test = LLSettingsSky::buildFromLegacyPreset(name, params_data);
+    //test->exportSettings(name);
+
 	return true;
 }
 
@@ -708,3 +712,4 @@ std::string LLWLParamManager::escapeString(const std::string& str)
 
 	return escaped_str;
 }
+