Perlin noise amazes me. Here is what it looks like in 2D.
Imagine that the above image is representing a map. Maybe the darker area are mountains, and the lighter are valleys.
It may seem relatively hard to generate such image randomly. Fortunately, some guy, Ken Perlin, developed a cool technique that does just that. He even won an academy award for it…
The technique can be applied to generate 1D Perlin noise, to generate a random-looking profile for example. Or to generate 3D Perlin noise, to add some volume information, like a bunch of clouds. In that example, we will work with 2D perlin noise. Maybe even 4D noise, but I will let you imagine what that would look like…
The technique is pretty simple. Basically, it is an average of few random images of different sizes.
The algorithm starts with a simple random image. Each pixel has a random value between 0 (black) and 1 (white). In this tutorial, I want to generate an image of 256 pixels wide. Here is the first random image:
Not very nice yet.
Let’s generate another one, that is half the size, so 256⁄2 = 128 pixels.
We need to add this second image to the first one. But since they are not of the same size, we have to take the smaller one, and scale it up by a factor of 2 to get an image of 256 pixels:
Now, the magic happens. We just take each pixel of those two 256 pixels wide images, average them, and save the result to a new image:
Not very impressive. Yet.
Now, the second step is repeated with an image half the size again. We started with 256 pixels, then 128. Now, let’s take a 64 pixels image, and resize it to 4 times its size:
And we add it to our previous image:
These operations are repeated for images of 32, 16, and 8 pixels: generate random image, resize, add to (or rather average with) the last obtained image:
The following image has 3 columns: the first one is a randomly generated image. The second one is the same image as the first column, but scaled to be of the same size as our target image (256 pixels, red lines). The third and last column contains average images between the image above itself, and the image to its left (blue lines). The algorithm starts with a randomly generated image (in the top right corner, and images are added together.
There are a lot of parameters to play with. For example in that example we started with an image of size 256. But we could start with a 64 pixels image resized to 256 pixels (basically skip the first 2 images). That would remove some of the fine grain to the final image. We can also add one or 2 extra steps at the end. Basically, up to a 2x2 pixels image (1x1 does not make any sense, since it would add the same value to every pixel of the image).
Another important factor is how an image is scaled up. In the above examples I used linear scaling, but other techniques will produce different results.
It is also possible to change the way two images are added together, in which order, and what formula is used. Here, much more importance is given to the last image I add, since it basically accounts for half the value of each pixels on the result. This can be tuned as well.
Colors ! It is very easy to apply a color map to this black and white map, and get completely different textures, like lava, ocean, dirt, wood, etc.
Different parameters will work better for different applications.
In a next article, I’ll play with colors, and explain how to generate Perlin noise to infinity, in a way that doesn’t require computing an initial noise the size of… infinity (which is how this whole tutorial thing actually started)