This is maybe a very stupid question.
Lets say i have a glVertex3f(0.78,0.45,0.21),
how do i calculate a normal for it?
This is maybe a very stupid question.
Lets say i have a glVertex3f(0.78,0.45,0.21),
how do i calculate a normal for it?
You can't really calculate a normal for a single vertex. A normal is a vector with length 1 that's perpendicular to the surface, and a surface needs a minimum of three vectors. If you're doing flat shading, you usually calculate one normal per polygon. If you're doing Gouraud shading, you usually calculate one normal per vertex so that you can interpolate between them.
To calculate the normal for a triangle, pick one vertex, subtract it from the other two, find the cross product of these other two, and normalize the resulting vector (divide each component by the vector's length).
To calculate the normal for a vertex, just average the normals for the triangles which use it.
All this stuff should be in the Red Book.
Hi !
You can not calculate a normal with only one vertex...
If you want a normal, you need at least a plane (3 points)... Then the normal for those 3 points could be the plane normal.
The thing is, if you do that, you won't have smooth shading.
I used to calculate my normals the following way :
1) For all my faces in the model, calculate the normal (normalized).
2) For all the vertices in the model, find which face they belong to. Add all the normals of these faces and normalize the result : you have your vertex normal.
I know many people will shout at me coz' it is a really simplistic approach......
In 2), you could multiply each normal you add by the surface of the face it belongs to. Then, you normalize... It means that the wider the face is, the most important is the contribution of its normal vector for the vertex normal....
Still in 2) : you do not always want to add all the normals of the faces the vertex belongs to.... Usually, you add them when the angle between the normals of two faces is more or less a certain limit angle (close to 0)... Otherwise you end up with a fully-smoothed object (which is stupid, say, for a cube !).
This might sound a bit confused (well, English is not my native language !) but the point is : you can not tell the normal of a vertex from its coordinates. In fact, you can never tell the normal of a vertex (from the mathematical point of view !).
Hope this will help....
Eric
P.S. : perhaps you should have a look on the net at normals generation...
well, the hell
if your vector is X, Y, Z
Nx = X / sqrt(X*X + Y*Y + Z*Z)
Ny = Y / sqrt(X*X + Y*Y + Z*Z)
Nz = Z / sqrt(X*X + Y*Y + Z*Z)
But, in the context of OpenGL, Vertex is not a vector (I mean starting from 0,0,0 to you)
But anyway....
(sorry for my badd inglish)
malkia@mindless.com
malkia/eastern.analog http://EasternAnalog.hypermart.net
BTW: Anybody got idea how to do fast normalization, I was thinking about NTAB[128][128][128], where NTAB[X][Y][Z] = X / sqrt(X*X+Y*Y+Z*Z), and X,Y,Z are from 0..1 (mapped to 0..127 though), I need it for my raycaster? any ideas? The other way is to rotate all my rays
Ok, but what if I have an eight sided polygon? Would I get an correct answer if I use the first three vertices? (assuming the face is 'flat')Originally posted by MikeC:
To calculate the normal for a triangle, pick one vertex, subtract it from the other two, find the cross product of these other two, and normalize the resulting vector (divide each component by the vector's length).
And doesn't it matter which sequences I use from the vertices, eg. (a-b, c-b) or (b-a, c-a) ?
John
Sjonny - yes, as long as your polygon is flat, you can generate a face normal from only three verts.
The order is important, and depends on your "front-facing" setting. For the default - frontfacing polys have vertices specified anticlockwise - pick three successive verts v1, v2 and v3 of your polygon in anticlockwise order. Then use the cross product of the vectors (v2-v1) and (v3-v1).
Just a precision MikeC : you can of course use any of three vertices of a flat polygon for calculating the normal providing THEY ARE NOT ALIGN ! Otherwise you end up with two colinear vectors and the dot product is nil... (not good for normalizing then !).
Well, this is just a special case but I thought it was worth mentioning it !
Eric
Eric - oops, yes, good point. Not sure why you'd have successive colinear verts in a polygon, but it's always the unexpected that trips you up.
You could also come unstuck if you picked three verts on a concave section of the polygon boundary - since your normal would then be pointing the wrong way - but that would probably serve you right for using concave polys.
Life is _so_ much simpler if you stick to triangles...
As a general rule, lookup tables are a bad idea on modern processors. You take more of a hit for thrashing the data cache than you would for just doing the calculation.Originally posted by malkia:
BTW: Anybody got idea how to do fast normalization, I was thinking about NTAB[128][128][128]
If you aren't too bothered about accuracy, there are fast algorithms to approximate the sqrt. Try a search for "Newton-Raphson iteration".
Yeah, MikeC, you are right, but I have also division - X / sqrt(X*X+Y*Y+Z*Z) - plus 3 multplications, also at the end i'll take BYTE, which i will use at another table - CTAB[256][256] which calculates tan(a)*tan(b)/( tan(a) + tan(b) )Originally posted by MikeC:
As a general rule, lookup tables are a bad idea on modern processors. You take more of a hit for thrashing the data cache than you would for just doing the calculation.
If you aren't too bothered about accuracy, there are fast algorithms to approximate the sqrt. Try a search for "Newton-Raphson iteration".
It's really weird. But algorithm i'm trying to implement is called "ACCELERATED RAY CASTING OF HEIGHT FIELD, USING INVERTED CONES"
So, at all I have 4.5MB (****in L2 is max 2MB) cache. But i don't care (for now)...
BTW: About optimization. I was trying to get ABSOLUTE value, without some JE, or JNE code, cause they causing bad pipelining
VC generates for labs(x) following
test eax, eax
jb down // or ja - can't think now at the moment
neg eax
down:
I'll rewrite this to:
int INLINE ABS32( int x )
{
return (x ^ (x>>31)) - (x >> 31);
}
which is i think - better (just on Pentiums only)