From b2d60cb807bc96f3cb900982cee34885df55be89 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 18 Nov 2018 07:28:03 -0800 Subject: [PATCH] SoftGPU: Cleanup lighting code a bit. Avoid using Length() when Length2() is enough, simplify some things. --- GPU/Common/SoftwareTransformCommon.cpp | 2 +- GPU/Software/Lighting.cpp | 31 +++++++++++++------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index 311333e791..d38784d2f5 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -399,7 +399,7 @@ void SoftwareTransform( }; auto calcShadingLPos = [&](int l) { Vec3f pos = getLPos(l); - if (pos.Length() == 0.0f) { + if (pos.Length2() == 0.0f) { return Vec3f(0.0f, 0.0f, 1.0f); } else { return pos.Normalized(); diff --git a/GPU/Software/Lighting.cpp b/GPU/Software/Lighting.cpp index 2a1e6398aa..96b0fef6cf 100644 --- a/GPU/Software/Lighting.cpp +++ b/GPU/Software/Lighting.cpp @@ -21,8 +21,11 @@ namespace Lighting { -void Process(VertexData& vertex, bool hasColor) -{ +static inline Vec3f GetLightVec(u32 lparams[12], int light) { + return Vec3(getFloat24(lparams[3 * light]), getFloat24(lparams[3 * light + 1]), getFloat24(lparams[3 * light + 2])); +} + +void Process(VertexData& vertex, bool hasColor) { const int materialupdate = gstate.materialupdate & (hasColor ? 7 : 0); Vec3 vcol0 = vertex.color0.rgb().Cast() * Vec3::AssignToAll(1.0f / 255.0f); @@ -35,11 +38,11 @@ void Process(VertexData& vertex, bool hasColor) for (unsigned int light = 0; light < 4; ++light) { // Always calculate texture coords from lighting results if environment mapping is active // TODO: Should specular lighting should affect this, too? Doesn't in GLES. - // TODO: Not sure if this really should be done even if lighting is disabled altogether + // This should be done even if lighting is disabled altogether. if (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP) { - Vec3 L = Vec3(getFloat24(gstate.lpos[3 * light]), getFloat24(gstate.lpos[3 * light + 1]),getFloat24(gstate.lpos[3 * light + 2])); - // In other words, L.Length() == 0.0f means Dot({0, 0, 1}, worldnormal). - float diffuse_factor = L.Length() == 0.0f ? vertex.worldnormal.z : Dot(L.Normalized(), vertex.worldnormal); + Vec3 L = GetLightVec(gstate.lpos, light); + // In other words, L.Length2() == 0.0f means Dot({0, 0, 1}, worldnormal). + float diffuse_factor = L.Length2() == 0.0f ? vertex.worldnormal.z : Dot(L.Normalized(), vertex.worldnormal); if (gstate.getUVLS0() == (int)light) vertex.texturecoords.s() = (diffuse_factor + 1.f) / 2.f; @@ -58,30 +61,28 @@ void Process(VertexData& vertex, bool hasColor) // L = vector from vertex to light source // TODO: Should transfer the light positions to world/view space for these calculations? - Vec3 L = Vec3(getFloat24(gstate.lpos[3 * light]), getFloat24(gstate.lpos[3 * light + 1]),getFloat24(gstate.lpos[3 * light + 2])); + Vec3 L = GetLightVec(gstate.lpos, light); if (!gstate.isDirectionalLight(light)) { L -= vertex.worldpos; } + // TODO: Should this normalize (0, 0, 0) to (0, 0, 1)? float d = L.Normalize(); - float lka = getFloat24(gstate.latt[3 * light]); - float lkb = getFloat24(gstate.latt[3 * light + 1]); - float lkc = getFloat24(gstate.latt[3 * light + 2]); float att = 1.f; if (!gstate.isDirectionalLight(light)) { - att = 1.f / (lka + lkb * d + lkc * d * d); + att = 1.f / Dot(GetLightVec(gstate.latt, light), Vec3f(1.0f, d, d * d)); if (att > 1.f) att = 1.f; if (att < 0.f) att = 0.f; } float spot = 1.f; if (gstate.isSpotLight(light)) { - Vec3 dir = Vec3(getFloat24(gstate.ldir[3 * light]), getFloat24(gstate.ldir[3 * light + 1]),getFloat24(gstate.ldir[3 * light + 2])); - float _spot = Dot(dir.Normalized(), L); + Vec3 dir = GetLightVec(gstate.ldir, light); + float rawSpot = Dot(dir.Normalized(), L); float cutoff = getFloat24(gstate.lcutoff[light]); - if (_spot >= cutoff) { + if (rawSpot >= cutoff) { float conv = getFloat24(gstate.lconv[light]); - spot = pow(_spot, conv); + spot = pow(rawSpot, conv); } else { spot = 0.f; }