Sunday, January 10, 2016

algorithm - Understanding Perlin Noise


I'm toying with Perlin Noise after some work with Diamond Square. I followed the implementation by Hugo Elias that basically, makes a series of functions with x,y as input to throw each coordinate value.


My PHP code is here:


I have two questions:


How do I use the algorithm to generate a height map in an array? I did not fully understand it and just ported to PHP the pseudocode, but doing the last function (map_perlined) after reading somewhere that the algorithm "magically" gives you transitioned values for each x,y point given (apparently, without having to read its adjacent values), I just get this when using as random function mt_rand(-100,100)/100;


enter image description here


And this when using the cryptographic: 1.0-(($n*($n*$n*15731+789221)+1376312589)&0x7fffffff)/1073741824.0; (which, BTW, can be implemented "as-is" in PHP?):


enter image description here



So, summing up, three questions:



  1. Is my code correct?

  2. The random function can be ported to PHP as described in the code? It throws no errors, but the results are not there.

  3. How do I actually use the algorithm?


UPDATE


Ok, made a PHP port of the code shown in Gustavson paper, and as other coder said, it just generate one octave. Have any other useful site/paper/guide about how to use this with the concepts of multiple octaves, amplitude, frequency, etc. to control the noise function? On Gustavson's paper just shows the results, not the actual implementation of the algorithm, perhaps i'm missing something?


UPDATE 2
@NATHAN



I made something like:


$persistence = 0.5;

for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {

for ($o = 0; $o < 8; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += SimplexNoise($i*$frequency, $j * $frequency) * $amplitude;

}

//$value = SimplexNoise($i, $j) + 0.5 * SimplexNoise($i, $j) + 0.25 * SimplexNoise($i, $j);
$this->mapArray[$i][$j] = new Cell($value);

And after normalizing the values to 0..1, I get a rather dull height map such as:


enter image description here


How do I seed the map? Perhaps what I need to implement is the 3d version with the third value a random height? But if so, I'd have to find out to take in consideration neighbour values, which I'd be ending with something like a diamond square algorithm, exactly what I do not want to do.


UPDATE 3


More Perlin work. I have yet to find a way to guide the noise to my results. Check these octaves and the final result:



Octave I to IV


Octave1Octave2Octave3Octave4


Summed up


Octaves 1-4 summed


Each octave is pretty much the same. Check the code:


$persistence = 0.5;

for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
$value = 0;


for ($o = 0; $o < 4; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += improved_noise($i*$frequency, $j*$frequency, 0.5)*$amplitude;

}
$this->map[$i][$j] = new Cell($value);

The results are normalized. What would you use have a strong influence in the development of the noise? I see examples where changing the amplitude gives soft or rough surfaces, but even if I give a huge amplitude, I see little difference.




Answer



What you implemented isn't Perlin noise. I'm not sure why Hugo Elias says it is, but he's confused. Here is Ken Perlin's reference implementation. It doesn't actually call any external random number generator, but uses a built-in hash function to produce the pseudorandom gradient vectors.


Note also that Perlin noise consists of just one octave. Summing up multiple octaves (scaled instances of the noise function), as Hugo Elias suggests, is a useful technique, but not part of Perlin noise. What you get by doing that is called fractal noise, sometimes "fractal Brownian noise" (because of the supposed similiarity to Brownian motion).


If you want to understand geometrically what the algorithm is doing, try this paper. It's about a different kind of noise called "simplex noise", but also includes an explanation of classic Perlin noise. Incidentally, simplex noise was also invented by Perlin and is supposed to be an improvement over his classic noise, so you might try implementing it too if you're interested in playing with noise functions.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...