mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-03 17:55:27 +02:00
Merge pull request #11567 from unknownbrackets/lighting
Correct shade mapping when light pos is all zeros
This commit is contained in:
6 files changed
+38
-10
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user