### Author Topic: Open-Source Perlin Noise C++ Library  (Read 9187 times)

#### Wes

• Newcomer
• Posts: 1
• Karma: +0/-0
##### Open-Source Perlin Noise C++ Library
« on: June 24, 2016, 07:03:35 PM »
Here is a C++ class for generating Perlin Noise. It is strongly based on Ken Perlin's java reference (found here http://mrl.nyu.edu/~perlin/noise/)
Before I go into detail, here are some demos:

1 Octave, 8 Frequency

7 Octaves, 3 Frequency, 0.5 Peristence

3 Octaves. 32 Frequency, 0.5 Persistence (Thresholded to look like caves)

The API centers around a class named Generator. The declaration is as follows:

Code: [Select]
`// A reference Perlin noise generatorclass Generator{ // Permutation vector for pseudo-random numbers std::vector<unsigned char> permutation; public: // Creates Perlin noise generator with reference permutation vector Generator(); // Creates Perlin noise generator with a custom seed Generator(unsigned int seed); // Returns noise value between -1.0 and 1.0 double get(double x, double y, double z) const; private: // Functions for interpolating noise static double lerp(double t, double a, double b); static double fade(double t); static double grad(int hash, double x, double y, double z);};`
To use this class, you simply construct an object and use the "get" function to generate noise. Here is an example:

Code: [Select]
`// Create reference Perlin generatorGenerator generator(); // Print noise at 55, 99, 0std::cout << generator.get(55, 99, 0) << std::endl; // Create new noise with new seedgenerator = Generator(42); // Print new noise at 55, 99, 0std::cout << generator.get(55, 99, 0) << std::endl;`
For convenience, I have created an additional class for generating fractal Perlin Noise in bulk. (Especially useful for procedural map generation in roguelikes) It has a constructor which accepts parameters for noise frequency, number of octaves, and persistence. The declaration is as follows:

Code: [Select]
`// A 2D array of doubles containing noise with easy access methodsclass Noise{ // 2D Array of doubles containing noise std::vector<double> map; // Dimensions of array unsigned short width, height;public: // Creates empty noise map Noise(); // Constructor that resizes map and populates it with noise Noise( unsigned short width,  // Number of columns unsigned short height, // Number of rows double frequency,      // Frequency of noise features unsigned int octaves,  // Number of octaves (halving frequency) double persistence,    // Compounding weight of octaves unsigned int seed      // Seed for Perlin noise engine ); // Returns a double from the map at the desired location // Values returned are between -1.0 and 1.0 // If the location does not exist, 0.0 is returned double get(unsigned short x, unsigned short y) const; // Resizes the noise map and populates it with noise void generate( unsigned short width,  // Number of columns unsigned short height, // Number of rows double frequency,      // Frequency of noise features unsigned int octaves,  // Number of octaves (halving frequency) double persistence,    // Compounding weight of octaves unsigned int seed      // Seed for Perlin noise ); private: // Sets the double at the provided location to the value provided void set(unsigned short x, unsigned short y,  double value); // Resized the double array (Invalidates current data) void resize(unsigned short width, unsigned short height);};`
To use this class, use the constructor to generate the noise and the "get" function to access the noise. Here is an example:

Code: [Select]
`// Generate noise with generation constructorNoise noise( 800,  // width 600,  // height 6.5,  // frequency 3,    // octaves 0.75, // persistence 42    // seed);// Print noise at 55, 99 using get functionstd::cout << noise.get(55, 99) << std::endl;// Generate new noise with generate functionnoise.generate( 800,  // width 600,  // height 6.5,  // frequency 3,    // octaves 0.75, // persistence 9001  // new seed!);// Print new noise at 55, 99 using get function againstd::cout << noise.get(55, 99) << std::endl;`
The demo images were generated with the following code using a ppm image library (https://github.com/WesOfX/ppm-image):
Code: [Select]
`int main(){ // Image size static constexpr unsigned short width = 512, height = 512; // Final image that will be saved PPM::Image image(width, height); // Noise that will be applied to image Perlin::Noise noise( width, height, 4.0, // Frequency 6,   // Octaves 0.5, // Persistence 0    // Seed ); // Apply noise to image for(unsigned short y = 0; y < height; y++){ for(unsigned short x = 0; x < width; x++){ // Convert noise value to 24 bit color value auto value = (unsigned char)(((noise.get(x, y) + 1) / 2) * 255); // Set pixel color to value image.set(x, y, PPM::Color(value, value, value)); } } // Save noise image image.write("Noise.ppm");}`
If you have any questions, feel free to post.
I you wish to read Ken Perlin's reference, it is located at http://mrl.nyu.edu/~perlin/noise/
The source is available on github at https://github.com/WesOfX/perlin-noise
Demo images created with https://github.com/WesOfX/ppm-image
Thank you
« Last Edit: June 25, 2016, 04:05:03 AM by Wes »