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