Terrain Rendering Issue

Started by
25 comments, last by Fahrenheit451 18 years, 10 months ago
Nah its not the texturing that is causing the problem, that was just left from some old code, there is not texture attached, and i did run it disabling texturing and stilll same result, i think it is definately a normal problem, normal being the normal used in lighting.
Advertisement
It looks like there's something wrong with the lighting, as has been mentioned. Have another look at the code that generates the vertex normals.
Haha ok im struggling, could someone please give me a breif lesson in how to compute normals for triangle strips? Im really new to this stufff and hvnt dont much vector work in yr11 yet, touched on it in physics and a little in math but i hvnt grasped it yet.

Thanks in advance, Nick :)

Cheers!!!
hi, I gave you some pseudo code for that a few post earlier ^^

basically, imagine that you have a heightmap grid like height[512][512]. The code is :

for (int x = 0; x < 511; x++){   for (int y = 0; y < 511; y++)   {      // these 2 vertices are the ones used for the strip      vertex1.x = x;      vertex1.y = height[x][y];      vertex1.z = y;      vertex2.x = x;      vertex2.y = height[x][y + 1];      vertex2.z = y + 1;      // now, for vertex1, take the next one in the X axis AND in the Z axis       nextX.x = x + 1;      nextX.y = height[x + 1][y];      nextX.z = y;      nextY.x = x;      nextY.y = height[x][y + 1];      nextY.z = y + 1;      // now, cross product between the 2 rays going from vertex1 to nextX and nextY      ray1 = nextX - vertex1;      ray2 = nextY - vertex1;      // replace the cross product and normalization by your code      normal1 = crossProduct(ray1, ray2);      normal1 = normalize(normal1);      // now, do it for the second vertex      nextX.x = x + 1;      nextX.y = height[x + 1][y + 1];      nextX.z = y + 1;      nextY.x = x;      nextY.y = height[x][y + 2];      nextY.z = y + 2;      ray1 = nextX - vertex1;      ray2 = nextY - vertex1;      normal2 = crossProduct(ray1, ray2);      normal2 = normalize(normal2);      // now, you have your vertices and normals.   }}


Maybe there's some error in this code, i just poped it out of my mind. But the principle is there : for a given vertex ((x, y) in the heightmap table) just extract a neighbour vertex in the x coordinate (e.g of coordinate (x + 1, y) or (x - 1, y) and a neighbour vertex in the y coordinate. Substracting these 2 new position to your current position, you'll get 2 rays that you can use to compute the normal by simply computing a cross product and normalizing.
Quote:Original post by NickyP101
Haha ok im struggling, could someone please give me a breif lesson in how to compute normals for triangle strips? Im really new to this stufff and hvnt dont much vector work in yr11 yet, touched on it in physics and a little in math but i hvnt grasped it yet.

Thanks in advance, Nick :)

Cheers!!!




Heres a thread I made earlier on how I do this. Since it's a terrain, calculating up front is best. If you need dynamic calculations, like for water, then there should be a shortcut routine in there also.

hth
F451
Ok after alot of learning and alot of help from all you :) i think ive partially fixed the problem, below is a screen shot of the latest:



Now my question is: See how the terrain looks soo pointy? how do i make it look smoother??

Cheers, Nick.
Make your heightmap smoother. (On a sidenote, it would be kind of you to use smaller images in the future. Those high resolution pictures can really hog bandwith.)
Run a gaussian blur over your heightmap. I noticed that the image you posted was pretty noisy, which will cause a lot of "spikes" in your terrain.
Also, make sure that you're saving the map at a high color depth, prefferably in a lossless format. Any dithering will cause artifacts like you're getting here, so GIFs don't work well for heightmaps, and JPEGs can give you unpleasant banding. TGAs or BMPs are best (RAW also works, but it doesn't have all the nice header info the other two have, which can be restrictive.)
Touching on the color depth again, it's also a good idea not to have a 1-1 corrospondance from pixle color to height. If you have a 256 color range and your landscape is 256 units high at it's peak, then every elevation change is going to be at least 1 unit. If you're landscape verts are spaced 1 unit apart, this means a MINIMUM angle of 45 degrees. (Think SimCity 2000's landscape.) If your max terrain height is only 64 units, though, then each progressive color value represents a half-unit change in height. Now your miminum angle is 22.5 degrees, which gives a much smoother appearance, and allows for more natural hills and such.

...I'm rambling again, aren't I? I'll stop. ^_^
// The user formerly known as Tojiro67445, formerly known as Toji [smile]
Here's a gamedev article on this : http://www.gamedev.net/reference/articles/article2164.asp

and a routine I use that was inspired by it, which gives a simple smoothing by averaging between neighbouring vertices. Looks clunky, and is not optimised, but it's simple enough to follow. I use and adjustment value of 1.0f:

//// Smooth heightmap based on averaging neighbouring vertices// Neighbour vertices chosen are dependent upon location on heightmap// so as to give better overall results//void SmoothTerrain(float adjust){  for ( int r = 0; r < hmap.size; r++ ) {    for ( int c = 0; c < hmap.size; c++ ) {      if ( r == 0 && c == 0 ) {        // back left corner - average 3 vertices        hmap.vert[r][c].y = ((hmap.vert[r+1][c].y*adjust)+(hmap.vert[r+1][c+1].y*adjust)+(hmap.vert[r][c+1].y*adjust))/3.0f;      } else if ( (r > 0 && r < (hmap.size-1)) && c == 0 ) {        // left edge - average 5 vertices        hmap.vert[r][c].y = ((hmap.vert[r+1][c].y*adjust)+(hmap.vert[r+1][c+1].y*adjust)+(hmap.vert[r][c+1].y*adjust)+(hmap.vert[r-1][c+1].y*adjust)+(hmap.vert[r-1][c].y*adjust))/5.0f;      } else if ( r == (hmap.size-1) && c == 0  ) {        // front left corner - 3        hmap.vert[r][c].y = ((hmap.vert[r][c+1].y*adjust)+(hmap.vert[r-1][c+1].y*adjust)+(hmap.vert[r-1][c].y*adjust))/3.0f;      } else if ( r == (hmap.size-1) && (c > 0 && c < (hmap.size-1)) ) {        // front edge - average 5 vertices        hmap.vert[r][c].y = ((hmap.vert[r][c+1].y*adjust)+(hmap.vert[r-1][c+1].y*adjust)+(hmap.vert[r-1][c].y*adjust)+(hmap.vert[r-1][c-1].y*adjust)+(hmap.vert[r][c-1].y*adjust))/5.0f;      } else if ( r == (hmap.size-1) && c == (hmap.size-1) ) {        // front right corner - average 3 vertices        hmap.vert[r][c].y = ((hmap.vert[r-1][c].y*adjust)+(hmap.vert[r-1][c-1].y*adjust)+(hmap.vert[r][c-1].y*adjust))/3.0f;      } else if ( ( r > 0 && r < (hmap.size-1)) && c == (hmap.size-1)  ) {        // right edge - average 5 vertices        hmap.vert[r][c].y = ((hmap.vert[r-1][c].y*adjust)+(hmap.vert[r-1][c-1].y*adjust)+(hmap.vert[r][c-1].y*adjust)+(hmap.vert[r+1][c-1].y*adjust)+(hmap.vert[r+1][c].y*adjust))/5.0f;      } else if ( r == 0 && c == (hmap.size-1) ) {        // back right corner - average 3 vertices        hmap.vert[r][c].y = ((hmap.vert[r][c-1].y*adjust)+(hmap.vert[r+1][c-1].y*adjust)+(hmap.vert[r+1][c].y*adjust))/3.0f;      } else if ( r == 0 && ( c > 0 && c < (hmap.size-1)) ) {        // back edge - average 5 vertices        hmap.vert[r][c].y = ((hmap.vert[r][c-1].y*adjust)+(hmap.vert[r+1][c-1].y*adjust)+(hmap.vert[r+1][c].y*adjust)+(hmap.vert[r+1][c+1].y*adjust)+(hmap.vert[r][c+1].y*adjust))/5.0f;      } else {        // internal - average 8 vertices        hmap.vert[r][c].y = ((hmap.vert[r-1][c-1].y*adjust)+(hmap.vert[r][c-1].y*adjust)+(hmap.vert[r+1][c-1].y*adjust)+(hmap.vert[r+1][c].y*adjust)+(hmap.vert[r+1][c+1].y*adjust)+(hmap.vert[r][c+1].y*adjust)+(hmap.vert[r-1][c+1].y*adjust)+(hmap.vert[r-1][c].y*adjust))/8.0f;      }    }  }}


Thank you all, and yeah i will make smaller images from now on :) Sorry about that.

Ill research what you guys have told me and get back to you soon!

Cheers, Nick!

This topic is closed to new replies.

Advertisement