diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4e5ad6051340f2d237aa21496315e8d4c472b577..054c8d793a5c4dd7cc625340a9c79db6a16e2890 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1353,7 +1353,7 @@
     <key>Type</key>
     <string>F32</string>
     <key>Value</key>
-    <real>11.0</real>
+    <real>9.0</real>
   </map>
 
   <key>CameraFocalLength</key>
@@ -1365,7 +1365,31 @@
     <key>Type</key>
     <string>F32</string>
     <key>Value</key>
-    <real>35</real>
+    <real>50</real>
+  </map>
+
+  <key>CameraFieldOfView</key>
+  <map>
+    <key>Comment</key>
+    <string>Vertical camera field of view for DoF effect (in degrees)</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>60.0</real>
+  </map>
+
+  <key>CameraAspectRatio</key>
+  <map>
+    <key>Comment</key>
+    <string>Camera aspect ratio for DoF effect</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>1.5</real>
   </map>
 
   <key>CameraCoCRatio</key>
@@ -1377,7 +1401,7 @@
     <key>Type</key>
     <string>F32</string>
     <key>Value</key>
-    <real>54</real>
+    <real>45</real>
   </map>
 
 
@@ -6622,9 +6646,9 @@
     <string>Vector3</string>
     <key>Value</key>
     <array>
-      <real>-0.35</real>
+      <real>-0.75</real>
       <real>1</real>
-      <real>0.7</real>
+      <real>1.0</real>
     </array>
   </map>
 
@@ -6638,9 +6662,9 @@
     <string>Vector3</string>
     <key>Value</key>
     <array>
-      <real>-1</real>
-      <real>-1</real>
+      <real>0.5</real>
       <real>-0.6</real>
+      <real>0.4</real>
     </array>
   </map>
   
@@ -6654,9 +6678,9 @@
     <string>Vector3</string>
     <key>Value</key>
     <array>
-      <real>-0.2</real>
+      <real>0.5</real>
       <real>-0.8</real>
-      <real>-0.2</real>
+      <real>0.3</real>
     </array>
   </map>
 
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
index 02712e0a5bceee1061e068bf8d09e7e3e516b84e..7c89c01ea4361ecb06cf08f5f405f7e58e3d1d02 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
@@ -17,8 +17,10 @@ uniform sampler2D bloomMap;
 
 uniform float depth_cutoff;
 uniform float norm_cutoff;
-uniform float near_focal_distance;
-uniform float far_focal_distance;
+uniform float focal_distance;
+uniform float blur_constant;
+uniform float tan_pixel_angle;
+uniform float magnification;
 
 uniform mat4 inv_proj;
 uniform vec2 screen_res;
@@ -39,11 +41,22 @@ void dofSample(inout vec4 diff, inout float w, float fd, float x, float y)
 	vec2 tc = vary_fragcoord.xy+vec2(x,y);
 	float d = getDepth(tc);
 	
-	if (d < fd)
+	float wg = 1.0;
+	//if (d < fd)
+	//{
+	//	diff += texture2DRect(diffuseRect, tc);
+	//	w = 1.0;
+	//}
+	if (d > fd)
 	{
-		diff += texture2DRect(diffuseRect, tc);
-		w += 1.0;
+		wg = max(d/fd, 0.1);
 	}
+	
+	diff += texture2DRect(diffuseRect, tc+vec2(0.5,0.5))*wg*0.25;
+	diff += texture2DRect(diffuseRect, tc+vec2(-0.5,0.5))*wg*0.25;
+	diff += texture2DRect(diffuseRect, tc+vec2(0.5,-0.5))*wg*0.25;
+	diff += texture2DRect(diffuseRect, tc+vec2(-0.5,-0.5))*wg*0.25;
+	w += wg;
 }
 
 void dofSampleNear(inout vec4 diff, inout float w, float x, float y)
@@ -64,22 +77,30 @@ void main()
 	
 	float sc = 0.75;
 	
-	float depth[5];
-	depth[0] = getDepth(tc);
+	float depth;
+	depth = getDepth(tc);
 		
 	vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
 	
-	if (depth[0] < far_focal_distance)
 	{ //pixel is behind far focal plane
 		float w = 1.0;
 		
-		float fd = (depth[0]-far_focal_distance)*0.5+far_focal_distance;
-		float sc = far_focal_distance - depth[0];
-		sc /= near_focal_distance-far_focal_distance;
+		sc = (abs(depth-focal_distance)/-depth)*blur_constant;
+		
+		sc /= magnification;
+		
+		// tan_pixel_angle = pixel_length/-depth;
+		float pixel_length =  tan_pixel_angle*-focal_distance;
+		
+		sc = sc/pixel_length;
+		
+		//diff.r = sc;
 		
-		sc = sqrt(sc);
+		sc = min(abs(sc), 8.0);
 		
-		sc = min(sc, 8.0);
+		//sc = 4.0;
+		
+		float fd = depth*0.5f;
 		
 		while (sc > 1.0)
 		{
@@ -96,41 +117,10 @@ void main()
 			dofSample(diff,w, fd, sc2,0);
 			sc -= 0.5;
 		}
+		
 		diff /= w;
 	}
-	else
-	{
-		float fd = near_focal_distance;
 		
-		if (depth[0] > fd)
-		{ //pixel is in front of near focal plane
-			//diff.r = 1.0;
-			float w = 1.0;
-			float sc = near_focal_distance-depth[0];
-			sc /= near_focal_distance;
-			sc *= 8.0;
-			sc = min(sc, 8.0);
-						
-			fd = depth[0];
-			while (sc > 1.0)
-			{
-				dofSampleNear(diff,w, sc,sc);
-				dofSampleNear(diff,w, -sc,sc);
-				dofSampleNear(diff,w, sc,-sc);
-				dofSampleNear(diff,w, -sc,-sc);
-				
-				sc -= 0.5;
-				float sc2 = sc*1.414;
-				dofSampleNear(diff,w, 0,sc2);
-				dofSampleNear(diff,w, 0,-sc2);
-				dofSampleNear(diff,w, -sc2,0);
-				dofSampleNear(diff,w, sc2,0);
-				sc -= 0.5;
-			}
-			diff /= w;
-		}	
-	}
-	
 	vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
 	gl_FragColor = diff + bloom;
 	
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index f0446b024cf4bdfcfcd307c70bc1090bf2152e9a..fc8abc20843f9a5610070b018d34b0750a1c4f41 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6160,44 +6160,59 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 		//convert to mm
 		subject_distance *= 1000.f;
 		F32 fnumber = gSavedSettings.getF32("CameraFNumber");
-		F32 focal_length = gSavedSettings.getF32("CameraFocalLength");
-		F32 coc_ratio = gSavedSettings.getF32("CameraCoCRatio");
+		const F32 default_focal_length = gSavedSettings.getF32("CameraFocalLength");
+		//F32 coc_ratio = gSavedSettings.getF32("CameraCoCRatio");
 
-		F32 coc = coc_ratio/mScreen.getHeight();
+		//F32 coc = coc_ratio/mScreen.getHeight();
 
-		F32 hyperfocal_distance = (focal_length*focal_length)/(fnumber*coc);
-
-		subject_distance = llmin(hyperfocal_distance, subject_distance);
-
-		//adjust focal length for subject distance
-		focal_length = llmax(focal_length, 1.f/(1.f/focal_length - 1.f/subject_distance));
-
-		//adjust focal length for zoom
 		F32 fov = LLViewerCamera::getInstance()->getView();
-		focal_length *= 1.f/fov;
-
-		F32 near_focal_distance = hyperfocal_distance*subject_distance/(hyperfocal_distance+subject_distance);
 		
-		//beyond far clip plane is effectively infinity
-		F32 far_focal_distance = 4096.f;
+		const F32 default_fov = gSavedSettings.getF32("CameraFieldOfView") * F_PI/180.f;
+		const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio");
+		
+		F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
+		
+		F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f);
+		F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/2.f);
 
-		if (subject_distance < hyperfocal_distance)
-		{
-			far_focal_distance = hyperfocal_distance*subject_distance/(hyperfocal_distance-subject_distance);
-			far_focal_distance /= 1000.f;
-		}
+		F32 focal_length = dv/(2*tanf(fov/2.f));
+		 
+		//F32 hyperfocal_distance = (focal_length*focal_length)/(fnumber*coc);
+
+		//subject_distance = llmin(hyperfocal_distance, subject_distance);
 
-		near_focal_distance /= 1000.f;
+		//adjust focal length for subject distance
+		//focal_length = llmax(focal_length, 1.f/(1.f/focal_length - 1.f/subject_distance));
 
-		shader->uniform1f("far_focal_distance", -far_focal_distance);
-		shader->uniform1f("near_focal_distance", -near_focal_distance);
+		F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
+	
+		// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+		// where	 N = fnumber
+		//			 s2 = dot distance
+		//			 s1 = subject distance
+		//			 f = focal length
+		//	
+
+		F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length));
+		blur_constant /= 1000.f; //convert to meters for shader
+		F32 magnification = focal_length/(subject_distance-focal_length);
+
+		shader->uniform1f("focal_distance", -subject_distance/1000.f);
+		shader->uniform1f("blur_constant", blur_constant);
+		shader->uniform1f("tan_pixel_angle", tanf(1.f/LLDrawable::sCurPixelAngle));
+		shader->uniform1f("magnification", magnification);
 
 		S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
 		if (channel > -1)
 		{
 			mScreen.bindTexture(0, channel);
-			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
 		}
+		//channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
+		//if (channel > -1)
+		//{
+			//gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+		//}
 
 		gGL.begin(LLRender::TRIANGLE_STRIP);
 		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);