normals

Started by
12 comments, last by gunning 18 years, 8 months ago
Let's say you are given a 3d model comprised of triangles, but it doesn't come with the normals. Now, let's say you need the normals for lighting purposes. Let's also say that the vertices of the triangles are in arbitrary order. Since there are two potential normals for each triangle, what is the best way of determining which normal is best? (i.e. which points outward) Mike http://www.coolgroups.com/
Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/
Advertisement
Maybe you'd have better luck someplace other then the lounge. [wink]
I would test it against adjacent normals to see if the one calculated is greater then or less then some delta. Mind you this will fail on sharp corners though, and you will have to come up with a way to ensure that the first normal is correct.
How are you supposed to get these adjacent normals?

Mike
http://www.coolgroups.com/
Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/
Unless you have other information (e.g. smoothing groups), the standard normal you use for a vertex is the average of the face normals of all faces which use that vertex.

Other contexts such as tangent space do complicate matters of course (for example the basis not always being orthonormal) - but for "normals" in the traditional sense, unless you have any other information about topology or form, averaging is the "correct" thing to do.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Calculate one normal, then move on to calculate the next. Now if the next if by definition beside the last one (because of shared vertecies) then your all set. Otherwise you will have to use some algorithm to find a polygon containing a vertex that is within an error range of a given vertex in the previous polygon. In the case to the later, I *highly* advise you then store that information back into a file (I recommend a custom format, as you are writing it you may as well get all the flexibility you can get) as the algorithm will probably be to time consuming to perform at run or load time.

Otherwise if the vertecies are shared then it is a search through the polygon list to find the first one that contains a given vertex from the last polygon you worked on. In the end you will probably have some untouched polygons (be sure to keep track of the polygons done). These you may have to do individually. Take a vertex from the polygon that has not been touched and search for another polygon that shares that vertex. The polygon you find is adjacent to your current one and its normal may be used to calculate which way the current polygon's normal should face.

Hope that helps.

[edit] If I am interpreting the OP correctly it is the face normals he is after, not the vertex normals. I could be wrong here however.
You say "Calculate one normal, then move on to calculate the next."

How do you calculate this one normal? There are two possible normals - which one do you choose?

Mike
http://www.coolgroups.com/
Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/
Thats the real trick. You will have to look at what information you have and what assumptions you can make. One option is that if you build this into a tool you may use user input to select the direction of the first normal. This would be the most straight forward. Otherwise you are going to have to make an educated guess. How you make this guess depends on the assumptions you can make about your data.

Or another option is to just randomly chose a facing for that first normal and then when the model is completely normalized perform a hit test of a line that starts clearly away from you model and pierces it at some point. Find the polygon it pierces and then test to see if the normal of that polygon is facing relatively toward the source of the line (ie facing outside). If not then flip all the normals.

To the best of my knowledge there is no easy way to address this, so just take it slow and think through what you are doing and you should be able to figure something out.
Quote:Original post by mike74
You say "Calculate one normal, then move on to calculate the next."

How do you calculate this one normal? There are two possible normals - which one do you choose?

Mike
http://www.coolgroups.com/


As long as you start from one area and move out from there, the surface should have consistent normals all across (and around, etc.)..

The first normal could be either way, the others would follow, as long as you don't randomly pick new starting points in the mesh..

Once all normals are calculated, you can visually examine the result and flip them all the other way if needed..

Unfortunately there are no defined rules for which is correct based on geometry alone, it depends on the mesh..at the very least you can make them all consistent and flip them if they're wrong..

If you're trying to do this at runtime and not as a pre-processing step you'll be in trouble :), there would be no way to check the result and correct it..
"Like all good things, it starts with a monkey.."
Listen dude... if you don't know which way the tris are facing, you're gonna have more problems than just lighting...
Backface culling is standard, and unless you disable it, your model won't even draw correctly.

Since the problem seems to be with finding the correct order of vertices, you might look into surface reconstruction from point clouds.

Among other sources, a guy at microsoft research has done some work + papers on this subject. Search google for "hugh hoppes"

Then again, since you've already constructed the triangles, you can probably streamline the process. I recall 3dsmax having a button to Uniform Normals... Anyway, I suppose you could start at the "top" or whatever, and if it's a continuous surface (without too much folding) you could probably start "moving" down the mesh and try to unify the normals based off of a dot product of an adjecent poly's normal and each of the 2 possible normals.
Hmm actually, that might work:

(i'm assuming you're working with indexed verticies)
1) start with only triangle, assume one normal direction
2) begin traversing the remaining triangles, find adjacent triangles (maybe recursive?) dot product the 2 possible normals with the last (adjacent) triangle, choose the "most similar" normal. Move this triangle to another array when completed, or set a flag (to signify Normal has been set)

That should do it. If you find the mesh is pointing the wrong way when you're done, just invert *all* the normals.

Good luck,

-Michael g.

(edit... hmm, that's what all the last posters said too... maybe I should read *all* the replys before replying)

This topic is closed to new replies.

Advertisement