diff --git a/.hgtags b/.hgtags
index 539f4a700c4bb64815d95f4050ebdec9bce7e9cb..c614db0d3e6ab5e840e5da4ec22102591b78b4be 100755
--- a/.hgtags
+++ b/.hgtags
@@ -461,3 +461,4 @@ fb1630153bac5552046ea914af3f14deabc1def8 3.6.0-materials-beta1
 69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release
 69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release
 0a56f33ad6aa112032b14a41dad759ad377bdde9 3.6.0-release
+75cf8e855ae1af6895a35da475314c2b5acf1850 3.6.1-release
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 9575d51bad249b78b01fa517932882eb917cb750..b72762837ea636398fece3c5651f664c2ee82ffb 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.6.1
+3.6.2
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index 0899caa2af6e84884ce371daa0caba5f8f5a0db9..143af0576c3560a1dbbaa3d60f4c1d4883198eb1 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -101,7 +101,7 @@ vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float
 		float dist = d/la;
 		da = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
 		da *= da;
-		da *= 1.4;
+		da *= 2.0;
 	
 
 		// spotlight coefficient.
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 6cd8caa1138bf31b9d4bc4c9cf14155b6857e970..53ade8ea64835db42287ae7ca762f78586997d6f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -142,7 +142,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
 		float dist = d/la;
 		float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
 		dist_atten *= dist_atten;
-		dist_atten *= 1.4;
+		dist_atten *= 2.0;
 
 		// spotlight coefficient.
 		float spot = max(dot(-ln, lv), is_pointlight);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index c95aa8bb3cc05241008dc97d42f43cfe9cbb739d..a955ef6e9d7f4c36e840e0e3cb7bdef6d99f77ab 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -45,9 +45,8 @@ uniform float sun_wash;
 
 uniform int light_count;
 
-#define MAX_LIGHT_COUNT		16
-uniform vec4 light[MAX_LIGHT_COUNT];
-uniform vec4 light_col[MAX_LIGHT_COUNT];
+uniform vec4 light[LIGHT_COUNT];
+uniform vec4 light_col[LIGHT_COUNT];
 
 VARYING vec4 vary_fragcoord;
 uniform vec2 screen_res;
@@ -105,73 +104,59 @@ void main()
 	vec3 npos = normalize(-pos);
 
 	// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
-	for (int i = 0; i < MAX_LIGHT_COUNT; ++i)
+	for (int i = 0; i < LIGHT_COUNT; ++i)
 	{
-		bool light_contrib = (i < light_count);
-		
 		vec3 lv = light[i].xyz-pos;
 		float dist = length(lv);
 		dist /= light[i].w;
-		if (dist > 1.0)
+		if (dist <= 1.0)
 		{
-			light_contrib = false;
-		}
-		
-		float da = dot(norm, lv);
-		if (da < 0.0)
-		{
-			light_contrib = false;
-		}
-		
-		if (light_contrib)
-		{
-			lv = normalize(lv);
-			da = dot(norm, lv);
+			float da = dot(norm, lv);
+			if (da > 0.0)
+			{
+				lv = normalize(lv);
+				da = dot(norm, lv);
 			
-			float fa = light_col[i].a+1.0;
-			float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
-			dist_atten *= dist_atten;
-			dist_atten *= 2.0;
+				float fa = light_col[i].a+1.0;
+				float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+				dist_atten *= dist_atten;
+				dist_atten *= 2.0;
 			
-			dist_atten *= noise;
+				dist_atten *= noise;
 
-			float lit = da * dist_atten;
+				float lit = da * dist_atten;
 						
-			vec3 col = light_col[i].rgb*lit*diff;
+				vec3 col = light_col[i].rgb*lit*diff;
 			
-			//vec3 col = vec3(dist2, light_col[i].a, lit);
+				//vec3 col = vec3(dist2, light_col[i].a, lit);
 			
-			if (spec.a > 0.0)
-			{
-				lit = min(da*6.0, 1.0) * dist_atten;
-				//vec3 ref = dot(pos+lv, norm);
-				vec3 h = normalize(lv+npos);
-				float nh = dot(norm, h);
-				float nv = dot(norm, npos);
-				float vh = dot(npos, h);
-				float sa = nh;
-				float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
-				float gtdenom = 2 * nh;
-				float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-								
-				if (nh > 0.0)
+				if (spec.a > 0.0)
 				{
-					float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
-					col += lit*scol*light_col[i].rgb*spec.rgb;
-					//col += spec.rgb;
+					lit = min(da*6.0, 1.0) * dist_atten;
+					//vec3 ref = dot(pos+lv, norm);
+					vec3 h = normalize(lv+npos);
+					float nh = dot(norm, h);
+					float nv = dot(norm, npos);
+					float vh = dot(npos, h);
+					float sa = nh;
+					float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+					float gtdenom = 2 * nh;
+					float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+								
+					if (nh > 0.0)
+					{
+						float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+						col += lit*scol*light_col[i].rgb*spec.rgb;
+						//col += spec.rgb;
+					}
 				}
-			}
 			
-			out_col += col;
+				out_col += col;
+			}
 		}
 	}
 	
-	if (dot(out_col, out_col) <= 0.0)
-	{
-		discard;
-	}
-	
 	frag_color.rgb = out_col;
 	frag_color.a = 0.0;
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index 0deb4fe3b6bb7e0222224a62ebf2237d39c6a0fd..14f6afc8c27925cbf32f721a7421fa2c82dddf87 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -318,6 +318,10 @@ void main()
 		}
 	}
 	
+
+	//not sure why, but this line prevents MATBUG-194
+	col = max(col, vec3(0.0));
+
 	frag_color.rgb = col;	
 	frag_color.a = 0.0;
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 7a4337c2776a92b050be3b953a80f98dc97be0e0..6e0218cb9c9afcba326ad885a820878851be0665 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -315,7 +315,10 @@ void main()
 			}
 		}
 	}
-	
+
+	//not sure why, but this line prevents MATBUG-194
+	col = max(col, vec3(0.0));
+
 	frag_color.rgb = col;	
 	frag_color.a = 0.0;
 }
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 1c0d45c11badc7023bc45c7ab289ddb3a4409246..0bdd42550474aefa3d931362b65efbea7276ceb3 100755
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -309,8 +309,8 @@ RenderVolumeLODFactor		1	2.0
 VertexShaderEnable			1	1
 WindLightUseAtmosShaders	1	1
 WLSkyDetail					1	128
-RenderDeferred				1	0
-RenderDeferredSSAO			1	0
+RenderDeferred				1	1
+RenderDeferredSSAO			1	1
 RenderShadowDetail			1	2
 RenderFSAASamples			1	2
 
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index fa9c2ce51f7913069516cf3251359a2d2e68268d..7bce629d3ec0e4918cb00d450434b8b9b475c105 100755
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -183,7 +183,7 @@ LLGLSLShader			gDeferredTreeShadowProgram;
 LLGLSLShader			gDeferredAvatarProgram;
 LLGLSLShader			gDeferredAvatarAlphaProgram;
 LLGLSLShader			gDeferredLightProgram;
-LLGLSLShader			gDeferredMultiLightProgram;
+LLGLSLShader			gDeferredMultiLightProgram[16];
 LLGLSLShader			gDeferredSpotLightProgram;
 LLGLSLShader			gDeferredMultiSpotLightProgram;
 LLGLSLShader			gDeferredSunProgram;
@@ -1112,7 +1112,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredImpostorProgram.unload();
 		gDeferredTerrainProgram.unload();
 		gDeferredLightProgram.unload();
-		gDeferredMultiLightProgram.unload();
+		for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i)
+		{
+			gDeferredMultiLightProgram[i].unload();
+		}
 		gDeferredSpotLightProgram.unload();
 		gDeferredMultiSpotLightProgram.unload();
 		gDeferredSunProgram.unload();
@@ -1353,15 +1356,18 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		success = gDeferredLightProgram.createShader(NULL, NULL);
 	}
 
-	if (success)
+	for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++)
 	{
-		gDeferredMultiLightProgram.mName = "Deferred MultiLight Shader";
-		gDeferredMultiLightProgram.mShaderFiles.clear();
-		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
-		gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-
-		success = gDeferredMultiLightProgram.createShader(NULL, NULL);
+		if (success)
+		{
+			gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);
+			gDeferredMultiLightProgram[i].mShaderFiles.clear();
+			gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
+			gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+			gDeferredMultiLightProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+			gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
+			success = gDeferredMultiLightProgram[i].createShader(NULL, NULL);
+		}
 	}
 
 	if (success)
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 438853cd6f7ef46117c5014842945789958e924e..ed8167947d39a350135f4ee41f81bd99110f9891 100755
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -30,6 +30,8 @@
 #include "llshadermgr.h"
 #include "llmaterial.h"
 
+#define LL_DEFERRED_MULTI_LIGHT_COUNT 16
+
 class LLViewerShaderMgr: public LLShaderMgr
 {
 public:
@@ -341,7 +343,7 @@ extern LLGLSLShader			gDeferredTerrainProgram;
 extern LLGLSLShader			gDeferredTreeProgram;
 extern LLGLSLShader			gDeferredTreeShadowProgram;
 extern LLGLSLShader			gDeferredLightProgram;
-extern LLGLSLShader			gDeferredMultiLightProgram;
+extern LLGLSLShader			gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT];
 extern LLGLSLShader			gDeferredSpotLightProgram;
 extern LLGLSLShader			gDeferredMultiSpotLightProgram;
 extern LLGLSLShader			gDeferredSunProgram;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 442b0b6d2d2ef685f8e875b664bdc835689dc103..c9f8a4d9ee3e6bef0da516b946e362e6c04e516d 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1201,15 +1201,7 @@ void LLPipeline::releaseLUTBuffers()
 {
 	if (mLightFunc)
 	{
-		U32 use_high_precision = gSavedSettings.getU32("RenderSpecularPrecision");
-
-		U32 pix_format = use_high_precision ? GL_R32F : GL_R16F;
-
-#if LL_DARWIN
-		pix_format = GL_R32F;
-#endif
-
-		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, pix_format, 0, 1, &mLightFunc);
+		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 0, 1, &mLightFunc);
 		mLightFunc = 0;
 	}
 }
@@ -1408,18 +1400,13 @@ void LLPipeline::createLUTBuffers()
 					ls[y*lightResX+x] = k;*/
 				}
 			}
-			// Need to work around limited precision with 10.6.8 and older drivers
-			//
-			U32 use_high_precision = gSavedSettings.getU32("RenderSpecularPrecision");
-				
-			U32 pix_format = use_high_precision ? GL_R32F : GL_R16F;
-
+			
+			U32 pix_format = GL_R16F;
 #if LL_DARWIN
-			// Forced to work around 10.6.8. driver bugs on most every GPU
+			// Need to work around limited precision with 10.6.8 and older drivers
 			//
 			pix_format = GL_R32F;
 #endif
-
 			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, pix_format, 1, &mLightFunc);
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
 			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
@@ -8694,10 +8681,6 @@ void LLPipeline::renderDeferredLighting()
 			vert[2].set(3,1,0);
 
 			{
-				bindDeferredShader(gDeferredMultiLightProgram);
-			
-				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
 				LLGLDepthTest depth(GL_FALSE);
 
 				//full screen blit
@@ -8709,7 +8692,7 @@ void LLPipeline::renderDeferredLighting()
 
 				U32 count = 0;
 
-				const U32 max_count = 8;
+				const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
 				LLVector4 light[max_count];
 				LLVector4 col[max_count];
 
@@ -8732,17 +8715,20 @@ void LLPipeline::renderDeferredLighting()
 					count++;
 					if (count == max_count || fullscreen_lights.empty())
 					{
-						gDeferredMultiLightProgram.uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
-						gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
-						gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
-						gDeferredMultiLightProgram.uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+						U32 idx = count-1;
+						bindDeferredShader(gDeferredMultiLightProgram[idx]);
+						gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+						gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
 						far_z = 0.f;
 						count = 0; 
+						mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 						mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
 					}
 				}
 				
-				unbindDeferredShader(gDeferredMultiLightProgram);
+				unbindDeferredShader(gDeferredMultiLightProgram[0]);
 
 				bindDeferredShader(gDeferredMultiSpotLightProgram);