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;
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?):
So, summing up, three questions:
- Is my code correct?
- The random function can be ported to PHP as described in the code? It throws no errors, but the results are not there.
- 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:
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
Summed up
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.