Lighting Attenuation Fixes
This commit is contained in:
parent
e7f2a04699
commit
f475e367f2
|
@ -56,46 +56,31 @@ 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));
|
||||
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 LIGHTDIF_SIGN:
|
||||
case LIGHTDIF_CLAMP:
|
||||
case LIGHTATTN_SPEC:
|
||||
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));
|
||||
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;
|
||||
default: _assert_(0);
|
||||
}
|
||||
}
|
||||
else // spec and spot
|
||||
{
|
||||
if (chan.attnfunc == 3)
|
||||
{ // spot
|
||||
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));
|
||||
"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));
|
||||
break;
|
||||
}
|
||||
|
||||
switch (chan.diffusefunc)
|
||||
|
@ -114,7 +99,7 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
|
|||
break;
|
||||
default: _assert_(0);
|
||||
}
|
||||
}
|
||||
|
||||
object.Write("\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue