BackFace Culling and Normals

Started by
4 comments, last by Magallo 23 years, 11 months ago
something about normals..... I know that a normal of a face is a vector that is perpendicular to it and that is pointing out where the face is oriented. Example: the normal of the front face of a cube is 0.0f, 0.0f, -1.0f that is a vector along the z axis that points out the screen, is it right ? So I know that a normal is something that is associated with a face, a polygon, that is a triangle. This means that I have to specify a Normal vector per triangle that is one call to glNormal3f every three call to glVertex3f just like that: for(...every triangles...) { glNormal3f(...); glVertex3f(...); glVertex3f(...); glVertex3f(...); } Is it right ? The problem is that i saw a Normal example at http://nate.scuzzy.net in witch the normal vector is specified for EVERY vertex and not for every face like that: for(...every triangle...) { glNormal3fv(...); glVertex3fv(...); glNormal3fv(...); glVertex3fv(...); glNormal3fv(...); glVertex3fv(...); } What is the difference ? How can I determine a normal per vertex instead of a normal per Triangles ? I realized a class that load and display a 3ds object. In my Draw function I didn''t use glNormal3f at all. After reading your normal code I decided to use them in my code. I was able to calculate the face normals of my 3ds object and I added a glNormal3f line of code in my Draw function but the only one thing I was able to see is only a little loss in frame rate (about 4 or 5 frame per second less that before) but no any kid of improvement. So, what are normals used for ? I calculate my face normals in Load3DSFile function, that is that my normals are static, they never change, but when I translate or rotate the camera positin and also the object, does the normals are always the same or I have to recalculate them ? If I have to recalculate them, how can I do ? Backface culling.... In the same example there was a backface implementation that enable you to determine if a triangle is visible or not and then to decide to call glNormal and 3 glVertex to render it or not. This makes a great performance improvement. I know that there is a function called glEnable(GL_CULL_FACE). It does the same effects of or not ? What are the differences ? I am not able to determine if a triangle is visible or not and then to render it or not. I have a class called Camera that lets me to move the point of view freely in the world. I use a tips. I don''t use the gluLookAt function but simply I use glTranslate or glRotate so that the eye is always at 0, 0, 0 and all the rest of the world moves on the opposite way relatively of camera movements. Assume this typedef struct { x, y, z; }VECTOR; typedef struct { VECTOR pos; VECTOR rot; }CAMERA; typedef struct { VECTOR v[3]; }TRIANGLE; CAMERA eye; TRIANGLE tri; Assume that the absolute position of the eye is eye.pos.x, eye.pos.y and eye.pos.z and the orientation (expressed in degrees respect of the x,y,z axis) of the eye is eye.rot.x, eye.rot.y, eye.rot.z and that I have a triangle tri with coordinates tri.v[0].x, tri.v[0].y, tri.v[0].z tri.v[1].x, tri.v[1].y, tri.v[1].z tri.v[2].x, tri.v[2].y, tri.v[2].z How can I determine if my triangle is visible or not ? Wow! The post is huge, I''m very sorry for my poor english and for my noisy question but I''ll appreciate a lot if you could help me with these problems. Thanks in advance Matteo Galletti tripuno@tiscalinet.it
Advertisement
You can find the normal of a vertex by averaging the nearby face normals.
Use the dot product of the normal and the view-vector to find out if the triangle is visible. (this depends on the sign of the dot product, but you can use this value to perform flat-shading, e.t.c.)
Have a look at http://andyhot.di.uoa.gr:8080/ at the 3D Java Engine
Normals are used to calculate lighting for that face, depending on the normal, opengl (and a good number of other rendering methods) use the normal to calculate the shading for that face.

I''m not sure what the purpose of setting a normal for each vertex would be, probably for more acurate lighting, Direct3D-IM for example prefers a normal for each vertex.

Typically you only need to calculate and set normals once, again they''re used for lighting so unless you''re doing something strange with your lights you should only need to calculate normals once. If you''re using 3ds objects you really only need to read the vectors from the file and calculate per-face normals, if you REALLY want code to do per-vertex normals I can paste code but in my opinion it''s more of a pain in the ass and I''m satisfied with per-face shading for most of my programs.

As for the culling stuff, I haven''t experimented with it and have always used the built-in culling
*glEnable(GL_CULL_FACE)*.

Hope this is of some help to you..

Will.
This Space Left Blank
Per vertex normals are good when you want a sphere or torus to light up properly. If you you use face normals you will see the faces very clearly, but if you use a normal per vertex (that is the weighted normal of the normals of the surrounding faces) you get smooth lighting, and the sphere appears to be realy round (you don''t see the individual faces anymore).

Just as the face normals you calculate the vertex normals just once at the beginning of your program. (when you load the model).


Hope this helps,
Quo
eh.. well.. here''s how it is. the lambert shading model,
I = Ka + Kd(N dot L), is not well suited for polygonal models. here''s why: in the real world, flat surfaces are shaded evenly if you disregard distance falloff and specular lighting, but hardly anything is truly flat. polygonal models generally approximate curved surfaces with a bunch of flat facets, and if you try to shade these facets using constant lighting (which is what is going to happen if you use surface normals), the surface will appear, well, faceted. gouraud, bless his heart, thought of a way around that. instead of using surface normals, you can average the normals of the surfaces adjacent to a vertex to produce vertex pseudo-normals, plug those into the lighting equation of your choice and obtain interpolated shading across a surface. here''s how the vertex pseudo-normals are obtained:

for [each vertex]
{
set [vertex].normal to zero
set [counter] to zero

for [each face]
{
determine whether [vertex] belongs to [face]
add [face].normal to [vertex].normal
increment [counter]
}

divide [vertex].normal by [counter]
normalize [vertex].normal
}

hope this helps.

-goltrpoat


--
Float like a butterfly, bite like a crocodile.

--Float like a butterfly, bite like a crocodile.
Thanks to all of you guys,
now I have a little knowledge to try something.
I''ll keep you on date about it...

This topic is closed to new replies.

Advertisement