LightingShaderGen: Perform some lighting calculations with integers.

This commit is contained in:
Tony Wasserka 2013-10-27 14:34:59 +01:00
parent 78623871f9
commit 387b9bf3c2
3 changed files with 27 additions and 25 deletions

View File

@ -9,7 +9,7 @@
#include "VideoCommon/XFMemory.h"
#define LIGHT_COL "(float4(%s[%d]).%s / 255.0)"
#define LIGHT_COL "%s[%d].%s"
#define LIGHT_COL_PARAMS(lightsColName, index, swizzle) (lightsColName), (index), (swizzle)
#define LIGHT_COSATT "%s[4*%d]"
@ -42,11 +42,8 @@ template<class T>
static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, const char* lightsColName, const char* lightsName, int coloralpha)
{
const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index];
const char* swizzle = "xyzw";
if (coloralpha == 1)
swizzle = "xyz";
else if (coloralpha == 2)
swizzle = "w";
const char* swizzle = (coloralpha == 1) ? "xyz" : (coloralpha == 2) ? "w" : "xyzw";
const char* swizzle_components = (coloralpha == 1) ? "3" : (coloralpha == 2) ? "" : "4";
uid_data.attnfunc |= chan.attnfunc << (2*litchan_index);
uid_data.diffusefunc |= chan.diffusefunc << (2*litchan_index);
@ -61,8 +58,9 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
case LIGHTDIF_SIGN:
case LIGHTDIF_CLAMP:
object.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(lightsName, index));
object.Write("lacc.%s += %sdot(ldir, _norm0)) * " LIGHT_COL";\n",
swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(", LIGHT_COL_PARAMS(lightsColName, index, swizzle));
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(lightsColName, index, swizzle));
break;
default: _assert_(0);
}
@ -94,14 +92,16 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
switch (chan.diffusefunc)
{
case LIGHTDIF_NONE:
object.Write("lacc.%s += attn * " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsColName, index, swizzle));
object.Write("lacc.%s += int%s(round(attn * float%s(" LIGHT_COL")));\n",
swizzle, swizzle_components,
swizzle_components, LIGHT_COL_PARAMS(lightsColName, index, swizzle));
break;
case LIGHTDIF_SIGN:
case LIGHTDIF_CLAMP:
object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * " LIGHT_COL";\n",
swizzle,
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," :"(",
LIGHT_COL_PARAMS(lightsColName, index, swizzle));
swizzle_components, LIGHT_COL_PARAMS(lightsColName, index, swizzle));
break;
default: _assert_(0);
}
@ -146,23 +146,23 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
if (color.ambsource) // from vertex
{
if (components & (VB_HAS_COL0<<j) )
object.Write("lacc = %s%d;\n", inColorName, j);
object.Write("lacc = int4(round(%s%d * 255.0));\n", inColorName, j);
else if (components & VB_HAS_COL0 )
object.Write("lacc = %s0;\n", inColorName);
object.Write("lacc = int4(round(%s0 * 255.0));\n", inColorName);
else
// TODO: this isn't verified. Here we want to read the ambient from the vertex,
// but the vertex itself has no color. So we don't know which value to read.
// Returing 1.0 is the same as disabled lightning, so this could be fine
object.Write("lacc = float4(1.0, 1.0, 1.0, 1.0);\n");
object.Write("lacc = int4(255, 255, 255, 255);\n");
}
else // from color
{
object.Write("lacc = float4(%s[%d])/255.0;\n", materialsName, j);
object.Write("lacc = %s[%d];\n", materialsName, j);
}
}
else
{
object.Write("lacc = float4(1.0, 1.0, 1.0, 1.0);\n");
object.Write("lacc = int4(255, 255, 255, 255);\n");
}
// check if alpha is different
@ -190,21 +190,21 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
if (alpha.ambsource) // from vertex
{
if (components & (VB_HAS_COL0<<j) )
object.Write("lacc.w = %s%d.w;\n", inColorName, j);
object.Write("lacc.w = int(round(%s%d.w * 255.0));\n", inColorName, j);
else if (components & VB_HAS_COL0 )
object.Write("lacc.w = %s0.w;\n", inColorName);
object.Write("lacc.w = int(round(%s0.w * 255.0));\n", inColorName);
else
// TODO: The same for alpha: We want to read from vertex, but the vertex has no color
object.Write("lacc.w = 1.0;\n");
object.Write("lacc.w = 255;\n");
}
else // from color
{
object.Write("lacc.w = float(%s[%d].w) / 255.0;\n", materialsName, j);
object.Write("lacc.w = %s[%d].w;\n", materialsName, j);
}
}
else
{
object.Write("lacc.w = 1.0;\n");
object.Write("lacc.w = 255;\n");
}
if (color.enablelighting && alpha.enablelighting)
@ -255,7 +255,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
GenerateLightShader<T>(object, uid_data, i, lit_index, lightsColName, lightsName, coloralpha);
}
}
object.Write("%s%d = mat * clamp(lacc, 0.0, 1.0);\n", dest, j);
object.Write("%s%d = mat * float4(clamp(lacc, 0, 255)) / 255.0;\n", dest, j);
object.Write("}\n");
}
}

View File

@ -413,7 +413,8 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
out.Write("\tfloat3 _norm0 = normalize(Normal.xyz);\n\n");
out.Write("\tfloat3 pos = float3(clipPos.x,clipPos.y,Normal.w);\n");
out.Write("\tfloat4 mat, lacc;\n"
out.Write("\tfloat4 mat;\n"
"\tint4 lacc;\n"
"\tfloat3 ldir, h;\n"
"\tfloat dist, dist2, attn;\n");

View File

@ -218,7 +218,8 @@ 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("float4 mat, lacc;\n"
out.Write("float4 mat;\n"
"int4 lacc;\n"
"float3 ldir, h;\n"
"float dist, dist2, attn;\n");