Raytracing vs. Echtzeitsimulation

Transcrição

Raytracing vs. Echtzeitsimulation
Raytracing vs. Echtzeitsimulation
Seminararbeit zum Hauptseminar
Grafik-Programmierung
von
Kadir Tuncer
Juni 2008
Inhaltsverzeichnis
1. Einführung
3
2. Raytracing
3
3
4
4
5
5
2.1 Vorwärts- und Rückwärtsraytracing
2.2 Raytracing Erweiterungen
2.2.1 Rekursives Raytracing
2.2.2 Diffuses Raytracing
2.2.3 Globale Beleuchtung
3. Echtzeitgrafik
5
6
6
6
3.1 Transformation & Rasterisierung
3.2 Tiefenpuffer
3.3 Texture Mapping
4. Darstellung von Wasser – Realtime vs. Raytracing
4.1 Wasser-Rendering in Echtzeit
4.1.1 Darstellung von Wellen
4.1.2 Darstellung von Kaustiken
4.2 Wasser-Rendering mit Raytracing
4.2.1 Generierung von „schaumgekrönten“ –Wellen
4.2.2 Darstellung von Kaustiken
5. Darstellung von Schatten – Realtime vs. Raytracing
5.1 Shadow Mapping in Echtzeit
5.2 Shadow Volumes – Ein Raytracing Algorithmus
7
7
7
9
10
10
11
11
12
13
6. Zusammenfassung & Ausblick
14
7. Referenzen & Quellen
15
2
1. Einführung
Raytracing sowie Echtzeitsimulation sind Verfahren, die das Ziel haben eine 3D Umgebung auf
eine 2D Ebene abzubilden. Diese Ausarbeitung zum Thema Raytracing vs. Echtzeitsimulation des
Hauptseminars Grafik-Programmierung befasst sich mit der Frage was ihre Vorteile bzw. Nachteile
sind, wann welches Verfahren eingesetzt wird und wie dies von statten läuft. Nach einer
allgemeinen Beschreibung beider Verfahren werden anschließend zwei konkrete Problemstellungen
aus beiden Perspektiven behandelt:
1. Darstellung von Wasser
2. Darstellung von Schatten
Dafür werden sowohl Lösungen vorgestellt, die bereits in heutigen Simulationen Verwendung
finden, als auch jene, die sich in der wissenschaftlichen Forschung befinden.
2. Raytracing
Raytracing oder Ray Tracing (dt. Strahlenverfolgung) ist eine Methode, um eine zwei-dimensionale
Bilddarstellung aus einer 3D-Welt herzuleiten. Der Grundgedanke liegt hierbei darin, die
Sichtbarkeit eines Objekts im Raum zu bestimmen, indem Lichtstrahlen verfolgt werden, die
letztendlich beim Beobachter bzw. bei der beobachteten Bildebene auftreffen.
2.1
Vorwärts- und Rückwärtsraytracing
Der triviale Gedanke wäre hier höchstwahrscheinlich, dass man die von der Lichtquelle bzw. den
Lichtquellen ausgehenden Lichtstrahlen verfolgt, die auf ihrem Weg bis zum Beobachter
gebrochen, reflektiert oder absorbiert werden können, so dass am Ende auf der Bildebene
Lichtstrahlen mit unterschiedlichen Farbinformationen eintreffen, genauso, wie es in der realen
Welt geschieht. Diese Technik wird als Vorwärtsraytracing beizeichnet. Da es ein sehr hoher und
überflüssiger (die meisten Lichtstrahlen treffen niemals auf der Bildebene auf) Aufwand ist, alle
Lichtstrahlen von allen Lichtquellen zu verfolgen und zu berechnen, wird es in wenigen
Ausnahmen verwendet. (s. Abb. 1).
Abbildung 1: Vorwärtsraytracing [A]
3
Stattdessen verwendet man Rüchwärtsraytracing, d.h. ausgehend vom Beobachter und der
Bildebene werden nur die Lichtstrahlen verfolgt, die für uns relevant sind, und zwar in der Richtung
Beobachter Æ Bildebene Æ Objekt Æ Lichtquelle (s. Abb. 2). Somit werden nur die
Lichtstrahlen beobachtet, die auch wirklich auf der Bildebene erscheinen.
Abbildung 2: Rückwärtsraytracing [B]
2.2
Raytracing Erweiterungen
Nun werden kurz einige Erweiterungen des Raytracingverfahrens vorgestellt, die dafür sorgen, dass
eine mit diesem Verfahren erstellte Abbildung realitätsnahe Eigenschaften erhält.
2.2.1 Rekursives Raytracing
Will man bei Lichtstrahlen erreichen, dass diese an spiegelnden Oberflächen gespiegelt und an
transparenten bzw. teil-transparenten Oberflächen gebrochen werden, so muss man die
Lichtstrahlen rekursiv verfolgen. Durch die Brechung bei teil-transparenten Objekten entstehen sog.
Sekundärstrahlen, die wiederum auf andere Objekte fallen und berechnet werden müssen. Somit
muss der Raytracing Algorithmus rekursiv für alle Lichtstrahlen durchgeführt werden (s. Listing 1).
For each pixel in image {
Create ray from eyepoint passing through this pixel
Initialize NearestT to INFINITY and NearestObject to NULL
For every object in scene {
If ray intersects this object {
If t of intersection is less than NearestT {
Set NearestT to t of the intersection
Set NearestObject to this object
}
}
}
If NearestObject is NULL {
Fill this pixel with background color
} Else {
Shoot a ray to each light source to check if in shadow
4
If surface is reflective, generate reflection ray: recurse
If surface is transparent, generate refraction ray: recurse
Use NearestObject and NearestT to compute shading function
Fill this pixel with color result of shading function
}
}
Listing 1: Rekursives Raytracing [C]
2.2.2 Diffuses Raytracing
Um der Darstellung noch mehr Realismus zu verleihen wird das rekursive Raytracing durch
Diffuses Raytracing ergänzt. Dadurch erreicht man bei der Verdeckungsberechnung, dass harte
Schatten geglättet werden, Tiefenunschärfe, Bewegungsunschärfe durch zeitliche Verteilung der
Strahlen, und Antialiasing durch Verteilung der Strahlen über die Fläche der Pixel. Dazu werden
mehrere Strahlen statt einem verwendet und der Mittelwert aller Farbinformationen ermittelt.
2.2.3 Globale Beleuchtung
Mit den bisherigen Verfahren ist noch nicht Möglich, bei der Abbildung Kaustiken (geometrisches
Helligkeitsmuster, das durch Intensitätsüberhöhung an der Einhüllenden eines breiten
Strahlenbündels auftritt [z.B. bei einer Lupe]) und Interreflexionen zu simulieren, da bei diffusen
Oberflächen keine Sekundärstrahlen ausgesendet werden. Daher verwendet man Methoden, die die
bisherigen Algorithmen mit Forwardraytracing kombinieren, wie z.B. das Path Tracing. Bei diesem
Verfahren werden Strahlen auch auf diffusen Oberflächen reflektiert, gebrochen und absorbiert, und
jedes Mal ein zufälliger Strahl generiert, der sich seinen Weg durch die Szene sucht.
3. Echtzeitsimulation
Im Gegensatz zum Raytracing, bei dem pro Bild zur Berechnung mehrere Minuten, Stunden oder
im schlimmsten Fall sogar Tage benötigt, kommt es bei der Echtzeitgrafik darauf an, möglichst
viele Bilder in kurzer Zeit darzustellen. Wenn man davon ausgeht, dass das menschliche Auge ab
16-18 Bildern pro Sekunde eine Bewegung wahrnimmt, so ist diese Rate das Minimum, das man
bei der Erzeugung von Echtzeitgrafik erreichen sollte. Wieder ist es unser Ziel eine
dreidimensionale Darstellung auf eine zweidimensionale Bildebene abzubilden. Da jedoch die
Methoden beim Raytracing zu aufwändig sind, werden physikalische Gesetze vereinfacht um dies
zu bewerkstelligen.
Durch die enormen Zeitvorteile der Echtzeitgrafik bilden sich weitere Vorteile. Der Benutzer hat
durch diesen Zeitvorteil die Möglichkeit mit der Darstellung zu interagieren, so dass Bilder je nach
der Eingabe des Benutzers in Echtzeit dargestellt werden. Dies wird vor allem in Computerspielen
und 3D-Modellierungssoftware wie z.B. CAD verwendet und seit wenigen Jahren sogar in
grafischen Oberflächen von Betriebssystemen wie z.B. Microsoft Windows Vista oder Linux
(Beryl).
In Echtzeitgrafiken werden zur Darstellung von Objekten Dreiecke bzw. Polygone (Vielecke)
verwendet, die zusammen die Oberfläche von Objekten bilden. Diese Polygone werden anhand von
Vektoren realisiert und die Anzahl von Polygonen bestimmt schließlich den Detailgrad und
Realitätsnähe der dargestellten Objekte. Angetrieben durch die Spielindustrie, werden im Gegensatz
zum Raytracing, Berechnungen von Polygon-, Farb- und Tiefeninformationen Hardwareseitig, d.h.
5
durch die GPU (Graphics Processing Unit) ausgeführt, das wiederum einen enormen Zeitvorteil
bietet und die CPU auslastet. Dazu sind viele der Algorithmen für Berechnungen wie Tiefenpuffer,
Texture Mapping, T&L (Transformation and Lighting) oder Antialiasing in der GPU implementiert,
welche dieser dann selbstständig ausführt.
3.1
Transformation & Rasterisierung
Um diese Polygone auf das Ausgabemedium abzubilden, also eine zweidimensionale Darstellung
einer 3D-Welt zu erhalten, müssen die Polygone transformiert werden. D.h. sie werden gedreht und
gestreckt, und anschließend auf das Ausgabemedium positioniert. Anschließend muss eine
Rasterisierung durchgeführt werden. Dabei werden aus den Vektordaten der Polygone einzelne
Pixel erstellt, die dann schließlich auf dem Ausgabemedium dargestellt werden. Was passiert, wenn
auf denselben Pixel zwei verschiedene Polygone gerastert werden, wird im nächsten Abschnitt
erläutert?
3.2
Tiefenpuffer
Um das Problem der Sichtbarkeit für Objekte in Echtzeit zu lösen, wird für die
Verdeckungsberechnung ein sog. Z-Buffer verwendet. Während der Framebuffer die
Farbinformationen der Pixel speichert, hält der Z-Buffer die Tiefeninformationen für alle Pixel im
sichtbaren Bild bereit. Der Z-Buffer ist im Allgemeinen als eine zweidimensionale Matrix realisiert,
welche für jede x,y-Koordinate einen z-Wert speichert, der später mit dem z-Wert eines anderen
Objekts in der selben Koordinate verglichen wird (s. Abb. 3). Somit werden genau die Pixel in den
Framebuffer geschrieben und später dargestellt die einen geringeren z-Wert haben als jene, die den
selben x,y-Wert besitzen.
Abbildung 3: Z-Buffer Matrix [D]
3.3
Texture Mapping
Die bisherigen Überlegungen befassten sich damit, wie und welche Pixel der Polygone dargestellt
werden, doch noch nicht welche Farbe diese Pixel haben sollen. Um den Objekten Farbe zu
verleihen werden auf die Oberfläche sog. Texturen abgebildet. Dies kann man sich in etwa so
vorstellen, dass man einen transparenten Würfel in ein farbiges Tuch wickelt. Eine Erweiterung des
Texture Mapping ist das Bump Mapping, wodurch Objekten eine unechte dreidimensionale
Oberfläche verliehen wird (s. Abb. 4).
6
+
=
Abbildung 4: Bump Mapping [E]
4. Darstellung von Wasser – Realtime vs. Raytracing
In diesem Abschnitt wird etwas näher auf die Darstellung von Wasser eingehen und auf welche Art
und Weise dies bei Raytracing und bei Echtzeitsimulation realisiert wird.
4.1
Wasser-Rendering in Echtzeit
Um die Darstellung von Wasser in Echtzeit simulieren zu können, müssen wir das Problem
zunächst in zwei Abschnitte unterteilen, nämlich Wellen und Kaustiken. Kaustiken sind
geometrische Helligkeitsmuster die durch Intensitätsüberhöhung von Lichtstrahlen entstehen. Um
diese realisieren zu können werden unterschiedliche Techniken verwendet, die jedoch alle auf der
GPU arbeiten, so dass der Geschwindigkeitsvorteil um das Rendering in Echtzeit ausführen zu
können zur Verfügung steht.
4.1.1 Darstellung von Wellen
Es gibt mehrere Methoden, die dazu dienen die Wasseroberfläche auf realistische Art und Weise in
Echtzeit zu rendern. Wir wollen dazu zunächst die einfache Methode anhand Multi-Texturing und
Bump Mapping vorstellten und anschließend auf die von Finch[1] beschriebene Methode zur
effektiven Simulation von Wasser aus physikalischen Modellen eingehen.
Multi-Texturing ist, wie der Name schon sagt, eine Verfahren, bei dem mehrere Texturen auf ein
Objekt abgebildet. Das bereits vorgestellte Bump Mapping ist ein solches Verfahren. Dazu wird als
Basistextur eine Map in der Farbe des Wassers gewählt und als zweite Textur eine Bump Map
darauf abgebildet, die die Muster einer Wellenbewegung aufweisen (s. Abb. 5) Dadurch erreicht
man an Stellen, an den die Bump Map dunkler ist, das das Ergebnis an diesen Stellen tiefer wirkt
und umgekehrt. Möchte man für Dynamik in der Abbildung sorgen, so muss man lediglich diese
Textur manipulieren, indem man sie streckt, dreht und überlagert.
Abbildung 5: Wasser Bump-Map [F]
7
Eine alternative zum Multi-Texturing ist das von Finch beschriebene Verfahren, das eine
realistischere Darstellung aufweisst. Dabei wird einerseits eine Wellensimulation für das die
Oberfläche aufspannende Netz benutzt und andererseits werden kleinere Wellenformen innerhalb
der Oberfläche simuliert. Dabei hat sich herausgestellt, dass für den Realismus hauptsächlich die
Letztere verantwortlich ist.
Die Wellenformen werden zunächst auf der Basis von Sinuskurven erstellt (s. Abb. 6).
Abbildung 6: Sinuskurve [G]
Daraus kann man dann die Funktionen:
Wi(x,y,t) = Ai x sin ( Di * (x,y) x wi + t x φi)
(1)
und
H(x,y,t) = ∑ ( Ai x sin ( Di * (x,y) x wi + t x φi) )
(2a)
herleiten, die Auskunft über die Position der einzelnen Wellen (1) und der gesamten Oberfläche
(2a) geben, wobei w = 2π/L die Frequenz der Wellenlänge, φ = S x 2π/L die Phasenkonstante der
Geschwindigkeit und D der Richtungsvektor, der die Richtung der Wellengipfel darstellt, ist. Um
eine Dynamik zu erhalten werden zufällig unterschiedliche Parameter gewählt. Außerdem arten
Wellen nach einiger Zeit aus, sodass sie durch neue Wellen mit anderen Parametern ersetzt werden.
Anhand dieser Funktionen kann man leicht die Richtung der Wellen herleiten, in dem man diese
Funktionen nach x ableitet, so dass wir für die gesamte Oberflache folgende Funktion erhalten:
∂/ ∂x (H(x,y,t)) = ∑ (wi x Di * x x Ai x cos ( Di * (x,y) x wi + t x φi) )
(2b)
Um diesen Wellen mehr Realismus zu verleihen, kann man sie dahingehend modifizieren, dass sie
schärfere Gipfel und flachere Täler haben (s. Abb. 6). Dazu müssen die Funktionen nicht-negativ
gesetzt und über einen Exponenten angehoben werden:
Wi(x,y,t) = 2Ai x [( (sin ( Di * (x,y) x wi + t x φi) + 1) / 2)]k
(1b)
Diese Funktion kann man nun weiterhin erweitern, und zwar so, dass die Tessellation an den Tälern
kleiner und an den Gipfeln größer ist. Dies wird durch sog. Gerstner Wellen erreicht, bei denen sich
die Eckpunkte zu den Gipfeln hin bewegen (s. Abb. 7).
8
Abbildung 7: Sinuskurve mit scharfen Spitzen und Gerstner Wellen [H;I]
Für die Generierung der Welle für die Gesamtoberfläche gibt es zwei verschiedene Modelle, die in
Abhängigkeit der Umgebung Verwendung finden. Zum einen wären das gerichtete Wellen, die man
bei größeren Gewässern wie z.B. Ozeanen verwendet, da sich hier durch dieses Modell
Wellenbewegungen realistischer darstellen lassen. Bei kleineren Gewässern die ihre Bewegung
durch andere Einflüsse als den Wind bekommen (z.B. Wasserfall) werden eher kreisförmige Wellen
bevorzugt. Abgesehen vom Gebrauch haben beide Modelle ihre Vorteile: Gerichtete Wellen sind
weniger rechenintensiv, da sie weniger Anweisungen auf der GPU benötigt. Dagegen kreisförmige
Wellen den Vorteil, dass sich das Muster aufgrund der Überlagerung niemals wiederholt.
4.1.2 Darstellung von Kaustiken
Auch bei der Darstellung von Kaustiken gibt es verschiedene Techniken. Man kann hier ebenso
nach dem Bump Mapping vorgehen und über die Bodentextur unter dem Wasser eine Kaustik
Textur überlagern (s. Abb. 8)
Abbild 8: Kaustik Bump-Map [J]
Die fortgeschrittenen Methoden zur Darstellung von Kaustiken basieren meist auf dem Raytracing
Verfahren. Daher wird hier ein alternativer Ansatz nach Musawir[2] et al. vorgestellt, der
ausschließlich auf der GPU ausgeführt wird. Das Caustics Mapping verwendet eine ähnliche
Technik wie das Shadow Mapping, das später in dieser Arbeit vorgestellt wird.
Für jeden Frame werden dazu folgende Schritte wiederholt:
Im ersten Schritt des Caustics Mapping müssen Informationen über die Beschaffenheit der
Umgebung gesammelt und anhand dieser Informationen eine Kaustik Textur erstellt werden. Um
die Kaustik Textur zu erstellen, müssen zunächst die 3D Positionen der Oberfläche, auf die
abgebildet wird, beschaffen werden. Diese werden auf eine sog. Positionstextur gerendert und dient
später der Berechnung der Strahlüberlagerung. Anschließend werden 3D Positionen der
Wasseroberfläche und der Normalen berechnet und ebenfalls auf eine Textur abgebildet. Auf diese
Textur wird dann ein Netz von Vertices abgebildet, und zwar so, dass auf jeden Pixel ein Vertex
abgebildet wird. Im nächsten Schritt muss die erstellte Textur auf diffuse Oberflächen bzw. Objekte
abgebildet werden.
9
Jetzt kann man anhand der erhaltenen Daten die Caustic-Map rendern. Dazu wird zunächst die
Lichtbrechung an jedem Vertex der Wasseroberfläche berechnet. Anschließend wird der
Schnittpunkt des gebrochenen Strahls und der Oberfläche, auf die die Kaustik abgebildet wird,
abgeschätzt. Schließlich wird noch die Intensität der Kaustik an diesem Punkt berechnet. Die
bisherigen Methoden versuchten den im zweiten Schritt gesuchten Schnittpunkt zu finden, indem
sie Raytracing verwendeten. Der nachfolgende durch Musawir et al. entwickelte sog. Image-Space
Algorithmus führt diesen Schritt in Echtzeit durch. Abbildung 9 zeigt wie dabei vorgegangen wird.
Der zu beleuchtende Punkt ergibt sich dann wie folgt: Entlang der Normalen des Vertex der
Wasseroberfläche führt der durch die Wasseroberfläche gebrochene Lichtstrahl. Der Punkt P1 hat
dann entlang der Normalen den Abstand 1 zum Vertex v. Zieht man eine Gerade zwischen diesem
Punkt und der Lichtquelle, so kommt man auf die Projektion von P1 und erhält eine Distanz d‘. P2
erhält man nun indem man d‘ Einheiten entlang der Normalen geht. Schließlich erhält man den
Schnittpunkt, und zwar so, dass es der Schnittpunkt mit der zu beleuchtenden Oberfläche zwischen
P2 und der Lichtquelle ist. Verfährt man so für jeden Vertex der Wasseroberfläche, so erhält man an
Punkten, auf denen sich mehrere solcher Schnittpunkte treffen Kaustiken. Zusätzlich kann man in
diesen Algorithmus eine Shadow Map einfügen, sodass dafür weniger zusätzlicher Aufwand
benötigt wird.
Abbildung 9: Der Abschätzungsalgorithmus [K]
4.2
Wasser-Rendering mit Raytracing
Beim Raytracing werden die für Wellen üblichen Formen ähnlich dem Ansatz der
Echtzeitsimulation generiert. Das heißt durch Sinuskurven und dessen Erweiterungen. Da Wellen
auf die selbe Art dargestellt werden, wollen wir uns im ersten Teil mehr ins Detail gehen und uns
den Schaumgebilden widmen, und anschließend den Kaustiken und wie diese beim Raytracing
realisiert wird.
4.2.1 Generierung von „schaumgekrönten“ -Wellen
Schaumgebilde auf Wellen entstehen bei bestimmter Beschaffenheit des Gewässers und der
Umgebung. Dies wäre zum einen die Geschwindigkeit des Windes über dem Gewässer. Dazu sind
schon weniger Meter pro Sekunde ausreichend. Des Weiteren ist die Fläche des Schaums abhängig
10
von der Temperaturdifferenz zwischen dem Gewässer und der Luft und der chemischen
Zusammensetzung des Wassers[3].
Um nun den Schaumanteil des Wassers festzustellen hat Monahan[4] folgende Formel entwickelt:
f = 1.59 * 10-5U2.55exp[0.0861(Tw-Ta)]
Hierbei steht U für die Windgeschwindigkeit und Tw und Ta für die Temperatur des Wassers und
der Luft. Anhand dieser Formel kann man nun die Wasseroberfläche mit Schaum mit dem Anteil f
bedecken, sodass für mehr Realismus gesorgt ist.
4.2.2 Darstellung von Kaustiken
Dem Snellschen Gesetz zu Folge erhält man gebrochene Lichtstrahlen durch ni sin θi = nt sin θt,
wobei 0i bzw. 0t für die Winkel oberhalb bzw. unterhalb der Wasseroberfläche stehen, wie in
Abbildung 10 zu sehen ist.
Abbildung 10: Snellsches Gesetz [L]
nit und nt sind sog. Indices of Refraction oder kurz IOR. Diese sind n=1 für Luft und n = 4 / 3 für
Wasser. Wenn man nun Lichtstrahlen auf diese Weise an der Oberfläche bricht, entstehen Stellen,
auf die mehr gebrochene Lichtstrahlen. Durch die Überlagerung mehrerer solcher gebrochenen
Lichtstrahlen entsteht Intensität und Formen, die letztlich als Kaustiken wahrgenommen werden.
5. Darstellung von Schatten – Realtime vs. Raytracing
Der nächste Abschnitt beschäftigt sich damit, wie weiche Schatten einerseits anhand Raytracing
und andererseits in Echtzeit simuliert werden. Das ist insofern eine Problemstellung, die es zu lösen
gilt, weil bisher immer von einer Punktlichtquelle ausgegangen wurde. Jedoch müssen bei mehreren
Flächenlichtquellen verschiedene Grauabstufungen für die Schatten gewählt werden, um eine
realistische Darstellung zu erhalten. Bei der Echtzeitsimulation hingegen hat man das Problem das
meine keine Schatten im eigentlichen Sinne hat, da es keine Lichtstrahlen existieren. Wie
Schattendarstellungen in Echtzeit entstehen erklärt der nächste Abschnitt.
11
5.1
Shadow Mapping in Echtzeit
Wie in den vorigen Abschnitten, ist hier ebenfalls zu sagen, dass es wiederum verschiedene
Möglichkeiten und Techniken gibt weiche Schatten in Echtzeit darzustellen.
Die trivialste Lösung des Problems ist wieder das Multitexturing. Für die Darstellung von Schatten
bei statischen Objekten kann man auf die Berechnung eines Schattens verzichten. Aus diesem
Grund verwendet man sog. Lightmaps, die nichts weiter sind als Texturen die speziell für die
Schattierung des bestimmten Objekts erstellt werden und auf die Basistextur überlagert werden (s.
Abb. 11).
Basistextur
Light Map
Ergebnis
Abbildung 11: Light Map [M]
Für dynamische Schattierung muss man dieses Multi-Texturing noch dahingehend erweitern, dass
für jedes Frame eine Shadow Map generiert wird. Aus diesem Grund wird hier das Shadow
Mapping vorgestellt, da sie zwar unpräziser aber dafür schneller ist und durch die GPU berechnet
werden kann.
Wie beim Caustics Mapping wird auch hier das Problem in zwei Teile gespalten:
1. Das Erstellen der Shadow Map
2. Das Abbilden auf die Szene
Um die Shadow Map zu erstellen, wird zunächst die Szene aus Perspektive des Lichts gerendert.
Aus dem gerenderten Bild kann man nun anhand des Z-Buffers eine sog. Depth Map erstellen, die
als Textur im Grafikspeicher abgelegt wird. Dieser Prozess muss für jede Lichtquelle wiederholt
werden und kann beschleunigt werden, indem man Berechnungen der Beleuchtung, der Texturen
und des Color Buffers vernachlässigt, da nur die Tiefeninformationen für die Shadow Map relevant
sind. Außerdem muss sie nur neu erstellt werden, wenn sich das Objekt oder die Lichtquelle
bewegt. Wenn sich nur der Beobachter bewegt muss keine neue Depth Map berechnet werden,
sondern das Abbilden.
Dazu wird als erstes die Szene aus der Sicht des Beobachters gerendert. Durch Transformation aller
Pixel aus der Sicht des Beobachters in das Koordinatensystem der Shadow Map und
anschließendem sog. Depth Test des Z-Buffers mit den Tiefenwerten der Shadow Map, wird die
Shadow Map auf die Szene aus der Sicht der Lichtquelle abgebildet. Wenn bei diesem Test der
Abstand des transformierten Punkts zur Lichtquelle größer ist als der Abstand des entsprechenden
Punktes in der Shadow Map, so muss dieser durch ein Objekt bedeckt sein und liegt somit im
Schatten. Da dieser Test nur Aufschluss gibt ob ein Punkt im Schatten liegt oder nicht, kann man
die Ecken mit helleren Graustufen bedecken, sodass man weichere Ecken bekommt, das für mehr
Realismus sorgt. Die einzelnen Schritte kann man in den folgenden Abbildungen nachvollziehen:
12
Aus der Sicht des
Lichts gerendert
Depth Map aus der
selben Sicht
Projizierte Depth Map
aus Beobachter Sicht
Endergebnis
Abbildung 9: Shadow Mapping Schritte [N]
5.2 Shadow Volumes – Ein Raytracing Algorithmus
Shadow Volumes sind Körper, die bestimmen ob ein Objekt schattiert wird, falls es sich innerhalb
des Körpers befindet.
Das von Crow[5] entwickelte Shadow Volumes Verfahren ist im Gegensatz zum Shadow Mapping
sehr rechenintensiv, aber dafür auch präziser bei der Abbildung von realitätstreuen Schatten. Es ist
nicht State of the Art, da es schon vielfach erweitert wurde. Da es als Grundlage für die heutigen
Verfahren wie z.B. Soft Shadow Volumes dient, möchte ich daher auf dieses Verfahren eingehen.
Um ein Schattenvolumen zu erzeugen, muss zunächst das Objekt untersucht werden, das den
Schatten erzeugt. Dieses besteht aus zweit Seiten: die beleuchtete und die im Schatten liegende
Seite. Die Punkte, die zwischen diesen beiden Seiten liegen, bilden zusammen die Silhouette. Diese
können durch Abtasten der Nachbarn ermittelt werden, indem der Z-Buffer der benachbarten
Punkte ermittelt wird. Bildet man nun von diesen Punkten ausgehend Strahlen, die sich von der
Lichtquelle wegbewegen, so erhält man einen Kegel dessen ausbreitende Seite ins unendliche
reicht. Nun muss man nur noch sog. Front- bzw. Back-Caps einfügen. Diese decken die zwei Seiten
des Körpers ab, einerseits auf der Rückseite des Objekts und andererseits auf der Oberfläche, die
die Strahlen schneidet (s. Abb.12). Somit erhalten wir unseren gewünschten Körper der das
Schattenvolumen darstellt.
Abbildung 12: Shadow Volumes [O]
13
6. Zusammenfassung & Ausblick
Die Vorteile beider Techniken liegen auf der Hand. Durch Raytracing erhält man photorealistische
Darstellungen, die kaum noch von realen Bildern zu unterscheiden sind. Dafür muss man lediglich
viel Zeit in Kauf nehmen, da dieses Verfahren sehr rechenintensiv ist und alleine die CPU auslastet.
Die Algorithmen für die Echtzeitsimulationen sind in der Hardware integriert und sind weniger
rechenintensiv aber auch weniger Realitätstreu. Die „Tricks“ mit den man bei der
Echtzeitsimulation arbeitet werden jedoch immer weiter optimiert, sodass sich Realtime Rendering
dem Raytracing immer weiter nähert. Hinzu kommt noch das Grafikkarten in noch kürzerer Zeit als
die CPU leistungsfähiger werden. Der Trend: Realtime Raytracing.
Bereits heute gibt es Projekte die Darstellungen anhand Raytracing in 20 fps erstellen können.
Bereits angesprochene Problemstellungen wie Kaustiken, globale Beleuchtung und Schatten
werden in einigen Projekten in Echtzeit mit Raytracing dargestellt. Das beste Beispiel ist dazu das
Computerspiel, dessen vorveröffentlichte Szenen teilweise in Echtzeit „geraytraced“ und teilweise
auf die übliche Art simuliert sind. Die folgenden Screenshots aus Realtime Raytracing Projekten
sollen einen Ausblick darüber geben, was die Computer Graphics Welt in dieser Richtung erwartet.
RealStorm Projekt (www.realstorm.com)
Quake Wars
OpenRT Projekt (www.openrt.de)
OpenRT Projekt
14
7. Referenzen & Quellen
[1]
„GPU Gems: Programming Techniques, Tips, and Tricks for Real-Time Graphics“,
Randima Fernando 2004.
[2]
Musawir Shah und Sumatra Pattanaik: Caustics Mapping : An Image-space technique for
Real-time Caustics, 2005.
[3]
Simon Premože and Michael Ashikhmin: Rendering natural waters, 2000.
[4]
E. Monahan and G. MacNiocaill, editors. Oceanic Whitecaps:Their Role in Air Sea
Exchange Processes. D. Reidel, 1986.
[5]
Crow, F. C. Shadow algorithms for computer graphics. In Computer Graphics (Proceedings
of SIGGRAPH 77), vol. 11, 242–248, 1977
[A]
A.S. Glassner, An Introduction to Ray Tracing. San Francisco: Morgan Kauffmann
Publishers, 2000.
[B]
http://en.wikipedia.org/wiki/Ray_tracing
[C]
http://en.wikipedia.org/wiki/Ray_tracing
[D]
http://de.wikipedia.org/wiki/Z-Buffer
[E]
http://de.wikipedia.org/wiki/Bumpmapping
[F]
http://www.filterforge.com/filters/4067-bump.html
[G]
A.S. Glassner, An Introduction to Ray Tracing. San Francisco: Morgan Kauffmann
Publishers, 2000.
[H;I] A.S. Glassner, An Introduction to Ray Tracing. San Francisco: Morgan Kauffmann
Publishers, 2000.
[J]
http://www.filterforge.com/filters/487.html
[K]
Musawir Shah und Sumatra Pattanaik: Caustics Mapping : An Image-space technique for
Real-time Caustics, 2005.
[L]
http://commons.wikimedia.org/wiki/Image:Example_snells_law.gif
[M]
http://wiki.delphigl.com/index.php/Tutorial_MultiTexturing
[N]
http://en.wikipedia.org/wiki/Shadow_mapping
[O]
http://www.ozone3d.net/tutorials/stencil_shadow_volumes.php
15