Riesige prozedural erzeugte 'Wildnis'-Welten


76

Ich bin sicher, dass Sie alle Spiele wie Dwarf Fortress kennen - massive, prozedural erzeugte Wildnis und Land. So ähnlich wie in diesem sehr nützlichen Artikel.

Ich fragte mich jedoch, wie ich dies in einem viel größeren Maßstab anwenden könnte. Mir fällt die Größenordnung von Minecraft ein (ist das nicht etwa 8x so groß wie die Erdoberfläche?). Pseudo-unendlich, denke ich, wäre der beste Begriff.

: D

Der Artikel spricht über fraktales Perlinrauschen. Ich bin in keiner Weise ein Experte, aber ich habe eine allgemeine Vorstellung (es ist eine Art zufällig erzeugtes Rauschen, das halbkohärent ist, also nicht nur zufällige Pixelwerte).

Ich könnte einfach die Bereiche X x X in der Größe definieren, einen Bereich laden-Typ hinzufügen und ein bisschen Rauschen haben, das einen Bereich erzeugt. Dies würde aber nur riesige Mengen von Inseln zur Folge haben.

Auf der anderen Seite glaube ich nicht, dass ich wirklich ein supermassives Blatt Perlin-Rauschen erzeugen kann. Und es wäre nur eine große Insel, denke ich.

Ich bin mir ziemlich sicher, dass Perlin-Lärm oder irgendein Lärm in irgendeiner Weise die Antwort wäre. Ich meine, die Karte sieht wirklich gut aus. Und Sie könnten die Ascii durch Fliesen ersetzen und etwas sehr Schönes bekommen.


9
"würde nur riesige Mengen an Inseln ergeben" - Oder es erzeugt Land mit Seen, wenn Sie nur Land / Wasser tauschen.

3
Trotzdem würden Sie eine große Anzahl von Seen in einem ziemlich normalen Muster erhalten.
Die kommunistische Ente

3
@Kylotan: Mincraft ist unendlich groß (nicht wirklich, aber wirklich groß ... Gesamtvolumen = Long.MaxValue x 128 x Long.MaxValue). Daher wird weder die gesamte Welt auf einmal generiert, noch wird die gesamte Karte gespeichert. Es generiert asynchron Bereiche mit 16x128x16 Blöcken, wenn diese zuvor noch nicht besucht wurden. Andernfalls werden sie von der Festplatte geladen.
Zfedoran

2
@Die kommunistische Ente: Ja, das ist wahr, ein Spiel wie Minecraft kann mit etwa 2 bis 4 Byte Daten pro Block davonkommen, aber nur ein Byte muss gespeichert werden, nachdem es nicht mehr sichtbar ist (ein Byte beschreibt die Art des Blocks) Die anderen Bytes beschreiben die Beleuchtung und andere Daten, die später neu berechnet werden können. Hier wird es interessant, Sie können RLE verwenden, um die gespeicherte Größe drastisch auf nur wenige Bytes zu reduzieren, da die Blöcke, wie Sie erwähnt haben, etwas kohärent sind.
Zfedoran

4
"Wirklich groß" ist nicht dasselbe wie "unendlich", und Sie können die beiden Begriffe nicht austauschbar verwenden. Wenn Sie die Karte so vergrößern, wie sie entdeckt wurde, ist dies eine endliche Größe, die bei Bedarf größer wird - ein ganz anderer Ansatz als unendlich zu sein. Jedes bisschen Wachstum kann nach Bedarf generiert werden. Die Geländedaten in Minecraft lassen sich sehr leicht komprimieren, da die Daten einen hohen Grad an Kohärenz aufweisen. (zB RLE wie erwähnt.)
Kylotan

Antworten:


35

Ich denke, ich verstehe besser, was Sie jetzt fragen.

Rauschen ist nicht zufällig - es sieht zufällig aus, basiert jedoch vollständig auf einer mathematischen Formel und ist wiederholbar. Alle Informationen sind in der Formel verschlüsselt. Dies bedeutet, dass Sie eine Formel haben können, die möglicherweise einen unendlichen Bereich abdeckt, und die Formel einfach für die Koordinaten des gewünschten Bereichs verwenden können. Wenn Sie einen angrenzenden Bereich benötigen, verwenden Sie die Formel einfach für die neuen Koordinaten erneut. Da die Formel kontinuierliche Werte liefert, werden die Bereiche nahtlos miteinander verbunden.

Hier ist ein vereinfachtes Beispiel, in dem Sinus anstelle von Perlin-Rauschen für die Höhenerzeugung verwendet wird und die Vorstellung, die Welt sei auf der X-Achse unendlich, auf der Y- und der Z-Achse jedoch nur 1 Einheit hoch.

Die Formel lautet: height(x,y) = sin(x/20)

Das Spiel beginnt und wir generieren Höhen für die nähere Umgebung, dh. (0,0) bis (9,0):

[0.0, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.34, 0.39, 0.43]

Wir haben einen Hügel, der sich nach rechts erhebt. Nehmen wir an, wir gehen bis zum Ende und müssen jetzt die Werte von (10,0 bis 19,0) generieren:

[0.48, 0.52, 0.56, 0.61, 0.64, 0.68, 0.72, 0.75, 0.78, 0.81]

Beachten Sie, wie der Hügel stetig ansteigt und dass der Wert bei (10,0) dem bei (9,0) folgt. Dies liegt daran, dass die Sinusfunktion stetig ist. Wenn Sie also zwei benachbarte Zahlen eingeben, erhalten Sie zwei benachbarte Ergebnisse - für eine bestimmte Definition von benachbart. Wenn Sie also Ihre Weltkoordinaten als Parameter für die Funktion verwenden, die Ihre Welt definiert, erhalten Sie eine kontinuierliche Landschaft, die unabhängig davon, wie viel oder wenig Sie gleichzeitig generieren, zusammenpasst. Wenn Sie neue Teile erstellen, werden diese automatisch aus den vorhandenen Teilen übernommen, da die Höhen bereits festgelegt sind.

Wenn sich die Welt nicht ändern wird, müssen Sie nicht einmal etwas speichern, da Sie anhand der Formel genau berechnen können, wie hoch die Höhe an einem bestimmten Punkt ist. Offensichtlich ist die Welt mit so etwas wie Minecraft total verformbar, so dass Sie einfach jeden Teil speichern, während Sie ihn erstellen. Angesichts der Tatsache, dass zwischen benachbarten Blöcken ein hohes Maß an Kohärenz besteht (dh, wenn ein Block Gras ist, ist es wahrscheinlich, dass auch der Block daneben Gras ist), können Sie die Daten sehr effizient komprimieren - die Lauflängencodierung würde funktionieren Na ja, aber dann wäre es fast jeder Standard-Kompressionsalgorithmus.

Während ich von der Höhe als dem offensichtlichsten Wert gesprochen habe, können Sie mit demselben System jedes gewünschte Merkmal generieren. Verwenden Sie eine mathematische Funktion mit stetigen Eigenschaften, bei der die Eingaben Ihre Weltkoordinaten sind und die über das Vorhandensein von Orientierungspunkten, Mineralvorkommen und Laichpunkten entscheiden kann. (Offensichtlich können sich die Werte in einer Formel auf eine andere Formel auswirken. Es macht keinen Sinn, ein Kohlevorkommen in der Luft zu platzieren. Daher generieren Sie die Welthöhenkarte und berechnen dann nur die Kohlemöglichkeiten für die Blöcke, die weit genug unter der Erde liegen.)


Sie haben definitiv geholfen, die Dinge aufzuklären, danke. :) Aber so etwas wie eine Rauschfunktion wäre nicht kontinuierlich. Und AFAICS, wenn es kontinuierlich ist, würde ich keine "zufällige" Welt erhalten. Oder fehle ich hier etwas?
Die kommunistische Ente

Entschuldigen Sie den doppelten Kommentar, aber ich glaube, dass das oben Gesagte davon getrennt ist. Wenn Sie sagen, dass Sie die Weltkoordinaten für das Perlin-Rauschen verwenden, wäre dies die gleiche Art von Effekt wie das Erzeugen des „riesigen“ Rauschens, jedoch in Teilen? Ich fühle mich heute etwas langsam.
Die kommunistische Ente

Nun, Ihre Geräuscherzeugung kann sicherlich kontinuierlich sein und ist es normalerweise, weil Sie es glätten. Um über Grenzen hinweg zu glätten, müssen Sie möglicherweise ein wenig über die Grenze lesen, aber das Prinzip bleibt dasselbe. Wenn das fragliche Rauschen pseudozufällige Daten benötigt, dann erzeugen Sie diese aus bekannten Größen - d. H. ein Hash Ihrer Weltkoordinaten. Die Leistungen sind dann vorhersehbar.
Kylotan

2
Was die Zufälligkeit betrifft, kann jede Welt ihren eigenen Startwert haben, der in den Berechnungen verwendet wird. z.B. sin (x + seed) anstelle von sin (x), in meinem obigen Beispiel. Jeder andere Same wird eine andere Welt erzeugen. Und in Bezug auf das riesige Blatt ... Ich bin mir nicht sicher, welche Relevanz das hat. Es spielt keine Rolle, wie viel oder wie wenig Sie generieren oder wann Sie dies tun. Der Anfangszustand der Welt wird durch die mathematische Formel definiert, und Sie verwenden diese Formel nur, um diesen Zustand nach Bedarf zu ermitteln.
Kylotan

32

Dieses Tutorial, das ich vor Jahren geschrieben habe, könnte Ihnen etwas geben, was Sie wollen:

Alt-Text

Wenn Sie die Inseländerung im letzten Schritt vornehmen, tendiert sie zu einer einzelnen Landmasse, die den Kartenrand nicht erreicht.


7
Tolle Visualisierungen!
Zfedoran

3
Ich erinnere mich, dass ich dieses Tutorial bei meiner Masterarbeit über die Simulation natürlicher Phänomene verwendet habe. Ich habe das Beispiel "Hügel" verwendet, um die Himmelskuppel über meiner 3D-Welt zu erstellen. Hervorragende Einführung in das Konzept der Geländegenerierung.
C. McAtackney

1
Verrückt, das ist großartig! Ich wusste nicht, dass es jemals jemand wirklich benutzt hat.
Munificent

1
OH MEIN GOTT !!! Ich habe dies auch in einem früheren Projekt verwendet ... der einfachste Weg, um Terrain zu generieren, auf das ich jemals gestoßen bin !!!
Krieg

15

Um eine große Insel zu erstellen, müssen Sie nicht alles auf einmal generieren. Ich würde Regionen asynchron aufbauen, wenn Sie sie besuchen.

Anstatt eine Maske zum Erstellen der Insel zu verwenden, wie im Artikel beschrieben, können Sie mit den Oktavenwellenlängen des Perlin-Rauschens spielen, um den gewünschten Look zu erzielen. Normalerweise beschreibt die erste Oktave die allgemeine Form des Geländes. Alle Oktaven danach fügen Sie einfach mehr Feinkörnigkeit hinzu. Spielen Sie daher mit der Wellenlänge der ersten Oktave, um zu steuern, wie groß Ihre Landmasse sein wird. Wenn die Landmasse in der Mitte sein soll, können Sie die Höhenkarte einfach um einen zunehmenden Betrag verringern, wenn Sie sich von der Mitte entfernen und dann das Rauschen normalisieren. Stellen Sie sich zum Beispiel vor, Sie kombinieren diese beiden Elemente, um Ihre Insel zu erstellen:

erste Oktave Einzelheiten

Dieser Artikel sollte helfen: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

Wenn Sie mehr über unendliche 3D-Welten und verschiedene Tricks erfahren möchten, mit denen Sie das Erscheinungsbild des Geländes durch Spielen mit den Ein- und Ausgängen für Rauschen ändern können, lesen Sie diesen Artikel: http://http.developer.nvidia.com /GPUGems3/gpugems3_ch01.html

Wenn Sie mit der Grafik-Pipeline und der Shader-Programmierung nicht vertraut sind, kann das Lesen etwas schwierig sein.


Die Art von Effekt, die ich erzielen möchte, ist so etwas wie ein 2-D-Top-Down der Minecraft-Karte (nicht das Spiel). Wenn ich nur weniger Oktaven verwenden würde, müsste ich dann nicht immer noch ein massives Blatt Perlin-Rauschen erzeugen? Oder könnte ich irgendwie nur eine sehr, sehr kleine Menge davon erzeugen?
Die kommunistische Ente

Ich glaube, Sie sind immer noch ein wenig verwirrt darüber, wie Perlin-Rauschen funktioniert. Sie können Blöcke mit 16 x 16 Blöcken einzeln generieren, indem Sie der Funktion die x- und y-Koordinatenoffsets für das Perlin-Rauschen senden. Beachten Sie, wie die PerlinNoise_2D-Funktion (float x, float y) die x- und y-Koordinate aufnimmt. Mit anderen Worten, es erzeugt Rauschen für eine bestimmte (x, y) Position. Das Erzeugen von weniger Oktaven ist auch nicht dasselbe wie das Ändern der Wellenlänge der Oktaven. Weniger Oktaven => Weniger feinkörniges Detail. Längere Wellenlänge => mehr gezoomt.
Zfedoran

Außerdem ist hier ein Artikel mit Code, der Ihnen zeigt, wie Sie Zoomen / längere Wellenlängen implementieren: dreamincode.net/forums/topic/66480-perlin-noise
zfedoran


7

Perlin Lärm und Freunde sind ein guter Ausgangspunkt, aber Sie möchten wahrscheinlich noch einen Schritt weiter gehen. Die meisten der beliebten Geräuschgeneratoren liefern ziemlich uninteressante Ergebnisse. Um das Terrain realistisch zu gestalten, sollten Sie sich die Algorithmen ansehen, die Erosionseffekte emulieren. Einer der fortschrittlichsten Spielesimulatoren der Welt - die Zwergenfestung - simuliert die Erosion als einen der Schritte, die die Welt aufbauen.

Eine der coolen Lösungen, die ich gesehen habe, wurde im Artikel "Advanced Particle Deposition" in Game Programming Gems 7 beschrieben. Es gibt viele andere im Internet, daher gibt es eine Menge Ressourcen, aus denen man ziehen kann (z. B. 1 oder 2 ). .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.