Ich spiele mit Perlin Noise, nachdem ich mit Diamond Square gearbeitet habe. Ich folgte der Implementierung von Hugo Elias , der im Grunde genommen eine Reihe von Funktionen mit x, y als Eingabe erstellt, um jeden Koordinatenwert zu werfen.
Mein PHP Code ist hier :
Ich habe zwei Fragen:
Wie benutze ich den Algorithmus, um eine Höhenkarte in einem Array zu generieren? Ich habe es nicht vollständig verstanden und habe nur den Pseudocode nach PHP portiert, aber die letzte Funktion (map_perlined) ausgeführt, nachdem ich irgendwo gelesen habe, dass der Algorithmus "magisch" Ihnen Übergangswerte für jeden angegebenen x, y-Punkt liefert (anscheinend, ohne dass Sie den Pseudocode lesen müssen) benachbarte Werte), ich bekomme dies nur bei Verwendung als Zufallsfunktionmt_rand(-100,100)/100;
Und dies bei Verwendung der kryptografischen 1.0-(($n*($n*$n*15731+789221)+1376312589)&0x7fffffff)/1073741824.0;
Methode (welche kann übrigens "wie besehen" in PHP implementiert werden?):
Zusammenfassend drei Fragen:
- Ist mein Code korrekt?
- Die Zufallsfunktion kann wie im Code beschrieben nach PHP portiert werden? Es werden keine Fehler ausgegeben, aber die Ergebnisse sind nicht da.
- Wie verwende ich den Algorithmus eigentlich?
AKTUALISIEREN
Ok, habe eine PHP-Portierung des in Gustavson Paper gezeigten Codes erstellt, und wie andere Programmierer sagten, erzeugt er nur eine Oktave. Haben Sie eine andere nützliche Seite, ein Dokument oder eine Anleitung, wie Sie diese mit den Konzepten von mehreren Oktaven, Amplitude, Frequenz usw. verwenden können, um die Rauschfunktion zu steuern? Auf Gustavsons Papier werden nur die Ergebnisse angezeigt, nicht die tatsächliche Implementierung des Algorithmus, vielleicht fehlt mir etwas?
UPDATE 2
@NATHAN
Ich habe etwas gemacht wie:
$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);
Und nachdem ich die Werte auf 0..1 normiert habe, erhalte ich eine ziemlich langweilige Höhenkarte wie:
Wie setze ich die Map? Vielleicht muss ich in der 3D-Version mit dem dritten Wert eine zufällige Höhe implementieren? Aber wenn ja, müsste ich herausfinden, um Nachbarwerte zu berücksichtigen, die mit so etwas wie einem Diamantquadrat-Algorithmus enden, genau das, was ich nicht tun möchte.
UPDATE 3
Mehr Perlin Arbeit. Ich muss noch einen Weg finden, um das Rauschen zu meinen Ergebnissen zu führen. Überprüfen Sie diese Oktaven und das Endergebnis:
Oktave I bis IV
Zusammengefasst
Jede Oktave ist ziemlich gleich. Überprüfen Sie den 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);
Die Ergebnisse werden normalisiert. Was würden Sie verwenden, um die Geräuschentwicklung stark zu beeinflussen? Ich sehe Beispiele, bei denen das Ändern der Amplitude weiche oder raue Oberflächen ergibt, aber selbst wenn ich eine große Amplitude gebe, sehe ich wenig Unterschied.
Antworten:
Was Sie implementiert haben, ist kein Perlin-Rauschen. Ich bin mir nicht sicher, warum Hugo Elias das sagt, aber er ist verwirrt. Hier ist die Referenzimplementierung von Ken Perlin. Es ruft eigentlich keinen externen Zufallszahlengenerator auf, sondern verwendet eine eingebaute Hash-Funktion, um die Pseudozufallsgradientenvektoren zu erzeugen.
Beachten Sie auch, dass Perlin-Rauschen nur aus einer Oktave besteht. Das Aufsummieren mehrerer Oktaven (skalierte Instanzen der Rauschfunktion), wie Hugo Elias vorschlägt, ist eine nützliche Technik, aber kein Teil des Perlin-Rauschens. Was Sie dabei erhalten, nennt man fraktales Rauschen, manchmal "fraktales Brownsches Rauschen" (wegen der vermuteten Ähnlichkeit mit der Brownschen Bewegung).
Wenn Sie geometrisch verstehen möchten, was der Algorithmus tut, versuchen Sie dieses Papier . Es handelt sich um eine andere Art von Rauschen, das als "Simplex-Rauschen" bezeichnet wird, enthält jedoch auch eine Erklärung des klassischen Perlin-Rauschens. Übrigens wurde Simplex-Rauschen auch von Perlin erfunden und soll eine Verbesserung gegenüber seinem klassischen Rauschen darstellen. Sie können es also auch implementieren, wenn Sie mit Rauschfunktionen spielen möchten.
quelle
Das ist ein weit verbreitetes Missverständnis. Was Hugo Elias "Perlin" -Rauschen nennt, ist in der Tat fraktales oder rosa Rauschen. Um besser zu verstehen, was Perlin-Rauschen ist, können Sie den in Nathan Reeds Antwort verlinkten Artikel von Perlin oder libnoise docs (es gibt den gleichen Fehler: Perlin-Rauschen ist das, was sie als Gradientenrauschen bezeichnen) oder CoherentNoise docs lesen .
Um Ihre Frage tatsächlich zu beantworten: Sie haben das erwartete Ergebnis nicht erhalten, weil die Rauschfrequenz zu hoch ist. Ihre Frequenzen beginnen mit 1 und erhöhen sich, was bedeutet, dass jedes Pixel in der resultierenden Karte einen zufälligen Wert hat. Um eine feinere Struktur der Karte zu sehen, müssen Sie das Rauschen "einzoomen". Ich spreche nicht wirklich PHP, aber ich nehme an, der Code sollte so aussehen:
Das heißt, Sie "strecken" eine Geräuschperiode über Ihre gesamte Karte. Natürlich können Sie auch andere Koeffizienten verwenden - probieren Sie einfach andere aus und sehen Sie, was passiert.
quelle