ComputerBase

Bericht: Raytracing in Spielen 2.0

von Daniel Pohl

Prolog

Dieser Artikel ist die Fortsetzung des Artikels „Raytracing in Spielen“ [1], welcher etwa vor einem Jahr auf ComputerBase veröffentlicht wurde. Seitdem gab es viele Fortschritte, durch die Echtzeit-Raytracing für Desktop-Maschinen immer näher rückt.

Leser, die mit den Details von Raytracing bisher noch nicht so vertraut sind, finden hier eine detaillierte Erklärung des Verfahrens.

Fortschritt

Nachdem mein letzter Artikel über Raytracing in Spielen unter anderem auf ComputerBase veröffentlicht worden war, habe ich mich intensiver mit dem Skalierungsverhalten von Raytracing mit steigender Zahl an CPU-Cores beschäftigt. Um eine 16-Core-Maschine zu simulieren, habe ich vier Quad-Core-PCs über Gigabit-Ethernet zusammengeschaltet und deren Rechenleistung vereinigt. Da mein Projekt zu dieser Zeit die Raytracing Library OpenRT [2] der Universität des Saarlandes benutzte, die Support für verteiltes Rendern bietet, war dies einfach zu bewerkstelligen.

OpenRT ist eine Raytracing-Bibliothek (C/C++), die vom Computergrafik-Lehrstuhl der Universität des Saarlandes entwickelt wurde. Die Syntax ist nahezu identisch zu der von OpenGL. Für Programmierer gibt es eine kostenlose Linux-Version, die für nichtkommerzielle Zwecke benutzt werden darf.

Leistungsskalierung
Skalierung von Raytracing mit verschiedener Anzahl an CPU-Cores

Die Ergebnisse waren verblüffend: Wenn man eine 16-Core-Maschine anstatt einer Single-Core-Maschine benutzt, dann steigt die Framerate um einen Faktor von 15,2!

Nach all der Aufmerksamkeit, die der vorhergehende Artikel über Raytracing in Spielen rund um den Globus erhalten hatte, wurde ich von verschiedenen Firmen mit Interesse an dieser Technologie angeschrieben. Eine davon war Intel. Bei Intel erzählte man mir, dass man über einen Echtzeit-Raytracer verfüge, der etwa zehn Mal schneller sei als alles andere, was bisher in diesem Bereich veröffentlicht wurde. Diese Zahlen konnte man bereits in einem wissenschaftlichen Artikel nachlesen, aber ich traute ihnen dennoch nicht, ohne es mit eigenen Augen gesehen zu haben. Also flog ich nach Santa Clara, „Silicon Valley“, in Kalifornien, um eine Live-Demonstration zu erhalten.

Mittlerweile bin ich bei Intel fest angestellter Wissenschaftler und arbeite weiter an Raytracing. Wie sich herausgestellt hat, ist das Interesse von Intel an Raytracing unter anderem deswegen so groß, da die Technik so gut geeignet ist für CPUs. Der Forschungsbereich ist Teil eines großen Programms (genannt „Tera-Scale Computing“) mit dem Ziel der Verbesserung der Skalierung von Software von einigen auf viele Kerne (mit vielen sind hier mehrere Hunderte gemeint).

Die Anstellung bei Intel ermöglichte es mir, Quake 4: Raytraced [3] mit dem neuen Intel-Raytracer auf verschiedenen Veranstaltungen, wie der Games Convention 2007 in Leipzig und dem Intel Developer Forum im Herbst 2007 in San Francisco, zu zeigen. Auf letztgenanntem Event wurde es sogar in der Keynote von Justin Rattner (Intel CTO) über virtuelle Welten demonstriert.

In HD-Auflösung konnten wir eine Framerate von etwa 90 Bildern pro Sekunde auf einer Dual-X5365-Maschine zeigen, wobei alle 8 Cores des Systems zum Rendern vollständig ausgenutzt wurden.

Forschritte IDF Herbst 2007

Raytracing vs. Rasterisierung

Ich wurde des Öfteren gefragt, ab wann Raytracing schneller sein wird als Rasterisierung (der Ansatz der heutigen GPUs zum Rendern). Nun, es gibt bereits jetzt Fälle, in denen Raytracing auf einer einzelnen Desktop-Maschine schneller ist!

Beispiel 1

Raytracing benutzt „Beschleunigungsstrukturen“, die die gesamte Geometrie einer virtuellen Welt anhand ihrer Position im Raum sortieren. Es gibt viele verschiedene Ansätze dies zu tun. Die bei Raytracing am häufigsten benutzten sind Uniform Grids, BSP-trees [4], kd-trees [5] und Bounding Volume Hierarchies (BVHs [6]).

Wie bereits in der Einleitung beschrieben, muss man beim Schießen eines Strahls herausfinden, welches Objekt entlang des Pfades des Strahls zuerst getroffen wird. Die grundlegende Idee der räumlichen Unterteilung mit Beschleunigungsstrukturen wird am Besten mit einem kleinen Beispiel beschrieben: Man stelle sich vor, man habe ein vier Stockwerke hohes Gebäude. Auf jedem Stockwerk befinden sich vier Räume und der Spieler befindet sich im obersten Stockwerk in dem Zimmer ganz links:

Räume – Ausgangssituation
Künstlerisch hochwertige Repräsentation eines Gebäudes
mit vier Stockwerken mit jeweils vier Zimmern.

Durch das Verfolgen des Strahls wollen wir herausfinden, ob ein bestimmtes Stück Geometrie getroffen wird oder nicht. In der Raytracing-Sprache: Wir schießen Strahlen aus der „Kamera“ (den Augen des Spielers) um mit diesen „Primärstrahlen“ festzustellen, was sichtbar ist und was nicht. Der naive Ansatz wäre, die Strahlen einfach gegen die komplette Geometrie zu testen, ob sie diese treffen. In unserem Beispiel würde man offensichtlich sehr viel Rechenaufwand verschwenden. Denkt man über die Situation ein wenig nach, so wird schnell klar, dass der Spieler links oben im Raum sehr unwahrscheinlich etwas sehen wird, das sich beispielsweise im Raum rechts unten befindet. Warum sollte man also überhaupt den Strahl darauf testen, ob er Geometrie in diesem Raum rechts unten trifft? Wie kann man diesen überflüssigen Rechenaufwand am Besten vermeiden?

Die Lösung sind hierarchische, räumliche Beschleunigungsstrukturen, mit denen man schnell feststellen kann, ob ein bestimmter Bereich für das Rendern ein relevantes Detail enthält. Ist dies nicht der Fall, so kann man auf einen Schlag einen haufen Berechnungsarbeit sparen und diese in anderen Bereichen nutzen, in denen hoch detaillierte, sichtbare Geometrie vorhanden ist.

Analytisch ausgesprochen ist einer der Vorteile von solch' hierarchischen Datenstrukturen, dass sie eine „lineare Suche“ (jedes Mal alles gegen alles testen) zu einer „logarithmischen Suche“ optimieren. Dies bedeutet, dass man von der obersten Hierarchiestufe, die den Raum aller Geometrie beinhaltet (in unserem Fall das gesamte Gebäude mit den 16 Räumen), nur dann in einen detaillierten Bereich (einen einzelnen Raum) vordringt, wenn es darin wirklich relevante Informationen gibt.

Räume – Schritt 1

… die nächste Stufe teilt die Räume in der Mitte von oben nach unten ...

Räume – Schritt 2

… die nächste Stufe teilt die links übrig bleibenden acht Räume in der Mitte und unterteilt sie in zwei Bereiche mit jeweils vier Räumen ...

Räume – Schritt 3

Im Falle der linearen Suche würde man jeden der einzelnen 16 Räume absuchen. Also einen Arbeitsaufwand von 16 betreiben. Im logarithmischen Fall würde man im Schritt eins die rechte Hälfte eliminieren. Im zweiten Schritt würde man den Bereich links unten eliminieren. Schritt drei würde die rechte Hälfte der vier verbleibenden Räume als irrelevant markieren. Im vierten Schritt findet man schließlich heraus, dass nur der eine Raum links oben relevant ist. Also benötigte man hier nur vier Arbeitseinheiten anstatt 16.

Wenn man nun das Gebäude auf 32 Räume vergrößert, so hätte man im linearen Fall 32 Arbeitseinheiten verglichen, aber nur 5 im Falle der logarithmischen Suche. Allgemein gilt: Wenn man die geometrische Komplexität einer Szene um das Zehnfache steigert, dann erhöht sich der Rechenaufwand bei der Verwendung der hierarchischen Beschleunigungsstrukturen nur um den Faktor zwei. Im Kontrast dazu steht die Rasterisierung mit ihrem linearen Verhalten, bei dem die Steigerung der Geometrie um das Zehnfache auch den zehnfachen Rechenaufwand bedeutet.

Dieses Verhalten ist im folgenden Diagramm dargestellt:

Raytracing vs. Rasterisierung

Die graue Kurve repräsentiert den Rechenaufwand von Raytracing, wenn man die Anzahl der Dreiecke erhöht. Die rote zeigt das lineare Verhalten der Rasterisierung. Wie man sehen kann, ist Raytracing bei einer niedrigen Anzahl an Dreiecken im Nachteil. Allerdings treffen sich die Kurven schnell und ab diesem Punkt ist Raytracing bei steigender Komplexität schneller als Rasterisierung, sobald die Beschleunigungsstruktur aufgebaut wurde. Wo genau dieser Schnittpunkt liegt, das hängt von vielen Faktoren ab: Der Performance der CPU, der Performance der GPU usw.. Aber der Trend ist eine mathematische Gewissheit: Die logarithmische Kurve wird immer einen Schnittpunkt mit einer linearen haben.

Durch das nahezu perfekte Skalierungsverhalten von Raytracing würde die graue Kurve bei einer Verdoppelung der CPUs oder CPU-Cores um die Hälfte schrumpfen und somit den Schnittpunkt näher in den Bereich der im Diagramm eingezeichneten Null bewegen. Je mehr CPUs bzw. Cores zur Verfügung stehen, umso schneller kommt man also an den Punkt, an dem man schneller als das Rasterisierungsverfahren auf der GPU ist.

Ein Beispiel, das eindeutig über dem Schnittpunkt liegt, ist das Modell einer Boeing 777 mit 350 Millionen Dreiecken. Dieses extrem hoch detaillierte Modell beinhaltet jede Schraube des Flugzeugs und wurde von Boeing Wissenschaftlern zur Verfügung gestellt, um nach Methoden zu forschen, mit denen man das komplette Flugzeug am besten in Bewegung grafisch darstellen kann.

Flugzeugmodell mittels Raytracing

Raytracing hat sich als die korrekte Lösung dafür erwiesen [7]. Bereits im Jahr 2004 konnte die Forschungsgruppe der Universität des Saarlandes dieses Modell mit 3 bis 7 Bildern pro Sekunde in einer Auflösung von 640x480 auf einer Dual-Core-CPU der damaligen Zeit rendern.

Es mag die Frage aufkommen, warum die erwähnten Beschleunigungsstrukturen nicht auch in der Rasterisierung verwendet werden? Sie werden benutzt! Allerdings mit einer geringeren Präzision. Einige Spiele haben gar verschieden aufgelöste Granulare zum Rendern von Grafik, für die Kollisionserkennung oder die AI (manchmal erzeugt über Bibliotheken von anderen Softwareherstellern). Neben dem erhöhten Speicherverbrauch ist ein weiteres Problem dieser multiplen Strukturen, dass man sie konsistent halten muss.

Hier ein Beispiel dafür, was passiert, wenn die Informationen aus der Kollisionserkennung nicht mit denen aus der Datenstruktur zum Rendern konsistent sind: In dem Spiel „Oblivion“ werden unterschiedlich detaillierte Repräsentationen der Welt zum Rendern bzw. für die Kollisionserkennung benutzt. Wenn sich eine Tür in dem Spiel langsam schließt, so ist dies für den Spieler klar sichtbar. In jedem Bild verändert sich der Winkel leicht, bis die Tür geschlossen ist. Daher kann man annehmen, dass es mindestens vier verschiedene Zustände für diese Tür gibt: offen, schließend, geschlossen, öffnend. Doch die Datenstruktur der Kollisionserkennung aktualisiert sich nicht mit demselben Detailgrad. Somit können andere computergesteuerte Charaktere wie „Velwyn“ nur zwei Zustände der Tür ausmachen: offen oder geschlossen.

Inkonsistenz in Oblivion

Im Spiel kann es daher dazu kommen, dass die Türe für den Spieler offensichtlich gerade dabei ist sich zu schließen, da Velwyn aber nur die Information bekommen kann, dass die Türe nicht geschlossen ist, kommt er zu der Annahme, dass die Tür also offen sein muss. Daher bewegt sich Velywn auf die Türe zu, bis er schlagartig darin feststeckt, sobald der Status der Tür auf geschlossen aktualisiert wurde. Das sieht dann so aus:

Inkonsistenz in Oblivion
Velwyn steckt in der Türe fest in Oblivion (2006).

(Natürlich kann man Raytracing auch für Kollisionserkennung benutzen um solche Probleme zu verhindern, aber das ist eine andere Geschichte).

Aber auch falls die Beschleunigungsstrukturen zum Rendern mit den anderen in der Rasterisierung konsistent sind, gibt es noch ein anderes Problem: In Raytracing testet man die Strahlen pixelgenau gegen die Dreiecke. In der Rasterisierung gibt es hingegen keine Strahlen, die genau gegen die Beschleunigungsstruktur getestet werden können, daher muss man sich wieder auf weniger effiziente Approximationen verlassen. Dies kann mit verschiedenen Methoden getan werden. Hier ein kurzer Überblick über zwei davon:

Beispiel 2

Das zweite Beispiel ist eine Fallstudie mit mehreren Reflektionen in Reflektionen auf Kugeln und Tori. (Ein Torus ist der mathematische Begriff für ein geometrischens Objekt in der Form eines Donuts. Der Plural von Torus ist Tori.)

Spiegelungen in Quake 4
Mehrfachspiegelungen in Spiegelungen.

Wenn man für einen Moment die Tatsache ignoriert, dass es generell unmöglich wäre, solch' eine Szene mittels Rasterisierung zu rendern, so stellt man fest, dass es auf einem anderen Weg (Raytracing) nicht nur möglich, sondern auch mit wesentlich weniger Rechenaufwand verbunden ist, als man zuerst angenommen hat! Denn Raytracing berechnet alle Reflektionen effizient und korrekt - aber eben nur, wenn sie wirklich benötigt werden, also sichtbar sind. In der folgenden Sequenz wird der Ablauf zum Erstellen des Bildes dargestellt und es wird veranschaulicht, wieviele Strahlen benutzt werden:

Schritt 1: Primärstrahlen – mindestens einer pro Pixel (rot markiert), alles auf dem Bildausschnitt ist sichtbar

Spiegelungen in Quake 4 – 1. Ebene

Schritt 2: Primäre Reflektionen (grün markiert), nur die spiegelnden Flächen reflektieren

Spiegelungen in Quake 4 – 2. Ebene

Schritt 3: Sekundäre Reflektionen (blau markiert), reflektierte Strahlen werden nur von den blauen Flächen erneut reflektiert

Spiegelungen in Quake 4 – 3. Ebene

Schritt 4: Tertiäre Reflektionen (gelb markiert), nur auf den gelben Flächen treffen bereits zweimal reflektierte Strahlen erneut auf und werden reflektiert

Spiegelungen in Quake 4 – 4. Ebene

Schritt 5: usw. usf. ...

Wie man eindeutig sieht, verringert sich die Anzahl an zusätzlichen Strahlen drastisch mit jedem weiteren Schritt. Daher kann selbst eine so komplexe Szene mit vielen Spiegelungen in Spiegelungen mit nur einem geringen zusätzlichen Kostenaufwand mittels Raytracing berechnet werden.

Reflektionen bei Rasterisierung

Um bei der Rasterisierung Reflektionen zu simulieren, wird die Szene aus mindestens einer Kameraposition vorgerendert und in einer Textur (einer so genannten Reflection Map, manchmal auch Cube Map genannt) gespeichert, die dann schichtweise über ein Multipass-Verfahren beim Rendern auf eine Oberfläche aufgeklebt wird. Die gleiche Methode wird beim Erzeugen der so genannten „Shadow Maps“ verwendet, bei der man ebenfalls einen weiteren Durchgang benötigt, bevor man die Szene rendern kann.

Es gibt verschiedene Fälle und Methoden dies zu tun (Quelle: Uni Erlangen [10]):

Doch alle Ansätze mittels Rasterisierung haben ihre Limitierungen:

Was all' diese Ansätze versuchen, ist eine Annäherung an Raytracing. Wie bereits im ersten Beispiel erwähnt: Die Geschwindigkeit von Raytracing skaliert logarithmisch mit der Anzahl der Dreiecke. Das trifft natürlich auch für alle Reflektionsstrahlen zu. Daher kann man in einer Szene mit vielen Polygonen und Reflektionen sogar noch mehr Vorteile aus dieser Situation ziehen.

Special Effects

Bei der Produktion von Kinofilmen wird Raytracing oft aufgrund der einzigartigen Fähigkeiten Special Effects zu liefern, die bei anderen Algorithmen nicht möglich wären, oder nur unzuverlässige Ergebnisse liefern würden, verwendet. Der folgende Abschnitt zeigt zwei Special Effects, die für Computerspiele relevant sind und den Spaßfaktor um Einiges erhöhen können: Kameraportale und Reflektionen.

Kameraportale

Ein mittlerweile bekanntes Feature in 3D-Shootern ist das Kameraportal. Es ermöglicht dem Spieler in einen Bereich der Szene (Spielwelt) zu sehen, in dem er sich physikalisch nicht befindet.

Portal in Quake 3
Kameraportal in Quake 3: Arena (1999)

Es ist sehr interessant zu sehen, wie einfach und effizient dieser Effekt mittels Raytracing realisiert werden kann. Hier die Aufstellung der Szene:

Portal in Quake 3

Der Spieler befindet sich auf der unteren Ebene. Vor ihm steht ein Kameraportal, durch das er hindurch sieht. Auf der oberen Ebene befindet sich ein Gegner. Was wir wollen, ist, dass das Portal uns (bzw. unser Sichtfeld) auf magische Art und Weise in die obere Ebene befördert. Für Raytracing bedeutet dies einfach nur, dass man für den Primärstrahl einen Offset (vom Auftreffpunkt auf dem Kameraportal aus zu einem neuen Ursprung) benötigt, um so den Strahl weiter zu verfolgen. Dies ist hier bildlich dargestellt:

Portal in Quake 3 mittels Raytracing

In Programmiersprache sieht dies wie folgt aus:

// Herausfinden des Auftreffpunkts des Strahls im Shader-Programm.

Vector3D hitPosition = getHitPositionOfRay(ray);

// Addieren eines 3D-Offsets zur Auftreffposition.

hitPositon += cameraPortalOffset;

// Schießen eines neuen Strahls von der Auftreffposition mit dem
// darauf addierten Offset in die gleiche Richtung.

finalColor = traceNewRay(hitPosition, getDirectionOfRay(ray));

Voilà, mit nur drei Zeilen Code hat man sein Kameraportal. Nachfolgend angewendet in Quake 3: Raytraced [12]:

Portal in Quake 3 mittels Raytracing
Kameraportal in Quake 3: Raytraced (2004).

Im Oktober 2007 hatte Valve ein Spiel namens „Portal“ veröffentlicht. Es beinhaltete ein innovatives, neues Spielkonzept: Durch geschicktes platzieren von Portalen innerhalb der Spielwelt war der Spieler in der Lage, wie von Geisterhand zu verschiedenen Orten in der Spielwelt zu gelangen und kleine Rätsel zu lösen. Aus technischer Sichtweise ist es sehr interessant zu sehen, wie dabei der Kameraportal-in-Kameraportal-Effekt implementiert wurde.

Valves Portal
Das Spiel „Portal” von Valve (2007)

Die Implementierung ist ziemlich robust. Das Spiel ist so ausgelegt, dass man dem Portal-in-Portal-Effekt niemals zu nahe kommt, um die Rekursionstiefe nicht zu stark zu erhöhen. Dennoch, nach einigem Experimentieren und Austesten kann man die Limitierung des Ansatzes im folgenden Screenshot, bei dem die Rekursionstiefe die vordefinierte Grenze überschritten hat, erkennen. Ersichtlich ist dies in der Mitte des Portals, in der sich die Kiste bei korrekter Darstellung öfters hätte wiederholen müssen.

Valves Portal – Limitierungen
Die Darstellung der Kiste wiederholt sich nur bis zu
einer gewissen Anzahl in der Mitte des Portals.

Es ist sehr interessant anzumerken, wie der Programmcode für den Effekt in Raytracing geändert werden muss, um Kameraportale in Kamerportalen zu unterstützen: Gar nicht! Es läuft immer noch mit genau demselben Code! Einzig geändert werden muss der Offset-Parameter, so dass dieser auf einen Platz vor dem Kameraportal zeigt. Dies ist hier bildlich dargestellt:

Portal-in-Portal-Effekt mittels Raytracing

Um so einen Effekt hingegen bei der Rasterisierung zu erzeugen, wird das Bild erst einmal mit einem „leeren“ Kameraportal in eine Textur gerendert. Anschließend muss man einen Teil dieser Textur auf den leeren Fleck kleben. Danach wiederholt man das Ganze noch einmal mit einer kleineren Version in der Mitte des Bereichs des leeren Flecks usw. usf. ...

Beim Rendern mit den nur drei Zeilen Programmcode bei Raytracing sieht das dann so aus:

Portal-in-Portal-Effekt mittels Raytracing
Szene aus Quake 4: Raytraced. In der Mitte ist die
Anzahl der Portale in Portalen bei 130.

Wie bei den Reflektionen ist der Portal-Effekt sehr effizient, da man bei der Berechnung nur für so viele zusätzliche Strahlen „zahlt“, wie man sie auch wirklich sieht. Auch der Effekt, dass die Anzahl an zusätzlichen Strahlen mit jedem weiteren Schritt stark abnimmt, trifft hier zu. Daher hat nur ein sehr geringer Anteil an Strahlen eine richtig hohe Rekursionstiefe und damit hohe Kosten.

Es wird mit Raytracing möglich sein, richtig beeindruckende Szenen wie z.B. zwei Kameraportale nebeneinander und diese wieder auf sich selbst projeziert zu generieren. Wie der Programmode dafür aussieht? Er bleibt derselbe!

Portal-in-Portal-Effekt mittels Raytracing
Q4RT: Zwei Kameraportale in Kameraportalen

Spiegelungen

Besseres Gameplay durch Spiegelungen um Gegner frühzeitig zu erkennen

Aus Sicherheitsgründen ist es mittlerweile üblich, Spiegel an Wänden in Ecken von Gebäuden anzubringen, damit Leute nicht ineinander rennen, wenn sie es gerade eilig haben (z.B. zum Mittagessen zu kommen.) Genau so würden hart gesottene 3D-Shooter-Spieler gerne um Ecken schauen können. Vielleicht ist gerade ein Gegner im Anmarsch? Vielleicht ein Verbündeter? Mit Raytracing ist dies ganz einfach zu lösen, indem man einen Spiegel in die Welt setzt und sich an den hinzugekommenen Möglichkeiten im Gameplay erfreut.

Spiegel in einem Bürokomplex Spiegel in einem Bürokomplex
Spiegel in Quake 3 mittels Raytracing
Quake 4: Raytraced – Zusätzlicher Spiegel in der Ecke, um in den
anderen Gang zu sehen.

Hier ist ein Video, bei dem die zusätzliche Information über einen herannahenden Gegner durch den zusätzlichen Spiegel in der Ecke ausgenutzt wird. Nur durch einen Blick in den Spiegel konnte der Spieler die Ankunft des Monsters vorhersehen und rechtzeitig eine Rakete in dessen Richtung feuern.

Gameplay-Video auf YouTube ansehen

Hybrid Rendering

Warum es eine schlechte Idee ist und warum es trotzdem gemacht werden wird.

Wie wird Raytracing für Spiele auf dem Markt erscheinen? Viele Leuten erwarten, dass es einen sanften Übergang geben wird. Von Rasterisierung über Rasterisierung mit Raytracing bis hin zu komplett „raytraced“. Die Annahme mancher ist, dass der größte Teil des Bildes rasterisiert wird und Raytracing nur in kleinen Bereichen, wie etwa einer spiegelnden Kugel, zum Einsatz kommen wird.

Es ist ein netter Gedankengang und reflektiert die Entwicklung, die im Bereich der Grafikkarten in der Vergangenheit vollzogen wurde. Anfänglich hatte man nur einen festen Renderpfad. Dann wurden einige kleine Teile für Entwickler geöffnet. Dieser entwickelte sich von den kompliziert zu programmierenden „Register Combiners“ zu den Vertex- und Pixelshadern, die wiederum über einen langen Zeitraum in kleinen Schritten verbessert wurden, wodurch stets ein sanfter Übergang von einem Fortschritt zum anderen aufkam.

Pixel Shader-Versionen
innerhalb von DirectX
Pixel Shader-
Version
DirectX-
Version
Release
1.0/1.18.0
2000
1.28.0a
2001
1.38.0a
2001
1.48.1
2001
2.09.0
2002
2.0a9.0b
2003
2.0b9.0b
2003
3.09.0c
2004
4.010
2006

Daher ist es durchaus verständlich, dass einige die Erwartung haben, dass Raytracing ebenfalls in kleinen Schritten eingeführt wird. Das Problem jedoch ist: Aus technischer Sicht macht es keinen Sinn, da die Kosten des Teils, der mit Raytracing berechnet wird, in vielen Fällen sehr schnell den ausschlaggebenden Teil der Berechnung einnehmen.

Beispiel 1

Lasst uns ein typisches Spieleszenario aus Quake 4 mit einer zusätzlichen, spiegelnden Kugel, die sich weit weg vom Auge des Betrachters befindet, annehmen:

Raytracing vs. Rasterisierung

Man könnte nun alles außer der Kugel mittels Rasterisierung rendern und nur Raytracing auf die Kugel anwenden. Um dies zu tun, benötigt man dennoch:

Wenn die Spielwelt sehr komplex ist, dann wird man vermutlich mehr Dreiecke rasterisieren als man Strahlen benötigt hätte, um dies zu tun – ein reiner Raytracer wäre also effizienter gewesen. Doch lassen wir diese Annahme einmal außen vor, so haben wir in diesem Szenario unter der Annahme, dass der Rasterisierer alle Sichtbarkeitstests auflöst, alle Primärstrahlen „gespart“.

Beispiel 2

Der obige Screenshot sieht ziemlich langweilig aus, da er keinerlei Beleuchtung und Schatten berücksichtigt. In dem unteren Beispiel ist nun jeder Pixel mit durchschnittlich drei bis fünf Lichtquellen gleichzeitig beleuchtet.

Raytracing vs. Rasterisierung

Wenn man Raytracing benutzt, um alle Schatten korrekt zu berechnen, dann würde jeder Pixel einen Primärstrahl und vier Schattenstrahlen benötigen. Würde man stattdessen Rasterisierung benutzen, um die gleiche Bildqualität zu erzeugen, würde man nur den einen Primärstrahl „sparen“. Die Ansätze der Rasterisierung in Bezug auf Korrektheit und Genauigkeit sind bei Schatten, Spiegelungen und Brechungen nicht akkurat genug. Speziell wenn man danach strebt, immer höhere Bildqualitäten zu erreichen, dann verpufft die Einsparung durch Rasterisierung für die Sichtbarkeitsberechnung (also anstatt Primärstrahlen) immer mehr.

Beispiel 3

Die beiden vorherigen Beispiele haben eine weit entfernte Spiegelung gezeigt. Aber was passiert, wenn man an solch' ein spiegelndes Objekt so nahe heran zoomt, dass es nahezu den gesamten Bildschirm füllt? In einer Spieleumgebung, in der der Spieler sich frei bewegen kann, sind solche Situationen nicht zu verhindern.

Raytracing vs. Rasterisierung

Nun müssen auf einen Schlag etwa 90 Prozent aller Pixel über Raytracing berechnet werden. Daher würde man bei dem Ansatz des Hybridrendering lediglich 10 Prozent für die Primärstrahlen „sparen“.

Beispiel 4

Ich überlasse es der Vorstellungskraft des Lesers heraus zu finden, wie sinnvoll der Ansatz des Hybridrendering ist, wenn in dieser Spiegelung auch die Beleuchtung mit Schatten dargestellt wird.

Raytracing vs. Rasterisierung

Die vorangegangenen Betrachtungen führen also zu der Schlussfolgerung, dass der Ansatz Hybridrendering zur Darstellung der 3D-Welt nicht unbedingt die beste Idee ist. Seine einzig' brauchbare Anwendung ist meiner Meinung nach eine zusätzliche Schicht wie ein HUD (Heads Up Display), eine Konsole oder vielleicht sogar die 3D-Perspektive eines Cockpits, jedoch nicht das Rendern der effektiven 3D-Szene.

Raytracing und Rasterisierung
Schriften und Fadenkreuz als zusätzliche Schicht über einem geraytractem
Bild durch teilweise durchsichtige Vierecke in OpenGL.

Nichtsdestotrotz wäre ich nicht überrascht, Demos zu dem Ansatz des Hybridrendering von Leuten zu sehen, die an diese Idee glauben. Jedoch bezweifle ich, dass die Methode es in einer überzeugenden Weise in ein kommerzielles Spiel schaffen wird.

Es wird sicherlich demnächst noch mehr zum Thema Raytracing geben. Und vielen Dank für das Lesen dieses Artikels! Stay tuned!

Über den Autor

Daniel Pohl Daniel Pohl ist Forscher bei Intel in Deutschland (bald bei Intel in Santa Clara, „Silicon Valley“, Kalifornien). Er trat dem Grafikteam von Intel bei, nachdem er sein Informatik-Diplom an der Universität Erlangen abgeschlossen hatte. Während seiner Studienzeit hatte er den Raytracing-Algorithmus auf die Spiele Quake 3 und Quake 4 angewendet. Seine Hauptgebiete sind 3D-Grafik und Spieleprogrammierung.

URL-Liste:

  1. http://www.computerbase.de/artikel/software/2007/bericht_raytracing_spielen/
  2. http://www.openrt.de
  3. http://www.q4rt.de
  4. http://de.wikipedia.org/wiki/Binary_Space_Partitioning
  5. http://en.wikipedia.org/wiki/Kd-tree
  6. http://en.wikipedia.org/wiki/Bounding_volume_hierarchies
  7. http://graphics.cs.uni-sb.de/Publications/
  8. http://en.wikipedia.org/wiki/Potentially_visible_set
  9. http://en.wikipedia.org/wiki/Portal_rendering
  10. http://www9.informatik.uni-erlangen.de:81/Teaching/SS2003/InCG/Material/textures.pdf
  11. http://local.wasp.uwa.edu.au/~pbourke/
  12. http://www.q3rt.de
Copyright © 1999–2009 ComputerBase Medien GbR