From 48d75dafcbb808f14759dc217155a8948a528dba Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sat, 29 Jun 2013 00:54:43 +0200 Subject: [PATCH] softgpu: Implement attenuation and spot factors. --- GPU/Software/Lighting.cpp | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/GPU/Software/Lighting.cpp b/GPU/Software/Lighting.cpp index d2157889c8..eb84a0224e 100644 --- a/GPU/Software/Lighting.cpp +++ b/GPU/Software/Lighting.cpp @@ -42,18 +42,45 @@ void Process(VertexData& vertex) if (!gstate.isLightChanEnabled(light)) continue; + Vec3 L = Vec3(getFloat24(gstate.lpos[3*light]&0xFFFFFF), getFloat24(gstate.lpos[3*light+1]&0xFFFFFF),getFloat24(gstate.lpos[3*light+2]&0xFFFFFF)); + L -= vertex.worldpos; + float d = L.Length(); + + float lka = getFloat24(gstate.latt[3*light]&0xFFFFFF); + float lkb = getFloat24(gstate.latt[3*light+1]&0xFFFFFF); + float lkc = getFloat24(gstate.latt[3*light+2]&0xFFFFFF); + float att = 1.f; + if (!gstate.isDirectionalLight(light)) { + att = 1.f / (lka + lkb * d + lkc * 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]&0xFFFFFF), getFloat24(gstate.ldir[3*light+1]&0xFFFFFF),getFloat24(gstate.ldir[3*light+2]&0xFFFFFF)); + float _spot = Dot(-L,dir) / d / dir.Length(); + float cutoff = getFloat24(gstate.lcutoff[light]&0xFFFFFF); + if (_spot > cutoff) { + spot = _spot; + float conv = getFloat24(gstate.lconv[light]&0xFFFFFF); + spot = pow(_spot, conv); + } else { + spot = 0.f; + } + } + + // diffuse lighting Vec3 ldc = Vec3(gstate.getDiffuseColorR(light), gstate.getDiffuseColorG(light), gstate.getDiffuseColorB(light)); Vec3 mdc = (gstate.materialupdate&2) ? Vec3(gstate.getMaterialDiffuseR(), gstate.getMaterialDiffuseG(), gstate.getMaterialDiffuseB()) : vertex.color0.rgb(); - Vec3 L = Vec3(getFloat24(gstate.lpos[3*light]&0xFFFFFF), getFloat24(gstate.lpos[3*light+1]&0xFFFFFF),getFloat24(gstate.lpos[3*light+2]&0xFFFFFF)); - L -= vertex.worldpos; - float factor = Dot(L,vertex.normal) / L.Length() / vertex.worldpos.Length(); + float diffuse_factor = Dot(L,vertex.normal) / d / vertex.worldpos.Length(); - vertex.color0.r() += ldc.r() * mdc.r() * factor / 255; - vertex.color0.g() += ldc.g() * mdc.g() * factor / 255; - vertex.color0.b() += ldc.b() * mdc.b() * factor / 255; + vertex.color0.r() += att * spot * ldc.r() * mdc.r() * diffuse_factor / 255; + vertex.color0.g() += att * spot * ldc.g() * mdc.g() * diffuse_factor / 255; + vertex.color0.b() += att * spot * ldc.b() * mdc.b() * diffuse_factor / 255; } // Currently only implementing ambient+diffuse lighting, so secondary color is always zero anyway