When it comes to 3D games, you often find yourself in a position where you need to have a big area where the action takes place - the terrain on which to place your roads, buildings and other things. There's many ways to go about this (ranging from having the artists model everything by hand to having it all procedurally generated), and today I'll be talking about a very simple, straightforward way to generate terrain, which also gives a great result.

This approach requires you to defined a few base texture maps, which we will use to generate and texture our terrain. First out is the height map, which in many ways is the most important one, as it will define the shape of the generated terrain. The heightmap is just a grayscale image, where black means lowest and white means highest point. There's various ways to go about acquiring a heightmap, including procedurally generating one, but the simplest way is simply to paint it in a paint program.

In addition to the heightmap, we'll need a few (four in this example) texture maps for the ground. It tends to work best if they are quite distinct, I've chosen sand, grass, and two different kinds of rocks. The idea is to divide the terrain into four different height spans, and use Texture map A for the first span, Texture map B for the second, and so on.

Once we've calculated the pixel color, we perform simple light calculations (N dot L lighting works fine) and do a simple ray-test to see if the light source can be seen from this point on the terrain (this is as simple as stepping along a line in three dimensions, checking the lines y-position against the heightmap value at each point). This gives us static lighting and shadows, which we can bake into the large terrain texture.

To make use of this in our game, we just create a grid of triangles corresponding to our height map, and textured with the large texture. The value for the y-coordinate of each vertex is taken from the heightmap, giving us a three-dimensional, fully textured model of the terrain. Since the texture map is stretched across such a large area, it can look way too blurred and stretched out, so to make it appear more detailed, we use the detail map together with the large texture, but tiled instead of stretched. As you can see on the picture above, this gives a very nice result, for very little effort - once you have a decent set of base texture maps, you can keep making new landscapes just by painting heightmaps!

If you add a plane with a semi-transparent water-texture on it, you can get rivers and lakes pretty much automatically, by adjusting the height of the water-plane, making your landscape much more alive.
A drawback of this technique is that it's using the same detail map for the whole terrain, so you can't have, for example a grass-pattern detail map in some areas, and a rock-patterned one elsewhere, but instead you have to settle for a pretty non-descript map which sort-of-works everywhere. There are other techniques which can address this issue, and I might write about them some other time...
Digg this
Add to reddit