mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
D3D11: Fix pow(0, 0) lighting handling.
This was previously fixed in GLES.
This commit is contained in:
parent
332788d0b5
commit
016d6ba764
1 changed files with 22 additions and 13 deletions
|
@ -604,7 +604,7 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
|||
bool diffuseIsZero = true;
|
||||
bool specularIsZero = true;
|
||||
bool distanceNeeded = false;
|
||||
|
||||
bool anySpots = false;
|
||||
if (enableLighting) {
|
||||
WRITE(p, " float4 lightSum0 = u_ambient * %s + float4(u_matemissive, 0.0);\n", ambientStr);
|
||||
|
||||
|
@ -618,6 +618,8 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
|||
specularIsZero = false;
|
||||
if (type != GE_LIGHTTYPE_DIRECTIONAL)
|
||||
distanceNeeded = true;
|
||||
if (type == GE_LIGHTTYPE_SPOT || type == GE_LIGHTTYPE_UNKNOWN)
|
||||
anySpots = true;
|
||||
}
|
||||
|
||||
if (!specularIsZero) {
|
||||
|
@ -631,6 +633,10 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
|||
WRITE(p, " float distance;\n");
|
||||
WRITE(p, " float lightScale;\n");
|
||||
}
|
||||
WRITE(p, " float ldot;\n");
|
||||
if (anySpots) {
|
||||
WRITE(p, " float angle;\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate lights if needed. If shade mapping is enabled, lights may need to be
|
||||
|
@ -654,12 +660,15 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
|||
bool doSpecular = comp != GE_LIGHTCOMP_ONLYDIFFUSE;
|
||||
bool poweredDiffuse = comp == GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE;
|
||||
|
||||
WRITE(p, " ldot = max(dot(toLight, worldnormal), 0.0);\n");
|
||||
if (poweredDiffuse) {
|
||||
WRITE(p, " float dot%i = pow(dot(toLight, worldnormal), u_matspecular.a);\n", i);
|
||||
// TODO: Somehow the NaN check from GLES seems unnecessary here?
|
||||
// If it returned 0, it'd be wrong, so that's strange.
|
||||
} else {
|
||||
WRITE(p, " float dot%i = dot(toLight, worldnormal);\n", i);
|
||||
// pow(0.0, 0.0) may be undefined, but the PSP seems to treat it as 1.0.
|
||||
// Seen in Tales of the World: Radiant Mythology (#2424.)
|
||||
WRITE(p, " if (ldot == 0.0 && u_matspecular.a == 0.0) {\n");
|
||||
WRITE(p, " ldot = 1.0;\n");
|
||||
WRITE(p, " } else {\n");
|
||||
WRITE(p, " ldot = pow(ldot, u_matspecular.a);\n");
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
|
||||
const char *timesLightScale = " * lightScale";
|
||||
|
@ -674,9 +683,9 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
|||
break;
|
||||
case GE_LIGHTTYPE_SPOT:
|
||||
case GE_LIGHTTYPE_UNKNOWN:
|
||||
WRITE(p, " float angle%i = dot(normalize(u_lightdir%i), toLight);\n", i, i);
|
||||
WRITE(p, " if (angle%i >= u_lightangle_spotCoef%i.x) {\n", i, i);
|
||||
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, float3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle%i, u_lightangle_spotCoef%i.y);\n", i, i, i);
|
||||
WRITE(p, " angle = dot(normalize(u_lightdir%i), toLight);\n", i);
|
||||
WRITE(p, " if (angle >= u_lightangle_spotCoef%i.x) {\n", i);
|
||||
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, float3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle, u_lightangle_spotCoef%i.y);\n", i, i);
|
||||
WRITE(p, " } else {\n");
|
||||
WRITE(p, " lightScale = 0.0;\n");
|
||||
WRITE(p, " }\n");
|
||||
|
@ -686,11 +695,11 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
|||
break;
|
||||
}
|
||||
|
||||
WRITE(p, " diffuse = (u_lightdiffuse%i * %s) * max(dot%i, 0.0);\n", i, diffuseStr, i);
|
||||
WRITE(p, " diffuse = (u_lightdiffuse%i * %s) * ldot;\n", i, diffuseStr);
|
||||
if (doSpecular) {
|
||||
WRITE(p, " dot%i = dot(normalize(toLight + float3(0.0, 0.0, 1.0)), worldnormal);\n", i);
|
||||
WRITE(p, " if (dot%i > 0.0)\n", i);
|
||||
WRITE(p, " lightSum1 += u_lightspecular%i * %s * (pow(dot%i, u_matspecular.a) %s);\n", i, specularStr, i, timesLightScale);
|
||||
WRITE(p, " ldot = dot(normalize(toLight + float3(0.0, 0.0, 1.0)), worldnormal);\n");
|
||||
WRITE(p, " if (ldot > 0.0)\n");
|
||||
WRITE(p, " lightSum1 += u_lightspecular%i * %s * (pow(ldot, u_matspecular.a) %s);\n", i, specularStr, timesLightScale);
|
||||
}
|
||||
WRITE(p, " lightSum0.rgb += (u_lightambient%i * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue