Skip to content

Commit

Permalink
Vulkan: remove array indexing for light parameters to match the other…
Browse files Browse the repository at this point in the history
… backends
  • Loading branch information
hrydgard committed Oct 21, 2020
1 parent 391d2ea commit 712f56f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 29 deletions.
35 changes: 28 additions & 7 deletions GPU/Common/ShaderUniforms.h
Expand Up @@ -121,13 +121,34 @@ R"( vec4 u_ambient;
vec3 u_matdiffuse;
vec4 u_matspecular;
vec3 u_matemissive;
vec3 u_lightpos[4];
vec3 u_lightdir[4];
vec3 u_lightatt[4];
vec2 u_lightangle_spotCoef[4];
vec3 u_lightambient[4];
vec3 u_lightdiffuse[4];
vec3 u_lightspecular[4];
vec3 u_lightpos0;
vec3 u_lightpos1;
vec3 u_lightpos2;
vec3 u_lightpos3;
vec3 u_lightdir0;
vec3 u_lightdir1;
vec3 u_lightdir2;
vec3 u_lightdir3;
vec3 u_lightatt0;
vec3 u_lightatt1;
vec3 u_lightatt2;
vec3 u_lightatt3;
vec4 u_lightangle_spotCoef0;
vec4 u_lightangle_spotCoef1;
vec4 u_lightangle_spotCoef2;
vec4 u_lightangle_spotCoef3;
vec3 u_lightambient0;
vec3 u_lightambient1;
vec3 u_lightambient2;
vec3 u_lightambient3;
vec3 u_lightdiffuse0;
vec3 u_lightdiffuse1;
vec3 u_lightdiffuse2;
vec3 u_lightdiffuse3;
vec3 u_lightspecular0;
vec3 u_lightspecular1;
vec3 u_lightspecular2;
vec3 u_lightspecular3;
)";

// HLSL code is shared so these names are changed to match those in DX9.
Expand Down
44 changes: 22 additions & 22 deletions GPU/Vulkan/VertexShaderGeneratorVulkan.cpp
Expand Up @@ -397,22 +397,22 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {

// TODO: Declare variables for dots for shade mapping if needed.

const char *ambientStr = ((matUpdate & 1) && hasColor) ? "color0" : "base.matambientalpha";
const char *diffuseStr = ((matUpdate & 2) && hasColor) ? "color0.rgb" : "light.matdiffuse";
const char *specularStr = ((matUpdate & 4) && hasColor) ? "color0.rgb" : "light.matspecular.rgb";
const char *ambientStr = ((matUpdate & 1) && hasColor) ? "color0" : "u_matambientalpha";
const char *diffuseStr = ((matUpdate & 2) && hasColor) ? "color0.rgb" : "u_matdiffuse";
const char *specularStr = ((matUpdate & 4) && hasColor) ? "color0.rgb" : "u_matspecular.rgb";
if (doBezier || doSpline) {
// TODO: Probably, should use hasColorTess but FF4 has a problem with drawing the background.
ambientStr = (matUpdate & 1) && hasColor ? "tess.col" : "base.matambientalpha";
diffuseStr = (matUpdate & 2) && hasColor ? "tess.col.rgb" : "light.matdiffuse";
specularStr = (matUpdate & 4) && hasColor ? "tess.col.rgb" : "light.matspecular.rgb";
ambientStr = (matUpdate & 1) && hasColor ? "tess.col" : "u_matambientalpha";
diffuseStr = (matUpdate & 2) && hasColor ? "tess.col.rgb" : "u_matdiffuse";
specularStr = (matUpdate & 4) && hasColor ? "tess.col.rgb" : "u_matspecular.rgb";
}

bool diffuseIsZero = true;
bool specularIsZero = true;
bool distanceNeeded = false;

if (enableLighting) {
WRITE(p, " vec4 lightSum0 = light.u_ambient * %s + vec4(light.matemissive, 0.0);\n", ambientStr);
WRITE(p, " vec4 lightSum0 = u_ambient * %s + vec4(u_matemissive, 0.0);\n", ambientStr);

for (int i = 0; i < 4; i++) {
GELightType type = static_cast<GELightType>(id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2));
Expand Down Expand Up @@ -450,9 +450,9 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {

if (type == GE_LIGHTTYPE_DIRECTIONAL) {
// We prenormalize light positions for directional lights.
WRITE(p, " toLight = light.pos[%i];\n", i);
WRITE(p, " toLight = u_lightpos%d;\n", i);
} else {
WRITE(p, " toLight = light.pos[%i] - worldpos;\n", i);
WRITE(p, " toLight = u_lightpos%d - worldpos;\n", i);
WRITE(p, " distance = length(toLight);\n");
WRITE(p, " toLight /= distance;\n");
}
Expand All @@ -464,10 +464,10 @@ 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 (u_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);
WRITE(p, " dot%i = pow(max(dot%i, 0.0), u_matspecular.a);\n", i, i);
WRITE(p, " }\n");
}

Expand All @@ -479,13 +479,13 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
timesLightScale = "";
break;
case GE_LIGHTTYPE_POINT:
WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0);\n", i);
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%d, vec3(1.0, distance, distance*distance)), 0.0, 1.0);\n", i);
break;
case GE_LIGHTTYPE_SPOT:
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, " float angle%i = length(u_lightdir%d) == 0.0 ? 0.0 : dot(normalize(u_lightdir%d), toLight);\n", i, i, i);
WRITE(p, " if (angle%i >= u_lightangle_spotCoef%d.x) {\n", i, i);
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%d, vec3(1.0, distance, distance*distance)), 0.0, 1.0) * (u_lightangle_spotCoef%d.y <= 0.0 ? 1.0 : pow(angle%i, u_lightangle_spotCoef%d.y));\n", i, i, i, i);
WRITE(p, " } else {\n");
WRITE(p, " lightScale = 0.0;\n");
WRITE(p, " }\n");
Expand All @@ -495,20 +495,20 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
break;
}

WRITE(p, " diffuse = (light.diffuse[%i] * %s) * max(dot%i, 0.0);\n", i, diffuseStr, i);
WRITE(p, " diffuse = (u_lightdiffuse%d * %s) * max(dot%i, 0.0);\n", i, diffuseStr, i);
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 (u_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);
WRITE(p, " dot%i = pow(max(dot%i, 0.0), u_matspecular.a);\n", i, i);
WRITE(p, " }\n");
WRITE(p, " if (dot%i > 0.0)\n", i);
WRITE(p, " lightSum1 += light.specular[%i] * %s * dot%i %s;\n", i, specularStr, i, timesLightScale);
WRITE(p, " lightSum1 += u_lightspecular%d * %s * dot%i %s;\n", i, specularStr, i, timesLightScale);
WRITE(p, " }\n");
}
WRITE(p, " lightSum0.rgb += (light.ambient[%i] * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale);
WRITE(p, " lightSum0.rgb += (u_lightambient%d * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale);
}

if (enableLighting) {
Expand Down Expand Up @@ -605,8 +605,8 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {

case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources.
{
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);
std::string lightFactor0 = StringFromFormat("(length(u_lightpos%d) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%d), worldnormal))", ls0, ls0);
std::string lightFactor1 = StringFromFormat("(length(u_lightpos%d) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%d), 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;
Expand Down

0 comments on commit 712f56f

Please sign in to comment.