The first thing we should ask ourselves is: What is the procedural content generation and what we can do with it on games? PCG is the automatic or computer-assisted generation of game content such as levels, landscapes, items, rules, quests etc. This time we are generating the terrain for a posible sandbox game using voxels, like Minecraft. I have decided to use voxels because they are easy to manage and will allow me to do whatever I want with the terrain (cliffs, mountains, canyons, caves, corridors between caves, etc)
To generate our terrain we will use a noise signal. What is noise? Noise is a general term for unwanted modifications that a signal may suffer. This definittion is usually for processing audio signals but in computer graphics noise is used to generate realistic contents. There are different algorithms to make noise, but the most common is Perlin Noise developed by Ken Perlin, who won an Academy Award for Technical Achievement for inventing it.
Perlin Noise is most commonly implemented as a 2D, 3D or 4D function, but can be defined for any number of dimensions.
The algorithm takes a noise function to generate a number of samples with different frequency and amplitude, these samples are summed to generate a new signal, you can see it on the next images in 1D and 2D.
As you can see, every sample adds a perturbation to the first one, being the first with greater amplitude the most significant, the next ones have less amplitude but greater frequency, which is what adds the disturbing values to the signal.
Knowing this, the Perlin Noise function comes from basically 2 parameters apart from the N coordenates in N-Dimension noise, the Persistance and the Octaves. Each successive noise function you add is know as an Octave and the Persistance deffines the amplitude of each Octave.
Now that we know the basics of Perlin Noise, Ken Perlin in 2001 designed an algorithm to address the limitations of his classic noise function, especially in higher dimensions. The Simplex Noise is a method for constructing an n-dimensional noise function comparable to Perlin Noise but with a lower computational overhead, especially in larger dimensions.
The advantages of simplex noise over Perlin noise:
- Simplex noise has a lower computational complexity and requires fewer multiplications.
- Simplex noise scales to higher dimensions (4D, 5D) with much less computational cost, the complexity is for n dimensions instead of the of classic noise.
- Simplex noise has no noticeable directional artifacts (is isotropic).
- Simplex noise has a well-defined and continuous gradient everywhere that can be computed quite cheaply.
- Simplex noise is easy to implement in hardware.
These are the reasons why I chose Simplex Noise instead of Perlin Noise. The values obtained are virtually the same but the algorithm is better.
Once we have defined the noise algorithm with the Persistance and the Octaves, we simply create a voxel at coordinates (X, Y, Z), where the Y-coordinate is the value obtained by the noise function. As the value comes between (-1, 1) we sum 1 and divide by 2 to get a value between (0, 1). Now we simply multiply that value by the maximum height that we want to our terrain.
This is what you get with a Persistence of 0.27 and 3 Octaves, I have divided the terrain in sectors because of limitations of Unity, there are 10×10 sectors with 20×20 cubes per sector (around 40k cubes), but this is not really important to see what we want to.
Here we have it, our procedurally generated terrain using voxels and Simplex noise but… is pretty boring, it would be great if it had some cliffs, canyons, high mountains, etc. To do that we have to create some biomes.
Biomes, taking Minecraft as model, are regions with varying geographical features, flora, heights, temperatures, humidity ratings, and sky and foliage colors. From now on we will focus our work on heights, using a curve values we can modify the height of our terrain and create completly different terrains with the same noise parameters.
The first curve on the right, is a straight line from 0 to 1, this means that if you get a value from the noise function equals to 0.1 and you evaluate this value with the curve, you will get the same value 0.1, in other words this is the curve used at the example seen before.
The other curve is quite different, more irregular, made by me. This curve will change the values obtained from the noise function significantly. When we have values from 0 to 0.52 the curve will return values near to 1, the values from 0.52 to 0.9 will be around 0.45, and from 0.9 to 1 will fall to 0.3. If we run the example with this curve what we see is a terrain made of cliffs and plains.
That’s all for now, the next goal should be add some textures to the cubes, figure out how to create a huge map where more than one biome enter to the game and how to deal with the transitions between biomes.