From bc69315f7867e86c287c4a2c47bf6e3dadb67203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Wed, 12 Sep 2007 23:46:47 +0200 Subject: [PATCH] wined3d: texm3x3(v)spec normalizes the normal vector. --- dlls/wined3d/arb_program_shader.c | 19 +++++++++++++++++-- dlls/wined3d/glsl_shader.c | 11 +++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 08ecfd1bdf8..0cbe75a41e9 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -872,8 +872,13 @@ void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg) { shader_addline(buffer, "MOV TMP2.y, fragment.texcoord[%u].w;\n", current_state->texcoord_w[1]); shader_addline(buffer, "MOV TMP2.z, fragment.texcoord[%u].w;\n", reg); - /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */ + /* Calculate reflection vector + */ shader_addline(buffer, "DP3 TMP.w, TMP, TMP2;\n"); + /* The .w is ignored when sampling, so I can use TMP2.w to calculate dot(N, N) */ + shader_addline(buffer, "DP3 TMP2.w, TMP, TMP;\n"); + shader_addline(buffer, "RCP TMP2.w, TMP2.w;\n"); + shader_addline(buffer, "MUL TMP.w, TMP.w, TMP2.w;\n"); shader_addline(buffer, "MUL TMP, TMP.w, TMP;\n"); shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -TMP2;\n"); @@ -896,8 +901,18 @@ void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg) { pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name); shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name); - /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */ + /* Calculate reflection vector. + * + * dot(N, E) + * TMP.xyz = 2 * --------- * N - E + * dot(N, N) + * + * Which normalizes the normal vector + */ shader_addline(buffer, "DP3 TMP.w, TMP, C[%u];\n", reg3); + shader_addline(buffer, "DP3 TMP2.w, TMP, TMP;\n"); + shader_addline(buffer, "RCP TMP2.w, TMP2.w;\n"); + shader_addline(buffer, "MUL TMP.w, TMP.w, TMP2.w;\n"); shader_addline(buffer, "MUL TMP, TMP.w, TMP;\n"); shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -C[%u];\n", reg3); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 9155a453eac..664ab618187 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1899,10 +1899,8 @@ void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg) { /* Perform the last matrix multiply operation */ shader_addline(buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str); - - /* Calculate reflection vector, 2*(tmp0.src1)*tmp0-src1 - * This is equivalent to reflect(-src1, tmp0); */ - shader_addline(buffer, "tmp0.xyz = reflect(-(%s), tmp0.xyz);\n", src1_param.param_str); + /* Reflection calculation */ + shader_addline(buffer, "tmp0.xyz = -reflect((%s), normalize(tmp0.xyz));\n", src1_param.param_str); shader_glsl_append_dst(buffer, arg); shader_glsl_get_write_mask(arg->dst, dst_mask); @@ -1936,10 +1934,7 @@ void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg) { /* Construct the eye-ray vector from w coordinates */ shader_addline(buffer, "tmp1.xyz = normalize(vec3(gl_TexCoord[%u].w, gl_TexCoord[%u].w, gl_TexCoord[%u].w));\n", current_state->texcoord_w[0], current_state->texcoord_w[1], reg); - - /* Calculate reflection vector (Assume normal is normalized): RF = 2*(tmp0.tmp1)*tmp0-tmp1 - * This is equivalent to reflect(-tmp1, tmp0); */ - shader_addline(buffer, "tmp0.xyz = reflect(-tmp1.xyz, tmp0.xyz);\n"); + shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n"); shader_glsl_append_dst(buffer, arg); shader_glsl_get_write_mask(arg->dst, dst_mask);