Questions regarding Perlin noise (how it works)

2.6k views Asked by At

I'm currently trying to learn Perlin noise, specifically 2D noise for terrain generation. I've been reading articles online over the past few days, but they don't all seem to agree on how Perlin noise works, and the ones that do seem authoritative are very complex to understand.

So I have some questions that I'm hoping someone here can help clarify.

  • Some articles talk about starting with a grid of random numbers (a 2D grid for 2D noise), which makes sense. However, other articles talk about filling the grid with gradient vectors. Which is actually used for Perlin noise?

  • I don't know what a "gradient" vector is, but if it's an actual vector, that means filling each point on the grid with two numbers, right? Is it just a way to get two random numbers per grid point, or is there a reason to treat it like a directional vector? The articles talk about calculating distances between the vectors, but I thought that was what the interpolation step was for...

  • Many articles on Perlin noise talk about combining multiple levels of noise into octaves with varying frequency and amplitude, to get the nice organic results that I'm looking for. However, other articles say that Perlin noise is just a single octave, and the act of combining multiple levels of noise into multiple octaves is actually "Fractional Brownian Noise". Which is actually correct? Is Perlin noise itself just a form of white noise, not the combined noise that everyone uses it for?

  • Some articles fill out the grid with an initial set of random values to work with, and some articles just write their noise function so that it isn't entirely random, but spits out the same value for a given input. Which makes sense so the result (especially in 2D) doesn't look chaotic. But what about when you start combining multiple octaves of noise (FBN)? Does each octave need to come from the same set of values? Or can you seed a separate grid (or generator function) for each octave? I'd like to avoid repetition (seeing the same pattern repeat over the resulting image), but I don't know what the logic behind it is.

  • As far as the grid of random values (or gradient vectors...) you start with, does the size of that grid have anything to do with the final size of the image you are creating? Or is is purely a function of the frequency? As you increase the sample resolution for each octave, are you using larger and larger grids, or just resampling the same initial grid at a finer resolution?

Any clarification would be very helpful. Thanks.

2

There are 2 answers

0
Richard Tingle On BEST ANSWER

I don't know what a "gradient" vector is, but if it's an actual vector, that means filling each point on the grid with two numbers, right? Is it just a way to get two random numbers per grid point, or is there a reason to treat it like a directional vector? The articles talk about calculating distances between the vectors, but I thought that was what the interpolation step was for

At each co-ordinate there is only a single number, however between grid points the actual value is interpolated. As such there is a gradient between (integer*) grid points. This can be seen here in Ken Perlins original source. An input of 1,2 or 3 floats (co-ordinates in 1D,2D or 3D space) returns a single float.

*Note that the input co-ordinates may be scaled such that integer grid points aren't at integer input co-ordinates.

Many articles on Perlin noise talk about combining multiple levels of noise into octaves with varying frequency and amplitude, to get the nice organic results that I'm looking for. However, other articles say that Perlin noise is just a single octave, and the act of combining multiple levels of noise into multiple octaves is actually "Fractional Brownian Noise". Which is actually correct? Is Perlin noise itself just a form of white noise, not the combined noise that everyone uses it for?

Perlin noise technically is the single octave, but isn't very useful like that. People therefore often combine many octave to create fractal noise (other base noise functions than Perlin can be used to create fractal noise). Often people just call fractal noise based on Perlin noise Perlin noise, this is wrong but common enough that you must make allowances for it.

Some articles fill out the grid with an initial set of random values to work with, and some articles just write their noise function so that it isn't entirely random, but spits out the same value for a given input. Which makes sense so the result (especially in 2D) doesn't look chaotic. But what about when you start combining multiple octaves of noise (FBN)? Does each octave need to come from the same set of values? Or can you seed a separate grid (or generator function) for each octave? I'd like to avoid repetition (seeing the same pattern repeat over the resulting image), but I don't know what the logic behind it is.

For the same input (co-ordinates & seed) the Perlin noise function should always spit out the same output. Whether you use this to prefill a grid or just get values as you go is entirely up to you. Each octave should have a different seed. This is a defined property of Perlin noise:

  • apparent randomness, it should look random to the human eye*
  • reproducable, meaning with the same input it will always give the
    same output*
  • smooth transition between values, meaning no sharp edges*

*ref http://www.angelcode.com/dev/perlin/perlin.html

As far as the grid of random values (or gradient vectors...) you start with, does the size of that grid have anything to do with the final size of the image you are creating? Or is is purely a function of the frequency? As you increase the sample resolution for each octave, are you using larger and larger grids, or just resampling the same initial grid at a finer resolution?

The inputted co-ordinates (and things like frequency that you set the function up with) should be what determines the properties of the noise. Assuming the range of entered co-ordinates remains the same the size of the grid should only effect the resolution with which you see the noise.

Different octaves of noise should have different seeds, but they are also on different scales; you are not just resampling the same grid at finer resolution for different octaves, you are scaling your co-ordinates.

0
Drinkwater On

This comes from my experience in using Perlin noise for procedural terrain.

Ordinary noise would have a square grid, where node values are randomly generated. Based on that, you define a function of two variables, such that:

  1. at a point that coincides with a grid node function value is equal to node value
  2. for any other point, given a grid square that contains it, do bilinear interpolation of the four node values, corresponding to that grid square

Pretty straightforward.

In Perlin noise, however, each grid node has a 2D vector for node value, not a single number. We still need our height function to map 2D plane to scalar height values, so saying that height at a node is equal to node value (2D vector) makes no sense.

Instead, height function at point P is defined like this:

  1. Take grid square that contains point P
  2. From each node of that square draw a vector V towards P
  3. For each node of that square take dot product of vectors V and that node's value (also a vector, remember), we get a scalar value
  4. Now we have four scalar values corresponding to each node. Just like with ordinary noise, do bilinear interpolation to find the height at point P

As a consequence of this definition, Perlin noise height function (PNHF) is always equal to 0 at grid nodes.

You can play with the domain of PNHF, for example rotating it, manipulating frequency (input scaling) and amplitude (output scaling), so you get an Octave.

Summing several different Octaves you can get pretty convincing terrains. The world's your playground. Good luck!