Perlin noise in C++11
Posted on July 18, 2012 by Paul
The code for this post is on GitHub: https://github.com/sol-prog/Perlin_Noise.
Ken Perlin’s noise function is the building block of many texture generation algorithms, you can use it to create realistically looking materials, clouds, mountains etc … The first version of this function was developed in 1988 and it is still used in various graphical libraries. In 2002 the author has published an improved version of his noise function.
I searched the Internet for a C++ implementation of the improved Perlin noise function, while obviously available in various libraries I didn’t found this implemented as a ready to use class. Also there seems to be a general confusion between what is a Perlin noise function, some websites confuse the Perlin noise function with FBM (Fractal Brownian Motion).
In the end I’ve found a Java reference implementationn of the improved Perlin function written by Ken Perlin himself. Converting this to C++11 was pretty straightforward.
Here is the class definition of my Perlin noise implementation:
The highlighted method from the above code allows the user to generate his own Perlin like function by creating a new permutation vector.
If you want to use the reference Perlin noise all you have to do is to create a PerlinNoise object in your code and call the noise member function:
The reference implementation uses a 3D form of the Perlin function, if you want to use this on a 2D domain you can simply ignore the third argument to the noise function. Geometrically, using a constant value for z can be seen as making a section trough the unit cube, so it make sense to keep this fixed for 2D images. You can also use the z channel for nice animation effects if you consider z as being the time of the animation.
If you want to create your own Perlin like function you could use a different version of the permutation array, which is basically a shuffled vector of integers from 0 to 255. I couldn’t resist the temptation of adding this capability to the PerlinNoise class:
- Start by generating an ordered sequence of integers from 0 to 255, we’ll store this in a C++ vector.
- Initialize a random number generator with a particular seed (you will want to save this number if you want to be able to repeat the obtained effect).
- Shuffle the ordered vector from the first step using the random engine initialized in the second step.
Here is the C++11 code that implements the above algorithm:
Thanks to mttd (see Comments) I’ve simplified a bit the above code using std::iota instead of std::generate and a lambda. This is the old version of the above member function:
In order to test this implementation of Perlin noise we’ll need an image I/O library. A few months ago I wrote a small PPM class that let’s you load, modify and save images in the PPM format. I’ll include here, for completeness, a part of the class definition, the complete code is on the Github repository:
Let’s write a small test program that will fill an image with Perlin noise and will save this as a PPM file on the disk:
For illustration purposes I’ve created a few images with the above code using the reference Perlin noise function and the permutation vector obtained with a seed = 237 (I chose 237 for no particular reason, you can use any positive integer number here, just record it in case you obtain some nicely looking textures and you want to be able to regenerate them at a later time).
A typical Perlin noise obtained with the reference permutation vector:
A typical Perlin noise obtained with my permutation vector:
A wood like Perlin noise obtained with the reference permutation vector:
A wood like Perlin noise obtained with my permutation vector:
The effect of using a different permutation vector is more pronounced in the last set of images.
If you are interested in reading more about procedural texture generations and various noise functions, you could read Texturing and Modeling: A Procedural Approach by D. S. Ebert, F. K. Musgrave, D. Peachey, K. Perlin, S. Worley:
If you are interested in learning more about the new C++11 syntax I would recommend reading The C++ Programming Language by Bjarne Stroustrup.
or, Professional C++ by M. Gregoire, N. A. Solter, S. J. Kleper: