Lighthouse3d.com

 Terrain Tutorial Index A TGA Library A Simple TGA Library TGA lib Source Height Maps Height Maps from Images Artificial Terrain Generation The Fault Algorithm Implementation Details Two Simple Variations The Circles Algorithm Smoothing Smoothing Matrix filters API details

# Terrain Tutorial

## Smoothing

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:

```    ```
for(x=1;x<maxWidth;x++)
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);

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