   transforming vertex normals
  okay, i need to do a little explaining first. I''m building a simple software rasterizer and an accompanying API that is modeled off of OpenGL (a very basic version of OpenGL). It''s coming along pretty well so far. I have a rotating cube in the screen that''s being lit by three different kinds of lights. It also has point sampled textures applied to it. The front end code looks very very similar to OpenGL. It''s kind of neat! Things left to do with the API are to include the option for bilinear texture filtering, fix some issues with clipping against the near plane, add support for a simple zbuffer, add support for alpha blending... there''s a lot left to do. but i''m having a LOT of fun with the project. And I''m learning a lot too, always a plus. Okay, here''s where I''m having a problem. I am running into a very strange error with this rotating cube demo. I know that I''m dealing with an orthogonal ModelView matrix, so the vertex normals can be transformed by the same matrix used on the vertices themselves (according to Eric Lengyel''s "Mathematics for 3D Game Programming and Computer Graphics", awesome book btw). So rather than go through the trouble of having to create an inverse transpose matrix of the current MV matrix every time it''s modified, i just use the MV matrix. The front, back, left, and right faces are illuminated correctly (with gouraud shading, it''s cool). However, the top and bottom faces are being illuminated. I''ve looked over a printout of the current MV matrix and the current normal the normals for the top and bottom face are not being transformed correctly. Here''s an example of the printout:CurrentNormal=[0.000000, 1.000000, 0.000000, 1.000000, ]MODEL_VIEW=1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 -4.000000 0.000000 0.000000 0.000000 1.000000 INV_MODEL_VIEW=1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 CurrentNormal=[0.000000, 1.000000, 0.000000, 1.000000, ]MODEL_VIEW=1.000000 0.000000 0.000000 0.000000 0.000000 0.999550 0.029995 0.000000 0.000000 -0.029995 0.999550 -4.000000 0.000000 0.000000 0.000000 1.000000 INV_MODEL_VIEW=1.000000 0.000000 0.000000 0.000000 0.000000 0.999550 0.029995 0.000000 0.000000 -0.029995 0.999550 0.000000 0.000000 0.000000 0.000000 1.000000 CurrentNormal=[0.000000, 0.999550, -0.029995, 1.000000, ]MODEL_VIEW=1.000000 0.000000 0.000000 0.000000 0.000000 0.998201 0.059964 0.000000 0.000000 -0.059964 0.998201 -4.000000 0.000000 0.000000 0.000000 1.000000 INV_MODEL_VIEW=1.000000 0.000000 0.000000 0.000000 0.000000 0.998201 0.059964 0.000000 0.000000 -0.059964 0.998201 0.000000 0.000000 0.000000 0.000000 1.000000 CurrentNormal=[0.000000, 0.998201, -0.059964, 1.000000, ]MODEL_VIEW=1.000000 0.000000 0.000000 0.000000 0.000000 0.995953 0.089879 0.000000 0.000000 -0.089879 0.995953 -4.000000 0.000000 0.000000 0.000000 1.000000 INV_MODEL_VIEW=1.000000 0.000000 0.000000 0.000000 0.000000 0.995953 0.089879 0.000000 0.000000 -0.089879 0.995953 0.000000 0.000000 0.000000 0.000000 1.000000 CurrentNormal=[0.000000, 0.995953, -0.089879, 1.000000, ]Note that the INV_MODEL_VIEW matrix is the same as the modelview except for the translation portion, i just have separate matrices for correctness. In this example, the top face is being rotated forward (out of the screen, so as to become visible). The z-coordinate of the vertex normal should become more positive, which would be the same as pointing out of the screen. But, it''s going in the opposite direction. Note that the transpose of the transformation matrix would transform the normal in the correct way. Well, to make a long story short, i tried using the transpose of the MV matrix and the inverse transpose, but neither technique worked correctly. I''ve poured over all the code and even gone through all the calculations by hand. Everything is mathematically correct but the numbers aren''t what they should be. So there must be something wrong with the technique I''m using? I''m sorry if this post is vague. The problem involves a lot of code and is kind of complicated in and of itself. Thanks in advance for any help or advice you can give me. I''m all out of ideas. -Justin 
  I'm not quite sure I follow your listing, are those normals pre or post transform or a mix?  Are they supposed to be homogenous? (in which case the w coordinate must be 0, you don't want them translated) Or is that trailing 1 the length?I'm pretty sure (but I haven't gone through it) that your technique should be working correctly.   [edited by - JuNC on August 17, 2003 6:04:17 PM];  hey JuNC. the initial normal is [0.0, 1.0, 0.0, 1.0] and all the normals in the listing are post transformation by the INV_MODEL_VIEW matrix. I know, i can''t figure out why my technique isn''t working. it''s messed. I''m so confused haha.  ;  Here''s what I think (though I might be wrong).You can''t use a matrix that has a translation to transform your normals, the matrix that transforms the normal must be purely a rotation. If you translate the normal, and then normalize it, you probably won''t notice that you''ve done something wrong, but the direction that the normal points will be completely wrong.So you know where to find the translation part of a matrix, right? Its the top 3 entries on the right side (which includes the -4 on the modelview matrix in your example). So, try transforming the normal with the translation set to 0 and see if that works. ;  Note that Eric uses 3x3 matrices in his description, the 4x4 counterpart of which has zero translation, as previously mentioned. ;quote:hey JuNC. the initial normal is [0.0, 1.0, 0.0, 1.0] and all the normals in the listing are post transformation by the INV_MODEL_VIEW matrix. If that vector is [x,y,z,w] then it is wrong.  Vectors in 3 space *must* have a w of 0.  Only (3 space) points have a w of 1.  You can either break out two transform routines (one that ignores the final column of the matrix for vectors) like the above two solutions, or store the w's correctly. [edited by - JuNC on August 18, 2003 5:35:37 AM];  use n = [x,y,z,0], and transform that trough the inverse transpose matrix.why? i''ve read in some nvidia document why..   "take a look around" - limp bizkitwww.google.com ;  just a reminder:to transform vertex normals with matrix that has perspective effect, you need to transform the full plane equation (x,y,z,d), instead of just the normal (x,y,z,0).see transform normals;  To start with, I took an identity matrix and rotated it on all 45 degrees in each direction I could, x, y, and z. 0.50000  0.50000 -0.70711  0.00000-0.14645  0.85355  0.50000  0.00000 0.85355 -0.14645  0.50000  0.00000 0.00000  0.00000  0.00000  1.00000Then I pick a resulting ray, I take the Z one.  I just did this to get a normal, that's all, normally(grin) you'll already have the normal before you want to transform it.  A normal is a ray, is an axis, or whatever you want to call it.I load another identity matrix and drop these X Y and Z components for this matrix in to the corresponding position spots. 1.00000  0.00000  0.00000  0.85355 0.00000  1.00000  0.00000 -0.14645 0.00000  0.00000  1.00000  0.50000 0.00000  0.00000  0.00000  1.00000The transformed normal is 0.85355, -0.14645, 0.50000I can now multiply this matrix by any rotation matrix, the result should be a properly tranformed normal.Rotated by -45 degress on the X axis: 1.00000  0.00000  0.00000  0.85355 0.00000  0.70711 -0.70711 -0.45711 0.00000  0.70711  0.70711  0.25000 0.00000  0.00000  0.00000  1.00000Looks good, as expected, X component doesn't change when rotated about the X axis.Ok, I'm ready for somebody to tell me how I did this wrong.  I already know there MUST be a better way to do it, I just wanted to chime in and hopefully provoke some better answers.   [edited by - wudan on August 18, 2003 4:04:02 PM] [edited by - wudan on August 18, 2003 4:11:26 PM];  I have no idea what you are talking about A normal is a vector representing a plane.  Rays are something very different (position & direction). You could all it an axis but probably don''t want to.  Explain what you are trying to do and we''ll tell you whats wrong.quote:1.00000 0.00000 0.00000 0.853550.00000 1.00000 0.00000 -0.146450.00000 0.00000 1.00000 0.500000.00000 0.00000 0.00000 1.00000The transformed normal is 0.85355, -0.14645, 0.50000Explain how you got this.  Sounds like something is severely wrong. 