From f475e367f2d1d4952cf4e9b8c86f68f9e09f3b73 Mon Sep 17 00:00:00 2001 From: NanoByte011 Date: Wed, 21 Jan 2015 15:55:32 -0700 Subject: [PATCH 1/2] Lighting Attenuation Fixes --- Source/Core/VideoCommon/LightingShaderGen.h | 89 +++++++++------------ Source/Core/VideoCommon/PixelShaderGen.cpp | 2 +- Source/Core/VideoCommon/VertexShaderGen.cpp | 2 +- Source/Core/VideoCommon/XFMemory.h | 8 +- 4 files changed, 43 insertions(+), 58 deletions(-) diff --git a/Source/Core/VideoCommon/LightingShaderGen.h b/Source/Core/VideoCommon/LightingShaderGen.h index b28fe5b386b6..b678c39b992a 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)); - } + 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 3567be8bd8fe..edc67cc83c99 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 2272ccc75c50..d1fc126dab0e 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 6ec28476d833..d244e9e3c170 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 From 0a9257ad37803c08178f4b242628e1d79a21251e Mon Sep 17 00:00:00 2001 From: NanoByte011 Date: Wed, 21 Jan 2015 22:30:41 -0700 Subject: [PATCH 2/2] Cleaned up whitespace Fixed Directional Attenuation (assumed, data was light dir vector already, but it was not!) --- Source/Core/VideoCommon/LightingShaderGen.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Core/VideoCommon/LightingShaderGen.h b/Source/Core/VideoCommon/LightingShaderGen.h index b678c39b992a..60979aa97b1d 100644 --- a/Source/Core/VideoCommon/LightingShaderGen.h +++ b/Source/Core/VideoCommon/LightingShaderGen.h @@ -56,19 +56,19 @@ 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); - + switch (chan.attnfunc) { case LIGHTATTN_NONE: case LIGHTATTN_DIR: - object.Write("ldir = normalize(" LIGHT_POS".xyz);\n", LIGHT_POS_PARAMS(index)); + 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("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: @@ -99,7 +99,7 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, break; default: _assert_(0); } - + object.Write("\n"); }