Following Terrain Height

Does anyone know the correct algorithm to use when calculating height based on a terrain heightmap? At the moment I have it referencing the nearest height value to the current viewpoint. This is very jerky however, especially when moving over hills! I’m trying to interpolate the height over each tile using the following:

HeightCurrent = terrain(current_x, current_z)
HeightNext = terrain(current_x, current_z+1)
PositionOnTile = current_z - (int)(current_z)
Height = (HeightNext-HeightCurrent) *PositionOnTile

Am I doing something wrong? Does anyone have a better method?

  • Phrantik
class Point2D{
	double xx, yy;// X is East, Y is North

float Terrain::getHeight(Point2D here) const{
	float xsquare = (here.xx - sw.xx) / ((ne.xx - sw.xx) / xdim);
//sw and ne are the corners of the heightmap (allows you to make the map as big and as detailed as you like)
//xdim and ydim are ints that store the resolution of the heightmap
	float ysquare = (here.yy - sw.yy) / ((ne.yy - sw.yy) / ydim);

	float d1 = xsquare - (int)xsquare;
	float d2 = 1 - d1;
	float height1 = d2 * getHeight((int)xsquare, (int)ysquare) + d1 * getHeight((int)xsquare + 1, (int)ysquare);
	float height2 = d2 * getHeight((int)xsquare, (int)ysquare + 1) + d1 * getHeight((int)xsquare + 1, (int)ysquare + 1);

	d1 = ysquare - (int)ysquare;
	d2 = 1 - d1;
	return d2 * height1 + d1 * height2;

Oh, boy, let me tell ya, there are many, many different methods to smooth out a height map. The simplest would be bilinear interpolation. In this approach only the center of each tile is at the given height of the height map and it then linearly approaches the height of the neighboring tiles in each direction. A variation on this theme is to add in a bit of low amplitude, high frequency noise to help hide the artifacts that appear when using linear interpolation alone. Another approach is to use bi-cubic patches. I’ve recently read of someone even using a Gaussian function to effectively smooth out a height map. I can’t remember where I read all about these methods, probably Gamasutra . Suffice it to say there are very many ways to do this and each has its own tradeoff. I suggest you research on these various approaches and then see what best fits your needs.
By the way, Don’t Disturb’s source code above is an implementation of the plain old bilinear method without noise.

[This message has been edited by DFrey (edited 07-01-2000).]

Thanks guys!