{"id":98,"date":"2013-11-08T15:46:23","date_gmt":"2013-11-08T15:46:23","guid":{"rendered":"\/\/3dbym.ru\/2013\/11\/calculating-face-normals\/"},"modified":"2013-11-08T15:46:23","modified_gmt":"2013-11-08T15:46:23","slug":"calculating-face-normals","status":"publish","type":"post","link":"https:\/\/3dbym.ru\/2013\/11\/calculating-face-normals\/","title":{"rendered":"Calculating Face Normals"},"content":{"rendered":"
If you want to have lighting in your scene, it is essential to have at the very least a normal vector for each triangle. Failure to do this will cause certain parts of the model to be unlit, or lit in a peculiar way.<\/p>\n
There really isn\u2019t anything to calculating a face normal. Follow these steps:<\/p>\n
1. First, you need two vectors in the plane of the triangle. Because you have three points that lie within the plane (the vertices of the triangle), it is easy to create two vectors. Going back to algebra or geometry, you might remember that a vector can be found by taking the terminal point minus the initial point. The points of the triangle are these points. The first vertex of the triangle (Vertex0) can be considered the initial point for both vectors, the second and third vertices are the terminal points of the first and second vectors (Vector1 and Vector2) respectively. Therefore, Vector1 will be Vertex1 minus Vertex0, and Vector2 will be Vertex2 minus Vertex0.<\/p>\n
2. A vector normal to the triangle points straight up at a 90-degree angle to the triangle\u2019s plane. Taking the cross product of the two vectors you just found will yield a single vector, orthogonal to the plane. It is important that you always take the cross product in the same order. The vector produced by crossing Vector1 with Vector2 (Vector1XVector2) is not the same as the vector produced by crossing them the other way (Vector2XVector1). The two opera\u00adtions will produce vectors pointing in opposite directions. If some of your faces appear to be lit incorrectly, make sure you are<\/p>\n<\/p>\n
computing your vectors and cross products correctly. However, if all of your faces are lit incorrectly, try crossing your vectors in the opposite order. The normals may be pointing into the model, rather than out of the model, as they should be.<\/p>\n
3. Before you send this vector to the renderer, be sure to convert it to a unit vector. Remember that a unit vector must have a magni\u00adtude of one. To create a unit vector, you divide each individual component of the vector by the vector\u2019s original magnitude. This can be done manually, or you can use the Normalize func\u00adtion of the CVector3 class.<\/p>\n
Take a look at this chapter\u2019s first demo, found on the CD in the Code\/ Chapter10\/Normals\/ directory, for a demonstration of face normals.<\/p>\n
Calculating Vertex Normals<\/a><\/p>\n The other type of normal is called the vertex normal. Now, instead of one normal for each polygon, one normal is used for every vertex.<\/p>\n Why use vertex normals instead of face normals? The answer is simple\u2014using vertex normals gives you a much nicer looking model. Instead of each polygon being flat-shaded, the lighting is now interpo\u00adlated between the vertices, giving a nice smooth shade.<\/p>\n Figures 10.1 and 10.2 compare the visual difference between vertex and face normals. Quite a difference, eh?<\/p>\n Calculating vertex normals is not difficult. The first thing to do is calcu\u00adlate all of the face normals. Then, for each vertex, you must determine which faces share that vertex. Once you find all of them, add up all of those faces\u2019 normals, and divide by the number of shared faces. This will give you a new unit vector, which is called the vertex normal.<\/p>\n \/\/pseudocode to calculate vertex normals from face normals for each vertex for each face<\/p>\n if face contains vertex<\/p>\n add the normal of the face to the normals of any other faces that share the vertex to obtain the final normal for the current vertex<\/p>\n divide the vector calculated by adding all the face normals together by the number of faces sharing the vertex<\/p>\n <\/p>\n Creating Your Own Format<\/a><\/p>\n Creating your own 3D model format can be very beneficial to your game. By \u201crolling your own,\u201d you can include whatever data you need, from vertices to animations in whatever order and whatever form you want. You can also include other data such as textures or even game — specific data such as character dialogue. Best of all, you are not limited by the constraints of an existing format, and you can change the format to fit your needs as you go.<\/p>\n The first thing you must decide about your format is whether it will be stored in text or binary form. Both ways have advantages and disadvan\u00adtages, discussed in the following sections.<\/p>\n Text-Based Format<\/a><\/p>\n If the format is stored in a text-based form, you sacrifice some storage space for readability. A text-based format will generally take up more room, due to each character using a full byte (\u201c255\u201d will take three bytes in text, only one in binary). Space may be a lower priority than, for instance, readability. Most text-based formats can be opened in a text editor and modifications can be made to the data without need-<\/p>\n <\/p>\n ing a full-fledged editor. This makes it easy to do simple things such as change the textures on the model or even tweak vertex positions.<\/p>\n Another downside to text-based models shows up when you go to load them. Text files can be a real pain to parse, particularly if small mistakes such as an extra space, or a blank line, are inserted at an odd place.<\/p>\n
\n ■<\/p>\n<\/td>\n<\/tr>\n<\/table>\n What else will the face information contain? Obviously it must contain indexes into the vertex array, but what about material information, texture coordinates, or normals? All these things can be stored with the faces as well.<\/p>\n
|