Skip to content

Commit

Permalink
GPU: Treat negative light exp same as 0.
Browse files Browse the repository at this point in the history
Based on hrydgard#12507 and some tests, seems like negative exponents are also
fixed to a 1.0f result.
  • Loading branch information
unknownbrackets committed Mar 23, 2020
1 parent 56a1b6d commit 4a0109d
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 10 deletions.
6 changes: 3 additions & 3 deletions GPU/Directx9/VertexShaderGeneratorDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
if (poweredDiffuse) {
// 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 (u_matspecular.a == 0.0) {\n");
WRITE(p, " if (u_matspecular.a <= 0.0) {\n");
WRITE(p, " ldot = 1.0;\n");
WRITE(p, " } else {\n");
WRITE(p, " ldot = pow(max(ldot, 0.0), u_matspecular.a);\n");
Expand All @@ -607,7 +607,7 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
case GE_LIGHTTYPE_UNKNOWN:
WRITE(p, " angle = length(u_lightdir%i) == 0.0 ? 0.0 : dot(normalize(u_lightdir%i), toLight);\n", i, 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) * (u_lightangle_spotCoef%i.y == 0.0 ? 1.0 : pow(angle, u_lightangle_spotCoef%i.y));\n", i, i, i);
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, float3(1.0, distance, distance*distance)), 0.0, 1.0) * (u_lightangle_spotCoef%i.y <= 0.0 ? 1.0 : pow(angle, u_lightangle_spotCoef%i.y));\n", i, i, i);
WRITE(p, " } else {\n");
WRITE(p, " lightScale = 0.0;\n");
WRITE(p, " }\n");
Expand All @@ -621,7 +621,7 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
if (doSpecular) {
WRITE(p, " if (ldot >= 0.0) {\n");
WRITE(p, " ldot = dot(normalize(toLight + float3(0.0, 0.0, 1.0)), worldnormal);\n");
WRITE(p, " if (u_matspecular.a == 0.0) {\n");
WRITE(p, " if (u_matspecular.a <= 0.0) {\n");
WRITE(p, " ldot = 1.0;\n");
WRITE(p, " } else {\n");
WRITE(p, " ldot = pow(max(ldot, 0.0), u_matspecular.a);\n");
Expand Down
6 changes: 3 additions & 3 deletions GPU/GLES/VertexShaderGeneratorGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
if (poweredDiffuse) {
// 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 (u_matspecular.a == 0.0) {\n");
WRITE(p, " if (u_matspecular.a <= 0.0) {\n");
WRITE(p, " ldot = 1.0;\n");
WRITE(p, " } else {\n");
WRITE(p, " ldot = pow(max(ldot, 0.0), u_matspecular.a);\n");
Expand All @@ -701,7 +701,7 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
case GE_LIGHTTYPE_UNKNOWN:
WRITE(p, " angle = length(u_lightdir%i) == 0.0 ? 0.0 : dot(normalize(u_lightdir%i), toLight);\n", i, i);
WRITE(p, " if (angle >= u_lightangle_spotCoef%i.x) {\n", i);
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, vec3(1.0, distance, distance*distance)), 0.0, 1.0) * (u_lightangle_spotCoef%i.y == 0.0 ? 1.0 : pow(angle, u_lightangle_spotCoef%i.y));\n", i, i, i);
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, vec3(1.0, distance, distance*distance)), 0.0, 1.0) * (u_lightangle_spotCoef%i.y <= 0.0 ? 1.0 : pow(angle, u_lightangle_spotCoef%i.y));\n", i, i, i);
WRITE(p, " } else {\n");
WRITE(p, " lightScale = 0.0;\n");
WRITE(p, " }\n");
Expand All @@ -715,7 +715,7 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
if (doSpecular) {
WRITE(p, " if (ldot >= 0.0) {\n");
WRITE(p, " ldot = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n");
WRITE(p, " if (u_matspecular.a == 0.0) {\n");
WRITE(p, " if (u_matspecular.a <= 0.0) {\n");
WRITE(p, " ldot = 1.0;\n");
WRITE(p, " } else {\n");
WRITE(p, " ldot = pow(max(ldot, 0.0), u_matspecular.a);\n");
Expand Down
2 changes: 1 addition & 1 deletion GPU/Software/Lighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static inline Vec3f GetLightVec(u32 lparams[12], int light) {
}

static inline float pspLightPow(float v, float e) {
if (e == 0.0f) {
if (e <= 0.0f) {
return 1.0f;
}
if (v > 0.0f) {
Expand Down
6 changes: 3 additions & 3 deletions GPU/Vulkan/VertexShaderGeneratorVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
if (poweredDiffuse) {
// 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 (light.matspecular.a == 0.0) {\n");
WRITE(p, " if (light.matspecular.a <= 0.0) {\n");
WRITE(p, " dot%i = 1.0;\n", i);
WRITE(p, " } else {\n");
WRITE(p, " dot%i = pow(max(dot%i, 0.0), light.matspecular.a);\n", i, i);
Expand All @@ -485,7 +485,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
case GE_LIGHTTYPE_UNKNOWN:
WRITE(p, " float angle%i = length(light.dir[%i]) == 0.0 ? 0.0 : dot(normalize(light.dir[%i]), toLight);\n", i, i, i);
WRITE(p, " if (angle%i >= light.angle_spotCoef[%i].x) {\n", i, i);
WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0) * (light.angle_spotCoef[%i].y == 0.0 ? 1.0 : pow(angle%i, light.angle_spotCoef[%i].y));\n", i, i, i, i);
WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0) * (light.angle_spotCoef[%i].y <= 0.0 ? 1.0 : pow(angle%i, light.angle_spotCoef[%i].y));\n", i, i, i, i);
WRITE(p, " } else {\n");
WRITE(p, " lightScale = 0.0;\n");
WRITE(p, " }\n");
Expand All @@ -499,7 +499,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
if (doSpecular) {
WRITE(p, " if (dot%i >= 0.0) {\n", i);
WRITE(p, " dot%i = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n", i);
WRITE(p, " if (light.matspecular.a == 0.0) {\n");
WRITE(p, " if (light.matspecular.a <= 0.0) {\n");
WRITE(p, " dot%i = 1.0;\n", i);
WRITE(p, " } else {\n");
WRITE(p, " dot%i = pow(max(dot%i, 0.0), light.matspecular.a);\n", i, i);
Expand Down

0 comments on commit 4a0109d

Please sign in to comment.