Ich entwerfe ein Spiel, das teilweise aus Planetenerforschung besteht. Ich möchte Pseudozufallsgenerierung für sie verwenden und aus einem definierten Startwert regenerieren, wenn ich sie laden muss, anstatt jedes Detail zu speichern, das zu schwer wäre. Ich speichere also nur den zufälligen Startwert und die vom Player vorgenommenen Änderungen in einer Datei.
Der Spieler muss in der Lage sein, den Planeten von der Umlaufbahn aus zu sehen (mit sehr geringen Details). Dann muss er auf den Boden sinken, die Details der Region, in der er landet, langsam erhöhen und die auf der anderen Seite befindlichen entladen des Planeten, die außerhalb des Sichtfeldes des Spielers gehen.
Wenn ich es auf einem ebenen Boden machen müsste, würde ich es leicht mit einem quadratischen Brocken-System machen. Das Problem dabei ist jedoch, dass Planeten - fast - Kugeln sind.
Was wäre also der beste Weg, um Bodendetails (Reliefs und geerdete Objekte) um einen bestimmten Punkt zu laden?
Ich habe zwar schon zwei Lösungen, aber beide haben eine Schwachstelle:
1. Schneiden Sie die Kugel in quadratische Stücke.
Sobald der Spieler nahe genug am Boden ist, muss ich nur die Details der nächsten Felder von seiner Position aus verbessern.
Wenn es nicht ausreicht, kann ich trotzdem jedes Quadrat in Unterquadrate schneiden, um es zu laden, wenn sich die Spieler auf oder nahe am Boden befinden.
Aber wie Sie auf dem Bild sehen können, gibt es ein Problem, wenn der Spieler versucht, auf einer Stange zu landen: Quadrate werden zu sehr schmalen Rechtecken oder sogar Dreiecken für die letzte Zeile und zusätzlich zu der Tatsache, dass es viele zu laden gäbe. Generation würde verzerrt erscheinen.
2. Ausgehend von einem Ikosaeder.
Hier könnte ich einfach die Dreiecks-Tessellation um die Position des Spielers erhöhen, wenn er sich nähert.
Aber ich weiß nicht, wie ich Dreiecke in der Nähe des Spielers ausfindig machen soll. Ich habe gehört, dass kartesische Koordinaten in diesem Fall nützlich sein könnten, aber ich weiß nicht, wie ich sie verwenden soll.
Ich verwende dafür C ++ / OpenGL, daher müssen hier hauptsächlich Scheitelpunkte generiert und geladen werden, die das Oberflächenrelief und die Farbe / Textur darstellen.
quelle
Antworten:
Okay, also habe ich es hier geschrieben:
http://www.maths.kisogo.com/index.php?title=Notes:Spherical_coordinates
(Ich brauchte das Mathe-Markup und es ist auch wirklich ziemlich lang)
Dokument anwenden
Das Dokument beginnt mit der Einführung des Begriffs einer Mannigfaltigkeit. Eine Mannigfaltigkeit ist dies, wo Teile davon "homöomorph" sind (im Grunde genommen: das Gleiche wie) Teile von R ^ n (R ^ 2 ist die x / y-Ebene, wie Sie möchten) kennt)
Ein Diagramm deckt einige (möglicherweise alle, obwohl es im Fall einer Kugel NICHT alle) einer Mannigfaltigkeit ab.
In dem Artikel entwickle ich 4 Diagramme für die Kugel, die Winkel bewahren, das heißt, sie halten regelmäßigen Abstand.
Wie Sie herausgefunden haben, ist es ziemlich schwierig, Koordinaten für Punkte auf einer Kugel anzugeben! Stattdessen geben wir (obwohl im Beispiel auf einem Kreis) jedem Punkt eine Koordinate der Form (i, x, y), wobei i eine Zahl zwischen 1 und 6 für eine Kugel und 1 und 4 für einen Kreis ist. Dies ist die Diagrammnummer.
X und y beziehen sich auf die Winkel in diesem Diagramm (oder nur auf x, wenn es sich um einen Kreis handelt).
Die 6 Diagramme einer Kugel sind die obere / untere Hemisphäre, die linke / rechte und die vordere / hintere Hemisphäre.
Koordinaten
Jetzt können Sie jedem Punkt eine "nette" Koordinate geben, die sich gut benimmt. In mathematischer Hinsicht sind die Bereiche der Diagramme "offene" Karten. Dies bedeutet, dass eine positive Zahl vorhanden ist, sodass sich auch ein Ball um jeden Punkt im Satz befindet. Zum Beispiel ist der Bereich (0,1) (die Menge, die x enthält, wenn 0 <x <1) offen, nehmen Sie ein beliebiges p in (0,1) (zum Beispiel 0,001), dann gibt es eine Zahl (zum Beispiel 0,0005) wie z dass jeder Punkt innerhalb von 0,0005 von 0,001 auch in (0,1) liegt.
Das heißt, Sie können Richtungen durch Diagramme führen.
Jetzt gibt es 45 Grad Überlappung in den Diagrammen, die wir entwickeln. Dies bedeutet , wenn Sie haben eine Funktion an den Koordinaten (i, x, y) Sie können sicher Punkte der Form angeben (i, x + a, y + b) so lange
a
undb
sind zwischen -45 und +45 (in Grad)Jeder Punkt der Form (i, x + a, y + b) kann problemlos in einen Punkt im "normalen" dreidimensionalen Raum umgewandelt werden.
Implementierung
Sie haben jetzt die Möglichkeit, Koordinaten für etwas auf einer Kugel zu speichern und Regionen mit großen Raumschwaden mit diesen Koordinaten zu kennzeichnen. Sie verhalten sich auch wie Koordinaten. Sie sind beispielsweise offen (was ein Problem ist, wenn Sie stattdessen 2 Winkel verwenden).
Sie können jetzt auch die Antworten "Wie erstelle ich eine reguläre Kugel?" Vollständig verwerfen, da Sie lediglich 6 Ebenen ausführen müssen und sicherstellen müssen, dass die Kanten der Ebenen aufeinander ausgerichtet sind (was trivial ist). Das Ergebnis ist:
Sie erhalten eine schöne Kugel mit benutzerfreundlichen Koordinaten
Bei Fragen bitte kommentieren, ich habe versucht, wenig Vorwissen anzunehmen. Ich bin auch neu im Unterrichten von Menschen
quelle
Wie Sie bereits gezeigt haben, gibt es eine Reihe von Lösungen für dieses Problem, aber keine 100% ideal. Kugeln sind schwierig.
Cube-basiert
Eine übliche Methode, die von Spore und wahrscheinlich auch von anderen Spielen verwendet wird (obwohl es schwer zu sagen ist, ohne unter die Haube zu gucken), besteht darin, die Kugel auf einen Würfel zu projizieren und über jeder Würfelfläche ein quadratisches Gitter zu verwenden.
(Dies beschreiben Alec Teal und dnk drone.vs.drones in den obigen Kommentaren.)
( Bild aus diesem Beitrag, in dem die Verwendung einer kubischen Darstellung für LoD beschrieben wird. )
Dies hat viele Vorteile der Breiten- und Längengradmethode mit viel weniger Spitzenverzerrung. Es ist einfach, zwischen Positionen auf dem Gesichtsgitter und Positionen auf der Kugel hin und her zu konvertieren, indem Sie entweder einen Vektor normalisieren oder durch seine größte Komponente im absoluten Wert dividieren. Es passt auch gut zu den Texturierungstechniken der Würfelzuordnung , die nützlich sein können, wenn Sie den gesamten Planeten aus der Ferne betrachten.
Der typische Mapping-Ansatz wird als gnomonische Projektion bezeichnet und weist immer noch ein Dichte-Mismatch-Problem auf, wie Sie im obigen Bild sehen können. Das Gitter ist in der Nähe der Würfelecken viel dichter als in der Mitte der Flächen. Wenn es auf Einheitlichkeit ankommt, können Sie dies mit den richtigen Mapping-Formeln reduzieren. Dies erschwert jedoch normalerweise das Umkehren des Mappings.
In allen Fällen tritt an den Ecken immer noch eine Winkelverzerrung auf, bei der ein gewöhnlicher Gitterschnittpunkt von vier Quadraten mit 90-Grad-Winkeln zu einem Zusammentreffen von drei Rauten mit 120-Grad-Winkeln wird.
Ikosaeder-basiert
Mein persönlicher Lieblingsansatz wäre die von Ihnen beschriebene ikosaedrische Version, da dadurch die maximale Winkelverzerrung so gering wie möglich gehalten wird. Wenn das Dreiecksgitter normalerweise sechs Dreiecke hat, die sich in einem Winkel von 60 Grad treffen, haben die Ikosaeder-Eckpunkte fünf Dreiecke, die sich in einem Winkel von 72 Grad treffen. Jeder hat also weniger Verzerrungen als die Quadrate im Würfelbeispiel.
Es ist nicht ganz so bekanntes Gebiet wie die Quadrate der Würfelversion, weshalb es wahrscheinlich nicht so beliebt ist. Es braucht ein bisschen mehr Mathe, um durchzuarbeiten.
Das Identifizieren von nahegelegenen Punkten ist jedoch nicht ganz so schwierig, wie es scheinen mag. Jede Ikosaeder-basierte geodätische Kugel kann auf ein regelmäßiges Dreiecksgitter abgeflacht werden:
Und ein reguläres Dreiecksgitter kann wie ein quadratisches Gitter behandelt werden, wie hier beschrieben .
Wenn Sie also einmal festgelegt haben, auf welchem Gesicht des Ikosaeders Sie sich befinden (was mit einem Raycast gegen ein Ikosaedernetz gemacht werden kann - ich kenne keine geschickte mathematische Methode, um diesen Teil zu vereinfachen), kann die Umgebung mithilfe von Vertrautem ausgefüllt werden Gitterdurchquerung. :)
Bearbeiten:
Wenn Sie eine geodätische Klasse I verwenden, können Sie Ihre Planeten in fünf rechteckige Diagramme packen, um Level-Chunks / Texturen / Heightmaps effizient zu speichern, ähnlich den sechs quadratischen Diagrammen, die Sie zum Speichern einer würfelbasierten Version verwenden würden:
(Dies könnte dazu beitragen, die Bedenken von Fuzzy Logic in einer anderen Antwort auszuräumen. Dies ist auch möglich, aber für Geodäten der Klasse II etwas komplizierter. Klasse III habe ich nicht untersucht.)
Der Trick ist, dass die Achsen dieser Diagramme bei der Verwendung nicht wirklich senkrecht zueinander stehen, sodass vorhandene Authoring- und Streaming-Tools / -Technologien dies nicht sofort unterstützen. Wenn Sie ohnehin vorhaben, Ihr eigenes Chunk-Streaming zu schreiben oder die Prozedurgenerierung im laufenden Betrieb zu verwenden, ist dies möglicherweise kein Problem. Möglicherweise können Sie das Authoring-Problem auch umgehen, indem Sie Ihre Quellzuordnungen in einer höheren Auflösung als erforderlich mit konventionelleren Tools generieren und sie dann durch einen Backprozess führen, der anhand von Stichproben entlang des Diagrammrasters eine dichte, effiziente Darstellung erstellt, die direkt passt in die ikosaedrische Struktur.
quelle
Quad-Sphere mit Chunked-LOD ist die bevorzugte Methode, wenn Sie in der Lage sein möchten, mit jedem detaillierten Terrain, entweder prozeduralen oder vordefinierten Höhenmaps und Texturen, vom Weltraum zum Boden zu gelangen.
Icosasphere bietet ein einheitlicheres Netz und ist leicht zu tessellieren, bereitet jedoch Probleme beim Versuch, Texturen und Höhenkarten zuzuordnen, die Sie zwischenspeichern müssen und auf diese Weise nicht sehr kompakt oder einfach sind.
Die Quad-Kugel hat Quetschpunkte, aber mit genügend Tessellation werden Sie sie sowieso nicht sehen. Dann können Sie Texturen abbilden und DLOD effektiv implementieren, als ob jede Region (Chunk) ein quadratisches Gitter wäre, ohne dass dies ein Problem darstellt. Dies ist im Vergleich zu einer Icosphere einfacher zu implementieren und wird sowohl in Bezug auf die Berechnung als auch in Bezug auf die Ressourcen effizienter.
Siehe Sean O'Neils Artikel über die Erzeugung eines prozeduralen Universums in Gamasutra:
- Teil 1 Perlin-Rauschen und fraktale Brownsche Bewegung für Höhenkarten und Texturen.
- Teil 2 ROAM-Algorithmus für das prozedurale Mesh mit DLOD zur Planetengenerierung. Leidet unter Leistungsproblemen. Nicht zu empfehlen, aber gut für den pädagogischen Wert.
- Teil 3 Behebt Probleme mit massiven Skalierungs-, Optimierungs- und Gleitkommaproblemen. Hauptsächlich bezogen auf die Universumsskala, aber auch anwendbar auf Planeten, wenn Sie von einer Skala von Lichtjahren zu Zentimetern wechseln möchten.
- Teil 4 Erläutert die Implementierung von Quad-Sphere mit Chunked (Quad-Tree) DLOD für die Planetengenerierung <- siehe insbesondere diesen Artikel
quelle
Ich bin kein Experte für Programmierung, aber Sie könnten eine Art Checkpoint haben. Während Sie einen Sicherheitskontrollpunkt passieren, kann die Oberfläche des Planeten mit Animation geladen werden und umgekehrt.
quelle