Merge pull request #11567 from unknownbrackets/lighting

Correct shade mapping when light pos is all zeros
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2018-11-18 10:15:41 +01:00
commit ccc4e2e9ca
6 files changed
+38 -10

No files matched your search

+17 -2
View File
@@ -391,8 +391,23 @@ void SoftwareTransform(
case GE_TEXMAP_ENVIRONMENT_MAP:
// Shade mapping - use two light sources to generate U and V.
{
Vec3f lightpos0 = Vec3f(&lighter.lpos[gstate.getUVLS0() * 3]).Normalized();
Vec3f lightpos1 = Vec3f(&lighter.lpos[gstate.getUVLS1() * 3]).Normalized();
auto getLPosFloat = [&](int l, int i) {
return getFloat24(gstate.lpos[l * 3 + i]);
};
auto getLPos = [&](int l) {
return Vec3f(getLPosFloat(l, 0), getLPosFloat(l, 1), getLPosFloat(l, 2));
};
auto calcShadingLPos = [&](int l) {
Vec3f pos = getLPos(l);
if (pos.Length() == 0.0f) {
return Vec3f(0.0f, 0.0f, 1.0f);
} else {
return pos.Normalized();
}
};
// Might not have lighting enabled, so don't use lighter.
Vec3f lightpos0 = calcShadingLPos(gstate.getUVLS0());
Vec3f lightpos1 = calcShadingLPos(gstate.getUVLS1());
uv[0] = (1.0f + Dot(lightpos0, worldnormal))/2.0f;
uv[1] = (1.0f + Dot(lightpos1, worldnormal))/2.0f;
+3 -3
View File
@@ -107,9 +107,9 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
Vec3f lightDir(0, 0, 0);
if (type == GE_LIGHTTYPE_DIRECTIONAL)
toLight = Vec3f(&lpos[l * 3]); // lightdir is for spotlights
toLight = Vec3Packedf(&lpos[l * 3]); // lightdir is for spotlights
else
toLight = Vec3f(&lpos[l * 3]) - pos;
toLight = Vec3Packedf(&lpos[l * 3]) - pos;
bool doSpecular = gstate.isUsingSpecularLight(l);
bool poweredDiffuse = gstate.isUsingPoweredDiffuseLight(l);
@@ -139,7 +139,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
break;
case GE_LIGHTTYPE_SPOT:
case GE_LIGHTTYPE_UNKNOWN:
lightDir = Vec3f(&ldir[l * 3]);
lightDir = Vec3Packedf(&ldir[l * 3]);
angle = Dot(toLight.Normalized(), lightDir.Normalized());
if (angle >= lcutoff[l])
lightScale = clamp(1.0f / (latt[l * 3] + latt[l * 3 + 1] * distanceToLight + latt[l * 3 + 2] * distanceToLight*distanceToLight), 0.0f, 1.0f) * powf(angle, lconv[l]);
+5 -1
View File
@@ -715,7 +715,11 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
break;
case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources.
WRITE(p, " Out.v_texcoord = float3(u_uvscaleoffset.xy * float2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 + dot(normalize(u_lightpos%i), worldnormal)) * 0.5, 1.0);\n", ls0, ls1);
{
std::string lightFactor0 = StringFromFormat("(length(u_lightpos%i) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%i), worldnormal))", ls0, ls0);
std::string lightFactor1 = StringFromFormat("(length(u_lightpos%i) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%i), worldnormal))", ls1, ls1);
WRITE(p, " Out.v_texcoord = float3(u_uvscaleoffset.xy * float2(1.0 + %s, 1.0 + %s) * 0.5, 1.0);\n", lightFactor0.c_str(), lightFactor1.c_str());
}
break;
default:
+5 -1
View File
@@ -810,7 +810,11 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
break;
case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources.
WRITE(p, " v_texcoord = vec3(u_uvscaleoffset.xy * vec2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 + dot(normalize(u_lightpos%i), worldnormal)) * 0.5, 1.0);\n", ls0, ls1);
{
std::string lightFactor0 = StringFromFormat("(length(u_lightpos%i) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%i), worldnormal))", ls0, ls0);
std::string lightFactor1 = StringFromFormat("(length(u_lightpos%i) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%i), worldnormal))", ls1, ls1);
WRITE(p, " v_texcoord = vec3(u_uvscaleoffset.xy * vec2(1.0 + %s, 1.0 + %s) * 0.5, 1.0);\n", lightFactor0.c_str(), lightFactor1.c_str());
}
break;
default:
+2 -1
View File
@@ -38,7 +38,8 @@ void Process(VertexData& vertex, bool hasColor)
// TODO: Not sure if this really should be done even if lighting is disabled altogether
if (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP) {
Vec3<float> L = Vec3<float>(getFloat24(gstate.lpos[3 * light]), getFloat24(gstate.lpos[3 * light + 1]),getFloat24(gstate.lpos[3 * light + 2]));
float diffuse_factor = Dot(L.Normalized(), vertex.worldnormal);
// 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);
if (gstate.getUVLS0() == (int)light)
vertex.texturecoords.s() = (diffuse_factor + 1.f) / 2.f;
+6 -2
View File
@@ -602,8 +602,12 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
break;
case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources.
WRITE(p, " v_texcoord = vec3(base.uvscaleoffset.xy * vec2(1.0 + dot(normalize(light.pos[%i]), worldnormal), 1.0 + dot(normalize(light.pos[%i]), worldnormal)) * 0.5, 1.0);\n", ls0, ls1);
break;
{
std::string lightFactor0 = StringFromFormat("(length(light.pos[%i]) == 0.0 ? worldnormal.z : dot(normalize(light.pos[%i]), worldnormal))", ls0, ls0);
std::string lightFactor1 = StringFromFormat("(length(light.pos[%i]) == 0.0 ? worldnormal.z : dot(normalize(light.pos[%i]), worldnormal))", ls1, ls1);
WRITE(p, " v_texcoord = vec3(base.uvscaleoffset.xy * vec2(1.0 + %s, 1.0 + %s) * 0.5, 1.0);\n", lightFactor0.c_str(), lightFactor1.c_str());
}
break;
default:
// ILLEGAL