Transforming Normals
Home | glhlib | GLU |
Problem Statement
You Can't Just Transform It
It should be obvious that merely transforming the normal by the object to world space transformation matrix won't work.
For example, it obviously won't work if the object to world space transformation is a translation.
If you think about it, you'll see it won't work if the transformation
is a non-uniform scale; angles are not preserved by non-uniform scale.
Solution
Consider the planar equation for a group of points:N = [a b c d] (remembering that the normal vector is [a b c]) P = [x y z 1] NPT = 0 (remember the plane equation a*x + b*y + c*z + d = 0)Assume the transformation matrix is M, then we want the transformed planar equation, (N' this is also the transformed normal vector we are interested in) to satisfy:
N'MPT = 0 (where MPT is a transformed point)of course,
NM-1MPT = 0 (since NPT = 0)so we get what we want if we transform the planar equation thusly,
N' = NM-1or by using column vectors and post-multiplying by the transformation matrix:
N'T = (NM-1)T = (M-1)TNT
Conclusion
And there you have it. To transform a normal using a homogenous transformation
matrix to world space you have to multiply it by the inverse transform matrix.
That is to say, first invert the matrix, then transpose the inverse.
I have created a freeware library called glhlib
that contains the functions for doing these. It goes well with projects written in
OpenGL.
In Block 12 (SOFTWARE MATRIX OPERATIONS. DOES NOT USE OPENGL), there is a bunch of
functions for doing matrix operations in software :
We would use it like this :
GLfloat WorldMatrix[16], InverseWorldMatrix[16], ITWorldMatrix[16];
glhQuickInvertMatrixf2(WorldMatrix, InverseWorldMatrix);
glhTransposeMatrixf2(ITWorldMatrix, InverseWorldMatrix);
//Now ITWorldMatrix contains our matrix of interest
//Let's transform a normal
GLfloat ObjectSpaceNormal[4], EyeSpaceNormal[4];
//This functions assumes w is 0.0
//The value 4 is submitted because we have 1 normal, and it has 4 elements, so 1*4 = 4!
glhMultiplyMatrixByVector4by4f_3(4, ObjectSpaceNormal, ITWorldMatrix, EyeSpaceNormal);
The SSE or 3DNow version of MultiplyMatrixByVector has not been written as of this writting.
|
This page is http://www.oocities.org/vmelkon/
This page is http://ee.1asphost.com/vmelkon/
Copyright (C) 2001-2005 Vrej M. All Rights Reserved.