some experiments with lighting, please test an let me know if is a improvement or make things worst

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6124 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado 2010-08-25 03:42:57 +00:00
parent 0f56f5076c
commit 3b30019fcb
2 changed files with 54 additions and 41 deletions

View File

@ -22,7 +22,7 @@ static const char ID[4] = {'D', 'C', 'A', 'C'};
// Update this to the current SVN revision every time you change shader generation code.
// We don't automatically get this from SVN_REV because that would mean regenerating the
// shader cache for every revision, graphics-related or not, which is simply annoying.
const int version = 6103;
const int version = 6123;
LinearDiskCache::LinearDiskCache()
: file_(NULL), num_entries_(0) {

View File

@ -112,7 +112,8 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
WRITE(p, "struct VS_OUTPUT {\n");
WRITE(p, " float4 pos : POSITION;\n");
WRITE(p, " float4 colors[2] : COLOR0;\n");
WRITE(p, " float4 colors_0 : COLOR0;\n");
WRITE(p, " float4 colors_1 : COLOR1;\n");
if (xfregs.numTexGens < 7) {
for (int i = 0; i < xfregs.numTexGens; ++i)
@ -224,20 +225,26 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
"float3 ldir, h;\n"
"float dist, dist2, attn;\n");
if(xfregs.nNumChans == 0)
{
if (components & VB_HAS_COL0)
WRITE(p, "o.colors_0 = color0;\n");
else
WRITE(p, "o.colors_0 = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
}
// lights/colors
for (int j = 0; j < xfregs.nNumChans; j++)
{
// bool bColorAlphaSame = xfregs.colChans[j].color.hex == xfregs.colChans[j].alpha.hex; unused
const LitChannel& color = xfregs.colChans[j].color;
const LitChannel& alpha = xfregs.colChans[j].alpha;
WRITE(p, "{\n");
WRITE(p, "lacc = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
if (color.matsource) {// from vertex
if (components & (VB_HAS_COL0 << j))
WRITE(p, "mat = color%d;\n", j);
else if (components & VB_HAS_COL0)
WRITE(p, "mat = color0;\n", j);
else
WRITE(p, "mat = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
}
@ -248,35 +255,50 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
if (color.ambsource) { // from vertex
if (components & (VB_HAS_COL0<<j) )
WRITE(p, "lacc = color%d;\n", j);
else if (components & VB_HAS_COL0 )
WRITE(p, "lacc = color0;\n", j);
else
WRITE(p, "lacc = float4(0.0f, 0.0f, 0.0f, 0.0f);\n");
}
else // from color
WRITE(p, "lacc = "I_MATERIALS".C%d;\n", j);
}
else
{
WRITE(p, "lacc = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
}
// check if alpha is different
if (alpha.matsource != color.matsource) {
if (alpha.matsource) {// from vertex
if (components & (VB_HAS_COL0<<j))
WRITE(p, "mat.w = color%d.w;\n", j);
else if (components & VB_HAS_COL0)
WRITE(p, "mat.w = color0.w;\n", j);
else WRITE(p, "mat.w = 1.0f;\n");
}
else // from color
WRITE(p, "mat.w = "I_MATERIALS".C%d.w;\n", j+2);
}
if (alpha.enablelighting)
if (alpha.enablelighting)
{
if (alpha.ambsource) {// from vertex
if (components & (VB_HAS_COL0<<j) )
WRITE(p, "lacc.w = color%d.w;\n", j);
else if (components & VB_HAS_COL0 )
WRITE(p, "lacc.w = color0.w;\n", j);
else
WRITE(p, "lacc.w = 0.0f;\n");
}
else // from color
WRITE(p, "lacc.w = "I_MATERIALS".C%d.w;\n", j);
}
else
{
WRITE(p, "lacc.w = 1.0f;\n");
}
if(color.enablelighting && alpha.enablelighting)
{
@ -315,30 +337,16 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
p = GenerateLightShader(p, i, workingchannel, "lacc", coloralpha);
}
}
if (color.enablelighting != alpha.enablelighting) {
if (color.enablelighting)
WRITE(p, "o.colors[%d].xyz = mat.xyz * saturate(lacc.xyz);\n"
"o.colors[%d].w = mat.w;\n", j, j);
else
WRITE(p, "o.colors[%d].xyz = mat.xyz;\n"
"o.colors[%d].w = mat.w * saturate(lacc.w);\n", j, j);
}
else
{
if (alpha.enablelighting)
WRITE(p, "o.colors[%d] = mat * saturate(lacc);\n", j);
else
WRITE(p, "o.colors[%d] = mat;\n", j);
}
WRITE(p, "o.colors_%d = mat * saturate(lacc);\n", j);
WRITE(p, "}\n");
}
if(xfregs.nNumChans == 1)
{
if (components & VB_HAS_COL1)
WRITE(p, "o.colors_1 = color1;\n");
else
WRITE(p, "o.colors_1 = o.colors_0;\n");
}
// zero left over channels
for (int i = xfregs.nNumChans; i < 2; ++i)
WRITE(p, "o.colors[%d] = float4(0.0f, 0.0f, 0.0f, 1.0f);\n", i);
// special case if only pos and tex coord 0 and tex coord input is AB11
// donko - this has caused problems in some games. removed for now.
bool texGenSpecialCase = false;
@ -402,11 +410,11 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
break;
case XF_TEXGEN_COLOR_STRGBC0:
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
WRITE(p, "o.tex%d.xyz = float3(o.colors[0].x, o.colors[0].y, 1);\n", i);
WRITE(p, "o.tex%d.xyz = float3(o.colors_0.x, o.colors_0.y, 1);\n", i);
break;
case XF_TEXGEN_COLOR_STRGBC1:
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
WRITE(p, "o.tex%d.xyz = float3(o.colors[1].x, o.colors[1].y, 1);\n", i);
WRITE(p, "o.tex%d.xyz = float3(o.colors_1.x, o.colors_1.y, 1);\n", i);
break;
case XF_TEXGEN_REGULAR:
default:
@ -489,6 +497,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("VertexShader generator - buffer too small, canary has been eaten!");
setlocale(LC_NUMERIC, ""); // restore locale
return text;
}
@ -515,19 +524,21 @@ char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char
}
}
else { // spec and spot
WRITE(p, "ldir = "I_LIGHTS".lights[%d].pos.xyz - pos.xyz;\n", index);
if (chan.attnfunc == 3) { // spot
if (chan.attnfunc == 3)
{ // spot
WRITE(p, "ldir = "I_LIGHTS".lights[%d].pos.xyz - pos.xyz;\n", index);
WRITE(p, "dist2 = dot(ldir, ldir);\n"
"dist = sqrt(dist2);\n"
"ldir = ldir / dist;\n"
"attn = max(0.0f, dot(ldir, "I_LIGHTS".lights[%d].dir.xyz));\n",index);
WRITE(p, "attn = max(0.0f, dot("I_LIGHTS".lights[%d].cosatt.xyz, float3(1.0f, attn, attn*attn))) / dot("I_LIGHTS".lights[%d].distatt.xyz, float3(1.0f,dist,dist2));\n", index, index);
}
else if (chan.attnfunc == 1) { // specular
WRITE(p, "attn = (dot(_norm0, "I_LIGHTS".lights[%d].pos.xyz) > 0.0f) ? max(0.0f, dot(_norm0, "I_LIGHTS".lights[%d].dir.xyz)) : 0.0f;\n", index, index);
WRITE(p, "ldir = float3(1,attn,attn*attn);\n");
WRITE(p, "attn = max(0.0f, dot("I_LIGHTS".lights[%d].cosatt.xyz, ldir)) / dot("I_LIGHTS".lights[%d].distatt.xyz, ldir);\n", index, index);
else if (chan.attnfunc == 1)
{ // specular
WRITE(p, "ldir = normalize("I_LIGHTS".lights[%d].pos.xyz);\n",index);
WRITE(p, "attn = (dot(_norm0,ldir) > 0.0f) ? max(0.0f, dot(_norm0, "I_LIGHTS".lights[%d].dir.xyz)) : 0.0f;\n", index, index);
WRITE(p, "attn = max(0.0f, dot("I_LIGHTS".lights[%d].cosatt.xyz, float3(1,attn,attn*attn))) / dot("I_LIGHTS".lights[%d].distatt.xyz, float3(1,attn,attn*attn));\n", index, index);
}
switch (chan.diffusefunc)
@ -538,13 +549,15 @@ char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char
case LIGHTDIF_SIGN:
case LIGHTDIF_CLAMP:
WRITE(p, "%s.%s += attn * %sdot(ldir, _norm0)) * "I_LIGHTS".lights[%d].col.%s;\n",
dest, swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(", index, swizzle);
dest,
swizzle,
chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0f," :"(",
index,
swizzle);
break;
default: _assert_(0);
}
}
WRITE(p, "\n");
setlocale(LC_NUMERIC, ""); // restore locale
WRITE(p, "\n");
return p;
}