diff --git a/hw/xbox/nv2a/pgraph/glsl/vsh-ff.c b/hw/xbox/nv2a/pgraph/glsl/vsh-ff.c index 73044bffc3..8770b8a73d 100644 --- a/hw/xbox/nv2a/pgraph/glsl/vsh-ff.c +++ b/hw/xbox/nv2a/pgraph/glsl/vsh-ff.c @@ -249,21 +249,21 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz alpha_source = alpha_source_specular; } - if (state->ambient_src == MATERIAL_COLOR_SRC_MATERIAL) { - mstring_append_fmt(body, "oD0 = vec4(sceneAmbientColor, %s);\n", alpha_source); - } else if (state->ambient_src == MATERIAL_COLOR_SRC_DIFFUSE) { - mstring_append_fmt(body, "oD0 = vec4(diffuse.rgb, %s);\n", alpha_source); - } else if (state->ambient_src == MATERIAL_COLOR_SRC_SPECULAR) { - mstring_append_fmt(body, "oD0 = vec4(specular.rgb, %s);\n", alpha_source); - } + // If emission and ambient sources are taken from a vertex color, the scene ambient color is reconstructed from + // the vertex colors. + bool use_scene_ambient = + state->emission_src == MATERIAL_COLOR_SRC_MATERIAL || state->ambient_src == MATERIAL_COLOR_SRC_MATERIAL; + mstring_append_fmt(body, + "oD0 = vec4(%s, %s);\n", + use_scene_ambient ? "sceneAmbientColor" : + (state->emission_src == MATERIAL_COLOR_SRC_DIFFUSE ? "diffuse.rgb" : "specular.rgb"), + alpha_source + ); - mstring_append(body, "oD0.rgb *= materialEmissionColor.rgb;\n"); - if (state->emission_src == MATERIAL_COLOR_SRC_MATERIAL) { - mstring_append(body, "oD0.rgb += sceneAmbientColor;\n"); - } else if (state->emission_src == MATERIAL_COLOR_SRC_DIFFUSE) { - mstring_append(body, "oD0.rgb += diffuse.rgb;\n"); - } else if (state->emission_src == MATERIAL_COLOR_SRC_SPECULAR) { - mstring_append(body, "oD0.rgb += specular.rgb;\n"); + if (state->emission_src == MATERIAL_COLOR_SRC_DIFFUSE || state->ambient_src == MATERIAL_COLOR_SRC_DIFFUSE) { + mstring_append(body, "oD0.rgb += diffuse.rgb * materialEmissionColor;\n"); + } else if (state->emission_src == MATERIAL_COLOR_SRC_SPECULAR || state->ambient_src == MATERIAL_COLOR_SRC_SPECULAR) { + mstring_append(body, "oD0.rgb += specular.rgb * materialEmissionColor;\n"); } mstring_append(body, "oD1 = vec4(0.0, 0.0, 0.0, specular.a);\n"); @@ -365,12 +365,23 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz " }\n" " vec3 lightAmbient = lightAmbientColor(%d) * attenuation;\n" " vec3 lightDiffuse = lightDiffuseColor(%d) * attenuation * nDotVP;\n" - " vec3 lightSpecular = lightSpecularColor(%d) * attenuation * pf;\n" - " lightSpecular *= vec3(lessThanEqual(lightSpecular.rgb, vec3(1.0)));\n", + " vec3 lightSpecular = lightSpecularColor(%d) * attenuation * pf;\n", state->specular_power, i, i, i); - mstring_append(body, - " oD0.xyz += lightAmbient;\n"); + switch (state->ambient_src) { + case MATERIAL_COLOR_SRC_MATERIAL: + mstring_append(body, + " oD0.rgb += lightAmbient;\n"); + break; + case MATERIAL_COLOR_SRC_DIFFUSE: + mstring_append(body, + " oD0.rgb += diffuse.rgb * lightAmbient;\n"); + break; + case MATERIAL_COLOR_SRC_SPECULAR: + mstring_append(body, + " oD0.rgb += specular.rgb * lightAmbient;\n"); + break; + } switch (state->diffuse_src) { case MATERIAL_COLOR_SRC_MATERIAL: @@ -416,12 +427,16 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz mstring_append(body, " oB1 = vec4(0.0, 0.0, 0.0, 1.0);\n"); } else { if (!state->separate_specular) { - mstring_append(body, - " oD0.xyz += oD1.xyz;\n" - " oD1 = specular;\n" - " oB0.xyz += oB1.xyz;\n" - " oB1 = backSpecular;\n" - ); + if (state->lighting) { + mstring_append(body, + " oD0.xyz += oD1.xyz;\n" + " oB0.xyz += oB1.xyz;\n" + ); + } + mstring_append(body, + " oD1 = specular;\n" + " oB1 = backSpecular;\n" + ); } if (state->ignore_specular_alpha) { mstring_append(body,