Algorithms: Perlin noise
Introduction
Noise synthesis is a fast method to generate realistic terrains with fractal properties. A good way to obtain noise synthesis is to generate coherent noise. Coherent noise is a smooth pseudo-random noise that has 3 main properties:
- the same input generates the same output
- a small change in the input gives a small change in the output
- a big change in the input gives a random change in the output
Perlin noise is a coherent noise generated interpolating a noise function.
Perlin Noise
A way to generate Perlin noise is using the sum of several coherent noise functions with increasing frequencies and decreasing amplitude, each function added to the final noise is called an octave because each function has double the frequency of the previous one.
The following image shows 8 octaves of coherent noise:
frequency and amplitude for each octave are computed by the following code:
freq = pow(2.0, i); ampl = pow(persistence, i);
Where i is the current octave number (from 0 to 7 in this case) and persistence is a value that determines the amplitude variation, a bigger value (> 0.5) means a rough output, while a smaller value (< 0.5) means a smooth output.
Adding more octaves gives a more detailed noise that can be used as heightmap, this is the result of the sum of 8 octave:
Implementation notes
I’ve implemented the code described by Hugo Elias with a fragment shader, so I’m not explaining the whole code, because it’s really similar to his pseudo-code, the only different function is the random number generator I use, it’s inspired by a tutorial of the Lumina IDE.
This is the formula:
1.0 - 2.0 * fract(sin(dot((cos(vec2(x, y)) * sin(seed)), vec2(15.12345, 91.98765))) * 115309.76543);
This random number generator returns a value in the range [-1.0, 1.0], this is important for something I’m going to explain later., the seed value is passed as uniform variable.
I’ve chosen to use the cosine interpolation as interpolation function instead of the built-in mix function because it gives better visual results summing 4 or less octaves and there’s no much gain in the execution time.
I’ve added another little improvement to the original code, a factor that allows to zoom the generated map, this is a common property in the fractal world.
The following image shows the same map from several zoom levels:
Some enhancements
A fast way to generate new terrains from a starting one is to apply some mathematical function to the base map. In order to get effective visual results the values has to be in the range [-y, +x], so the values has not to be normalized before the filtering.
The following image shows some different functions applied to the terrain showed above in this post:
The top-left square has been generated using the sin function and shows a stronger contrast and more erosion, the top-right one uses the abs function and shows a stronger erosion, the bottom-left square is obtained by the sqrt function and shows interesting lines that looks like rivers, finally, the bottom-right square is generated by the composition of the sin and abs functions and shows the main features of the first two squares combined.




sandra407:
Hi! I was surfing and found your blog post… nice! I love your blog.
Cheers! Sandra. R.
9 September 2009, 5:15 pmangelina jolie:
I love your site.
Love design!!! I just came across your blog and wanted to say that I
10 September 2009, 5:11 pmmegan fox:
Sign: umsun Hello!!! rcuwwymhyw and 8457ssgfhphzye and 7006I love your blog.
I just came across your blog.
11 September 2009, 4:40 pmcelebrity fuck you:
Sign: zdbrw Hello!!! frbdc and 6505pswxnssdem and 5187 : Cool!
24 August 2010, 7:35 pm