Skip to main content
gamedev.net
🔒 Locked

[solved] normals question

Started by ProgrammingNerd Aug 1, 2005 at 11:04 AM 8 replies 650+ views
Original Post
ProgrammingNerd
ProgrammingNerd
When computing normals for directx lighting, do you need to compute normals for vertices, faces, or both? How can you manually compute these normals. I'm writing a program in dos to compute the normals, given vertex and index data. Thanks to anyone who replies, ProgrammingNerd [Edited by - ProgrammingNerd on August 1, 2005 3:47:57 PM]
gunning
gunning
DirectX only stores the normals of vertices. There is a function to do this for you: D3DXComputeNormals. If you wanted to do this yourself, you would need to compute adjacency tables and for each vertex average the normals of the faces to which it belongs. A normal can be computed by taking the cross product of two edges of the triangle. Be care though of how you order your vertices and which two edges you choose because that determines in which direction the normal points.
....[size="1"]Brent Gunning
ProgrammingNerd
ProgrammingNerd
Thanks for your info! I'm writing my own mesh format and am making a simple command line program for creating the meshes. Purely for testing purposes. Which would be better: creating the normals at design time ie when I save my mesh, or at load time, where I could put the vertex and index data into a ID3DXMesh interface and compute the normals that way?
neneboricua19
neneboricua19
In general, its always best to create normals at content creation time. The reason for this is that the artist who originally created the model knows which way he/she wants the normals to point because they may want light to affect the model in certain ways. Most often, the artist will just let the content creation tool generate the normals automatically anyway. It all depends on what the particular model will be used for.

neneboricua
ProgrammingNerd
ProgrammingNerd
How can I create normals? What skittleo said could help, but how can I know what direction the normal is facing?
jollyjeffers
jollyjeffers
Quote:
Original post by ProgrammingNerd
How can I create normals? What skittleo said could help, but how can I know what direction the normal is facing?

Typically a mesh will be saved out using a particular "winding order" - that is the vertexes of a given triangle and listed in a particular order: ClockWise or CounterClockWise.

One of the fun things when using some standard meshes is that this changes (iirc. Lightwave generated an opposite order to 3DSMax).

Anyway, my point being - if you order your vertex/index data in a consistent manner then you should be able to determine which direction the normal will face depending on which sides you want to pick. There are mathematical methods, but trial-and-error has worked just fine for me in the past [grin]

To create a normal, the mathematics is quite simple.

Take 3 points of a triangle: P0, P1 and P2. They form a triangle like the following:
P<sub>0</sub>-----P<sub>1</sub>      /     /    /   /  /P<sub>2</sub>


If you were to take the vectors from P0 to P1 and P0 to P2, take their cross product, and then normalize this you would have a FACE NORMAL:

D3DXVECTOR3 v01 = p1 - p0;D3DXVECTOR3 v02 = p2 - p0;D3DXVECTOR3 norm;D3DXVec3Cross( &norm, &v01, &v02 );D3DXVec3Normalize( &norm, &norm );//"norm" contains your face normal.


If you reference that back to what skittleo originally said - you could store the computed normal in each of the 3 vertexes that make up the face. But this gives very flat lighting, which can be useful - but for the most part looks rubbish.

The alternative is to use what's been mentioned as "smoothing groups" - for a given vertex, compute the face normal for all the triangles it is shared by and then sum up and normalize those to create a single vertex normal.

hth
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
ProgrammingNerd
ProgrammingNerd
Thanks for all your help, JollyJeffers, neneboricua, and skittleo! One last question regarding this. How can I easily compute a attribute table without using directx. I'm thinking that I just loop through all my triangles, pick two vertices of the triangle, and search for a triangle with those two verts and store the result. Though this would probably be too slow for anything practicle.

thanks again,
ProgrammingNerd
jollyjeffers
jollyjeffers
Do you mean attributes (textures/materials) or adjacency (neighbouring triangles)? You've used the former word to describe something that sounds more like the latter [smile]

The simplest way that I can think of relies on index data - do you have that? If you do, then you can loop through each triangle and look for the same index data.

I wouldn't worry hugely about performance as it's a one-time algorithm unless you physically add/remove vertex data. You can just store the adjacency information for later use...

hth
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
gunning
gunning
^

My thought too.

An alternative though is to throw all of your vertices and triangles into a ID3DXMesh object and use D3DX to compute the normals. Then lock the vertex and index buffers and extract the data back out again.
....[size="1"]Brent Gunning
ProgrammingNerd
ProgrammingNerd
Thanks for all of your help! I will just do what skittleo said: through everything into a ID3DXMesh object, and compute the normals that way. Atleast for now.

Man, I don't know what I would do without this website.

[Edit] I just rate all of you

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.