Perlin Noise

May 05, 2020

GameMaker Studio 2 Tutorials

Overview

Perlin Noise, created by Ken Perlin, is a type of gradient noise used in computer graphics.
What is “gradient noise”? Instead of getting a unique random value each time you call the function, you will input a seed, and that will give you a consistent value. It does this by looking up the seed in a pre-determined set of random values, and interpolating the values based on a gradient, or weight.

Algorithm

  1. Input coordinates in the form of (x, y).
  2. Find the (4) nearest integer points that surround the coordinates.
  3. Find the gradient, or weight of the coordinates to each point. This can be simply the distance, or some smoothing function can also be used.
  4. Get random values seeded by the points.
  5. Interpolate between each of these values.

Code

function rand_2d(_x, _y) {
    // Pseudo-random number generator
    return abs(frac(sin(dot_product(_x,
    _y, 12.9898, 4.1414)) * 43758.5453));
}

function smoothstep(_x) {
    return _x * _x * (3 - 2 * _x);
}

function noise_2d(_x, _y) {

    // Getting integer points that contain the coordinate
    var _x0 = floor(_x);
    var _y0 = floor(_y);
    var _x1 = _x0 + 1;
    var _y1 = _y0 + 1;

    // Determining gradients by getting distance from points
    var _xFrac = _x - _x0;
    var _yFrac = _y - _y0;
    // Uncomment these two lines if you want smoother values
    _xFrac = smoothstep(_xFrac);
    _yFrac = smoothstep(_yFrac);

    // Get noise values and interpolate
    var _v0, _v1;
    _v0 = lerp(rand_2d(_x0, _y0), 
               rand_2d(_x1, _y0), 
               _xFrac);
    _v1 = lerp(rand_2d(_x0, _y1), 
               rand_2d(_x1, _y1), 
               _xFrac);
    return lerp(_v0, _v1, _yFrac);
}

Example

Example Image Here, I rendered a map of generated Perlin noise values, sampling from 0-10 in both dimensions, using the smoothstep function for gradients. Pure black is a value of 0, while pure white is a value of 1.

Final Thoughts

There’s tons to be improved and played with when you go back to refactor this code. Try finding a smoother function to calculate gradients. After that, you can use this however you want, whether it’s generating terrain, or making interesting textures.

Thanks for reading!

-AH