Procedural macro-terrain generation

Procedural macro-terrain generation

Jattenalle's picture

Abstract

A simple procedural method of generating realistic approximations of macro-scale terrain features such as continents with several advantages over pure noise methods. This is not a programming tutorial, though it assumes the reader has knowledge of certain aspects such as normalization and modulus variable wrapping. If you are not a programmer then this method will not be of much use as it would be prohibitively time consuming to perform the same steps in an image editing suite such as Photoshop or Gimp.

A sample of a resulting heightmap is attached below.

Dependencies

This method relies on a number of pre-existing shapes generated by a different algorithm. Those shapes can be found here, the more of these shapes there are the better as it avoids repetition.

Why is this better than noise?

Pure noise based functions tend to generate macro-scale features that are "snaking" or fractal. Neither of which resemble real terrain features. While noise functions can quite successfully be used for such features it requires a lot of tweaking and magic numbers to "get right". The method shown here is more straight forward, and does not require tedious tweaking to achieve good results.

Rundown

The entire method can be broken into 5 simple steps:

  1. Pick a random point
  2. Add a random blended shape
  3. Move point slightly
  4. Add random shapes across the entire map for seafloor detail
  5. Normalize the map

Step 1 is performed once for each continent you want, for example 32 times. Each time you perform step 1 you also perform step 2 and 3 several times, more for finer grain detail, less for coarser. Step 4 is an optional step that basically involves going over the entire map and adding random shapes at very low blend values for some sea-floor detail. And finally normalize the map so it's easier to work with, for example float 0.0 to 1.0 or ubyte 0 to 255, whatever suits your needs the best. Save the map to disk or use it directly from memory.

Step 1 details

The random point will be roughly the center of a continent.

Step 2 details

Remember that this step is performed several times (Such as 32) for each step 1 above When adding the shape make sure to handle points that fall outside your map borders appropriately. For example if you want Horizontal seamless you need to wrap the X coordinate if it falls under zero or over your map width, easily accomplished with a modulus if you are using a custom blit routine. Other than that this is a fairly straight-forward step, simply add a blended shape to your map with overflow taken into account.

Step 3 details

Remember that this step is performed once for each step 2 Move the point we picked in step 1 a random distance in any random direction; a random value in the range -1/32th to 1/32th of the size of your map is a good starting point.

Step 4 details

A simple step to add detail to parts of the map missed in step 1, and there will be a lot of those. Those parts are your ocean floor, if you do not need ocean floor details then this step can be skipped. Step over your map in increments and add a random shape at a very low blend value, lower increments mean more detail but also more time required to generate the map.

Step 5 details

Normalize the map, as straight forward as it gets.

All done

Simple as that! Questions?

Attachments: 
Preview
sample_result.jpg sample_result.jpg 160.9 Kb [544 download(s)]