PDA

View Full Version : 3D Terrain generator

lost
26-May-2004, 00:23
Hello,
I am in the process of making a program that creates an infinite terrain...It basically generates a large array of height values from a perlin noise function (using cubic interpolation to smooth the curves). Basically, I have the terrain generating, but I am running into a problem creating normals for proper lighting.

void TerrainMap::makeNormals()
{
Vector3 up, left, down, right;
float myHeight;
//subroutines for making the normals from the points
for (int i=0; i&lt;width; i++) {
for (int j=0; j&lt;height; j++) {
myHeight=getTerrain(i,j);
up=Vector3(0,-1,myHeight-getTerrain(i,j-1));
down=Vector3(0,-1,myHeight-getTerrain(i,(j+1)%height));
left=Vector3(-1,0,myHeight-getTerrain(i-1,j));
right=Vector3(-1,0,myHeight-getTerrain((i+1)%width,j));
up.normalize(); down.normalize();
left.normalize(); right.normalize();
//now make some cross products
//add the up and down/left and right (linearly like :D)
//normalize
down.normalize();
right.normalize();
//now set normal to be cross product
normals[j*width+i]=right.cross(down);
normals[j*width+i].normalize();
//if y s in neg direction then flip
if (normals[j*width+i].y&lt;0)
normals[j*width+i].scale(-1);

Now what I wanted to do here was basically add the vertical components and horizontal components and then use their cross product as the normal.

Does this seem like a valid technique to make normals or is there a better more simple way. Also, it seems to be running into issues with the lighting besides normal related issues as I am not sure how to make lights stay in a stationary position as I am changing the modelview matrix to move about the scene.

The code is compiled with vs.net 2003 and available at if the above didnt make sense
http://www.tc.umn.edu/~vant0038/Terrain.rar

Thanks!
(When compiled, arrow keys move the terrain, l toggles lighting, and space toggles wireframe mode)

Simon F
26-May-2004, 07:43
Lost:
If you are using cubic interpolation for the terrain, then you should be able to use the derivative of the function in x and z (i.e dSurface/dx and dSurface/dy) to give you two tangents for your normals.