Archived

This topic is now archived and is closed to further replies.

Calculating Normals for Terrain

Recommended Posts

This is a newbie question, i know. I trying to build a terrain model that can be viewed and looks pretty good, but i have not done a whole lot of 3D (ok almost zero). I know theres editors for terrain out there, but i wanted to do this myself to improve my ability. Ok here is what i have. I programmed a data structure that holds the mesh information the mesh is made up of triangles that can be scalene, but have some restrictions. Here is what the grid looks like in 2D * * * * * * * * * * * * (you get the idea) I built a simple 2D editor that changes the positions of the vertics in 3D. Now i''m working on rendering (i''m using OpenGL). I need to calculate the normals for each vertex. I''m not sure how to do this, so i need some help. Here is how i thinks it''s done, so if this works tell me. There are 6 lines that come to any one vertex. Each line can be represented as a triplet of floats that are the distances the line covers [x] [y] [z] If i average each x from the lines to produce one number, do the same for y and z, this produces a new line that goes in the average of all the lines. I calculate the length of the line and divide to make it 1 and then put in glNormal3f(). So, will this work? I see that this would produce normals heading into the ground, is that OK? Also the average uses the length of the lines, so the normal favors the direction of the long distance, is this what you want, or is the normal only affected by the plane, not the length? Any comments helpfull, Daniel RELIGION IS THE ROOT OF ALL EVIL

Share on other sites
To calculate a vertex normal you must first calculate the surrounding face (triangle) normals and average them together:

If you have a triangle give by 3 points a,b,c, you subtract them to get two edges (p,q):

p=b-a;
q=c-a;

Now take the cross product of vector p and vector q, and you have the normal to the triangle. If you are going to use the normal for something else, then normalize it to make its magnitude 1 -- you do not need to normalize it now if you are just using it for the vertex normal.

Next you loop through all your vertices and for each vertex sum up all of the surrounding triangle normals and divide by the number of surrounding triangles. Then you normalize the resulting vector and you are finished.

Direct3D has a function to do this for you. I don''t know about open GL.

Share on other sites
Just a few notes...

I''m not certain about DirectX, but for OpenGL it is vital to normalize the vertex normal or else your lighting will produce very strange results.

OpenGL will generate the normals for you when using surfaces (bezier,etc), but because of its low-level nature I doubt it can calculate vertex normals for meshes. It can normalize them on the fly, but I highly recommend doing this before hand because it can take quite a bite out of performance.

You may want to consider sticking all of your vertex data into an interleaved vertex array (glInterleavedArrays), which will give you an efficiency boost due to the cutdown on the number of OpenGL calls.

-Matt

Share on other sites
Thanks for the reply, although a have a few more questions.

invective you said that you need 2 vectors for each adjacent triangle, can it be any 2? Also, what is taking the cross product of two vectors? how do you do it? (i''m just now taking geometry, not much knowledge on vector space)

RELIGION IS THE ROOT OF ALL EVIL

Share on other sites
I really hated linear algebra, so my vector math isn't too good either. I think its any two vectors, but just make sure you obtain them as above b-a, c-a, not b-a, c-b etc or you may end up flipping the normal. It doesn't matter what vertex is a, what is b, or what is c, as long as you are consistant. The cross product of 2 vectors gives you a third vector that is orthogonal (perpendicular) to the other two. Since you can see that the vectors p and q will represent the triangle, the cross product of the two vectors is a vector orthogonal to the triangle, which is exactly what a normal is supposed to be.
R = P cross Q

Rx = Py*Qz - Pz*Qy
Ry = Pz*Qx - Px*Qz
Rz = Px*Qy - Py*Qx

Again, D3D has built in vector classes, overloaded operators, and functions to do the cross prduct for you, so you might want to see if there is an openGL equivalent. If not, I believe you can also link just the D3Dmath lib and header if you just want the math functions.

Example:
  D3DXVECTOR3 r, p, q,;p = b - a;q = c - a;D3DXVec3Cross (&r, &p, &q);

Edited by - invective on November 11, 2001 4:11:37 PM

Share on other sites
Thanks for the clarification.

I was wondering, do think it prudent for me to start to learn DirectX? People keep saying all the things it does to make life easier, will it help me make graphics easier?

RELIGION IS THE ROOT OF ALL EVIL

Share on other sites
quote:

I was wondering, do think it prudent for me to start to learn DirectX?

Functionally, I think there is very little difference between the two. In fact they are similar enough that I sometimes look through OpenGL code and tutorials, and I have no problem converting them to Direct3d. I can''t tell you whether or not one is "better" or "easier" than the other. I just use Direct3d, because I used directdraw before it, so I am used to the style of the API. I think its most important that you try to understand the fundamentals of 3d graphics and programming first. There are plenty of tutorials to walk you through coding for either API. Direct3d does provide lots of wrapper classes and helper functions though, for everthing from loading textures and meshes to doing matrix and vector math. If OpenGL does not have equivalent features, you make want to switch just to simplify your programming and learning curve.

• Forum Statistics

• Total Topics
628378
• Total Posts
2982334

• 10
• 9
• 15
• 24
• 11