From: Petrichor Park ppark@codeweavers.com
DirectX's FFP normalizes the zero vector to the zero vector, but GLSL normalizes them to all NaN.
This patch creates `ffp_normalize`, which normalizes vectors but has DirectX's behavior on 0 vectors. Further patches in this set switch other calls from GLSL's `normalize` to the 0-safe version.
This fixes [36564](https://bugs.winehq.org/show_bug.cgi?id=36564). --- dlls/wined3d/glsl_shader.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 7dc0de1b596..67562d33205 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -9071,6 +9071,11 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr declare_out_varying(gl_info, buffer, FALSE, "float ffp_varying_fogcoord;\n"); }
+ shader_addline(buffer, "\nvec3 ffp_normalize(vec3 n)\n{"); + shader_addline(buffer, " float lensq = dot(n, n);\n"); + shader_addline(buffer, " return lensq == 0.0 ? n : (n * inversesqrt(lensq));\n"); + shader_addline(buffer, "}"); + shader_addline(buffer, "\nvoid main()\n{\n"); shader_addline(buffer, "float m;\n"); shader_addline(buffer, "vec3 r;\n"); @@ -9132,7 +9137,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr }
if (settings->normalize) - shader_addline(buffer, "normal = normalize(normal);\n"); + shader_addline(buffer, "normal = ffp_normalize(normal);\n"); }
shader_glsl_ffp_vertex_lighting(buffer, settings, legacy_lighting); @@ -9173,11 +9178,11 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR: shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u]" - " * vec4(reflect(normalize(ec_pos.xyz), normal), 1.0);\n", i, i); + " * vec4(reflect(ffp_normalize(ec_pos.xyz), normal), 1.0);\n", i, i); break;
case WINED3DTSS_TCI_SPHEREMAP: - shader_addline(buffer, "r = reflect(normalize(ec_pos.xyz), normal);\n"); + shader_addline(buffer, "r = reflect(ffp_normalize(ec_pos.xyz), normal);\n"); shader_addline(buffer, "m = 2.0 * length(vec3(r.x, r.y, r.z + 1.0));\n"); shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u]" " * vec4(r.x / m + 0.5, r.y / m + 0.5, 0.0, 1.0);\n", i, i);