C # Perlin-Rauschen - „endlose“ Geländestücke erzeugen?

7

Ich schreibe gerade einen kleinen Side Scroller in C #, um sowohl C # zu lernen als auch Spaß zu haben. Im Moment habe ich einen einfachen Zufallsgenerator, der die Welt erzeugt, aber es ist nicht gerade großartig. Bei einigen Nachforschungen habe ich festgestellt, dass die Erzeugung von Perlin-Rauschen mir einiges helfen kann. Das Problem ist, ich möchte eine "endlose" Landschaft haben, die aus mehreren Stücken besteht.

Grundsätzlich sind meine Fragen / Bedenken:

  1. Wie bringt Notch am Beispiel von Minecraft (Ignorieren der 3. Dimension) jeden Block dazu, sich perfekt miteinander zu verbinden? Tunnel, Höhlen, Erzadern, Berge, flache Gebiete, Biomes usw. sind alle miteinander verbunden, obwohl jedes Stück separat und manchmal zu einem viel späteren Zeitpunkt erzeugt wird. Dies ist der Schlüssel für mich. Ich möchte, dass der Spieler nach rechts gehen kann und beim Gehen mehr Landschaft erzeugt, die mit der vorherigen Landschaft verbunden ist, einschließlich unterirdischer Tunnel und Höhlensysteme.
  2. Wie würde dies unter der Annahme geschehen, dass jeder Block ein Quadrat ist und die Welt 10 Quadrate hoch und unendlich viele Quadrate breit ist? Dh jeder "Block" ist 128x128 Kacheln und die Welt ist insgesamt 1.280 Kacheln hoch. (Dies ist so, dass ich eine unendlich tiefe Karte erstellen kann, wenn ich möchte - und auch um zu zeigen, dass alle 4 Seiten eines Blocks / Quadrats in der Lage sein müssen, eine Verbindung herzustellen und fortzufahren, was das vorherige Quadrat / Block getan hat).
Jon
quelle

Antworten:

10

Finden Sie eine C # -Implementierung von Simplex Noise, es ist wie Perlin, aber besser benommen und schneller.

Die Sache mit kontinuierlichen Rauschfunktionen wie Perlin und Simplex ist, dass sie deterministisch sind, Rauschen ist nicht zufällig . Was die meisten Rauschimplementierungen verwenden, ist ein Seed-Wert, der in das erzeugte Rauschen versetzt wird, wodurch sich Seed = 1 von Seed = 2 unterscheidet.

Aufgrund der obigen Beobachtung können Sie den Samen weiterhin wiederverwenden, und das gesamte neue Terrain, das beim Bewegen durch die Geräuschfunktion erzeugt wird, stimmt überein, da es nur dort ankommt, wo Sie aufgehört haben.

Dieser Teil davon ist ziemlich einfach und sehr schön. Was Sie mit dem erzeugten Geräusch machen, ist, wo die Magie passiert.

Für James ist das möglich, aber mein persönlicher Geschwindigkeitstest mit einem 3D-Rauschen zeigte, dass Simplex bei 3 schneller ist, könnte eine beliebige Anzahl von Faktoren in meinem persönlichen Test sein, aber er stimmte mit der allgemeinen Idee in der Literatur überein. Selbst wenn es langsamer wäre, würde ich Simplex empfehlen, da es nicht die "quadratischen" Artefakte zeigt, die Perlin macht.

Für Jon ist Noise eine mathematische Funktion, die nur Ergebnisse von Parametern ausspuckt und bei gleichen Parametern die gleiche Zahl zurückerhält. Ich sehe, woher die Verwirrung kommen könnte.

Diese Rauschfunktion wird wie folgt abgetastet: Anzahl = Rauschen (x, y, z); für dreidimensionales Rauschen. Beispielsweise kann Ihre erste Karte von X = 0,0 bis X = 1,9 abtasten, die Karte rechts davon wird fortgesetzt und von X = 2,0 bis 3,9 abgetastet

Ein Teil der Kunst, Rauschen zu verwenden, besteht darin, gute Bereiche zum Abtasten zu finden, zu entscheiden, wie viele Oktaven es gibt, zu filtern und zu verarbeiten usw. Schauen Sie sich eine praktische Rauschbibliothek an, um einige Beispiele und einen Quellcode von Perlin in Aktion zu sehen.

Patrick Hughes
quelle
2
Ich dachte, Simplex wäre nur in höheren Dimensionen schneller als 3 oder 4 über Perlin-Rauschen? Dass Perlin Simplex speziell zusammenstellte, um die höhere Dimension zu kompensieren, verlangsamte seinen ursprünglichen Algorithmus.
James
Wenn ich also beim Erstellen einer Welt einen zufälligen Startwert generiere und diesen Startwert weiter einspeise, wird eine Fortsetzung der neuen Geräuschkarte, die rechts von der ersten Geräuschkarte platziert wird, fortgesetzt? Dh wenn die anfängliche Rauschkarte eine Eisenader hat, wird diese Eisenader in der neuen Karte fortgesetzt? Wie genau funktioniert das? Woher weiß der Algorithmus, dass er die Rauschkarte auf der linken, rechten, oberen oder unteren Seite "fortsetzen" muss?
Jon
@Jon Ich habe meine Antwort bearbeitet, um besser zu beschreiben, was Rauschfunktionen tun. Ich hoffe, es ist sinnvoller, wie Rauschen verwendet werden kann, um fortlaufend Karten Stück für Stück zu erstellen. Die wichtigste Idee ist immer noch, dass Rauschen nicht zufällig ist.
Patrick Hughes
@PatrickHughes Wow, deine Bearbeitung hat es einiges geklärt, danke. Jetzt muss ich nur noch eine einfache C # / XNA-Klasse finden, mit der Simplex-Rauschen erzeugt werden kann.
Jon
2

Eine Rauschtabelle wird wie jede andere nahtlose Texturkarte vorberechnet, um nahtlos zu kacheln. Deshalb können Sie zu Punkt X gehen und es wird jedes Mal das gleiche sein, sehr wichtig in Animationen, damit sich die Texturen nicht von Bild zu Bild ändern.

Es gibt einen Thread dazu auf answers.unity3d.com (prozedurale Side-Scroller-Level-Generierung)

Das 1994 erschienene Buch "Procedural Modeling and Texturing" behandelt auch Rauschen und Multifraktale (geschichtetes Rauschen mit unterschiedlichen Frequenzen und Rotationen).

user16190
quelle
Ich verstehe Sie vielleicht falsch oder habe mich nicht sehr gut erklärt - ich möchte sie nicht nahtlos kacheln, ich möchte eine Reihe einzigartiger "Chunks" (Noise Maps) generieren, die miteinander verbunden sind - ich nicht. Ich möchte nicht, dass einer von ihnen gleich ist. Ich möchte nur, dass sie erkennen, dass "Hey, der Typ neben mir hat auf halbem Weg einen Tunnel - ich sollte diesen Tunnel fortsetzen"). Genau so wie Minecraft es macht, aber in 2d.
Jon