Please send me your comments
Terrain Tutorial



A TGA Library
A Simple TGA Library
TGA lib Source

Height Maps
Height Maps from Images

Computing Normals
Simulating Lighting
Implementation Details
Screen Shots

Source Code

Artificial Terrain Generation
The Fault Algorithm
Implementation Details
Two Simple Variations
The Circles Algorithm

Mid Point Displacement
The MPD Algorithm

Particle Deposition

Matrix filters
API details

Source (Linux and Win32)

[Previous: Particle Deposition] [Next: Matrix Filters]

Terrain Tutorial


Most of the terrains generated so far look a little bit rough. In this section a few techniques to smooth a terrain will be presented. The concepts in here are borrowed from the image processing field, so if you're familiar with image processing filters you'll most certainly recognise some, if not all, the stuff in here. Of course you don't actually need to do it yourself, just import the height map image into an image processing application and apply a blurring filter to it. But thats not fun, is it?

The simplest of all is probably a band smoothing filter. This filter can be applied to rows and/or columns. For any point in the terrain its new height will be computed taking into account the height of one of its neighbours, i.e.

    height[x,z] = height[x-1,z] * (1-k) + height[x,z] * k

where k, a value between 0 and 1, is the roughness constant. If k = 1, then the terrain will remain unchanged. On the other hand, if k = 0 then the new height will be set to the height of the respective neighbour.

This filter can be applied to a row as shown in the pseudo code bellow:

		height[x,z] = height[x-1,z] * (1-k) + 
			      height[x,z] * k;

In order to properly apply this filter it is necessary to iterate both in rows and columns, as well as in both directions, as shown in the pseudcode bellow. It is assumed that the terrain is stored in a bidimensional array maxWidth x maxLength.

	/* Rows, left to right */
	for(x = 1;x < maxWidth; x++)
	    for (z = 0;z < maxLength; z++)
		height[x,z] = height[x-1,z] * (1-k) + 
			      height[x,z] * k;

	/* Rows, right to left*/
	for(x = maxWidth-2;x < -1; x--)
	    for (z = 0;z < maxLength; z++)
		height[x,z] = height[x+1,z] * (1-k) + 
			      height[x,z] * k;

	/* Columns, bottom to top */
	for(x = 0;x < maxWidth; x++)
	    for (z = 1;z < maxLength; z++)
		height[x,z] = height[x,z-1] * (1-k) + 
			      height[x,z] * k;

	/* Columns, top to bottom */
	for(x = 0;x < maxWidth; x++)
	    for (z = maxLength; z < -1; z--)
		height[x,z] = height[x,z+1] * (1-k) + 
			      height[x,z] * k;

The effect of the filter depends on the value of k. As mentioned before, large values, i.e. close to 1.0, will produce a small change in the terrain. Of course it is possible to pass the filter several times over the terrain until the desired level of smoothness is found. The following sequence shows a terrain generated with the mid point displacement algorithm, the terrain with 1 pass of the smoothing filter, and finally with 5 passes. The value of k is 0.75.

Original Terrain

1 Pass of the smoothing filter

5 Passes of the smoothing filter

In the source code, namely in the terrain.cpp file, you'll find the function to smooth the terrain:

void terrainSmooth(float k);

k - the smoothing constant. Takes a value between 0.0 and 1.0. The larger the value the smoother the result.

[Previous: Particle Deposition] [Next: Matrix Filters]

Site designed and maintained by António Ramires Fernandes
Your comments, suggestions and references to further material are welcome!