Sign in to follow this  

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

This topic is 4675 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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;

Share this post


Link to post
Share on other sites
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,

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
IMO, the best solution is simple: Triangulate. Everything else is just creating trouble for nothing. If you're using a rendering API(OpenGL or D3D), polygons are converted to triangles anyway before they're sent to the graphics card.

Just make a function that takes a N-vertex face and converts it to triangles. It's pretty simple and straightforward. You don't need more memory to store the geometry, since you're not addding any vertexes, triangles can share vertexes. And you can use triangle fans or strips for even more performance. In fact, I think that using triangle fans is exactly the same as using N-sided polygons, it's just a difference in perception.

If you really want to work with the model as is, then when calculating normals just do a temporary triangulated copy of the model, and use it just for that purpose. Attach the calculated vertex normals to the original model, and you're set.

Share this post


Link to post
Share on other sites

This topic is 4675 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this