summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2015-01-22 11:46:33 +0100
committerPierre Bourdon <delroth@gmail.com>2015-01-22 11:46:33 +0100
commit4984215971e0c03a16e40b0c1703840bfa2cdab8 (patch)
treea1321827a3267b04a64b42116661374bc6b868d4 /Source
parente7f2a04699c0e7e622028b4feba07fb6f46142bf (diff)
parent0a9257ad37803c08178f4b242628e1d79a21251e (diff)
Merge pull request #1941 from NanoByte011/lighting_attn
Lighting Attenuation Fixes
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/VideoCommon/LightingShaderGen.h89
-rw-r--r--Source/Core/VideoCommon/PixelShaderGen.cpp2
-rw-r--r--Source/Core/VideoCommon/VertexShaderGen.cpp2
-rw-r--r--Source/Core/VideoCommon/XFMemory.h8
4 files changed, 43 insertions, 58 deletions
diff --git a/Source/Core/VideoCommon/LightingShaderGen.h b/Source/Core/VideoCommon/LightingShaderGen.h
index b28fe5b386..60979aa97b 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))
- {
- // 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
+
+ switch (chan.attnfunc)
{
- if (chan.attnfunc == 3)
- { // spot
+ case LIGHTATTN_NONE:
+ case LIGHTATTN_DIR:
+ object.Write("ldir = normalize(" LIGHT_POS".xyz - 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));
- }
+ 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);
- }
+ 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