Help: How to create normals for polygons with 5+ vertices?

Started by
9 comments, last by mikeman 19 years ago
Hi everyone, After doing all the reading on how to create normals for a few days, I'm going a bit berserk. I know by now how to create normals for tris and quads, but how about normals for faces made up of more than 4 vertices? I disected every example I could find, but I'm at a loss. Nate Robbins' GLM has a nice routine, but it triangulates my models. Here's what I have: a huge list of vertices (some models are over 60Mb in size) and a list of faces referencing the vertices. Some models have faces of 10 or more vertices. For starters, how do I get nicely faceted models? My math sucks, so a bit of pseudo code would be appreciated. I also would like to know what to do to get smooth normals. Here's the code I created (in Delphi pascal), the best idea I came up with so far was to normalise each vertex and use that normal for each vertex in a face. With a poor result. I know I'm missing some point, just can't figure out what... Please help me out! Thanks... The code: function NormalizeVertex(v: TVertex): TNormal; var l : single; begin l := 1 / sqrt((v.x * v.x) + (v.y * v.y) + (v.z * v.z)); if (l = 0.0) then l := 1.0; Result.i := v.x * l; Result.j := v.y * l; Result.k := v.z * l; end; function GetCross2Normal(var v1, v2: TVertex): TNormal; var n1 : TVertex; begin n1.x := v1.y * v2.z - v1.z * v2.y; n1.y := v1.z * v2.x - v1.x * v2.z; n1.z := v1.x * v2.y - v1.y * v2.x; Result := NormalizeVertex(n1); end; function GetCross3Normal(var p1, p2, p3: TVertex): TNormal; var v1, v2, n1 : TVertex; begin v1.x := p1.x - p2.x; v1.y := p1.y - p2.y; v1.z := p1.z - p2.z; v2.x := p2.x - p3.x; v2.y := p2.y - p3.y; v2.z := p2.z - p3.z; n1.x := v1.y * v2.z - v1.z * v2.y; n1.y := v1.z * v2.x - v1.x * v2.z; n1.z := v1.x * v2.y - v1.y * v2.x; Result := NormalizeVertex(n1); end;
Advertisement
Hello,

If you want to generate normals to 5+-sided polygons, you end up with 2 choices:

1) your polygon is planar: choose 3 points wich are not aligned, and Do The Work.
2) your polygon is not planar: triangulate. It should be obvious that these are not valid polygons, and you should not deal with them.

Or maybe I didn't understand and you want to compute per-vertex normals. In this case, you still have to compute per-face normals. The normal of a particular vertex N is the average of the normal of the adjacent faces.

HTH,
Hi Emmanuel,

Would it be save to assume that when have a triangle that I can use my GetCross2Normal() and with quads GetCross3Normal() ?

Also, would it be an idea to calculate some average vertex of all the vertices in a face and normalize that?

And, before I dive into the net again for a few days, how do I figure out which vertices are not aligned ?

And no, I want per-face normals. It's hard enough to get that working.

B.T.W. I am using Wavefront OBJ models...
Hello,

In order to determine whether the 3 points are aligned, you can formed two vectors from the three points you have, and do a dot product of these two vectors to see whether the two vectors is facing the same direction, or exaclt the opposite direction. If yes, then the three points are aligned.

Eg

bool IsAligned(Point p1, p2, p3)
{
Vector v1 = p1 - p2;
Vector v2 = p3 - p2;

if (DorProduct(v1, v2) is almost equal (-1))
return true;
return false;
}

And I think your assumption is correct, it should be safe to use GetCross2Normal() for traingle and GetCross3Normal() for quads?

Wish it help!
Nachi Lau (In Christ, I never die)www.sky-dio.com/Nachi
Use Newell's Method for computing the normal for polygons with more than three vertices. See my post here, with source code.

The variable "sum" normalized, is the normal (the example shows how to compute the area).

Here's another link from Graphics Gems III.

Graphics Gems Series
Thanks all, at least I have some new points of view I can test...
There's vertex normals for smooth shading and there's poly normals for flat shading, so it depends on what kind of normals err type of shading you want.
Is it not a little unusual to get models with >4 sides? Triangles are obviously the most common but quads wouldn't be too surprising, but why have a model with 10-sided polys, it's just asking for trouble? Even if they are planar then you can get odd results from floating point rounding effects making the poly non-planar. I'd personally triangulate every non-triangular polygon first to get a more standard model.
Unless there is something I've not understood - where are these models sourced? 60MB means they must have around 1million vertices right?

But if they are planar polys then just get the normal from 2 edges of the poly as you would for a triangle.
I'd like to be able to do both kinds of smoothing, flat and smooth. I am fairly new at 3D programming, however, so I'm taking it one step at a time.
Tris and quads are obviously most convenient to handle, but if I want to exchange models with others, I can't keep changing the buildup of polygons to my liking. Furthermore, I am working with Poser 5 (Curious Labs) and would like to create morphs for available models, another reason why I simply can't change the structure of models.

My 60Mb model is actually 1.45mln vertices, wich urges me to tackle a performance problem too...

Here's a link to an example OBJ file, a 3D globe with faces made up of 10+ vertices:

Globe

[Edited by - maxxarcher on March 30, 2005 2:57:54 AM]
For flat shading.. just pick 2 edges and do a cross product. It simply does not matter how many edges the polygon has as long as its a real flat polygon. Any two edges describe the orientation of the plane the polygon forms.

For calculating vertex normals.. for each shared FACE connected to a vertex you calculate its normal and the ange between the two edges of the face that touch the vertex.. scale the normals based on the this angle so that small angled faces do not contribute as much as the large angled faces. The proper proportion is Angle / SumOfAllAngles. Sum up all these scaled normals, normalize it, and you have the proper vertex normal.

This topic is closed to new replies.

Advertisement