diff --git a/Source/Core/VideoCommon/LightingShaderGen.h b/Source/Core/VideoCommon/LightingShaderGen.h
index b28fe5b386..b678c39b99 100644
--- a/Source/Core/VideoCommon/LightingShaderGen.h
+++ b/Source/Core/VideoCommon/LightingShaderGen.h
@@ -56,65 +56,50 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
 
 	uid_data.attnfunc |= chan.attnfunc << (2*litchan_index);
 	uid_data.diffusefunc |= chan.diffusefunc << (2*litchan_index);
-	if (!(chan.attnfunc & 1))
+	
+	switch (chan.attnfunc)
 	{
-		// atten disabled
-		switch (chan.diffusefunc)
-		{
-			case LIGHTDIF_NONE:
-				object.Write("lacc.%s += " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(index, swizzle));
-				break;
-			case LIGHTDIF_SIGN:
-			case LIGHTDIF_CLAMP:
-				object.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index));
-				object.Write("lacc.%s += int%s(round(%sdot(ldir, _norm0)) * float%s(" LIGHT_COL")));\n",
-				             swizzle, swizzle_components, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(",
-				             swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
-				break;
-			default: _assert_(0);
-		}
-	}
-	else // spec and spot
-	{
-		if (chan.attnfunc == 3)
-		{ // spot
+		case LIGHTATTN_NONE:
+		case LIGHTATTN_DIR:
+			object.Write("ldir = normalize(" LIGHT_POS".xyz);\n", LIGHT_POS_PARAMS(index));
+			object.Write("attn = 1.0f;\n");
+			break;
+		case LIGHTATTN_SPEC:
+			object.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index));
+			object.Write("attn = (dot(_norm0, ldir) >= 0.0) ? max(0.0, dot(_norm0, " LIGHT_DIR".xyz)) : 0.0;\n", LIGHT_DIR_PARAMS(index));
+			object.Write("cosAttn = " LIGHT_COSATT".xyz;\n", LIGHT_COSATT_PARAMS(index));
+			object.Write("distAttn = %s(" LIGHT_DISTATT".xyz);\n", (chan.diffusefunc == LIGHTDIF_NONE) ? "" : "normalize", LIGHT_DISTATT_PARAMS(index));			
+			object.Write("attn = max(0.0f, dot(cosAttn, float3(1.0, attn, attn*attn))) / dot(distAttn, float3(1.0, attn, attn*attn));\n");
+			break;
+		case LIGHTATTN_SPOT:
 			object.Write("ldir = " LIGHT_POS".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(index));
 			object.Write("dist2 = dot(ldir, ldir);\n"
-			             "dist = sqrt(dist2);\n"
-			             "ldir = ldir / dist;\n"
-			             "attn = max(0.0, dot(ldir, " LIGHT_DIR".xyz));\n",
-			             LIGHT_DIR_PARAMS(index));
+				"dist = sqrt(dist2);\n"
+				"ldir = ldir / dist;\n"
+				"attn = max(0.0, dot(ldir, " LIGHT_DIR".xyz));\n",	LIGHT_DIR_PARAMS(index));
 			// attn*attn may overflow
 			object.Write("attn = max(0.0, " LIGHT_COSATT".x + " LIGHT_COSATT".y*attn + " LIGHT_COSATT".z*attn*attn) / dot(" LIGHT_DISTATT".xyz, float3(1.0,dist,dist2));\n",
-			             LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_DISTATT_PARAMS(index));
-		}
-		else if (chan.attnfunc == 1)
-		{ // specular
-			object.Write("ldir = normalize(" LIGHT_POS".xyz);\n", LIGHT_POS_PARAMS(index));
-			object.Write("attn = (dot(_norm0,ldir) >= 0.0) ? max(0.0, dot(_norm0, " LIGHT_DIR".xyz)) : 0.0;\n", LIGHT_DIR_PARAMS(index));
-			// attn*attn may overflow
-			object.Write("attn = max(0.0, " LIGHT_COSATT".x + " LIGHT_COSATT".y*attn + " LIGHT_COSATT".z*attn*attn) / (" LIGHT_DISTATT".x + " LIGHT_DISTATT".y*attn + " LIGHT_DISTATT".z*attn*attn);\n",
-			             LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index),
-			             LIGHT_DISTATT_PARAMS(index), LIGHT_DISTATT_PARAMS(index), LIGHT_DISTATT_PARAMS(index));
-		}
-
-		switch (chan.diffusefunc)
-		{
-			case LIGHTDIF_NONE:
-				object.Write("lacc.%s += int%s(round(attn * float%s(" LIGHT_COL")));\n",
-				             swizzle, swizzle_components,
-				             swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
-				break;
-			case LIGHTDIF_SIGN:
-			case LIGHTDIF_CLAMP:
-				object.Write("lacc.%s += int%s(round(attn * %sdot(ldir, _norm0)) * float%s(" LIGHT_COL")));\n",
-				             swizzle, swizzle_components,
-				             chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(",
-				             swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
-				break;
-			default: _assert_(0);
-		}
+				LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_DISTATT_PARAMS(index));
+			break;
 	}
+
+	switch (chan.diffusefunc)
+	{
+		case LIGHTDIF_NONE:
+			object.Write("lacc.%s += int%s(round(attn * float%s(" LIGHT_COL")));\n",
+				            swizzle, swizzle_components,
+				            swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
+			break;
+		case LIGHTDIF_SIGN:
+		case LIGHTDIF_CLAMP:
+			object.Write("lacc.%s += int%s(round(attn * %sdot(ldir, _norm0)) * float%s(" LIGHT_COL")));\n",
+				            swizzle, swizzle_components,
+				            chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(",
+				            swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
+			break;
+		default: _assert_(0);
+	}
+	
 	object.Write("\n");
 }
 
diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp
index 3567be8bd8..edc67cc83c 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/PixelShaderGen.cpp
@@ -401,7 +401,7 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
 		out.Write("\tfloat3 pos = WorldPos;\n");
 
 		out.Write("\tint4 lacc;\n"
-				"\tfloat3 ldir, h;\n"
+				"\tfloat3 ldir, h, cosAttn, distAttn;\n"
 				"\tfloat dist, dist2, attn;\n");
 
 		// TODO: Our current constant usage code isn't able to handle more than one buffer.
diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp
index 2272ccc75c..d1fc126dab 100644
--- a/Source/Core/VideoCommon/VertexShaderGen.cpp
+++ b/Source/Core/VideoCommon/VertexShaderGen.cpp
@@ -176,7 +176,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
 	out.Write("o.pos = float4(dot(" I_PROJECTION"[0], pos), dot(" I_PROJECTION"[1], pos), dot(" I_PROJECTION"[2], pos), dot(" I_PROJECTION"[3], pos));\n");
 
 	out.Write("int4 lacc;\n"
-			"float3 ldir, h;\n"
+			"float3 ldir, h, cosAttn, distAttn;\n"
 			"float dist, dist2, attn;\n");
 
 	uid_data->numColorChans = xfmem.numChan.numColorChans;
diff --git a/Source/Core/VideoCommon/XFMemory.h b/Source/Core/VideoCommon/XFMemory.h
index 6ec28476d8..d244e9e3c1 100644
--- a/Source/Core/VideoCommon/XFMemory.h
+++ b/Source/Core/VideoCommon/XFMemory.h
@@ -44,10 +44,10 @@
 #define LIGHTDIF_SIGN  1
 #define LIGHTDIF_CLAMP 2
 
-#define LIGHTATTN_SPEC 0 // specular attenuation
-#define LIGHTATTN_SPOT 1 // distance/spotlight attenuation
-#define LIGHTATTN_NONE 2
-#define LIGHTATTN_DIR  3
+#define LIGHTATTN_NONE 0 // no attenuation
+#define LIGHTATTN_SPEC 1 // point light attenuation
+#define LIGHTATTN_DIR  2 // directional light attenuation
+#define LIGHTATTN_SPOT 3 // spot light attenuation
 
 #define GX_PERSPECTIVE  0
 #define GX_ORTHOGRAPHIC 1