Stefan Dösinger : wined3d: texm3x3(v) spec normalizes the normal vector.

Alexandre Julliard julliard at winehq.org
Thu Sep 13 07:17:27 CDT 2007


Module: wine
Branch: master
Commit: bc69315f7867e86c287c4a2c47bf6e3dadb67203
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bc69315f7867e86c287c4a2c47bf6e3dadb67203

Author: Stefan Dösinger <stefandoesinger at gmx.at>
Date:   Wed Sep 12 23:46:47 2007 +0200

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 08ecfd1..0cbe75a 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 9155a45..664ab61 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);




More information about the wine-cvs mailing list