Terrain Rendering v 1.0



Ähnliche Dokumente
Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Primzahlen und RSA-Verschlüsselung

C++ Tutorial: Timer 1

Professionelle Seminare im Bereich MS-Office

Erstellen von x-y-diagrammen in OpenOffice.calc

Advanced Rendering Interior Szene

Hohe Kontraste zwischen Himmel und Landschaft abmildern

Zeichen bei Zahlen entschlüsseln

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3

EINFACHES HAUSHALT- KASSABUCH

geben. Die Wahrscheinlichkeit von 100% ist hier demnach nur der Gehen wir einmal davon aus, dass die von uns angenommenen

Erstellen einer Collage. Zuerst ein leeres Dokument erzeugen, auf dem alle anderen Bilder zusammengefügt werden sollen (über [Datei] > [Neu])

6.2 Scan-Konvertierung (Scan Conversion)

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016

Alle Schlüssel-Karten (blaue Rückseite) werden den Schlüssel-Farben nach sortiert und in vier getrennte Stapel mit der Bildseite nach oben gelegt.

Grundlagen der Theoretischen Informatik, SoSe 2008

CSS-Grundlagen. Etwas über Browser. Kapitel. Die Vorbereitung

Informationsblatt Induktionsbeweis

Der Kalender im ipad

Konzepte der Informatik

Inhalt. 1 Einleitung AUTOMATISCHE DATENSICHERUNG AUF EINEN CLOUDSPEICHER

Satzhilfen Publisher Seite Einrichten

infach Geld FBV Ihr Weg zum finanzellen Erfolg Florian Mock

Eigenen Farbverlauf erstellen

Handbuch. NAFI Online-Spezial. Kunden- / Datenverwaltung. 1. Auflage. (Stand: )

Meet the Germans. Lerntipp zur Schulung der Fertigkeit des Sprechens. Lerntipp und Redemittel zur Präsentation oder einen Vortrag halten

Alle gehören dazu. Vorwort

Lineare Funktionen. 1 Proportionale Funktionen Definition Eigenschaften Steigungsdreieck 3

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

OECD Programme for International Student Assessment PISA Lösungen der Beispielaufgaben aus dem Mathematiktest. Deutschland

DIE IEDLE VON CATAN THEMEN-SET ZUM ARTENSPIE FÜR ZWEI SPIELER WIND & WETTER. Stefan Strohschneider Stephan Leinhäuser

Datensicherung. Beschreibung der Datensicherung

Datei Erweiterungen Anzeigen!

Anleitung über den Umgang mit Schildern

Kulturelle Evolution 12

Geld Verdienen im Internet leicht gemacht

Wordpress: Blogbeiträge richtig löschen, archivieren und weiterleiten

Seite 1. Datum einfügen

Punkt 1 bis 11: -Anmeldung bei Schlecker und 1-8 -Herunterladen der Software

Technische Analyse der Zukunft

1 topologisches Sortieren

3D-Konstruktion Brückenpfeiler für WinTrack (H0)

Raytracing. Schlussbericht. Jonas Lauener 1995, Áedán Christie 1997 Melvin Ott 1997, Timon Stampfli 1997

Tipp III: Leiten Sie eine immer direkt anwendbare Formel her zur Berechnung der sogenannten "bedingten Wahrscheinlichkeit".

Das große ElterngeldPlus 1x1. Alles über das ElterngeldPlus. Wer kann ElterngeldPlus beantragen? ElterngeldPlus verstehen ein paar einleitende Fakten

Nachhilfe-Kurs Mathematik Klasse 13 Freie Waldorfschule Mitte

Einfärbbare Textur erstellen in GIMP (benutzte Version: 2.6.7)

Adobe Photoshop. Lightroom 5 für Einsteiger Bilder verwalten und entwickeln. Sam Jost

Physik & Musik. Stimmgabeln. 1 Auftrag

Jede Zahl muss dabei einzeln umgerechnet werden. Beginnen wir also ganz am Anfang mit der Zahl,192.

Repetitionsaufgaben Wurzelgleichungen

impact ordering Info Produktkonfigurator

Wir arbeiten mit Zufallszahlen

Unterrichtsmaterialien in digitaler und in gedruckter Form. Auszug aus: Lernwerkstatt für die Klassen 7 bis 9: Linsen und optische Geräte

AGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom b

Rasterpunkte und Rasterdichte (Knoten/km)

Herstellen von Symbolen mit Corel Draw ab Version 9

Persönliche Zukunftsplanung mit Menschen, denen nicht zugetraut wird, dass sie für sich selbst sprechen können Von Susanne Göbel und Josef Ströbl

Austausch- bzw. Übergangsprozesse und Gleichgewichtsverteilungen

Plotten von Linien ( nach Jack Bresenham, 1962 )

Was meinen die Leute eigentlich mit: Grexit?

Guide DynDNS und Portforwarding

S/W mit PhotoLine. Inhaltsverzeichnis. PhotoLine

Lichtbrechung an Linsen

FAQ Spielvorbereitung Startspieler: Wer ist Startspieler?

ACDSee Pro 2. ACDSee Pro 2 Tutorials: Übertragung von Fotos (+ Datenbank) auf einen anderen Computer. Über Metadaten und die Datenbank

Leitfaden zur ersten Nutzung der R FOM Portable-Version für Windows (Version 1.0)

Berechnungen in Access Teil I

Tutorial: Entlohnungsberechnung erstellen mit LibreOffice Calc 3.5

Zahlen auf einen Blick

Die neue Aufgabe von der Monitoring-Stelle. Das ist die Monitoring-Stelle:

Gruppenrichtlinien und Softwareverteilung

ONLINE-AKADEMIE. "Diplomierter NLP Anwender für Schule und Unterricht" Ziele

mysql - Clients MySQL - Abfragen eine serverbasierenden Datenbank

AUSBILDUNG eines OBEDIENCE HUNDES

Dokumentation von Ük Modul 302

8. Berechnung der kalkulatorischen Zinsen

LU-Zerlegung. Zusätze zum Gelben Rechenbuch. Peter Furlan. Verlag Martina Furlan. Inhaltsverzeichnis. 1 Definitionen.

Mathematik: Mag. Schmid Wolfgang Arbeitsblatt 3 1. Semester ARBEITSBLATT 3 RECHNEN MIT GANZEN ZAHLEN

Wo möchten Sie die MIZ-Dokumente (aufbereitete Medikamentenlisten) einsehen?

Computeria Rorschach Mit Excel Diagramme erstellen

Lassen Sie sich dieses sensationelle Projekt Schritt für Schritt erklären:

ACDSee 2009 Tutorials: Rote-Augen-Korrektur

Dokumentation für das Spiel Pong

! " # $ " % & Nicki Wruck worldwidewruck

Folge 19 - Bäume Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12

Lernerfolge sichern - Ein wichtiger Beitrag zu mehr Motivation

RS-Flip Flop, D-Flip Flop, J-K-Flip Flop, Zählschaltungen

Terrain-Rendering mit Geometry Clipmaps

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

Gleichungen Lösen. Ein graphischer Blick auf Gleichungen

Geld wechseln kann als Visualisierung des Zehnerübergangs dienen. Die Zwischengrössen (CHF 2.-, 5.-, 20.-, 50.-) weglassen.

Partitionieren in Vista und Windows 7/8

Lineare Gleichungssysteme

Würfelt man dabei je genau 10 - mal eine 1, 2, 3, 4, 5 und 6, so beträgt die Anzahl. der verschiedenen Reihenfolgen, in denen man dies tun kann, 60!.

Ein Spiel für 2-3 goldhungrige Spieler ab 8 Jahren.

40-Tage-Wunder- Kurs. Umarme, was Du nicht ändern kannst.

5. Bildauflösung ICT-Komp 10

Datenbanken Kapitel 2

50. Mathematik-Olympiade 2. Stufe (Regionalrunde) Klasse Lösung 10 Punkte

Transkript:

Tutorial: Terrain Rendering 1 Terrain Rendering v 1.0 Einleitung In dem folgenden Abschnitt geht es darum, ein Terrain für ein Computerspiel in Echtzeit darzustellen. Zuerst wird ein kurzer Überblick über die verschiedenen Möglichkeiten gegeben. Danach wird anhand des Quadtrees gezeigt, wie man ein Terrain explizit erstellen kann. Zum Schluss möchte ich noch auf die Methoden der Texturierung und Beleuchtung eines Terrains eingehen. Theoretisches Fundament Es existieren zahlreiche Möglichkeiten mit kleinen aber feinen Nuancen, eine Landschaft in Echtzeit darzustellen kann. Eine Variante wäre, das Terrain als ein riesiges 3D-Modell zu laden und zu rendern. Ein solcher Ansatz wird Brute-Force genannt, was übersetzt so viel wie rohe Gewalt bedeutet. Das heisst, alle Triangles des Mesh werden ohne jegliche Optimierung durch die Render- Pipeline gejagt. Der Brute-Force-Ansatz gehört zu den statischen Verfahren und stellt, zumindest heute noch, nicht gerade die erste Wahl dar, da der Grafikprozessor extrem belastet wird. Der Vorteil dieser Methode jedoch ist, dass die CPU kaum beansprucht wird und somit genügend Reserven für andere Dinge wie z.b. die Physik oder die K.I. zur Verfügung hat. Die momentan sicherlich populärste Methode ist der Weg über so genannte Height-Maps. Height- Maps (Höhenkarten) sind nichts anderes als Graustufen-Bitmap-Grafiken. Der einzige Farbkanal dieser Bitmap hat also 8-bit zur Verfügung, das heisst, jeder Pixel auf der Grafik hat einen Wert zwischen 0 und 255. Und wozu soll das gut sein? Nun, stellen wir uns ein Gitter aus Punkten vor, die alle in derselben Ebene liegen. Wenn wir nun sozusagen die Height-Map über dieses Gitter legen, jedem Vertex einen Pixel zuordnen und die Farbwerte der Pixel als Höhenwerte des Gitters an dieser Stelle interpretieren, dann haben wir bereits ein kleines Terrain! Dunkle Pixel bedeuten flache Stellen, helle Pixel bedeuten hügelige Stellen. Die folgende Abbildung zeigt ein solches Gitter, das aus 5x5 Vertices resp. 4x4x2 Triangles besteht: Abb. 1: Von-Oben-Ansicht auf das Terrain-Mesh

Tutorial: Terrain Rendering 2 Je heller der Pixel in der Height-Map an der Stelle (u / v), desto höher das Terrain an der Position (x / y). Height-Maps bringen drei wesentliche Vorteile mit sich: Einfache Implementierung, wenig Festplattenspeicher, einfach zu erstellen (z.b. mit einem Bildbearbeitungsprogramm). Was man mit Height-Maps nicht realisieren kann, sind so genannte Overhangs, also überhängende Hügel. Das wäre, als ob man einem Wert x zwei Funktionswerte y zuweisen würde. In der Regel stört das aber kaum, denn Elemente wie Höhlen kann man trotzdem darstellen, indem man die in Form von 3D- Modellen in die Landschaft pflanzt. Möchte man auf das Erstellen des Terrains lieber ganz verzichten, so kann man diese Arbeit dem Modell-Designer überlassen. Das Terrain wird dann in einzelne rechteckige Teile zerlegt (sog. Mesh- Blocks) und von jedem dieser Terrain-Abschnitte werden mehrere, verschieden detaillierte Versionen abspeichert. Der Programmierer braucht dann nur noch zu prüfen, wie weit die Kamera von einem Terrainstück entfernt ist und entsprechend eine detailreichere oder bei grösserer Entfernung eben eine detailärmere Version des Terrainstücks zu laden und zu verschieben. Dieses System, mit zunehmender Distanz weniger Details darzustellen, nennt sich LOD (Level-of-Detail). Wo wir doch schon beim Thema sind: LOD s können natürlich, wie bei gewöhnlichen Modelldateien, auch mit einem Algorithmus berechnet werden. Man unterscheidet zwischen CLOD (Continuous Level-of- Detail) und DLOD (Discrete Level-of-Detail). Der erstgenannte Algorithmus ist, wie der Name schon sagt, ein Verfahren zum Erstellen kontinuierlicher Detailstufen. Der Nachteil liegt auf der Hand: Da in Echtzeit entschieden wird, wie viele Vertices wirklich gerendert werden, ist CLOD eine relativ prozessorlastige Angelegenheit und deshalb aus meiner Sicht nicht sehr empfehlenswert. Die Alternative ist, wie bereits erwähnt, DLOD. Dabei werden, wie bei den Modellen, einige Detailstufen per Algorithmus berechnet und abgespeichert. Vorteilhaft an DLOD ist natürlich, dass das Ganze vor Beginn der Laufzeit geschieht und somit relativ schnell ist. Geo-Mipmapping ist ein Beispiel für DLOD. Ähnlich wie bei den Texturen werden unterschiedliche Mip-Level eines Terrain-Blocks erstellt (daher der Name). Von einer zur nächsten Tesselierungsstufe wird die Dreiecksanzahl halbiert resp. verdoppelt. Je nach Distanz des Blocks zur Kamera wird ein anderer Mip-Level verwendet. Damit nehmen wir der Grafikkarte viel Arbeit ab, was sich in der Performance auszahlt. Wie jede Technik hat aber auch das Geo-Mipmapping einige Haken und Ösen. Von einer zur nächsten Mip-Stufe gehen Vertices verloren. Dies hat zur Folge, dass, wenn zwei Terrain-Blocks unterschiedlichen Triangulationsgrades zusammenkommen, sich so genannte Cracks (Löcher) bilden. Ein weiteres Problem des Geo-Mipmapping ist das Vertex-Popping. Wenn das Terrain seine Tesselierung ändert, dann kann es vorkommen, dass plötzlich ein Vertex wie aus dem Nichts hervorpoppt, der eben aufgrund des geringeren Detailgrades höherer Mip-Stufen weggelassen resp. vom Algorithmus aussortiert wurde. Eine Technik namens Geo-Morphing soll genau das verhindern. Der Vertex wird quasi langsam an seine Endposition gemorpht (von move).

Tutorial: Terrain Rendering 3 Abb. 2: Cracking Das letzte Verfahren, das ich noch erwähnen möchte, ist das ROAMing (Realtime Optimally Adapting Mesh). Ziel des Algorithmus ist es, das Terrain in Echtzeit optimal der Render-Pipeline anzupassen. Das Terrain wird ebenfalls in so genannte Patches (= Blocks) aufgeteilt. Gestartet wird, im Gegensatz zum Geo-Mipmapping, mit der niedrigen Tesselierung. Liegt ein Patch nahe an der Kamera, so wird er weiter verfeinert. ROAMing ist ein CLOD-Algorithmus und deshalb einiges CPU-lastiger als Geo- Mipmapping. Das Ziel der dynamischen Verfahren ist es, so viele Dreiecke wie nur möglich aus der Render-Pipeline zu entfernen und somit die Grafikkarte zu entlasten. Die meisten dynamischen Verfahren haben den Vorteil, dass man jeden einzelnen Vertex in Echtzeit bequem und schnell verändern kann, und damit ist das Terrain zerstörbar! Das heisst, bei einer Granatendetonation braucht man nur die Höhenwerte der Vertices an der betroffenen Stelle etwas zu erniedrigen und schon sieht das Terrain wesentlich realistischer aus! Nun noch ein paar Worte zur Kollisionsabfrage beim Terrain. Für die Kollisionsabfrage zwischen 3D- Modellen verwendet man Binary-Trees oder Octrees, doch wie sieht es bei einem Terrain aus? Da das Terrain relativ flach ist, eignet sich hier ein Quadtree relativ gut. Der Quadtree ist sozusagen die zweidimensionale Version des Octrees. Bei Terrains mit sehr grossen Höhenunterschieden kann es durchaus effektiver sein, den Octree zu verwenden. In der Regel jedoch stellt der Quadtree die schnellste Variante dar. Ein Leaf würde ich nicht zu klein wählen. (16x16x2 bis 64x64x2 Dreiecke pro Leaf).

Tutorial: Terrain Rendering 4 Geometrie erstellen Bisher haben wir einiges zum Thema Terrain-Rendering gehört. Nun geht es an die Umsetzung der Theorie! Anhand der Abmessungen der Height-Map wird ein entsprechend grosses Gitter erzeugt. Abb. 3: Height-Map Betrachten wir nun die Indices für die ersten vier Quadrate des folgenden Gitters (wir gehen von Dreieckslisten aus): Abb. 4: Gitter von oben (0, 1, 5), (5, 1, 6), (1, 2, 6), (6, 2, 7), (2, 3, 7), (7, 3, 8), (3, 4, 8), (8, 4, 9) Die Regelmässigkeit, die wir feststellen können, ist folgende (Zählung beginnt bei null): (n, n+1, n+5), (n+5, n+1, n+6) Nun die ersten zwei Quadrate in der zweiten Zeile: (5, 6, 10), (10, 6, 11), (6, 7, 11), (11, 7, 12) Wenn wir also von einer zur nächsten Zeile springen, müssen wir zu jedem Index fünf addieren! In der allgemeinen Form lassen sich die Indices eines Quadrats in der Spalte x und der Zeile y wie folgt ermitteln ( Res steht für die Anzahl der Spalten, in dem Beispiel oben also vier): [ x+(y (Res), x+1+(y Res), x+5+(y Res) ], [ x+5+(y Res), x+1+(y Res), x+6+(y Res) ] Möchte man nun die Nummer eines Vertex an der Position (x / y), so reicht die Formel

Tutorial: Terrain Rendering 5 Index = (y * Res) + x Damit erhalten wir also den Index des Vertex in der Spalte x und der Zeile y. Mit den Triangles und Vertices können auch die Normals berechnet werden: Abb. 5: Normalenvektoren berechnen Das normalisierte Kreuzprodukt der beiden Richtungsvektoren AC und BD ergibt den Normalenvektor des Vertex X. Nun haben wir die Geometrie komplett erstellt. Spätestens jetzt muss man sich für einen der oben beschriebenen Algorithmen entscheiden. Ich bevorzuge eine Hybrid-Lösung, also eine Kombination aus statischem und dynamischem Verfahren. Wenig Prozessorlast, einfache Implementierung und zerstörbares Terrain. Diesen Ansprüchen ist das Geo-Mipmapping gewachsen. Nun gilt es die weiter oben erwähnten Problemchen, welche diese Technik mit sich bringt, zu beseitigen. Doch vorerst noch die Implementierung des Quadtrees (den brauchen wir für die Kollisionsabfrage) im Pseudocode: CreateTree(Indices) { // Wurzelknoten erstellen RootNode->IsLeaf = TRUE; RootNode->Indices = Indices // Rekursive Funktion aufrufen und Wurzelknoten übergeben SplitNode(RootNode); } /*----------------------------------------------------------------*/ SplitNode(Node) { // Bounding-Box dieses Nodes erstellen CreateBoundingBoxes(Node); // wenn die Anzahl der Dreiecke kleiner gleich 32x32x2 ist, // dann ist ein Knoten genug klein, ein Leaf zu werden if (NumTriangles <= 32*32*2) { // das ist jetzt ein Leaf! Node->IsLeaf = TRUE; // drei Tesselierungsstufen erstellen! GenerateMipLevels(Node); } // den maximalen Fehlerwert beim Wechsel zum // grösseren Mip-Level berechnen ComputeCrackingValues(pNode, ileafsize);

Tutorial: Terrain Rendering 6 // es ist ein Knoten, also vier Kindäste erstellen // // _ _ // 1 _ _ 2 // // // // 4 3 // // // // Triangles aufteilen - sortieren nach den x- und z-werten! // Wenn ein Vertex eines Triangles auf der einen Seite liegt, // gehört dieses Dreieck zum aktuellen Kindast! // alle Dreiecke durchgehen for (int z = 0; z < ileafsize; z++) { for (int x = 0; x < ileafsize; x++) { // wohin gehört das aktuelle Dreieck? // links oben? if (UpLeft) AddTriangleToNode(Node->Child[0]); // oben rechts? if (UpRight) AddTriangleToNode(Node->Child[1]); // unten rechts? if (DownRight) AddTriangleToNode(Node->Child[2]); } } // unten links? if (DownLeft) AddTriangleToNode(Node->Child[3]); // Funktion ruft sich selbst wieder auf (für // die Kindäste) SplitNode(Node->Child[0]); SplitNode(Node->Child[1]); SplitNode(Node->Child[2]); SplitNode(Node->Child[3]); } /*----------------------------------------------------------------*/ Der Quadtree ruft selbst einige Hilfsfunktionen auf, so z.b. die Funktion GenerateMipLevels. Diese Funktion ist nichts anderes als ein Algorithmus, der die verschiedenen Mip-Levels der Terrain-Blocks erstellt. Wie das Problem des Crackings gelöst wurde, kann den folgenden Abbildungen entnommen werden:

Tutorial: Terrain Rendering 7 Abb. 6: Cracking vermeiden (links low-poly, recht high-poly) Abb. 7: Geo-Mipmapping Die Vertices an den Rändern der Blöcke sind bei allen Mip-Stufen gleich angeordnet. Das hat den Nachteil, dass einige Daten der Height-Map einfach weggelassen werden, auch in der höchsten Triangulationsstufe, dafür aber können Terrain-Blöcke unterschiedlichen Mip-Levels beliebig nebeneinander gelegt werden, ohne dass Cracks entstehen. Eine weitere Funktion, die beim Erzeugen des Quadtree aufgerufen wird, ist ComputeCrackingValues. Diese Methode geht alle Vertices des Nodes durch, berechnet den grössten Fehlerwert (Cracking-Value), der beim Wechsel auf eine höhere Mip-Stufe entsteht. Und wozu brauchen wir das? Ganz einfach deshalb, damit wir nachher beim Rendern diese Zahl als Faktor für die Auswahl der Mip-Stufe verwenden können, um Artefakte wie Vertex-Popping ein wenig zu reduzieren.

Tutorial: Terrain Rendering 8 Abb. 8: Fehlerwert (Cracking-Value), wenn V2 weggelassen wird Anmerkung: Wenn verschiedene Terrain-Blocks an derselben Position eigene Vertices haben, kann es sein, dass diese beiden Vertices wegen der Ungenauigkeit des Datentyps Float nicht exakt dieselben Koordinaten haben. Alle Vertices sollten deshalb im selben Vertex-Buffer untergebracht sein. Dadurch müssen beim Draw-Call (Renderaufruf) zwar mehr Vertices gesperrt und wieder entsperrt werden, dafür aber können keine Löcher im Terrain-Mesh entstehen. Rendern Das Terrain ist nun komplett. Bevor wir alle Mesh-Blöcke zum Rendern schicken, können wir noch einiges optimieren, beginnend mit dem View-Frustrum Culling. Sehr simpel aber effektiv: Wir durchwandern den Quadtree rekursiv und prüfen jeweils die Bounding-Boxen der Knoten, ob sie im View-Frustrum (und somit im sichtbaren Bereich) liegen. Ist die Box komplett ausserhalb der Clipping- Planes, dann kann dieser ganze Ast des Quadtrees (also alle Kindäste und deren Leaves) weggelassen resp. aus der Render-Pipeline entfernt werden. Durch das so genannte PVS-System (Potentially Visible Set) können nochmals einige tausend Triangles gecullt werden, vorausgesetzt, die Kamera befindet sich direkt über dem Boden (klappt also nicht aus der Vogelperspektive). Da alles vor der Laufzeit berechnet werden kann, lohnt sich PVS in der Regel. Idee: Es wird geprüft, von welchem Terrain-Block welcher Terrain-Block sichtbar ist. Ich habe das so gemacht, dass ich einfach die obersten Punkte der beiden Bounding-Boxen der Blocks, die es zu vergleichen gilt, zu Linien verbunden habe. Dann habe ich geprüft, ob diese Linien das Terrain an irgendeiner Stelle schneiden. Berührt eine der Linien das Terrain nicht, so wird der Block A als sichtbar bei Block B eingetragen und umgekehrt. So lässt man den Algorithmus immer weiter laufen, bis alle Terrainstücke auf Sichtbarkeit getestet wurden. Dieser einfache Test ist logischerweise nicht ganz genau, aber es dauert so schon relativ lange, bis das PVS berechnet ist (bei 64 Blöcken, und das ist ein sehr kleines Terrain, etwa 3 Sekunden).

Tutorial: Terrain Rendering 9 Abb. 8: Ohne PVS (20464 Triangles) Abb. 9: Mit PVS (15840 Triangles) Die dritte und letzte Culling-Technik, die ich noch erwähnen möchte, ist Occlusion Culling. Wenn beispielsweise vor einem Hügel steht, dann würde es doch reichen, nur diese Hügelpolygone zu zeichnen und alles dahinter zu vergessen? Genau das wird mit Occlusion-Culling erreicht. Ein so genannter Occluder (kann mit einem Quader verglichen werden) wird so in den Hügel platziert, dass er möglichst gross ist und doch nicht sichtbar wird. Beim Rendern kann dann jeweils ein zweites View- Frustrum erstellt werden, nämlich mithilfe der Occluder-Daten und der Kameraposition. Alle Objekte, die komplett in diesem View-Frustrum liegen, müssen dann nicht gerendert werden. Das klingt momentan vielleicht etwas besser als es eigentlich ist, denn wirklich viel bringt Occlusion-Culling für ein Terrain nicht, im Gegenteil: Die Framerate sackt aufgrund der zusätzlichen Tests sogar etwas ein.

Tutorial: Terrain Rendering 10 Das Hauptproblem beim Rendern eines Terrains ist wohl die Sichtweite. Einerseits möchte man dem Betrachter unendliche Sichtweite gewähren, andererseits wird dies aufgrund mangelnder Hardwareleistung kaum möglich sein. Eine simple aber effektive Methode, die Sichtweite elegant zu beschränken, ist das Einbauen von Nebel oder Tiefenunschärfe. Diese Effekte kennen wir ja in der Natur auch: Die Sichtweite wird durch Wettereffekte wie z.b. die Luftfeuchtigkeit und natürlich die Wahrnehmungskraft unserer Augen eingeschränkt. Das Rendern selbst ist eigentlich reines Pfannkuchenessen. Nur die Blocks, die das Culling überstanden haben und in der Liste der Sichtbaren Terrainstücke des Patches, in welchem sich der Spieler aufhält, enthalten sind, werden schlussendlich gerendert. Texturierung Diese Thematik ist ein Thema für sich. Es gibt zahlreiche Möglichkeiten, ein Terrain sinnvoll zu texturieren. Im Folgenden werden drei Techniken kurz erläutert. Splattering. Texture-Splattering erlaubt eine individuelle Gestaltung der einzelnen Höhenstufen und basiert auf der Interpolation und dem Zusammenblenden zweier Texturen innerhalb einer Höhenstufe. Möchte man mehr als zwei Texturen verwenden (z.b. eine für Sand, eine für Gras und eine für Gestein), dann muss man nach folgendem Schema vorgehen: Textur eins und zwei setzen, Schicht eins (z.b. Höhe 0 bis 0.5) rendern, Textur zwei und drei setzen, Schicht zwei rendern. In Abhängigkeit der Höhe wird dann der Gewichtungsfaktor verändert, also einer Textur mehr Transparenz zugeordnet. Die Formel lautet: Pixelfarbe = Texel 1 * Gewichtung 1 + Textur 2 * (1 Gewichtung 1 ) Wenn ein Faktor (z.b. Gewichtung 1 ) 0.3 beträgt, dann heisst das, dass die Farbe des Texels der ersten Textur zu 30% in die Endfarbe einfliesst. Detailtextur und Color-Map. Detail- und Color-Mapping kann mit der oben genannten kombiniert werden. Zuerst wird eine so genannte Color-Map über das gesamte Terrain gestreckt. Diese Textur gibt der Landschaft einmal eine Grundfarbe. Danach wird eine Detailtextur ungestreckt nebeneinander auf das Terrain gelegt (Wrapping) und mit der Grundfarbe der Color-Map vermischt. Volumentexturen. Das Verwenden von Volumentexturen ist eine recht speicherintensive Methode. Die w-achse entspricht der Höhe, also der y-koordinate des Terrains. Je nach Höhe wird eine andere Texturschicht verwendet. Hinweis: Nicht alle Grafikkarten unterstützen Volumentexturen. Texture-Splattering mit Wrapping halte ich für die beste Methode. Die Gewichtungsfaktoren für die einzelnen Texturen können sogar in einer Textur, einer so genannten Alpha-Map abgespeichert werden, denn mit einem Pixel-Shader lassen sich die Texturen viel freier kombinieren und es ist auch problemlos möglich, noch andere Faktoren (etwa die Beleuchtung) in die Texturierung einfliessen zu lassen.

Tutorial: Terrain Rendering 11 Abb. 10: Lightmap des Terrains Beleuchtung Zur Beleuchtung der Terrains könnten gewöhnliche Direct3D-Lichter verwendet werden. Bei statischen Lichtquellen (evtl. die Sonne) ist es jedoch empfehlenswert, von so genannten Light-Maps Gebrauch zu machen. Eine Light-Map ist nichts anderes als eine 8-bit Textur (jeder Texel hat also einen Wert zwischen 0 und 255). Die beleuchteten Stellen werden also beim Laden des Programms berechnet und dann in Form einer Textur abgespeichert. Zur Laufzeit fallen dann keine zusätzlichen Berechnungen mehr an, wir brauchen nur noch die Lichttextur über das Terrain zu legen (jedem Vertex wird ein Texel der Light-Map zugeordnet), und schon wird der Eindruck einer echten Lichtquelle vermittelt. Abb. 11: Lightmap des Terrains Nun stellt sich natürlich noch die grosse Frage, wie wir diese Lightmap überhaupt berechnen können. Der Algorithmus dazu ist nichts anderes als ein simpler Raytracer. Das Verfahren heisst deshalb Ray- Tracing, weil man von der Lichtquelle aus zu jedem Punkt auf dem Terrain einen Strahl schiesst und prüft, ob er irgendwo von einem Objekt oder vom Terrain selbst unterbrochen wird. Wir gehen also

Tutorial: Terrain Rendering 12 Vertex für Vertex des Terrains durch und bilden diesen Vertex-zu-Lichtquelle-Vektor. Kommt ein anderes Objekt oder das Terrain selbst mit dem Strahl in Kontakt, so liegt der aktuelle Vertex im Schatten und kann auf den ambienten Farbwert gesetzt werden. Wird der Lichtstrahl hingegen nicht unterbrochen, so kommt simple N.L-Beleuchtung zur Anwendung (Punktprodukt aus der normalisierten Vertexnormalen und dem normalisierten Lichtvektor). Abb. 12: Artefakte - eckige Schatten Da diese Schatten jedoch nur per-vertex berechnet wurden, wird das auf dem Terrain hässlich eckig aussehen, wenn zwischen zwei Vertices einige Duzend Pixel kleben. Solche Artefakte lassen sich mit einem Blur-Shader 1 elegant verwischen. Dadurch sehen die Schatten weicher und realistischer aus. Die Rechenzeit für ein Terrain der Grösse 513 x 513 Vertices beträgt in etwa 30 Sekunden. Abb.13: Weiche Schatten 1 mehrere Texture-Lookups (also mehrmals aus der Light-Map die Farbe lesen) im Pixel-Shader mit jeweils leicht verschobenen Texturkoordinaten kombinieren

Tutorial: Terrain Rendering 13 Die Erde eine Scheibe? Auch wenn das Terrain 3072 x 3072 Einheiten gross ist und noch mit dem Faktor zwei multipliziert wird, irgendwann wird der Spieler das Ende des Terrains entdecken. Um dem entgegen zu wirken, könnte man als Height-Map beispielsweise eine kachelfähige Textur verwenden, die man dann beliebig oft in x- und z-richtung hintereinander legen kann. Das hat aber den Nachteil, dass die Landschaft keine markanten Hügel aufweisen darf, ansonsten wird es dem Spieler komisch vorkommen, wenn er nach x-einheiten Terrain wieder derselbe Berg auftaucht. Stattdessen könnte man die Kernzone des Terrains detaillierter ausgearbeitet und am Ende dieser Zone einfach eine kachelfähige Height-Map mit eintöniger Landschaft beliebig oft wiederholen. Wir liefern dem Spieler also so oft hintereinander dasselbe Terrainstück, bis es ihm zu langweilig wird und er in die Kernzone der Karte zurückkehrt. Eine alternative Möglichkeit wäre, dem Spieler den Freiraum zu rauben und ihn sozusagen in einen Talkessel einzusperren (z.b. durch zu starke Steigung des Terrains). Bei einer Insel haben wir es noch leichter: Die Wasseroberfläche können wir problemlos beliebig oft wiederholen, ohne dass der Spieler etwas merkt. Ausblick Momentan sieht das Terrain noch recht karg aus. Es fehlen Vegetation, Wasser, Gestein usw. Ausserdem ist das Terrain noch relativ klein. Wenn wir mehr als eine Height-Map verwenden würden, dann bräuchten wir eine Art Manager für das Laden und Entladen der Terrain-Daten aus dem und in das System-RAM. Fazit: Es noch genügend Arbeit! Abb. 14: Das fertige Terrain mit dem Himmel

Tutorial: Terrain Rendering 14 Quellenverzeichnis Literaturverzeichnis: - Scherfgen, David (2003). 3D Spieleprogrammierung - Modernes Gamedesign mit DirectX 9 in C++. München: Carl Hanser Verlag - Zerbst, Stefan (2002). 3D Spieleprogrammierung mit DirectX in C++ - Band II. Braunschweig: Books on Demand GmbH - http://www.flipcode.com/articles/article_geomipmaps.pdf [Stand: 28.03.05] - http://www.gamedev.net/reference/articles/article1817.asp [Stand: 10.10.05] - http://www.usf.de/downloads/usf2001/ringe_roettger_terrain_rendering.ppt [Stand: 12.10.05] Abbildungsverzeichnis: Abb. 1 14: eigene Screenshots und Grafiken Copyright 2005, Reto Da Forno Irrtümer vorbehalten 12.10.05 http://www.keepcoding-development.ch.vu