Amnesia used to be his favorite word, but then he forgot it! Concept 9.1 : Normal Vectors - Theory ===================================== What is so abnormal about Normals? and Why do computer graphics experts such as you need to associate with them ? Idea: ===== The normal is just the name of the vector that is perpendicular to a plane. For a flat surface one perpendicular direction is the same for every point on the surface but for a general curved surface, the normal direction might be different at each point on the surface. And all that effort you put into learning about lighting would be a waste and incomplete without knowing how normals affect lighting. The angle between (the normal to a surface), and the vector from the surface to the light source defines how much the surface is facing the light source and this information is used to compute how brightly the surface should be lit. A few common day normals we have already seen are: The Z-axis sticks straight out of the XY plane, which implies that the Z axis is the normal of the XY plane. Similarly the X axis is the normal of the YZ plane and so on. The Dot and Cross Products ========================== These two concepts of vector manipulation are necessary. So hark back to those good old linear algebra days, when life seemed better spent out of the classroom!. The Dot (.) Product: ==================== The dot product yields a numeric value. Hence it is a scalar value i.e. it has no direction associated with it. A dot product is symbolized by you guessed it a dot ('.') Consider two vectors A, B their dot product is obtained as follows : A.B = (Ax * Bx) + (Ay * By) + (Az * Bz) all we do here is to multiply the x, y and z components of each vector and then simply add them up The Cross (X) Product: ====================== The cross product is again a function of two vectors. The key point to remember is that the product of the cross product of two vectors is a vector i.e. it has both quantity and direction. Again consider two vectors A, and B . Their cross product will result in a vector C given as : C = A X B Cx = (Ay * Bz) - (By * Az) Cy = (Az * Bx) - (Bz * Ax) Cz = (Ax * By) - (Bx * Ay) and C happens to be perpendicular to both A and B!!. Try the above equations with some of the known coordinate axis. eg. A(1,0,0) x B(0,1,0) (our good old X-Y plane) should yield C = (0, 0, 1) i.e. the Z axis as one would expect. Remember that the cross product of two vectors is not commutative. i.e. A X B is not the same as B X A. In fact, B X A is the exact opposite vector of A i.e. its the same line, just pointing in the opposite direction. The Length of a Vector: ======================= One more mathematical tool which comes in handy when dealing with vectors is their lenght. This is given by the simple formula shown below : If a vectors coordinates are (x, y, z) then the length of this vector is given as /--------------- length = \__/ x^2 + y^2 + z^2 Normal Vector Calculation for a Polygon ======================================= Say we have a polygon as shown below bounded by points P1, ... P4 : --> P2 A .--------- . \ P1 \ -->\ B\ \ . P3 . P4 o Get two tail-to-tail vectors from the polynomial. o Label them as A and B. How do we know which one to label A and which one to label B?. Well to do this properly you have to be a little innovative. When rendering objects make sure that the vertices of the faces go in either a consistent Clockwise (CW) fashion or a counter-clockwise (CCW) manner. Then you start at a consistent point in the polygon (eg the first vertex) and you know the association between points and vectors. In our case we have labelled P2P1 as vector A and P2P3 as vector B. o Now we actually assign values to the vectors A and B as follows: A = (P1 - P2) B = (P2 - P3) o Now just use the crossproduct formula described above and we get our normal vector. There still remains one more step towards accomplishing our goal. o THE NORMALIZED NORMAL VECTOR : Yes we need to normalize our normal vector so that it has unit length. o To accomplish the above step calculate the length of the normal vector using the formula for lenght of a vector. o Once you know the length of the vector, divide the x, y, and z components of the normal vector by its length. This gives a normalized normal vector!! A Real World Example ==================== What good is all this theory if we cant have an example to trust it. Lets assume the following : P1 = (4, 3, 0) P2 = (2, 4, -1) P3 = (-2, -3, 1) P4 = (3, -4, 2) then vector A going from P2 to P1 is given as : A = (P1 - P2) = (4 - 2)x, (3 - 4)y (0 - (-1))z = (2)x, (-1)y, (1)z = (2, -1, 1) Similarly vector B is given as follows: B = (P2 - P3) = (2 - (-2))x, (4 -(-3)) y, (-1 - 1)z = (4)x, (7)y, (-2)z = (4, 7, -2) Now find out the cross product i.e. AXB Let C = AxB then C is given as follows: Cx = (Ay *Bz) - (By * Az) = (-1 * -2) - (7*1) = 2 - 7 = 5 Cy = (Az * Bx) - (Bz * Ax) = (1 * 4) - (-2 * 2) = 4 + 4 = 8 Cz = (Ax*By) - (Bx * Ay) = (2 * 7) - (4 * -1) = 14 + 4 = 18 Therefore the normal vector is given as: C = (5, 8, 18) The length of this normal vector is given as length = sqrt ( 5^2 + 8^2 + 18^2) = sqrt(25 + 64 + 324) = sqrt(413) = 20.322401 Therefore the normalized normal vector is given as C = (5/length, 8/length, 18/length) Wow, does this mean we have to go through all these calculations in setting up normals. Not really. Normal vectors remain normalized as long as your model transformations include only rotations and translations. If you perform irregular transformations such as scaling or multiplying by a shear matrix or if you specify non-unit length normals then you should have OpenGL automatically normalize your normal vectors after the transformations. To do this call glEnable() with GL_NORMALIZE as its arguement. Setting the Normal in OpenGL ============================ Use glNormal*() to set the current normal to the value of the arguement passed in. Subsequent calls to glVertex*() cause the specified vertices to be assigned the current normal. Often each vertex has a different normal, which necessiates a series of alternating calls.