Jump to content
  • Advertisement
Sign in to follow this  
sipickles

Extracting normals

This topic is 4690 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

Hello, I am presently playing with terrains and exploring two methods - heightmapped and meshed. In my heightmap version I have a lovely wireframe landscape, I am using one big vertex buffer, and index buffer, then chopping up the index buffer into different sectors ( I plan to introduce LOD to these sectored index buffers) My problem is I can't light the terrain because I have no normals for each indice. Can anyone demystify for me how I go about building normal values for each indice? I know how to make a face normal but I want to average the normals from adjacent polys to achieve smooth shading. Many thanks Simon

Share this post


Link to post
Share on other sites
Advertisement
sipickles,

If you know how to compute face normals you're already half way there. Generally what is done is a 2-pass algorithm. The first pass generally goes over all of the vertices on the heightfield and computes an array of face normals. The number of face normals will be equal to the number of triangles on the heightfield. This is usually Height * Width * 2. (simple. =)

The second pass then goes through each of the vertices and using a mapping gets the face normals for all the triangles attached to the current vertex. The face normals are then averaged. (add up all the face normals, then divide each component of the normal vector by the number of triangles ).


0 - 1 - 2
| \ | \ |
3 - 4 - 5
| \ | \ |
6 - 7 - 8


As an example, In the above diagram you can see that vertex 0 is used by two triangles. Vertex 1 is used by three triangles, vertex 5 is used by six triangles. You should note that if all of your diagonals go the same direction, a single vertex can be part of at most six triangles.

Share this post


Link to post
Share on other sites
sordid,

Who were you talking to? You average the face normals, not the vertex normals, just as I said in my post. As well, all of the face normals are normalized vectors (unit vectors/direction vectors).

Share this post


Link to post
Share on other sites
Yes because you want a larger sized triangle to have more influence on the normal than a smaller one. If you imagine in irregular mesh with tiny triangles and some huge ones the influence of the tiny ones can make the lighting look really odd. In this case though as he is using a regular mesh there should be no difference either way.

Share this post


Link to post
Share on other sites
Quote:
Original post by jwalsh
sordid,

Who were you talking to? You average the face normals, not the vertex normals, just as I said in my post. As well, all of the face normals are normalized vectors (unit vectors/direction vectors).


I was talking to the last person who replied in the thread.

What you said was that for each vertex (in the second pass) you add up the normals of all the faces that the vertex in question is attached to, and then you average that vector.

This is what I was referring to, and is also the method I have used for many years. Recently, however, I stumbled across many people saying that the preferred method is to normalize the resultant sum of face normals for that vertex, rather than average it.

Share this post


Link to post
Share on other sites
Quote:
Original post by jwalsh
Do I need to post a GD.net article on computing normals for heightmaps? =)

[lol] you could if you have time!

Anyway, what Trip99 and Sordid are saying is correct - just that it might be "extra" to the question at hand.

That is, if you have 6 faces (hence 6 face normals) sharing a given vertex, you can go in one of two ways:

Averaging - compute all 6 normals and then add all 6 X coordinates (all 6 y, z etc..) and divide through by 6.

Normalising - computer all 6 normals and add them together, you should have a vector that is length-6, thus a regular Normalize() operation will effectively divide through by 6.

If you're dealing with unit-vectors (e.g. proper Normals!) all the time then they obviously boil down to the same thing. If, however, your intermediary values are NOT unit length then you'll get different results from the above two methods.

As Trip99 points out, for an irregular mesh this can be beneficial as it considers the surface area of the triangle as a weight in the equation - a large triangle gets more impact on the normal than a small triangle.

However, what Trip99 didn't really say (or I don't read it in there!), is that on a regularly spaced heightmap (e.g. each sample point is evenly spaced out on an XZ plane) you still get different sized triangles due to the "height stretch" on the edges of steep slopes.

It's a fairly minor point, but you can (in a few cases) get much better lighting if you compute (in the first pass) the cross-product based direction vector for each face. In the second pass you add the adjacent (6 or more) cross-product directions together and then normalize them.

Although, as jwalsh is saying, averaging is fine for most cases and you have to be desiring perfection (or just plain picky) to worry about this!

hth [grin]
Jack

Share this post


Link to post
Share on other sites
Quote:
However, what Trip99 didn't really say (or I don't read it in there!), is that on a regularly spaced heightmap (e.g. each sample point is evenly spaced out on an XZ plane) you still get different sized triangles due to the "height stretch" on the edges of steep slopes.

It's a fairly minor point, but you can (in a few cases) get much better lighting if you compute (in the first pass) the cross-product based direction vector for each face. In the second pass you add the adjacent (6 or more) cross-product directions together and then normalize them.


I must admit I never thought of the triangles being different sized due to the heights - that is very interesting - I am off to try it!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!