Raytracing in Spielen I: Strahlen versprechen den Fotorealismus
2/5Raytracing
Wie funktioniert Raytracing? Der Reihe nach! Zuerst wird eine Szenerie im dreidimensionalen Raum festgelegt. Diese soll in dem folgenden Beispiel eine Lichtquelle (in der Skizze als Glühbirne dargestellt) und verschiedene geometrische Objekte enthalten: Eine Kugel, ein Dreieck und einen Würfel.
Für die Lichtquelle wurden gewisse Attribute festgelegt. Beispielsweise ihre Intensität und Farbe und die von der Distanz zwischen Lichtquelle und beleuchtetem Objekt abhängige Abschwächung der Intensität. Für die grüne Kugel soll in einem Shader-Programm festgelegt sein, dass sie grün ist und eine Oberfläche aus reflektierendem Material besitzt. Ferner wird darin überprüft, ob der betrachtete Punkt auf der Kugel beleuchtet ist, oder sich im Schatten befindet. Das Shader-Programm des roten Dreiecks definiert kein außergewöhnliches Material. Die Farbe ist Rot. Zusätzlich testet das Programm, ob der relevante Punkt auf dem Dreieck von der Lichtquelle beleuchtet wird.
Um ein Bild zu Erzeugen, das von der Position des Spielers und dessen Blickrichtung abhängig ist, wird eine virtuelle Kamera in die Szene gesetzt. Sie repräsentiert das Auge des Betrachters.
Der Raytracing-Algorithmus selbst ist ziemlich einfach:
- Von der virtuellen Kamera aus werden für jedes Pixel des zu berechnenden Bildes so genannte Primärstrahlen geschossen.
- Für jeden Strahl wird der Schnittpunkt hitpointprimary mit der Szenerie errechnet. Dieser ergibt sich, indem man dem Primärstrahl von seiner Ausgangsposition in seine Richtung so lange folgt, bis er auf ein Objekt trifft. In diesem Beispiel ist dies die grüne Kugel. Wir wollen im Folgenden nur diesen einen Strahl weiter betrachten.
- Das Shader-Programm des getroffenen Objekts, hier das der grüne Kugel, wird aufgerufen.
- Darin wird zuerst die festgelegte Farbe, hier grün, als Basis für weitere Berechnungen genommen.
- Da zuvor festgelegt wurde, dass das Material reflektierend sein soll, schießt nun das Shader-Programm einen Reflexionsstrahl vom SchnittpunktPrimärstrahl aus in die reflektierte Richtung.
- Der Reflexionsstrahl trifft ein Objekt (hier das rote Dreieck) an der Stelle SchnittpunktReflexionsstrahl.
- Das Shader-Programm des roten Dreiecks wird aufgerufen.
- Um für dieses Shader-Programme festzustellen, ob der betrachtete Punkt beleuchtet ist – also ob Licht bis zu diesem Punkt vordringt –, wird vom SchnittpunktReflexionsstrahl in die Richtung der Lichtquelle ein so genannter Schattenstrahl geschossen.
- Es wird mit dem Schattenstrahl festgestellt, dass sich ein Objekt (im Beispiel die grüne Kugel) zwischen SchnittpunktReflexionsstrahl und der Lichtquelle befindet.
- Im Shader-Programm des roten Dreiecks wird daher keine Beleuchtung dazu addiert, wodurch der Punkt einen schattigen Bereich repräsentiert.
- Das Shader-Programm des roten Dreiecks gibt also lediglich das im Material als Farbe definierte Rot an das Shader-Programm der grünen Kugel zurück.
- Nun befindet man sich wieder im Shader-Programm der grünen Kugel. Die erhaltene Farbe, hier Rot, wird auf den bisherigen Farbwert, Grün, addiert. Abschließend soll noch festgestellt werden, ob der Punkt auf der Kugel beleuchtet wird. Dazu wird ein Schattenstrahl vom SchnittpunktPrimärstrahl in die Richtung der Lichtquelle geschossen.
- Durch den Schattenstrahl wird festgestellt, dass sich kein Objekt zwischen SchnittpunktPrimärstrahl und der Lichtquelle befindet.
- Ein aus den Attributen der Lichtquelle (Intensität, Distanz) errechneter Wert wird zur bisherigen Farbe des Pixels auf der grünen Kugel addiert.
- Der fertig berechnete Farbwert wird an die Kamera gegeben und stellt nun einen Pixel des gerenderten (sichtbaren) Bildes dar: Ein von der Lichtquelle erleuchtetes Pixel der grünen Kugel, auf dem sich ein rotes, nicht erleuchtetes Pixel des Dreiecks spiegelt.
Für ein effizientes Raytracing benutzt man eine Beschleunigungsstruktur, in die die gesamte Geometrie der 3D-Szene gespeichert wird. Dies kann beispielsweise ein BSP-Baum sein. Durch die Verwendung dieser Technik verursacht der ohnehin im fertigen Bild nicht sichtbare blaue Würfel keinen zusätzlichen Berechnungsaufwand.