Archived

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

IainC

[Musings / Req for help] Normal generation from a heightmap

Recommended Posts

Hi all, I''m working on some terrain generation code that works on a subdivided mesh. Up to the point of calculating vertex normals, I''ve been able to get away with not actually storing the vertex/triangle information - ie, every vertex has no idea which other verts are it''s neighbours. To provide a simplified overview:
  
void Init() {
	// Build base object ready for subdivision

	glNewList(displayList, GL_COMPILE);
	// For each face in object call Subdivide with depth=5

	glEndList();
}

void Subdivide(float *v1, float *v2, float *v3, long depth) {
	if (depth == 0) {
		OutputTriangle(v1, v2, v3);
	} else {
		// Recursively call Subdivide with depth-1

	}
}

void OutputTriangle(float *v1, float *v2, float *v3) {
	glBegin(GL_TRIANGLES);
		// Call OutputVertex for each point

	glEnd();
}

void OutputVertex (Vector3f *point) {
	// Deform the point using a noise function and call glVertex3f

}
  
I have texture generation working from the same noise function that deforms the mesh, and texture coord generation working fine too. My problem is generating normals. Given that I can very easily have my noise function generate a heightmap image representing the landscape (in the same way I''m building the texture), is there any way I can use this heightmap to work out the normal for a given vertex? I''m already stepping into a similar 2d array to get the deformation value so converting the point on the mesh into a (u, v) coordinate is not a problem - my only problem is actually calculating the normal from the information in the heightmap. The aim is to be able to call glNormal before each vertex with a correct normal without having to rewrite the whole thing to keep track of which verts/tris have which other verts/tris as their neighbours. I think that it must be something to do with looking at the neighbouring pixels of the one in question on the heightmap, but I just can''t see how to use this to get a normal! I''ve Googled and tried the usual sources, but to no avail. Any thoughts? Anyone seen any terrain generation code than works in a similar way? Many thanks for any help anyone can offer. I. www.coldcity.com code, pics, life

Share this post


Link to post
Share on other sites
If you can get the actual heightmap then you can use "finite distance" method (like used in nVidia''s normal-map generator).

You should never let your fears become the boundaries of your dreams.

Share this post


Link to post
Share on other sites
>>I think that it must be something to do with looking at the neighbouring pixels of the one in question on the heightmap, but I just can''t see how to use this to get a normal!<<

basically find out how much ''slope'' the pixel/point is on,
eg (p == pixel not doing bounds checking + the code wont compile but u should get the idea)
(p[A+1].y - p[A-1].y) = the difference in height between the pixel to the east of the chossen pixel + the pixel on the west.
ok if the answer to the above is 0 then theres no height difference between the 2 pixels (thus the normal is(0,0,1) 1 in the z part cause its pointing straight up into the air (cause the slope is 0)
normally though for a bumpy surface this number will be in the region 0->1.0 (it will never quite reach one though)

float amount = sqrt(answerslopex*answerslopex + (also do y here) + 1.0) // ie normalize it
N.x = answerslopex * (1.0/amount)
N.z = amount;

btw if u use dot3 u may need to convert the normal into a color to be used for the dot3 eg(0,0,1)->(0.5,0.5,1)

(btw u also want to check the pixels north + south (pixelslopeY) of the wanted pixel as well as the one east-west(pixelsslopeX))

sorry about the explantion

http://uk.geocities.com/sloppyturds/kea/kea.html
http://uk.geocities.com/sloppyturds/gotterdammerung.html

Share this post


Link to post
Share on other sites