Repository

Topics

j3d.org

Terrain Generation Implementation

Author: Justin Couch (justin@vlc.com.au)

Since Ken Musgrave's 1989 paper on procedurally generated terrains, the fascination with artificially generated terrains has steadily grown. Not only does the basic terrain ideas work, but they can be applied to other areas, such as cloud textures. Fractal terrains, as they have become known as, is the basis of the very popular commercial product Bryce (and very recently, Ken's latest effort - MojoWorld).

 

Code Outline

All terrain oriented code can be found in the package org.j3d.geom.terrain. As the package suggests, this is part of geometry generation area and so fits in with the generalised architecture outline described in the Geometry Generation page.

Classes

For generating fractal terrains, there is only one real class involved - FractalTerrainGenerator. This class makes use of other classes from different packages as you can see in Figure 1.

The terrain generator class is responsible for evaluating the fractal height values and placing them in a grid. The grid is then shipped off to the ElevationGridGenerator to turn it into real 3D coordinates. The coordinate and texture values are applied there and the whole lot is returned to the caller. Color per-vertex information, using a color ramp, is applied by user code and not the generator.


Figure 1: The static class structure for terrain generation

Generating Terrain Values

Terrain values are created in a sub-division type manner. The code starts with a simple 2x2 grid of points set to some base height (typically zero). The grid square is divided into 4 squares by dividing each side in half. The new points have their basic height calculated as the average of the two corners and then have a random fluctation added (which may actually be negative).

Once all five new points have been processed, the four grids are now again subdivided and the same process takes place again in each individual grid. This time, the amount of random fluctuation is divided by the amount of roughness. Thus if roughness is set to 0.5 then the maximum amount of fluctuation that can be applied is half of the previous iteration.

The process continues subdividing the surface for the given number of iterations. Each iteration adds an exponentially larger number of points, so given a standard JVM setup, the practical maximum is 9 iterations.

Once the terrain heights are completed, the next step is to apply a sea level if needed. In this situation, the system will iterate through all the height values and if the height is less than the sea level height, the generator will change the height value to the sea level value. Finally, the heights are passed to the elevation grid generator for tesselation.

The code offers a basic seed terrain for you to use. The idea of this is to allow the user to create the basic forms of hills and valleys. Unfortunately the code currently does not offer you the ability to set the border values. Setting border values is useful when you want to blend two tiles of fractal terrain together and need the edges to exactly match. This feature needs to be added.

Generating textures

Another use of fractal terrains is in generating cloud textures. These creators use the fractal terrain system to generate the height points but do not perform the 3D tesselation. Instead, height values are converted to colours based on the height data. Because fractal terrains lead to smooth height transitions, the output effect is a nice smooth colour transition that approximates a cloud or fire form.

To generate an image texture, the code starts with building a set of fractal height values first. The user then supplies the HeightImageCreator with a color ramp which describes a colour and height combination. The creator then iterates through all of the heights and maps the colour to the height value. Finally, an image is generated from the colour values and returned to the user.

Because the caller may want different types of images, both greyscale and colour output is available. For efficiency, these generate the appropriate image type. A greyscale image will be created with just a one or two component image, while colour output will generate a full 32-bit image.

 

Other References