Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm learning some basics of OpenGL but I'm wondering why there is a call glNormal to set the normal of vertices.

If I create a simple triangle like this:

glBegin(GL_TRIANGLES);
    glVertex3f(0,0,0);
    glVertex3f(1,0,0);
    glVertex3f(0,1,0);
glEnd();

Shouldn't the normals be defined implicitly by the type of the geometric primitive? If I don't set a normal will OpenGL calculate it?

share|improve this question
6  
I would just like to point out that this code is using deprecated fixed-function pipeline, and in modern OpenGL both normals and vertices are just generic vertex attributes. –  Bartek Banachewicz Mar 8 '13 at 14:49
4  
Don't use immediate mode. It's deprecated. I highly recommend Learning Modern 3D Graphics Programming. –  rightfold Mar 8 '13 at 14:52
    
I think comment on use of immediate mode is completely irrelevant here. Yes, one shouldn't use it, but the point of the question remains the same irrespective of whether it's immediate mode, vertex arrays, VBO, generic attribs, fixed attribs, or bits of toast. –  Darth Satan Mar 8 '13 at 15:21
    
The reason it is not automatically determined is because it would make the lighting very polygony (for lack of a better word). What I mean by this is, all verticies on a triangle would have the same normal value. For flat surfaces this is what we would expect, however if you had a model of a persons face, each triangle on the face would have the same lighting value (making it very easy to see the polygons). By specifying your own normal values you can make things look much smoother (normally you find a normal by averaging the normal values of all triangles containing the current vertex). –  Benjamin Danger Johnson Mar 8 '13 at 17:40

4 Answers 4

up vote 21 down vote accepted

Calling glNormal multiple times between glBegin/End allows you to set a normal per vertex instead of per primitive.

glBegin(GL_TRIANGLES);
    glNormal3f(0,0,1);
    glVertex3f(0,0,0);
    glNormal3f(0,0,1);
    glVertex3f(1,0,0);
    glNormal3f(0,0,1);
    glVertex3f(0,1,0);
glEnd();

For a more complex mesh consisting of multiple triangles you would want the normal at one vertex depend on the other triangles of the surrounding geometry and not just the normal of the triangle it belongs to.

Here is an example of the same geometry with:

  • on the left per-vertex normals - so each vertex of a face has a different normal (for this sphere it means all normals point outward from its center), and
  • on the right per-face normals - each vertex gets the same normal value (since you specify it only once, or because it uses the default normal value of (0,0,1)):

per-vertex normals on the left, per-face normals on the right

The default shade model (GL_SMOOTH) causes the normals of the face's vertices to be interpolated across the face. For the per-vertex normals this results in a smooth shaded sphere, but for the per-face normals you end up with the characteristic faceted look.

share|improve this answer

The short answer is that you don't actually have to set a normal at all. Normal vectors are only used if you're performing OpenGL lighting (or perhaps some other calculation that may depend on them), but if that doesn't apply to you (or if you're using some other method to do lighting, e.g. lightmaps) then you can quite happily omit all glNormal calls.

So let's assume that you are doing something where specifying glNormal makes sense and look at it some more.

glNormal can be specified per-primitive or per-vertex. With per-primitive normals all that it means is that all of the normals for each vertex in the primitive face in the same direction. Sometimes this is what you want but sometimes it isn't - where per-vertex normals come in useful is that they allow each vertex to have it's own facing.

Take the classic example of a sphere. If each triangle in a sphere had the same normal then the end result would be quite faceted. That's probably not what you want, you want a smooth shading instead. So what you do is average the normals for each triangle that shares a common vertex, and get a smooth shaded result.

share|improve this answer

No, GL does not calculate a norm for you. It cant't know what the normal should be. Your primitives don't mean anything outside of rasterization (and a few other places). GL doesn't know which faces (triangles) share a vertex (calculating this at runtime is very expensive without using different data structures).

You need to preprocess a mesh's "triangle soup" to find common vertices and calculate normals. This should be done before the game runs for speed.

There are also cases like hard edges where geometrically there is a shared vertex at the corner, but you want separate normals so it lights correctly. In the GL/D3D rendering model, you need two separate vertices (at the same position) for this, each with a separate normal.

You'll need all this for UVs and texture mapping, too.

share|improve this answer

You need the glNormal to implement some features coder-dependant. For instance you might wish to create normals dat preserve hard edges.

share|improve this answer
4  
Perhaps you'll want to improve your answer a bit. –  Bartek Banachewicz Mar 8 '13 at 14:50
    
If you want me to improve my answer you would need to point out the weak spots. I can elaborate on it though. As xblax used to think, each normal "should" be calculated in the same way. Even despite the difference between interpolated normals for each pixel vs each face. Let's dwelve into the topic a bit more. –  Aron Boguta Mar 11 '13 at 14:05
    
Sometimes you might wish to maintain the hard edge and make it more distinctive. Here are some sample images : titan.cs.ukzn.ac.za/opengl/opengl-d5/trant.sgi.com/opengl/… PS. Sorry for double posting. I am new to the SE interface –  Aron Boguta Mar 11 '13 at 14:14
    
there's an "edit" button. –  Bartek Banachewicz Mar 11 '13 at 15:04
    
You cannot edit after 5 minutes –  Aron Boguta Mar 11 '13 at 22:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.