Je joue avec Perlin Noise après avoir travaillé avec Diamond Square. J'ai suivi l' implémentation par Hugo Elias qui, fondamentalement, crée une série de fonctions avec x, y en entrée pour lancer chaque valeur de coordonnée.
Mon code PHP est ici :
J'ai deux questions:
Comment utiliser l'algorithme pour générer une carte de hauteur dans un tableau? Je ne l'ai pas bien compris et j'ai simplement porté en PHP le pseudocode, mais en faisant la dernière fonction (map_perlined) après avoir lu quelque part que l'algorithme vous "magiquement" vous donne des valeurs de transition pour chaque point x, y donné (apparemment, sans avoir à lire son valeurs adjacentes), je reçois juste ceci lors de l'utilisation comme fonction aléatoiremt_rand(-100,100)/100;
Et ceci lors de l'utilisation de la cryptographie: 1.0-(($n*($n*$n*15731+789221)+1376312589)&0x7fffffff)/1073741824.0;
(qui, BTW, peut être implémenté "tel quel" en PHP?):
Donc, en résumé, trois questions:
- Mon code est-il correct?
- La fonction aléatoire peut être portée en PHP comme décrit dans le code? Il ne génère aucune erreur, mais les résultats ne sont pas là.
- Comment utiliser réellement l'algorithme?
MISE À JOUR
Ok, fait un port PHP du code montré dans le papier Gustavson, et comme l'a dit un autre codeur, il ne génère qu'une octave. Avez-vous un autre site / document / guide utile sur la façon de l'utiliser avec les concepts d'octaves multiples, d'amplitude, de fréquence, etc. pour contrôler la fonction de bruit? Sur le papier de Gustavson montre juste les résultats, pas l'implémentation réelle de l'algorithme, peut-être que je manque quelque chose?
MISE À JOUR 2
@NATHAN
J'ai fait quelque chose comme:
$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);
Et après avoir normalisé les valeurs à 0..1, j'obtiens une carte de hauteur plutôt terne telle que:
Comment amorcer la carte? Peut-être que je dois implémenter la version 3D avec la troisième valeur une hauteur aléatoire? Mais si c'est le cas, il faudrait que je prenne en considération les valeurs des voisins, que je terminerais par quelque chose comme un algorithme carré de diamant, exactement ce que je ne veux pas faire.
MISE À JOUR 3
Plus de travail Perlin. Je n'ai pas encore trouvé de moyen de guider le bruit vers mes résultats. Vérifiez ces octaves et le résultat final:
Octave I à IV
Résumé
Chaque octave est à peu près la même. Vérifiez le 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);
Les résultats sont normalisés. Qu'est-ce que vous utiliseriez pour influencer fortement le développement du bruit? Je vois des exemples où le changement d'amplitude donne des surfaces douces ou rugueuses, mais même si je donne une amplitude énorme, je vois peu de différence.
Réponses:
Ce que vous avez implémenté n'est pas du bruit Perlin. Je ne sais pas pourquoi Hugo Elias le dit, mais il est confus. Voici l'implémentation de référence de Ken Perlin. Il n'appelle en fait aucun générateur de nombres aléatoires externe, mais utilise une fonction de hachage intégrée pour produire les vecteurs de gradient pseudo-aléatoires.
Notez également que le bruit Perlin se compose d'une seule octave. Résumer plusieurs octaves (instances mises à l'échelle de la fonction de bruit), comme le suggère Hugo Elias, est une technique utile, mais ne fait pas partie du bruit de Perlin. Ce que vous obtenez en faisant cela est appelé bruit fractal, parfois «bruit brownien fractal» (en raison de la similitude supposée avec le mouvement brownien).
Si vous voulez comprendre géométriquement ce que fait l'algorithme, essayez cet article . Il s'agit d'un type de bruit différent appelé "bruit simplex", mais comprend également une explication du bruit Perlin classique. Soit dit en passant, le bruit simplex a également été inventé par Perlin et est censé être une amélioration par rapport à son bruit classique, vous pouvez donc essayer de l'implémenter aussi si vous êtes intéressé à jouer avec les fonctions de bruit.
la source
C'est une idée fausse commune. Ce que Hugo Elias appelle le bruit «Perlin» est en fait du bruit fractal ou rose. Pour mieux comprendre ce qu'est le bruit Perlin, vous pouvez lire l'article de Perlin lié dans la réponse de Nathan Reed, ou libnoise docs (il y a la même erreur là-bas: Perlin noise est ce qu'ils appellent Gradient noise), ou CoherentNoise docs .
Maintenant, pour répondre à votre question: vous n'avez pas obtenu le résultat attendu car la fréquence du bruit est trop élevée. Vos fréquences commencent par 1 et augmentent, ce qui signifie que chaque pixel de la carte résultante a une valeur aléatoire. Pour voir une structure plus fine de la carte, vous devez "zoomer" sur le bruit. Je ne parle pas vraiment PHP, mais je suppose que le code devrait ressembler à ceci:
Autrement dit, vous "étirez" une période de bruit sur l'ensemble de votre carte. Bien sûr, vous pouvez utiliser d'autres coefficients - essayez simplement différents, voyez ce qui se passe.
la source