diff options
author | StapleButter <thetotalworm@gmail.com> | 2017-05-03 23:54:31 +0200 |
---|---|---|
committer | StapleButter <thetotalworm@gmail.com> | 2017-05-03 23:54:31 +0200 |
commit | 7c1443b973a6d0cb63370382501325eaec785e7e (patch) | |
tree | 19f1feb151a1791d0f4e480c1e094a208c5e8692 | |
parent | 9e622dcc66481350f240c5495f680613b7c98fa6 (diff) |
fix lighting behavior with normals that overflow
-rw-r--r-- | src/GPU3D.cpp | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 906b04b..de2916c 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -976,10 +976,6 @@ void SubmitVertex() s32 CalculateLighting() { - // TODO: this requires matrix mode 2, apparently - // hardware seems to read garbage when matrix mode isn't 2 - // also, non-normal normals seem to be treated as zero? or overflow to negative? - if ((TexParam >> 30) == 2) { TexCoords[0] = RawTexCoords[0] + (((s64)Normal[0]*TexMatrix[0] + (s64)Normal[1]*TexMatrix[4] + (s64)Normal[2]*TexMatrix[8]) >> 21); @@ -1001,6 +997,11 @@ s32 CalculateLighting() if (!(CurPolygonAttr & (1<<i))) continue; + // overflow handling (for example, if the normal length is >1) + // according to some hardware tests + // * diffuse level is saturated to 255 + // * shininess level mirrors back to 0 and is ANDed with 0xFF, that before being squared + s32 difflevel = (-(LightDirection[i][0]*normaltrans[0] + LightDirection[i][1]*normaltrans[1] + LightDirection[i][2]*normaltrans[2])) >> 10; @@ -1011,9 +1012,9 @@ s32 CalculateLighting() (LightDirection[i][1]>>1)*normaltrans[1] + ((LightDirection[i][2]-0x200)>>1)*normaltrans[2]) >> 10); if (shinelevel < 0) shinelevel = 0; + else if (shinelevel > 255) shinelevel = (0x100 - shinelevel) & 0xFF; shinelevel = ((shinelevel * shinelevel) >> 7) - 0x100; // really (2*shinelevel*shinelevel)-1 if (shinelevel < 0) shinelevel = 0; - else if (shinelevel > 255) shinelevel = 255; if (UseShininessTable) { @@ -1155,7 +1156,6 @@ void PosTest() void VecTest(u32* params) { - // TODO: apparently requires matrix mode 2 // TODO: maybe it overwrites the normal registers, too s16 normal[3]; |