Archived

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

IainC

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

Recommended Posts

IainC    127
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
_DarkWIng_    602
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
zedzeek    529
>>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