Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to add seed to Perlin noise?

I'm trying to implement 2D Perlin noise generation in C++, and some implementations I found use no seed at all (here, here or here). Other implementations take a seed value to get different noise depending on the noise value.

However I found example code where one added the seed value to the function parameters calculating the noise value for each octave (see PerlinNoise::Total() in the linked code). Another one uses a 3D seed function and uses the fixed seed value as the z value (couldn't find the example just now). Other articles suggest using other noise functions.

So my question would be, what the best way would be to add a seed value to Perlin noise generation is. Given the same seed value, the same noise values should be generated. If the solution would be to have a custom noise function, I would be interested if it could be implemented using Boost.Random (or C++11's Standard C++ Library classes).

Edit: To answer what I mean with "best" way: What's the best way that gives me Perlin noise like it was supposed to work, e.g. a gradient noise function.

like image 765
vividos Avatar asked Aug 27 '11 08:08

vividos


People also ask

Is simplex noise better than Perlin noise?

The advantages of simplex noise over Perlin noise: Simplex noise has lower computational complexity and requires fewer multiplications. Simplex noise scales to higher dimensions (4D, 5D) with much less computational cost: the complexity is. for.

Does Minecraft use Perlin or simplex noise?

Minecraft is specifically using Perlin noise calculations, like the kind you'd use to create a rough-looking texture for a 3D model. It starts out on a very broad level, painting a basic topographical map, and adds "noise" through finer terrain details like lakes, shrubbery and animals.

What is the algorithm for Perlin noise?

Perlin noise is a popular procedural generation algorithm invented by Ken Perlin. It can be used to generate things like textures and terrain procedurally, meaning without them being manually made by an artist or designer. The algorithm can have 1 or more dimensions, which is basically the number of inputs it gets.

What is lacunarity in Perlin noise?

Lacunarity. A multiplier that determines how quickly the frequency increases for each successive octave in a Perlin-noise function. The frequency of each successive octave is equal to the product of the previous octave's frequency and the lacunarity value.

How do you add a seed to a Perlin noise model?

Other authors added the seed value somewhere in this formula. The solution to add a seed to this type of Perlin noise implementation is to write a function that uniformly distributes output values for given x and y values (and by returning the same value for the same x and y values, of course).

How to seed the noise function?

So a seeding method that sets z, e.g. z = 10.0 * seed, could work for "seeding". Another way to seed the noise function would be this: If you always just get noise in a range of [0.0; 64.0 [ for x and y, one could seed the noise by adding an offset to x, y or both when calling the noise function: noise (x + 64.0*seed, y + 64.0*seed).

Is there a way to generate Simplex noise with boost random?

Google for Simplex Noise. The Simplex Noise function looks a lot like Perlin and has some properties that are preferable to Perlin Noise. The randomness is in the look-up table, that you can seed when you generate it. If boost random allows you to have pseudo randon generation I do not see why not.

Is there a good noise generator with random seed values?

I've used libnoise ( libnoise.sourceforge.net) which has a variety of noise types with seed values. Google for Simplex Noise. The Simplex Noise function looks a lot like Perlin and has some properties that are preferable to Perlin Noise. The randomness is in the look-up table, that you can seed when you generate it.


1 Answers

Since no one is going to write up an answer from the comments, I'm trying myself. Please upvote when I'm correct, comment when not :)

There are several implementations and example code that (try to) implement Perlin noise. First, there is the Improved Noise reference implementation from Ken Perlin himself.

Case 1: Improved Noise reference implementation

The noise function takes three double values and outputs a value. When generating a 2D bitmap using x and y, and keeping z constant, one gets the well known Perlin noise pattern. When z is varied between 0.0 and 1.0, the noise clouds seem to "change" slowly. So a seeding method that sets z, e.g. z = 10.0 * seed, could work for "seeding".

Another way to seed the noise function would be this: If you always just get noise in a range of [0.0; 64.0[ for x and y, one could seed the noise by adding an offset to x, y or both when calling the noise function: noise(x + 64.0*seed, y + 64.0*seed).

Case 2: Tutorial style Perlin noise code

Then there is an implementation of Perlin noise (adapted and used in many other Perlin noise tutorials) that have a base noise function like this (pseudocode):

function Noise2(integer x, integer y)
    n = x + y * 57
    n = (n<<13) ^ n;
    return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589)
       & 7fffffff) / 1073741824.0);    
end function

My main skepticism came from the magic numbers and the trust of the authors of these pages that the formula leads to uniformly distributed noise. Other authors added the seed value somewhere in this formula.

The solution to add a seed to this type of Perlin noise implementation is to write a function that uniformly distributes output values for given x and y values (and by returning the same value for the same x and y values, of course). This function can be written using Boost.Random (code not tested):

double Noise2(int x, int y)
{
   uint32_t seeds[3] = { uint32_t(x), uint32_t(y), seed };
   boost::mt19937 rng(seeds, seeds+3);
   boost::uniform_real<> dist(0.0, 1.0);
   boost::variate_generator<boost::mt19937&, boost::uniform_real<> >
      die(rng, dist);
   return die();
}

The random number generator has some ctors, among them one that takes a range of uint32_t's that determine the initial state of the RNG.

There also are libraries that generate coherent noise, such as libnoise, that may be of help here.

Simplex Noise

I didn't ask of Simplex noise, but the one implementation (from Stefan Gustavson) I found uses a similar technique (some precomputed tables) like Ken Perlin's reference implementation, and could be seeded just like case 1 above. Commenter Robinson mentioned seeding when generating the look-up table, but I don't know how that would work.

like image 80
vividos Avatar answered Nov 15 '22 19:11

vividos