Landschaften - Institut für Visualisierung und Interaktive Systeme
Transcription
Landschaften - Institut für Visualisierung und Interaktive Systeme
Seminar Algorithmen für Computerspiele“ ” Prozedurale Modellierung: Terrains Katrin Scharnowski 13. Juli 2010 Institut für Visualisierung und Interaktive Systeme Universität Stuttgart Inhaltsverzeichnis 1 Prozedurale Modellierung 1.1 Begriff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Anwendungsgebiete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Heightmap-basierte Terrain-Modellierung 2.1 Einführung . . . . . . . . . . . . . . . 2.2 Der Fault-Algorithmus . . . . . . . . . 2.3 Voronoi-Diagramme . . . . . . . . . . 2.4 Noise . . . . . . . . . . . . . . . . . . . 2.4.1 Spektral-Synthese . . . . . . . 2.4.2 Perturbation . . . . . . . . . . 2.5 Thermale Erosion . . . . . . . . . . . . 2.6 Praxis . . . . . . . . . . . . . . . . . . 2.7 Beispiele . . . . . . . . . . . . . . . . . 2.7.1 Tribal Trouble . . . . . . . . . 2.7.2 Terragen . . . . . . . . . . . . . 2 2 2 2 . . . . . . . . . . . 5 5 5 7 9 9 9 10 12 13 13 13 . . . . . . . . . . 15 15 15 16 16 17 18 18 19 19 19 4 Schluss 4.1 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Bewertung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 21 21 Literatur 21 3 Voxel-basierte Terrain-Modellierung 3.1 Einführung . . . . . . . . . . . . 3.2 Der Marching-Cubes-Algorithmus 3.3 Eine Dichte-Funktion generieren 3.3.1 Initialisierung . . . . . . . 3.3.2 Spektral-Synthese . . . . 3.4 Praxis . . . . . . . . . . . . . . . 3.4.1 Plattformen . . . . . . . . 3.5 Beispiele . . . . . . . . . . . . . . 3.5.1 Forever War . . . . . . . . 3.5.2 Acropora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Prozedurale Modellierung 1.1 Begriff Möchte man ein Modell erzeugen, so gibt es dafür im Allgemeinen verschiedene Vorgehensweisen. Neben der rein manuellen Modellierung kann z.B. über verschiedene Scan-Verfahren die Form von realen Objekten zu Geometrie-Daten ausgewertet werden. Prozedurale Modellierung stellt eine weitere Möglichkeit dar. Hier werden die Modelle von einem dafür vorgesehenen Algorithmus erzeugt und der menschliche Einfluss auf das Ergebnis ist nur indirekt möglich, indem einzelne Parameter der entsprechenden Prozedur verändert werden. 1.2 Motivation Durch prozedurale Modellierung besteht, neben der Reduzierung des Festplattenspeicherbedarfs, die Möglichkeit Arbeitszeit einzusparen. Dies zeigt sich vor allem wenn viele ähnlich aussehende Objekte erstellt werden sollen, da hier der entsprechende Algorithmus einmal implementiert werden muss und zur eigentlichen Modellierung nur die Veränderung der entsprechenden Parameter nötig ist. Prozedurale Modellierung ermöglicht es außerdem durch die Verwendung spezieller Algorithmen bestimmte physikalische Vorgänge in der Natur besonders exakt zu imitieren und so den Realismus der Ergebnisse zu erhöhen. Jedoch muss bedacht werden, dass sich prozedurale Modellierung trotz der Vorteile nicht für jede Art von Modell eignet. Schwierig sind vor allem Objekte, die aus vielen unterschiedlich aussehenden Einzelteilen bestehen, die eine bestimmte festgelegte Anordnung haben, dazu zählen z.B. Alltagsgegenstände wie Fahrräder, ein Uhrwerk, aber auch Gesichter. Zudem benötigt das prozedurale Erstellen von Modellen, je nach Art der Implementierung, unter Umständen eine merkliche Rechenzeit, was als Preis für den geringeren Festplattenspeicherbedarf gesehen werden kann. Es lässt sich außerdem sagen, dass, subjektiv betrachtet, die indirekte Einflussname über Parameter nicht immer so intuitiv ist wie beispielsweise die manuelle Modellierung in einem entsprechenden Programm. 1.3 Anwendungsgebiete Wie bereits angedeutet eignet sich prozedurale Modellierung vor allem für Objekte, die eine gewisse Regelmässigkeit innerhalb ihres Aufbaus aufweisen. Dies trifft zum Beispiel auf natürliche Vegetation zu. Bei der prozeduralen Modellierung von 1.3 Anwendungsgebiete 3 Pflanzen wird über sogenannte selbstorganisierende Modelle versucht die Natur nachzuahmen, indem die Geometrie unter der Einhaltung bestimmter Regeln, die sich am natürlichen Wachstumsprozess orientieren, aufgebaut wird (siehe auch [9]). Derartige prozedurale Modelle werden z.B. in der Entwicklungsumgebung SpeedTree verwendet, die in diversen kommerziellen Spielen zum Einsatz kommt. Abbildung 1.1: Ein prozedurales Baum-Modell (links), prozedurale Vegetation in The Elder Scrolls IV: Oblivion (rechts) [1]. Ein weiteres Anwendungsgebiet stellt die prozedurale Modellierung von Gebäuden bzw. Architektur dar. Hier werden die Objekte durch sogenannte Shape-Grammars gebildet, die, basierend auf einer Menge von kontextsensitiven Ersetzungsregeln, die Modelle aufbauen. Diese Regeln machen es möglich unter bestimmten Bedingungen Objekte zu transformieren oder durch andere Objekte zu ersetzen und so die gewünschte Menge von Modellen zu erzeugen. Abbildung 1.2: Zwei prozedural modellierte Gebäude, die auf derselben Menge von Ersetzungsregeln basieren [7]. Zu guter Letzt bietet es sich noch an Terrains bzw. Landschaften prozedural zu erzeugen. Speziell bei der Simulation von Erosion oder bei der Erzeugung “zufälliger“ Unregelmäßigkeiten ist es schwer sich auf rein manuelle Methoden zu beschränken, da der Aufwand, die 4 Prozedurale Modellierung nötige Präzision und die Komplexität zu hoch wären. Abbildung 1.3: Ein prozedural erzeugtes Terrain, die detailreiche Oberflächenstruktur wäre durch manuelle Modellierung nur schwer zu erreichen [8]. 2 Heightmap-basierte Terrain-Modellierung 2.1 Einführung Heightmaps zeichnen sich besonders durch ihren einfachen Aufbau und ihre einfache Implementierung aus. Es wird lediglich ein zweidimensionales Array erzeugt, in dem die jeweiligen Höhenwerte gespeichert werden. Dieses Array lässt sich als Triangle-Strip oder mit Hilfe von Triangle-Fans rendern, wobei sich die Koordinaten der Vertizes aus den Indizes des Arrays und den Höhenwerten an der entsprechenden Stelle ergeben. Heightmaps können aufgrund ihrer Struktur auch als Textur, bzw. Bild aufgefasst werden, das mit Graustufen-Werten gefüllt ist. Darum wird ein solches Graustufen-Bild oft als Repräsentation für eine Heightmap gewählt (Abbildung 2.1). Abbildung 2.1: Repräsentation einer Heightmap durch ein Graustufen-Bild (links) und als Polygon-Grafik gerendert (rechts) [8]. 2.2 Der Fault-Algorithmus Um mit dem Fault-Algorithmus eine Terrain-Form zu erzeugen wird zunächst eine zufällige Gerade g in der x-z-Ebene bestimmt, die die Heightmap in zwei Abschnitte teilt. Die Höhenwerte der Punkte können anschließend berechnet werden, indem jeder Punkt der Heightmap einem der beiden Abschnitte zuordnet wird. Dafür wird der Richtungsvektor von g als Normalen-Vektor einer senkrecht auf der Heightmap stehenden Ebene aufgefasst. Sei nun e(x, y, z) = ax + by + cz + d die Koordinatengleichung dieser Ebene und of f s das aktuell verwendete Offset, dann ist 6 Heightmap-basierte Terrain-Modellierung ( h(x, z) + of f s, h(x, z) = h(x, z) − of f s, falls e(x, 0, z) ≥ 0 falls e(x, 0, z) < 0 Es werden also alle Punkte der Heightmap im ersten Abschnitt um ein bestimmtes Offset angehoben und die Punkte im zweiten Abschnitt um dasselbe Offset abgesenkt, wodurch eine Treppenform erzeugt wird. Dieses Vorgehen wird nun jeweils mit einer neuen zufälligen Gerade sooft wiederholt bis die gewünschte Anzahl von Iterationsschritten erreicht ist (siehe auch [2]). (a) eine Iteration (b) 10 Iterationen (c) 25 Iterationen (d) 50 Iterationen (e) 100 Iterationen (f) 400 Iterationen Abbildung 2.2: Zustand der Heightmap nach 1, 10, 25, 50, 100 bzw. 400 Iterationen des Fault-Algorithmus bei konstantem Offset. Neben der Wahl eines konstanten Offsets wie in Abbildung 2.2 besteht die Möglichkeit den Wert nach jedem Iterationsschritt durch einen bestimmten Faktor zu verringern. Da auf diese Art aber relativ schnell keine wahrnehmbaren Höhenunterschiede mehr erzeugt werden, bietet es sich an das Offset asymptotisch gegen einen geeigneten Grenzwert laufen zu lassen, so dass auch nach einer größeren Anzahl von Iterationsschritten noch eine Veränderung zu sehen ist. Eine weitere Möglichkeit der Variation stellt das Ersetzen der Treppenform durch andere Funktionen dar. Eine Verwendung des Cosinus oder Sinus hätte beispielsweise ein glatteres und runderes Aussehen des Terrains zur Folge. Einen ähnlichen Ansatz wie der Fault-Algorithmus verfolgt der Circles-Algorithmus, wobei der Unterschied lediglich in der Art der Aufteilung der Heightmap liegt. Nach der Bestimmung eines zufälligen Punktes p auf der Heightmap werden alle Punkte, die sich innerhalb 2.3 Voronoi-Diagramme 7 eines bestimmten Radius um p befinden so verschoben, dass sie eine nach oben gerichtete Halbkugel bilden. Dabei kann der Radius, ähnlich dem Offset, wie oben beschrieben, variiert werden. Anders als beim Fault-Algorithmus lassen sich so z.B. durch die Wahl eines anfangs großen, schnell kleiner werdenden Radius, einzelne herausstehende Berge generieren. Abbildung 2.3: Terrain nach 1 bzw. 300 Iterationen des Circles-Algorithmus 2.3 Voronoi-Diagramme Voronoi-Diagramme definieren eine Aufteilung des Raumes in zusammenhängende Punktemengen, sogenannte Regionen in Abhängigkeit einer Teilmenge Q = {q0 , q1 , ..., qn } von Punkten. Die Region eines Punktes qi enthält dabei genau diejenigen Punkte, die zu diesem Punkt einen geringeren Abstand als zu allen anderen Punkten aus Q haben. Formal ist eine Region definiert durch R(qi ) = { p | ∀qj ∈ Q, j 6= i : dist(p, qi ) < dist(p, qj ) } Es gibt also auch Punkte die keiner Region zugeordnet werden. Diese Punkte haben zu mehreren Elementen aus Q denselben Abstand und bilden somit die Kanten des VoronoiDiagramms. Aus Sicht der Terrain-Generierung ermöglichen Voronoi-Diagramme damit eine explizite Kontrolle über einzelne zusammenhängende Punktemengen auf der Heightmap. Eine Möglichkeit aus einem Voronoi-Diagramm ein Terrain zu generieren besteht darin, die Höhenwerte als Linearkombination der Abstände zu den einzelnen Punkten aus Q zu berechnen. Die endgültige Form des Terrain kann dann durch die vorherige Festlegung von Koeffizienten c0 , ..., cn beeinflusst werden. Um die Koeffizienten richtig zuzuordnen werden zuerst die Abstände zu den qi bestimmt und anschließend aufsteigend der Größe nach geordnet. Die Höhe h(x, z) ist dann h(x, z) = c0 d0 + c1 d1 + ... + cn dn 8 Heightmap-basierte Terrain-Modellierung Abbildung 2.4: Ein Voronoi-Diagramm mit 7 Regionen (die zugehörigen Punkte qi sind rot dargestellt). Punkte, die auf den Kanten (blau) liegen gehören zu keiner Region. mit d0 < d1 < ... < dn (siehe auch [8]). Aufgrund der vielen auffällig geraden Kanten sehen die so entstandenen, meist wabenartigen, Formen in der Regel recht unnatürlich aus und müssen noch weiter bearbeitet werden (siehe Abschnitt 2.4). (a) c0 = 1, restliche ci = 0 (b) c0 = −1, c1 = 1, restliche ci = 0 (c) c0 = 1, c1 = −1, restliche ci = 0 (d) willkürliche ci Abbildung 2.5: Voronoi-Diagramme und die Auswirkung verschiedener Koeffizienten auf das Terrain. 2.4 Noise 9 2.4 Noise Bei der prozeduralen Terrain-Generierung ist es nicht immer einfach eine interessante Grundform und eine abwechslungsreiche Terrain-Oberfläche innerhalb einer Prozedur zu erzeugen. Die Verwendung von Noise ermöglicht es die oftmals steril wirkenden, glatten Oberflächen im Nachhinein interessanter zu gestalten indem die Werte einer Noise-Funktion auf eine vorhandene Heightmap addiert werden. 2.4.1 Spektral-Synthese Eine simple Möglichkeit Noise-Funktionen zu erstellen bietet die sogenannte SpektralSynthese. Dabei werden zuerst einzelne Noise-Funktionen mit verschiedenen Frequenzen und Amplituden erzeugt, indem in festen Abständen Zufallswerte zugewiesen und die Werte dazwischen interpoliert werden. Diese Funktionen werden anschließend, wie in Abbildung 2.6 zu sehen, addiert und ergeben so eine neue Funktion mit höherem Detailgrad. (a) f0 (b) f1 (c) f2 = f0 + f1 Abbildung 2.6: Spektral Synthese im 1D-Raum, f1 besitzt im Vergleich zu f0 eine verdoppelte Frequenz, sowie eine halbierte Amplitude, f2 entspricht der Addition der beiden Funktionen. Dieses Vorgehen lässt sich auf beliebig viele Dimensionen erweitern um Heightmaps (siehe Abbildung 2.7), 3D-Texturen oder sogar Bewegungsmuster zu erzeugen. 2.4.2 Perturbation In einigen Fällen reicht es nicht aus die Höhenwerte durch Noisefunktionen vertikal zu verschieben, insbesondere wenn sich im Terrain einzelne gerade Linien stark abzeichnen, wie es beispielsweise bei Terrains der Fall ist, die mit Voronoi-Diagrammen erzeugt wurden. Hier kann es helfen die Werte zusätzlich horizontal zu verschieben und somit zu “verwirbeln“. Dafür wird jedem Punkt auf der Heightmap ein zufälliges Offset in x- und z-Richtung zugewiesen und der Wert entsprechend verändert. Sei also n(x, z) eine Noise-Funktion, dann wird die neue Heightmap berechnet durch hneu (x, z) = halt (x + n(x, z), z + n(x, z)) 10 Heightmap-basierte Terrain-Modellierung (a) 2D-Noise mit jeweils in der nächsten Detailstu- (b) Die Summe aller Detailstufen fe halbierter Amplitude, sowie verdoppelter Fre- entspricht der endgültigen Noisequenz. Funktion. Abbildung 2.7: Spektral-Sythese im 2D-Raum erzeugt eine mit Rauschen gefüllte Heightmap [3]. Dabei ist zu beachten, dass n(x, z) eine stetige Funktion sein sollte, damit Punkte, die in der alten Heightmap nahe beieinander liegen, auch ein ähnliches Offset zugewiesen bekommen. Würde n(x, z) nur aus weißem Rauschen bestehen, dann würde die ursprüngliche TerrainForm nicht nur verwirbelt, sondern komplett zerstört werden, da nebeneinanderliegende Höhenwerte dann keinerlei Zusammenhang mehr hätten. Abbildung 2.8: Ein mit Voronoi-Diagrammen erstelltes Terrain vor (links) und nach der Anwendung von Perturbation. 2.5 Thermale Erosion Durch die Imitation von thermaler Erosion kann der Realismus-Grad des Terrains noch weiter erhöht werden. Dabei wird ein Vorgang in der Natur nachgeahmt, bei dem durch 2.5 Thermale Erosion 11 starke Temperaturschwankungen (z.B. Tag- und Nachtwechsel) bestimmte Gesteinsschichten rissig und porös werden und schließlich wegbrechen. Das so entstandene Geröll verteilt sich anschließend in der näheren Umgebung und füllt tiefer liegende Mulden und Täler auf. Das Gelände erhält hierdurch ein etwas flacheres, gleichmäßigeres Aussehen wie in Abbildung 2.9 zu sehen. Abbildung 2.9: Ein Terrain vor und nach der Anwendung thermaler Erosion (100 Iterationsschritte) [4]. Um diesen physikalischen Vorgang in einem Algorithmus zu formalisieren wird zunächst ein minimaler Höhenunterschied H festgelegt, den zwei benachbarte Punkte auf der Heightmap mindestens haben müssen. Anschließend werden nach und nach alle Punkte der Heightmap mit ihren 8 Nachbarpunkten q0 · · · q7 verglichen. Ist der Höhenunterschied eines Punktes p zu einem seiner Nachbarn qi dabei größer als H, wird solange Material von p nach qi verteilt bis der Höhenunterschied H entspricht. Eine exakte Umsetzung dieses Verfahrens wäre zwar mathematisch möglich, beispielsweise durch ein lineares Gleichungssystem, bei dem die Unbekannten für die Menge von Material ständen, die einem Punkt qi zugeteilt würde. Jedoch würde man damit unter Umständen die Gesetze der Physik missachten, da dieses Gleichungssystem auch negative Lösungen haben könnte. Eine Möglichkeit, Material so zu verteilen, dass die Höhenunterschiede zwischen den einzelnen Punkte sich asymptotisch an H annähern wird in [8] beschrieben. Dafür werden zunächst alle Höhenunterschiede di eines Punktes mit seinen Nachbarpunkten ausgerechnet. Anschließend werden das Maximum dM AX dieser Höhenunterschiede, sowie die Summe dT OT AL aller di > H berechnet. Nachbarpunkte, die den Mindesthöhenunterschied H bereits unterschritten haben werden bei der Berechnung von dT OT AL folglich nicht beachtet. Zudem wird ein Koeffizient c zu Steuerung der Stärke der Erosion festgelegt. Sei nun h die Höhe des aktuell betrachteten Punktes p und hi die Höhe eines Nachbarpunktes qi , dann berechnet sich die neue Höhe aller Punkte wie folgt (siehe Abbildung 2.10): 12 Heightmap-basierte Terrain-Modellierung hi = hi + c ∗ (dM AX − H) ∗ di dT OT AL es ist außerdem h = h + c ∗ (dM AX − H) H d1 H d0 h0 h h1 h0 h h1 Abbildung 2.10: Höhenwerte vor (links, mit dM AX = d0 ) und nach Durchführung eines Iterationsschrittes (rechts) bei c = 0.45 und H = 1.0. h1 hat den Mindesthöhenunterschied H unterschritten und wird beim nächsten Iterationsschritt nicht weiter erhöht. 2.6 Praxis In der Praxis ist es oft notwendig, dass ein Terrain bestimmte Anforderungen erfüllt, die auch durch eine geschickte Wahl von Algorithmen nicht immer garantiert werden können. In Strategiespielen werden beispielsweise oft große, zusammenhängende Flächen benötigt um z.B. Gebäude zu platzieren oder Einheiten bewegen zu können. Um diese Anforderung zu erfüllen ist es nötig nach der eigentlichen Erstellung des Terrains noch einige Nachbesserungen vorzunehmen. Zum Einen besteht die Möglichkeit das gesamte Terrain, wie in Abbildung 2.11 zu sehen, um ein bestimmtes Offset nach unten zu verschieben und alle negativen Werte auf 0 zu clippen. Der Vorteil dieser Methode ist, dass sie auf jede beliebige Heightmap angewendet werden kann, da die ursprüngliche Form des Terrains keine Rolle spielt. Abbildung 2.11: Ein Terrain vor und nach dem Vorgang des Clippens [8]. 2.7 Beispiele 13 Eine andere Vorgehensweise besteht darin bestimmte Gebiete der Heightmap einzuebnen (Abbildung 2.12). Hierfür ist jedoch eine explizite Kontrolle über vereinzelte Regionen nötig, weswegen sich besonders Terrains anbieten, die mit Hilfe von Voronoi-Diagrammen erstellt worden sind. Hier besteht zudem die Möglichkeit bei der Wahl der flachen Regionen eine weitere Zufallskomponente einzubringen. Abbildung 2.12: Schwarze Regionen werden eingeebnet und weiße Regionen behalten ihre Höhe (links). Auf das Terrain angewendet ergeben sich einzelne flache Regionen (rechts) [8]. 2.7 Beispiele 2.7.1 Tribal Trouble Tribal Trouble1 ist ein Strategiespiel, das 2005 von Oddlabs2 veröffentlicht wurde und prozedural erzeugtes Terrain verwendet. Die Erzeugung des Terrains wird dabei nur durch einige wenige Parameter, die unter Anderem das Vorkommen von durch Voronoi-Diagramme erzeugten Hügeln beschreiben, gesteuert. Es wird außerdem ein modifizierter, geschwindigkeitsoptimierter Erosions-Algorithmus verwendet ([8]). The Procedurality Engine ist ein Ableger der in Tribal Trouble verwendeten Terrain-Engine und wurde von Oddlabs unter der GPL veröffentlicht. 2.7.2 Terragen Terragen3 ist ein Modeling-Programm, das die prozedurale Erstellung von Heightmapbasierten Terrains ermöglicht. Dabei werden unter Anderem einige der hier vorgestellten Algorithmen, wie beispielsweise der Fault-Algorithmus oder die Spektral-Synthese, verwendet. 1 http://tribaltrouble.com http://oddlabs.com 3 http://www.planetside.co.uk/ 2 14 Heightmap-basierte Terrain-Modellierung Abbildung 2.13: Tribal Trouble ist ein Strategiespiel, das prozedural erzeugtes Terrain verwendet. Abbildung 2.14: Terragen ist ein prozedurales Modeling-Programm für Heightmap-basierte Terrains. 3 Voxel-basierte Terrain-Modellierung 3.1 Einführung Die Verwendung von Heightmaps zur Datenrepräsentation bietet einige Vorteile wie die einfache Implementierung und das einfache Rendering. Allerdings birgt der einfache Aufbau auch den entscheidenden Nachteil, dass einige Formen wie Aushöhlungen oder Brücken sich nicht darstellen lassen, da pro (x,z)-Koordinate nur ein Höhenwert abgespeichert wird. Um diese Einschränkung zu umgehen, müssen Voxel-basierte Modelle verwendet werden. Die Daten werden dabei in einem dreidimensionalen Array, der sogenannten Dichte-Funktion gespeichert. Mit Hilfe des Vorzeichens dieser Funktion kann nun bestimmt werden, welche Vertizes sich oberhalb und welche sich unterhalb der Terrain-Oberfläche befinden. Sei d(x, y, z) die Dichte-Funktion, dann gilt: d(x, y, z) > 0 ⇔ der Punkt befindet sich unterhalb der Terrain-Oberfläche d(x, y, z) < 0 ⇔ der Punkt befindet sich oberhalb der Terrain-Oberfläche d(x, y, z) = 0 ⇔ der Punkt befindet sich exakt auf der Terrain-Oberfläche -2 -3 -3 -3 -2 -2 -2 -1 -1 1 -1 -2 -2 -2 -1 -1 -1 -1 1 2 1 -1 -1 -2 -1 1 1 1 2 2 2 2 3 1 -1 -2 -1 1 2 2 1 -1 -1 1 2 2 1 -1 -1 -1 1 2 2 2 3 3 3 4 3 4 3 2 2 1 -1 -2 -1 1 1 -1 -1 -1 -1 1 2 2 3 4 3 4 2 3 2 2 2 2 3 4 3 4 1 2 1 2 1 2 1 2 1 2 Abbildung 3.1: Senkrechter Querschnitt durch einen Terrain-Block. Die Oberfläche verläuft zwischen den positiven und den negativen Werten. 3.2 Der Marching-Cubes-Algorithmus Um die Werte der Dichte-Funktion in Polygone umzuwandeln kann der Marching-CubesAlgorithmus verwendet werden. Dafür wird zuerst das komplette Terrain in Voxel, Würfelförmige Unterabschnitte, ähnlich einem Pixel im 2D-Bild, aufgeteilt. Anschließend werden in 16 Voxel-basierte Terrain-Modellierung jedem Voxel die Vorzeichen der Dichtewerte der 8 Ecken betrachtet. Anhand dieser Werte lässt sich für jeden Voxel bestimmen, welche der Ecken sich innerhalb und welche sich außerhalb des Terrains finden befinden. Man unterscheidet dabei 3 Fälle: Fall 1: die Vorzeichen aller 8 Ecken sind positiv Fall 2: die Vorzeichen aller 8 Ecken sind negativ Fall 3: es gibt positive und negative Werte Wenn Fall 1 oder Fall 2 eintrifft liegt der Voxel entweder komplett außerhalb (alle Vorzeichen sind negativ) oder komplett innerhalb (alle Vorzeichen sind positiv) des Terrains. Beim Rendern müssen diese Voxel folglich nicht beachtet werden. Im dritten Fall schneidet der entsprechende Voxel die Terrain-Oberfläche. Es können nun mit Hilfe der Dichtewerte der Ecken die genauen Schnittpunkte der Polygone mit den Würfelkanten interpoliert werden, da diese laut Definition genau auf dem Nullpunkt zwischen Ecken mit jeweils unterschiedlichem Vorzeichen liegen. Anschließend kann die Zusammensetzung der Polygone hergeleitet oder aus einer entsprechenden Look-Up-Table ausgelesen werden. Abbildung 3.2: Die 14 grundlegenden Fälle des Marching-Cubes-Algorithmus [6], alle weiteren Fälle lassen sich durch entsprechende Translationen herleiten. 3.3 Eine Dichte-Funktion generieren 3.3.1 Initialisierung Wenn eine bestimmte Form angestrebt wird ist es wichtig die Dichte-Funktion entsprechend zu initialisieren. Für die Terrain-Generierung ist eine Ebene nützlich, daher setzt man 3.3 Eine Dichte-Funktion generieren 17 d(x, y, z) = −y Hierdurch bekommen alle Punkte mit einer positiven Y-Koordinate einen negativen Wert und im Gegenzug alle anderen Punkte einen positiven Wert, was in einer Ebene auf der Höhe 0 resultiert. Zusätzlich gilt, dass der Dichtewert betragsmäßig immer größer wird je weiter man sich von der Oberfläche dieser Ebene entfernt. Dies ist ein entscheidender Punkt, wenn es darum geht Noise-Funktionen zu der Dichte-Funktion zu addieren. 3.3.2 Spektral-Synthese Auch im 3D-Raum lässt sich eine Spektral-Synthese, wie in Abschnitt 2.4.1 beschrieben, durchführen. Das Vorgehen ist dabei fast identisch, mit dem Unterschied, dass 3D-NoiseFunktionen verwendet werden und im 3D-Raum interpoliert wird. Abbildung 3.3 enthält eine solche 3D-Noise-Funktion nachdem sie mit Hilfe des Marching-Cubes-Algorithmus gerendert wurde. Die Polygone sind dabei gleichmäßig im Raum verteilt. Abbildung 3.3: 3D-Rauschen mit Hilfe des Marching-Cubes-Algorithmus visualisiert [5]. Um ein Terrain aufzubauen ist es jedoch wünschenswert, dass sich Unregelmässigkeiten vorallem in der Nähe der Oberfläche bilden und frei schwebende Geländeteile möglichst vermieden werden. Dies kann zum Teil erreicht werden durch die oben beschriebene Initialisierung. Durch die niedrigen Werte in der Nähe der Oberfläche gibt es bei Addition der Noise-Funktion vorallem dort immer wieder Vorzeichenwechsel der Dichtewerte, was eine Verschiebung der Oberfläche zur Folge hat. Weiter weg von der Oberfläche passiert das potentiell weniger bis garnicht, da dort die Werte betragsmäßig zu hoch sind. Vorausgesetzt ist ein entsprechender Wertebereich der Noise-Funktion. Durch die Addition von verschiedenen Noise-Funktionen kann die Oberfläche nun in jede beliebige Richtung verschoben werden, wodurch auch Höhlen und Überhänge möglich werden. Trotz der Initialisierung kann es jedoch vorkommen, dass sich einzelne Teile komplett vom Gelände ablösen, dieser Umstand lässt sich rein prozedural nur schwer beheben. 18 Voxel-basierte Terrain-Modellierung Abbildung 3.4: Ein voxelbasiertes Terrain nach mehrmaligem Aufaddieren verschiedener Noise-Funktionen [6]. 3.4 Praxis 3.4.1 Plattformen Wenn vereinzelt ebene Flächen auftreten sollen, können diese gezielt an den entsprechenden Stellen ins Terrain integriert werden. Dafür werden zunächst der Ort (x, z) und die gewünschte Höhe h der Plattform festgelegt. Anschließend wird jedem Punkt innerhalb eines bestimmten Radius ein fixer Wert zugewiesen: d(x, y, z) = h − y Dies erzeugt geometrisch gesehen einen Zylinder der Höhe h an der Stelle (x, z). Um die so entstandene Plattform besser in die Umgebung einzufügen kann nun das ursprüngliche Terrain mit einer bestimmten Gewichtung in den neuen Höhenwert miteingerechnet werden. Die Zuweisung eines fixen Wertes wird dann beispielsweise ersetzt durch d(x, y, z) = d(x, y, z) · 0.3 + (h − y) · 0.7 Auch hier werden vor allem in der Nähe der Plattform-Oberfläche Unregelmäßigkeiten auftreten, da die Plattform ähnlich wie die Ebene in Abschnitt 3.3.1 initialisiert wurde. Um die Plattform-Ränder vollkommen ins Gelände überzublenden kann die Gewichtung der ursprünglichen Dichte-Funktion nach außen hin immer weiter erhöht werden. Ein ähnliches Vorgehen wird in [6] beschrieben. 3.5 Beispiele 19 -2 -3 -3 -3 -2 -2 -2 -1 -1 1 -1 -2 -2 -2 -1 -1 -1 -1 1 2 1 -1 -1 -2 -1 1 1 1 2 2 -2 -3 -3 -1 -1 -1 -2 -1 -1 1 -1 -2 -2 0 0 0 -1 -1 1 2 1 -1 -1 1 1 1 1 1 2 2 2 2 3 1 -1 -2 -1 1 2 2 1 -1 -1 1 2 2 1 -1 -1 -1 1 2 2 2 3 3 3 4 3 4 2 2 3 1 -1 2 2 1 3 2 1 4 2 3 4 2 3 4 2 2 1 2 2 2 3 3 3 4 3 4 3 2 2 1 -1 -2 -1 1 1 -1 -1 -1 -1 1 2 2 3 4 3 4 3 2 2 1 5 1 -1 6 5 6 5 6 1 1 2 2 3 4 3 4 2 3 2 2 2 2 3 4 3 4 2 3 2 2 7 8 7 8 1 2 2 2 3 4 3 4 1 2 1 2 1 2 1 2 1 2 1 2 7 8 Abbildung 3.5: Querschnitt durch das Terrain vor (links) und nach dem Einfügen der Plattform (rechts). Abbildung 3.6: Eingefügte Plattform mit ausgeblendeten Rändern [6]. 3.5 Beispiele 3.5.1 Forever War Forever War1 ist ein quelloffener Egoshooter, der mit Voxel-basiertem, zufällig erzeugtem Terrain arbeitet. Es gibt zudem einen Level-Editor der verschiedene Arten von 3D-Noise erzeugen kann. 3.5.2 Acropora Bei Acropora2 handelt es sich um einen prozedurales Modeling-Programm, das unter Anderem die 3D-Spektralsynthese verwendet. 1 2 http://foreverwar.sourceforge.net/ http://www.voxelogic.com/ 20 Voxel-basierte Terrain-Modellierung Abbildung 3.7: Forever War Abbildung 3.8: Acropora 4 Schluss 4.1 Zusammenfassung Es wurden einige Voxel-basierte sowie Heightmap-basierte Verfahren zur Terrain-Generierung, zur Verwendung von Noise-Funktionen, sowie der Simulation von Erosion vorgestellt. Abschließend lässt sich sagen, dass viele der 2D-Algorithmen sich ins Dreidimensionale übertragen lassen. Ein Beispiel hierfür ist die bereits erwähnte Spektral-Synthese. Denkbar wäre auch eine 3D-Version des Fault-Algorithmus, wobei die Gerade durch eine den TerrainBlock schneidende Ebene ersetzt werden könnte. 4.2 Bewertung Trotz der zahlreichen Vorteile prozeduraler Modellierung ist es in der Praxis teilweise sinnvoll prozedurale mit manueller Modellierung zu kombinieren. Dadurch kann der Nachteil der fehlenden Kontrolle bei rein prozeduraler Modellierung umgangen werden. Auf diese Art lassen sich Probleme wie beispielsweise die frei schwebenden Geländeteile bei der Verwendung von 3D-Noise im Nachhinein beheben. Geskriptete Ereignisse wie sie in Computerspielen oft vorkommen erfordern meist eine bestimmte Form des Terrains. Auch hier bietet sich die Kombination beider Methoden an, da so die wesentliche Grundform an die speziellen Anforderungen manuell angepasst und im Nachhinein das Terrain prozedural erodiert oder mit mehr Details versehen werden kann. Literaturverzeichnis [1] http://www.speedtree.com. [2] http://www.lighthouse3d.com/opengl/terrain/. [3] http://freespace.virgin.net/hugo.elias/models/m_perlin.htm. [4] http://www.m3xbox.com/GPU_blog. [5] http://local.wasp.uwa.edu.au/~pbourke/texture_colour/perlin. [6] Ryan Geiss. GPU Gems 3, chapter Generating Complex Procedural Terrains Using the GPU. Addison-Wesley Professional, 2007. [7] Pascal Müller, Peter Wonka, Simon Haegler, Andreas Ulmer, and Luc Van Gool. Procedural modeling of buildings. 2006. [8] Jacob Olsen. Realtime procedural terrain generation. 2004. [9] Wojciech Palubicki, Kipp Horel, Steven Longay, Adam Runions, Brendan Lane, Radomı́r Měch, and Przemyslaw Prusinkiewicz. Self-organizing tree models for image synthesis. 2009. Erklärung Ich versichere, dass ich die Arbeit ohne fremde Hilfe und ohne Benutzung anderer als der angegebenen Quellen angefertigt habe, und dass die Arbeit in gleicher oder ähnlicher Form noch keiner anderen Prüfungsbehörde vorgelegen hat und von dieser als Teil einer Prüfungsleistung angenommen wurde. Alle Ausführungen, die wörtlich oder sinngemäß übernommen wurden, sind als solche gekennzeichnet. Stuttgart, den 13. Juli 2010 (Katrin Scharnowski)