Photon Mapping unter Verwendung eines SIMD Ray Tracers Studienarbeit Vorgelegt von Andreas Langs Institut für Computervisualistik Arbeitsgruppe Computergraphik Betreuer: Prüfer: Dipl.-Inform. Markus Geimer Prof. Dr.-Ing. Stefan Müller Juni 2005 I NHALTSVERZEICHNIS 1 Inhaltsverzeichnis Einleitung 1 Grundlagen 1.1 Photon Mapping . . . . . . . . . 1.1.1 Datenstrukturen . . . . . 1.1.2 Final Gathering . . . . . . 1.2 Beschleunigungsverfahren . . . . 1.2.1 Russisches Roulette . . . . 1.2.2 Precomputed Illuminance 1.2.3 SIMD . . . . . . . . . . . . 1.3 Photometrische Konsistenz . . . 1.4 Dream . . . . . . . . . . . . . . . 2 . . . . . . . . . 3 3 4 6 7 7 7 8 9 12 . . . . . . . . 12 12 13 14 16 16 16 17 20 . . . . . 22 22 22 22 24 27 4 Fazit 4.1 Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 27 Anhang 29 Abbildungsverzeichnis 31 Literatur 32 . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Erweiterte Systemarchitektur 2.1 Physikalisch korrekte Beleuchtung . . 2.2 Vorverarbeitung (First Pass) . . . . . . 2.2.1 Verschießen der Photonen . . . 2.2.2 Balancierung der Photon Map 2.2.3 Precomputed Illuminance . . . 2.3 Darstellung (Second Pass) . . . . . . . 2.3.1 Auswerten der Photon Map . . 2.3.2 Final Gathering . . . . . . . . . 3 Ergebnisse 3.1 Evaluation der Beleuchtungsqualität 3.2 Evaluation der Performance . . . . . 3.2.1 Messreihe 1 . . . . . . . . . . 3.2.2 Messreihe 2 . . . . . . . . . . 3.2.3 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I NHALTSVERZEICHNIS 2 Einleitung Die weiterhin unvermindert steigende Leistungsfähigkeit heutiger Computer ermöglicht es seit kurzer Zeit, im Bereich der Computergrafik realistische, direkte Beleuchtung von 3D Szenen in interaktiven Frameraten1 auf der CPU mit dem Ray Tracing Verfahren zu berechnen. Dies wird durch ausgefeilte Beschleunigungsstrukturen, Ausnutzung von aktuellen Features und hohen Taktraten der CPU und verschiedenen Parallelisierungstechniken erreicht. Gerade die Parallelisierungstechniken halfen, einige Geschwindigkeitssprünge zu erreichen. Da wäre zum einen der Einsatz von Clustern von Rechnern zu nennen: Dabei kommt heutzutage keine für diese Aufgabe speziell optimierte Rechnerhardware zum Einsatz, sondern kostengünstige Computer, die mit handelsüblicher Netzwerktechnik (z.B. GigabitEthernet) verbunden werden. Eine weitere Parallelisierungstechnik sind die in eigentlich allen aktuellen CPUs anzutreffenden Erweiterungen für SIMD Operationen. Dabei können u.a. mathematische und logische Operationen auf Vektoren von Werten angewendet werden, also z.B. die Addition von 4 float-Werten in einer Operation. Als Grundlage der darzustellenden Szenen dienen dazu noch hauptsächlich Szenenbeschreibungen aus Dreiecken, wobei ähnliche Geschwindigkeiten auch mit Freiformflächen erreicht werden können, wie in [Abe05] gezeigt wird. Weiterhin findet in der Regel hauptsächlich nur eine Simulation der direkten Beleuchtung statt; globale Beleuchtungseffekte wie Kaustiken und diffuse Beleuchtung werden aus Geschwindigkeitsgründen nicht berücksichtigt. Seit einigen Jahren existieren jedoch auch für die globale Beleuchtung Ansätze, die ohne den hohen Berechnungsaufwand der ursprünglichen Monte Carlo Ray Tracing Verfahren wie (Bidirectional)Path Tracing oder Metropolis Light Transport auskommen. Zu diesen Ansätzen gehört das sog. Photon Mapping, das 2001 von Henrik Wann Jensen [Jen01] vorgestellt wurde. Dieses Verfahren, das die Lichtsimulation in die beiden Schritte Vorverarbeitung und Darstellung aufteilt, soll in dieser Arbeit vorgestellt werden. Die erreichbaren hohen Darstellungsgeschwindigkeiten werden anhand einer Erweiterung des optimierten Ray Tracers DREAM um Photon Mapping gezeigt. Dabei werden die verschiedenen Optimierungsstufen dargelegt und bewertet. 1 Wenn von interaktiven Frameraten im Kontext dieser Studienarbeit die Rede ist, bezieht sich dies auf eine Auflösung von 512x512 Pixeln und Frameraten von mehr als einem Frame pro Sekunde (von Echtzeit spricht man ab 25 Frames pro Sekunde). 3 1 Grundlagen In diesem Kapitel werden die Grundlagen der bei dieser Arbeit verwendeten Techniken vorgestellt. Dazu gehört ganz allgemein das Verfahren des Photon Mapping, welches die Simulation des globalen Beleuchtungsmodells beschreibt, sowie Erweiterungen wie Final Gathering. Weiterhin wird eine Einführung zu den verwendeten Datenstrukturen gegeben und ein Beschleunigungsverfahren für das Photon Mapping vorgestellt. Danach wird die Parallelisierungstechnik SIMD erläutert und deren plattformübergreifende Implementierung in DREAM. Diese Technik ist einer der Gründe für die hohen Geschwindigkeit von DREAM als auch des Photon Mapping. 1.1 Photon Mapping Im Gegensatz zu klassischen Monte Carlo Ray Tracing Verfahren oder Finite Elemente Radiosity Techniken verwendet das 2001 von Henrik Wann Jensen [Jen01] vorgestellte Verfahren des Photon Mapping einen anderen Ansatz. Dabei wird die Lichtinformation von der Geometrie getrennt. Finite Elemente Methoden wie Radiosity haben Probleme mit komplexen Geometrien und leiden unter Mesh-Artefakten, die beim Unterteilen großer Flächen auftreten. Monte Carlo Ray Tracing Verfahren leiden unter hochfrequentem Rauschen, welches nur durch lange Berechnungszeiten beseitigt werden kann. Photon Mapping hingegen leidet eher unter tieffrequentem Rauschen, was jedoch bei der Wahrnehmung als wesentlich weniger störend empfunden wird. Außerdem kann zur Vermeidung von diesem Rauschen Final Gathering (siehe Abschnitt 1.1.2) verwendet werden. Beim Photon Mapping werden Photonen von den Lichtquellen aus in die Szene geschossen und nach Interaktion mit dieser in einer geometrieunabhängigen Datenstruktur, der Photon Map, gespeichert. Die Trennung der Lichtinformation von der Geometrie bietet entscheidende Performance Vorteile bei komplexen Szenen, da keine Tesselierung der Geometrie notwendig ist, und vereinfacht die Lichtrepräsentation enorm. Im Vergleich zu Bidirektionalem Path Tracing, einem Monte Carlo Ray Tracing Verfahren, kann die Photon Map als Cache von Licht-Pfaden gesehen werden. Dieser erste Schritt braucht bei statischen Szenen, wie sie in DREAM vorkommen, nur einmalig ausgeführt werden und fällt somit unter die Vorverarbeitung der Szene. Nachdem die Photon Map aufgebaut wurde, wird während des Renderns der Szene neben der direkten Beleuchtung des gefunden Schnittpunktes mit einer diffusen Oberfläche nun auch noch die Informationen in der Photon Map zu diesem Schnittpunkt ausgewertet. Dazu werden eine 1.1 P HOTON M APPING 4 Abbildung 1: Zweidimensionaler kd-tree definierbare Anzahl an Photonen aus einer definierbaren Umgebung eingesammelt und deren “Licht” flächengewichtet. Photon Mapping besteht im Wesentlichen aus diesen beiden Schritten, auch Passes genannt. Wie diese beiden Schritte genau funktionieren wird im Abschnitt 2.2 bzw. 2.3 beschrieben, ebenso wie deren implementierungsspezifischen Eigenschaften. 1.1.1 Datenstrukturen Das Photon Mapping Verfahren benötigt zwei wesentliche Datenstrukturen. Zum einen gibt es eine Datenstruktur für ein Photon, in dem die nötigen Informationen pro Photon abgespeichert werden. Zum anderen müssen alle Photonen in der Photon Map abgelegt werden. Diese wird als kd-tree realisiert. Ein kd-tree bietet sich deshalb gut an, weil die Photonen in einem dreidimensionalen Raum als Punkte nichtuniform verteilt sind und auf einem kd-tree die Suche nach den k-nächsten Nachbarn in der Aufwandsklasse O(k + log n) liegt. Diese Suche muss pro Schnittpunkt durchgeführt werden, und muss deshalb sowohl eine günstige Aufwandsklasse haben als auch bei der Implementierung besonders optimiert werden. Alternativen zum kd-tree wären ein 3D Grid oder ein Voronoi-Diagramm. Das Grid scheidet allerdings wegen der nichtuniformen Verteilung der Photonen im Raum aus. Das Voronoi-Diagramm im dreidimensionalen Raum benötigt einen Speicher der Größe O(n2 ) bei n Photonen. Dies ist bei möglicherweise Millionen von Photonen zu viel Speicher. kd-tree Ein kd-tree ist eine Möglichkeit, eine Punktmenge geordnet in einem Baum abzulegen. In Abbildung 1 ist dies für den zweidimensionalen 1.1 P HOTON M APPING typedef struct Photon { union { float pos[3]; float4 position; }; Vector3 normal; short plane; float4 luminousFlux; float4 precomputedIlluminance; } Photon; 5 // photon position // // // // surface normal at photon position splitting plane for kd-tree luminous flux per Photon precomputed illuminance Abbildung 2: Datenstruktur eines Photons Fall gezeigt. Der kd-tree ist in der Implementierung nichts anderes als ein entsprechend sortiertes Array von Photonen. Dafür muss der kd-tree allerdings links-balanciert sein. Dies wird in der Vorverarbeitung sichergestellt. Henrik Wann Jensen wählte einen links-balancierten kd-tree, weil er der Meinung war, so die durchschnittliche Suchdauer der k-nächsten Nachbarn zu verkürzen. Wie jedoch Wald et. al. in [Wal04] zeigten, kann durch eine Balancierung mit einem entsprechenden Kriterium die Suchdauer im Durchschnitt mehr reduziert werden, als dies mit der Linksbalancierung der Fall ist. Keinesfalls ist ein so balancierter Baum jedoch langsamer als ein links-balancierter Baum. Die Photon Repräsentation Die Datenstruktur für ein Photon (Abbildung 2) entspricht grob der von Jensen, wurde jedoch für die SIMDTraversierung des kd-Tree und für eine zum restlichen System einheitliche Behandlung der photometrischen Größen abgeändert. Die Position eines Photons kann sowohl per float-Array Zugriff ausgelesen werden, als auch als float4-SIMD Datentyp. Für die Normale wurde der Vector3 Datentyp von DREAM verwendet, da dieser Operatoren für Vektoren bereitstellt. Der Wert plane ist für den kd-tree notwendig, er gibt die Achse der Splitting-Plane an. In luminousFlux wird der Lichtstrom des Photons gespeichert, in precomputedIlluminance die vorab berechnete Beleuchtungsstärke wenn diese Optimierung aktiv ist. Jensen legte bei seinem Design eines Photons Wert auf eine möglichst kompakte Repräsentation. Wie sich jedoch in Messungen zeigte, ergibt die hier verwendete größere Datenstruktur nur eine sehr geringfügige Geschwindigkeitseinbuße. 1.1 P HOTON M APPING 6 Abbildung 3: Vergleich: Mit/Ohne Final-Gathering Auf dem linken Bild ist die Cornell-Box mit 645 Photonen in der Photon-Map zu sehen, wenn die Photon-Map direkt ausgewertet wird. Im rechten Bild wurde bei gleichen Randbedingungen Final-Gathering verwendet. Das “Rauschen” ist deutlich geringer. 1.1.2 Final Gathering Bei dem bis jetzt besprochenen Verfahren des Photon Mapping wird die Photon Map ausgelesen, sobald ein Strahl des Ray Tracers eine diffuse Oberfläche trifft. Da Photon Mapping auch zum Teil in die Kategorie der Monte Carlo Verfahren fällt (die Photonen werden per Zufall im Raum verteilt), ist es wie alle diese Verfahren anfällig für Rauschen im Ergebnisbild. Dieses Rauschen nimmt ab, wenn mehr Photonen in die Szene verschossen werden. Eine weitere Möglichkeit zur Minimierung des Rauschens besteht darin, nicht an der Stelle, an der der Ray Tracing Strahl die diffuse Oberfläche trifft, die Photon Map auszulesen, sondern von diesem Punkt aus mehrere Strahlen in zufällige Richtungen (evtl. BRDF gesampled) zu senden und bei deren erstem Schnittpunkt die Photon Map auszulesen. Diese Strahlen (Final Gather Rays) des Final Gathering werden nicht reflektiert oder transmittiert. Die aufsummierte Beleuchtungsstärke der dort eingesammelten Photonen muss dann noch mit der Anzahl der Final Gather Rays gewichtet und mit der Oberflächenfarbe des Ausgangspunkts multipliziert werden. Diese Optimierung der Darstellungsqualität ist sehr rechenaufwändig und damit zeitintensiv, jedoch verbessert sich die Qualität der Bilder enorm, wie in Abbildung 3 zu sehen ist. Außerdem wird in den Ergebnissen gezeigt, dass trotz Final Gathering interaktive Frameraten möglich sind. 1.2 B ESCHLEUNIGUNGSVERFAHREN 7 1.2 Beschleunigungsverfahren Das Verfahren des Photon Mapping ist von sich aus, im Vergleich zu anderen Verfahren zur Simulation der globalen Beleuchtung, recht schnell. Um zum Schluss ein System zu erhalten, das interaktive Frameraten bietet, sind jedoch weitere Beschleunigungsverfahren nötig. Dazu gehören sowohl Verfahren, die den Photon Mapping Algorithmus an sich optimieren, als auch Techniken für eine performante Implementierung. Diese sollen nun im Folgenden vorgestellt werden. Außerdem wird es einen Überblick über das SIMD Framework von DREAM geben. 1.2.1 Russisches Roulette Die Verwendung von Russischem Roulette beim Photon Mapping hat zwei Hauptgründe. Erstens beschleunigt es das Verschießen der Photonen, da es wichtige von unwichtigen Photonen trennt und deren Anzahl und TracingVorgänge somit reduziert. Zweitens sorgt es dafür, dass die Energie jedes Photons in der Szene gleich ist, was für das Bestimmen der Leuchtdichte wichtig ist. Das Russische Roulette wird während der Vorverarbeitung beim Aussenden der Photonen verwendet, um zu entscheiden, ob ein Photon diffus oder spekular reflektiert, transmittiert oder absorbiert wird. Das Ergebnis wird durch Wahrscheinlichkeitsangaben beim Material für jede der vier Optionen beeinflusst. Es wird also, wenn ein Photon eine Oberfläche trifft, per Russischem Roulette (dem die Materialeigenschaften übergeben wurden) entschieden, wie es mit dem Photon weiter geht. Die Vereinfachung kann man an folgendem Beispiel erkennen: Wir haben ein Material mit der Wahrscheinlichkeit 0.5, das ein Photon absorbiert wird, und eine Wahrscheinlichkeit von ebenfalls 0.5, das es reflektiert wird. Auf eine Oberfläche mit diesem Material schießen wir 1000 Photonen. Wir können nun 1000 Photonen reflektiert weiterschicken, wobei bei jedem ausgehenden Photon dessen Energie halbiert wird, oder wir können Russisches Roulette verwenden. Dann werden nur 500 Photonen mit der vollen Energie weiterverfolgt und wir haben bei dieser ersten Reflexion schon die Hälfte der Tracing-Vorgänge gespart. Es kann gezeigt werden, dass beide Arten die statistisch gleiche Energieverteilung liefern. Jedoch ist offensichtlich, dass bei Verwendung von Russischem Roulette weniger Berechnungsaufwand nötig ist. 1.2.2 Precomputed Illuminance Der zeitaufwändigste Vorgang beim Auslesen der Photon Map ist die Suche der k-nächsten Photonen zu einem gegebenen Schnittpunkt für die Bestimmung der Beleuchtungsstärke. Um die nötige und teure Traversierung 1.2 B ESCHLEUNIGUNGSVERFAHREN 8 des kd-trees zu minimieren, entwickelte Christensen 2000 ein Verfahren namens Precomputed Irradiance [Chr00]2 . Dabei wird während der Vorverarbeitungsphase, nachdem alle Photonen verschossen worden sind, für jedes Photon (nach Christensen reicht auch nur jedes vierte Photon) die Beleuchtungsstärke bestimmt, indem ein Illuminance Estimate wie im Darstellungsvorgang durchgeführt wird. Zur Darstellungszeit müssen nun nicht mehr eine große Zahl von k Photonen eingesammelt, deren Lichtstrom aufsummiert und in Beleuchtungsstärke umgerechnet werden. Vielmehr muß nur noch das nächste Photon gefunden und dessen Precomputed Illuminance Wert verwendet werden. 1.2.3 SIMD SIMD (Single Instruction Multiple Data) ist ein Feature für parallele Operationen auf Vektordatentypen, das in vielen aktuellen Prozessoren zu finden ist. Im Bereich der Intel-kompatiblen CPUs sind diese Erweiterungen als MMX, 3DNow, SSE, SSE2, SSE3 bekannt, bei den PowerPC-kompatiblen CPUs wie dem G4 von Motorola oder G5 von IBM nennen sie sich AltiVec und Apple nennt sie VelocityEngine. Heutzutage werden üblicherweise 128 Bit breite Register verwendet, in denen z.B. vier 32 Bit große float Werte, aber mittlerweile auch zwei 64 Bit große double Werte und weitere Kombinationen abgelegt werden können. Für diese Vektordatentypen werden spezielle Befehle wie z.B. die Addition oder das bitweise AND zur Verfügung gestellt. Diese Befehle verarbeiten diese 128 Bit breiten Register und somit die 2-16 Werte, die in diesen gespeichert sind, parallel. Dadurch kann bei z.B. vier float Werten eine theoretische Geschwindigkeitssteigerung bis zum Vierfachen erreicht werden, da nicht mehr vier Additionen hintereinander berechnet werden müssen, sondern nur noch eine. Leider stellen die verschiedenen Prozessoren und Versionen der Erweiterungen unterschiedliche Befehle zur Verfügung, was eine plattformübergreifende Entwicklung sehr erschwert. Für dieses Problem stellt DREAM jedoch eine Abstraktionsschicht bereit. Diese stellt Funktionen zur Verfügung, die die plattformspezifischen Unterschiede verbirgt. Ein weiteres Problem, das vor dem Anwender verborgen wird, ist, dass nicht alle Befehle auf allen Prozessoren zur Verfügung stehen. In der Abstraktionsschicht werden als Datentypen der Typ float4 und bool4 und entsprechende Funktionen zur Verfügung gestellt. 2 Christensen spricht von Bestrahlstärke, genau wie Jensen. In dem hier implementierten System werden annähernd photometrische Größen und nicht strahlungsphysikalische Größen verwendet. Deshalb wird Beleuchtungsstärke und nicht Bestrahlstärke (Illuminance statt Irradiance) verwendet. Siehe dazu Abschnitt 2.1. 1.3 P HOTOMETRISCHE K ONSISTENZ 9 1.3 Photometrische Konsistenz Die ursprüngliche Version von DREAM ist durch und durch auf Geschwindigkeit optimiert, so daß die Beleuchtung weniger einen realistischen, sondern eher einen Computergrafik-Look hat. Da die globale Beleuchtung, die ja nun durch das Photon Mapping ergänzt werden soll, bei der Wahrnehmung eine entscheidende Rolle für ein Gefühl der Richtigkeit der Beleuchtung hat, musste auch die direkte Beleuchtung geringfügig angepasst werden. Wir wollen mit einem Ray Tracer in der Regel die natürliche Interaktion von Licht in einer Szene simulieren. Deshalb liegt es nahe, bei der Simulation radiometrische bzw. photometrische Größen zu verwenden. Die photometrischen Größen unterscheiden sich von den radiometrischen Größen dadurch, dass sie die physiologischen Aspekte des menschlichen Sehens berücksichtigen. Das Helligkeitsempfinden über den sichtbaren Spektralbereich ist auf Grund des Aufbaus des Auges nicht linear. 1924 wurde diese Helligkeitsempfindung des “internationalen Standard-Beobachters” in der V(λ)-Kurve festgelegt (DIN 5031). Durch die Gewichtung der strahlungsphysikalischen Größen mit der V(λ)-Kurve ergeben sich die photometrischen Größen: X = Km Z 780nm 380nm X(λ)V (λ)dλ In der erweiterten Version von DREAM wird für die Definition der Lichtquelle die radiometrische Größe des Strahlungsflusses und ein RGBWert für die Farbe angegeben. Diese Werte werden intern in einen photometrisch konsistenten RGB-Wert umgewandelt, der der Lichtstärke entspricht. 1.3 P HOTOMETRISCHE K ONSISTENZ Photometrie Einheiten 10 Strahlungsphysik Einheiten Radiometry Q Lichtmenge lm · s Strahlungsmenge Luminous energy Φ J =W ·s Radiante energy Lichstrom lm Strahlungsfluß/ Leistung Radiant flux/ Luminous flux W power I Lichtstärke Luminous cd = lm · sr −1 Strahlstärke W · sr−1 Radiant intensity intensity L cd · m−2 Leuchtdichte Luminance Strahldichte W · m−2 · sr−1 Radiance (const) B Spezifische Lichtausstrahlung (ausgehend) Radiosity/ Spezifische Lichtausstrahlung (ausgehend) W · m−2 Radiosity Luminosity E Beleuchtungsstärke (einfallend) lx = lm · m−2 Illuminance Bestrahlungsstärke (einfallend) W · m−2 Irradiance Tabelle 1: Photometrische Größen (Aus: Vorlesungsunterlagen von Prof. Müller zur Vorlesung “Photorealistische Computergraphik” WS 03/04: 02_Grundlagen_1_2.pdf Seite 68.) Im Folgenden sollen die wichtigsten photometrischen Größen kurz vorgestellt werden. Lichtstrom Der Lichtstrom ist die gesamte Energie, die durch einen bestimmten Bereich des Raumes fließt, und wird in lm (Lumen) angegeben. Den Lichstrom kann man sich an Abbildung 4 veranschaulichen. In der Mitte sitzt eine Punktlichtquelle, und um diese befinden sich in diesem Beispiel zwei gedachte Kugeln. Der Lichstrom ist die Energie, die die innere oder äußere Kugel durchströmt. Der Lichtstrom ist an beiden gemessenen Kugeln gleich, wobei der Lichtstrom in einer Teilfläche der äußeren Kugel natürlich kleiner ist als in einer gleichgroßen Teilfläche der inneren Kugel, da die Gesamtoberfläche der äußeren Kugel größer ist. Beleuchtungsstärke Die Beleuchtungsstärke ist die Flächendichte des Lichtstroms. Für das Beispiel mit der Punktlichtquelle aus Abbildung 4 be- 1.3 P HOTOMETRISCHE K ONSISTENZ 11 Abbildung 4: Lichtstrom und Beleuchtungsstärke deutet dies, das auf einem infinitesimal kleinen Flächenelement der inneren Kugel die Beleuchtungsstärke kleiner ist als auf einem infinitesimale kleinen Punkt auf der äußeren Kugel. Im Beispiel ist die Beleuchtungsstärke genau: Φ mit r=Radius 4πr2 Dadurch verringert sich die Beleuchtungsstärke quadratisch mit dem Abstand zur Lichtquelle. Dieser Effekt ist in Abbildung 5 zu sehen. E= Lichtstärke Lichtstärke ist die Lichtstromdichte pro Raumwinkel. Der Raumwinkel ist die räumliche Erweiterung des zweidimensionalen Winkels im Bogenmaß. Er ist definiert durch das Verhältnis der bedeckten Kugeloberfläche (Kugelkalotte) zum Quadrat des Kugelradius. Die Einheit ist Steradiant3 . Leuchtdichte Die Leuchtdichte beschreibt den Helligkeitseindruck, den der Mensch wahrnimmt. Sie ist definiert als Lichtstromdichte pro Raumwinkel pro Fläche. Die Tatsache, das sich die Leuchtdichte entlang eines 3 Aus: Vorlesungsunterlagen von Prof. Müller zur Vorlesung “Photorealistische Computergraphik” WS 03/04: 02_Grundlagen_1_2.pdf Seite 27. 1.4 D REAM 12 Strahls in einem leeren Raum nicht ändert, prädestiniert sie für die Verwendung beim Ray Tracing. Die Leuchtdichte wird überall dort berechnet, wo ein Primärstrahl eine Oberfläche trifft. 1.4 Dream Als Grundlage dieser Studienarbeit dient der optimierte Ray Tracer DREAM [Gei03]. Dieser wird im Rahmen der Dissertation von Markus Geimer entwickelt. Er ist in der Lage, Szenen mit mehreren hunderttausenden Dreiecken auf einem handelsüblichen Computer in interaktiven Frameraten darzustellen. Seine hohe Geschwindigkeit bezieht er aus einer sorgfältigen Implementierung, die insbesondere die SIMD Fähigkeiten moderner CPUs verwendet. So ist die komplette Architektur darauf ausgelegt, 4 Strahlen parallel zu verarbeiten. Außerdem ist DREAM konsequent für Multi-Threading ausgelegt, so dass mehrere CPUs normalerweise die zu erwartenden Geschwindigkeitssteigerungen mit sich bringen. DREAM benötigt als Szenenbeschreibung eine DSD-Datei (DREAM Scene Description). DSD Dateien können mit Hilfe eines Konverters aus Dateien in einem erweiterten nff-Format [Hai87] erzeugt werden. Bei diesem Konvertierungsvorgang wird ebenfalls die optimierte Bounding Volume Hierarchie erzeugt, die als Beschleunigungsstruktur verwendet wird. Von DREAM existieren mittlerweile vier Varianten, wobei die Dreiecksvariante als Basis für die drei Anderen fungierte. Die in einer Studienarbeit von Oliver Abert entwickelte Variante dreamBSE [Abe05] kann Freiformflächen aus IGES Dateien auf einem Rechner rendern. Robert Bärz entwickelte ebenfalls in einer Studienarbeit [Bär04] für die Dreiecksvariante eine Netzwerkkomponente, so dass ein Cluster aus Rechnern gemeinsam an einem Frame rechnen kann. Und schließlich entstand mit dieser Studienarbeit eine Variante mit Photon Mapping zur Simulation der globalen Beleuchtung. 2 Erweiterte Systemarchitektur Im Folgenden werden nun die Änderungen und Erweiterungen an DREAM näher erläutert und Implementierungsdetails vorgestellt. Bei der Erweiterung von DREAM wurde darauf geachtet, dass so wenig wie möglich an existierenden Schnittstellen geändert werden muss, um ggf. Photon Mapping auch in die anderen beiden Varianten integrieren zu können. 2.1 Physikalisch korrekte Beleuchtung Für eine physikalisch korrekte Beleuchtung mussten einige kleine Änderungen an DREAM vorgenommen werden. So wurde z.B. die mit der Entfernung quadratisch abnehmende Beleuchtungsstärke ergänzt. Dadurch 2.2 V ORVERARBEITUNG (F IRST PASS ) 13 Abbildung 5: Quadratisch abnehmende Beleuchtungsstärke Das Bild auf der linken Seite zeigt die Cornellbox-Szene ohne quadratische Abnahme der Beleuchtungsstärke, auf der rechten Abbildung sind die Hotspots zu erkennen, die durch die physikalisch korrekte Abnahme der Beleuchtungsstärke entstehen. Auf beiden Bilder ist jeweils nur direkte Beleuchtung zu sehen, Schatten, Reflexionen, Refraktionen und Photon Mapping sind deaktiviert. ergeben sich die “Hotspots” an den Wänden mit den abgedunkelten Ecken, die man in Abbildung 5 erkennen kann. Um das Photon Mapping konsistent integrieren zu können, wurden weiterhin die lichttechnischen Größen auf photometrische bzw. strahlungsphysikalische Einheiten umgestellt. So besitzt nun jede Lichtquelle neben einer Farbe auch noch eine Leistungsangabe (Strahlstärke) in Watt. Alle Berechnungen werden jedoch nicht auf verschiedenen Wellenlängen durchgeführt, wie es für eine korrekte strahlungsphysikalische Simulation notwendig wäre. Es wird vielmehr mit RGB-float-Werten gerechnet die den photometrischen Größen entsprechen. Außerdem wurde aus den Materialeigenschaften die ambiente Farbe entfernt, da diese keine physikalische Grundlage besitzt. Sie wurde zuvor für eine sehr grobe Annäherung von Umgebungslicht verwendet. 2.2 Vorverarbeitung (First Pass) Bevor die Photon Map zur Darstellung verwendet werden kann, muss sie erstellt werden. Dieser Vorgang (First Pass) muss bei statischen Szenen nur einmal ausgeführt werden und wird zwischen dem Laden der Szene und der Hauptschleife durchgeführt. Der First Pass besteht aus mehreren Schritten: 2.2 V ORVERARBEITUNG (F IRST PASS ) 14 2.2.1 Verschießen der Photonen Zuerst wird die Gesamtstrahlstärke aller Lichtquellen ermittelt und damit dann die Strahlstärke eines Photons: radiantF luxP erP hoton = GesamtzahlDerP hotonen Gesamtstrahlstaerke Danach wird festgelegt, wie viele Photonen pro Lichtquelle verschossen werden: AnzahlP hotonen = StrahlstaerkeDerLichtquelle∗radiantF luxP erP hoton Dadurch erhalten alle Photonen die gleiche Strahlstärke, was für das Bestimmen der Beleuchtungsstärke wichtig ist; und entsprechend werden von schwächeren Lichtquellen weniger Photonen abgegeben. Von jeder Lichtquelle in der Szene aus werden dann die Photonen verschossen. Dieser Vorgang wird Photon Tracing genannt. Anhand des zurückgelegten Weges werden die Photonen entweder in die Global Photon Map oder in die Caustic Photon Map abgelegt. Dabei werden Photonen, die nur spekular reflektiert wurden, in der Caustic Map, alle anderen in der Global Photon Map abgelegt. Implementierung Für das Aussenden der Photonen von den Lichtquellen wurde die Basisklasse aller Lichquellen, die Klasse LightSource, um die virtuelle Funktion emitPhotons erweitert, die dann spezifisch für die verschiedenen Lichtquellen implementiert wurde. Dabei werden z.B. bei einer Punktlichtquelle die Photonen uniform über eine Kugel um die Punktlichtquelle herum verteilt, bei einer Flächenlichtquelle uniform über die Fläche und cosinusgewichtet über den Halbraum in Richtung der Normalen ausgesendet. Nachdem für jedes Photon eine Ausgangsposition und eine Richtung bestimmt wurde, wird die rekursiv ausgelegte Funktion tracePhotons aufgerufen. Diese Funktion hat folgende Parameter: photons Ein Packet von Rays (von dem nur ein Ray verwendet wird), das den Ausgangspunkt und die Richtung des Photons enthällt. luminousFlux Der Lichtstrom eines Photons, der durch die Gesamtleistung aller Lichtquellen in der Szene bestimmt wurde. rng Ein Zufallszahlengenerator, der für das Russische Roulette benötigt wird. recursioncounter Zählt die Anzahl der Reflexionen/Transmissionen eines Photons, um die Rekursion bei einer bestimmten Maximaltiefe abbrechen zu können. 2.2 V ORVERARBEITUNG (F IRST PASS ) 15 caustic Anhand der Reflexion eines Photons wird festgestellt, ob das Photon in der Global Photon Map oder in der Caustic Map abgelegt werden muss. Ist die letzte Reflexion eine spekulare oder transmittierende, gilt caustic = true, und das Photon wird in der Caustic Map abgelegt. Die Funktion tracePhotons ist prinzipiell genau so aufgebaut, wie die schon vorhandene Funktion shade. Trifft ein Photon auf eine Oberfläche, wird der Schnittpunkt und die Normale der getroffenen Oberfläche berechnet und per Russischem Roulette entschieden, wie es weiter geht. Folgende Möglichkeiten können sich mit unterschiedlicher Wahrscheinlichkeit je nach getroffenem Material ergeben: Diffuse-Reflexion Es wird eine neue Richtung für das reflektierte Photon durch Cosinusverteilung in den vorderen Halbraum in Richtung der Oberflächennormalen bestimmt, und das Photon wird durch rekursiven Aufruf von tracePhotons mit den neuen Werten weiter geschickt. Der Lichtstrom des ausgehenden Photons wird nach Jensen entsprechend den Materialeigenschaften angepasst um Colorbleeding zu erreichen. Spekulare-Reflexion Der Winkel der neue Richtung entspricht dem Einfallswinkel des Photons zur Normalen in entgegengesetzter Richtung. Das Photon wird durch rekursiven Aufruf von tracePhotons mit den neuen Werten weiter geschickt. Ebenfalls wird wie bei der diffusen Reflexion der Lichtstrom angepasst. Transmission Je nach Brechungsindizes der Materialien, aus denen das Photon kommt und in die es eindringt, wird die neue Richtung nach Snell’s Law bestimmt. Dabei wird der Weg des Photons entweder gebrochen oder totalreflektiert. Mit der neuen Richtung wird wiederum die Funktion tracePhotons rekursiv aufgerufen; der Lichtstrom wird nicht geändert. Absorption Das Photon wird je nach Art der letzten Reflexion bzw. Transmission in der Global Photon Map oder Caustic Map gespeichert. Das Photon wird nicht weiter geschickt, die Rekursion endet. Ein Photon wird ebenfalls absorbiert, unabhängig vom Ergebnis des Russischen Roulette, wenn eine definierte maximale Rekursionstiefe erreicht wird. Dadurch wird verhindert, das eine Photon “unendlich” lange durch die Szene geschickt wird. 2.3 D ARSTELLUNG (S ECOND PASS ) 16 2.2.2 Balancierung der Photon Map Während des Photon Tracing Vorgangs werden alle Photonen flach in zwei Arrays (Photon Map und Caustic Map) abgelegt. Während der Balancierung werden nun diese beiden unsortierte Array zu links-balancierten Bäumen sortiert. Die Implementierung ist diejenige, die auch Jensen verwendet. 2.2.3 Precomputed Illuminance Wird Precomputed Illuminance verwendet, wird für jedes Photon in der Global Photon Map, nicht aber in der Caustic Map, ein Illuminance Estimate durchgeführt. Dabei wird für jedes Photon dessen Position genommen (statt des Schnittpunktes eines Strahls), und die Beleuchtungsstärke berechnet. 2.3 Darstellung (Second Pass) Für die Darstellung musste die vorhandene Shading-Funktion geringfügig angepasst werden. Die Shading-Funktion berechnet für jeden Strahl dessen Farbwert. Dabei gibt es verschiedene Möglichkeiten und Kombinationen dieser, wie der Farbwert zustande kommt. Es wird von Null ausgegangen und die verschiedenen Komponenten jeweils hinzugefügt. • Direkte Beleuchtung. Je nach Einstellung wird ein Schattenstrahl zu jeder Lichtquellen gesendet und festgestellt, ob der aktuelle Schnittpunkt beleuchtet wird. Wenn der Punkt beleuchtet wird, wird der Farbwert, den die Lichtquelle liefert, entsprechend dem Beleuchtungsmodell aufaddiert. • Reflexion. Wenn ein Strahl eine reflektierende Oberfläche trifft, wird vom Schnittpunkt aus ein reflektierter Strahl ausgesendet. Dessen Schnittpunkt wird bestimmt und die Shading-Funktion rekursiv aufgerufen. Dies passiert nur bis zu einer vorgegebenen Rekursionstiefe. • Transmission. Wenn ein Strahl eine transparente Oberfläche trifft, wird ein transmittierender Strahl mit Hilfe von Snell’s Law ausgesendet, dessen Schnittpunkt bestimmt, und die Shading-Funktion rekursiv aufgerufen. Dabei wird eine mögliche Totalreflexion entsprechend berücksichtigt. Dies passiert nur bis zu einer vorgegebenen Rekursionstiefe. Für die Erweiterung um Photon Mapping wurde nun eine zusätzliche Möglichkeit ergänzt. Hat der Strahl eine diffuse Oberfläche getroffen, wird die Global Photon Map ausgewertet. Dies kann auf zwei Arten erfolgen: 2.3 D ARSTELLUNG (S ECOND PASS ) 17 1. Die Globale Photon Map wird direkt ausgewertet. Dabei wird für den Schnittpunkt die Leuchtdichte der indirekten Beleuchtung bestimmt (es wird ein luminance estimate durchgeführt, siehe Abschnitt 2.3.1) und der resultierende Farbwert aufaddiert. 2. Es wird Final Gathering verwendet. Dann wird von dem Schnittpunkt aus eine definierbare Anzahl an Strahlen Cosinus-verteilt in die Szene geschossen und dort (ohne weitere Reflexionen oder Refraktionen) die Global Photon Map ausgewertet (wiederum per luminace estimate), mit der Anzahl der Strahlen gewichtet und der resultierende Farbwert aufaddiert. Danach wird in beiden Fällen die Caustic Map per luminance estimate ausgewertet und dieser resultierende Farbwert ebenfalls aufaddiert. Da die Caustic Map eine hohe Dichte an Photonen besitzt, tritt dort kaum Rauschen, wie bei der direkten Auswertung der Global Photon Map, auf. 2.3.1 Auswerten der Photon Map Der besondere Augenmerk der gesamten Implementierungsarbeiten lag ganz klar auf der Implementierung des Illuminance Estimate. Dieser wird schließlich für jeden Strahl aus der Kamera aufgerufen; wenn Final Gathering verwendet wird, sogar n-mal für jeden Strahl der Kamera. Luminance Estimate Die Funktion luminanceEstimate() wird von der shading() Funktion aufgerufen. Sie dient dazu, Datenstrukturen zu konvertieren und dann die illuminanceEstimate() Funktion aufzurufen, um dann aus der Beleuchtungsstärke die Leuchtdichte durch Gewichtung mit der BRDF zu gewinnen. Illuminance Estimate Der Illuminance Estimate hat die Aufgabe, für einen gegebenen Schnittpunkt die k-nächsten Photonen im maximalen Radius max_dist um den Schnittpunkt in der Photon Map einzusammeln, den Lichtstrom der Photonen aufzusummieren und mit der Fläche, in der diese Photonen lagen, zu gewichten. Das Aufsummieren und Gewichten mit der Fläche ist trivial, das Finden der k-nächsten Photonen ist jedoch ein Hauptaugenmerk dieser Studienarbeit. Im Laufe der Optimierungsarbeiten entstanden drei rekursive und eine iterative Funktion zur Suche der Photonen. Die rekursiven Funktionen sind, was den Algorithmus angeht, wesentlich übersichtlicher als die iterative Variante. Christensen beschreibt in [Chr02] jedoch, dass eine iterative Variante für das Finden der k-nächsten Photonen bis zu 25% schneller sein kann als die rekursive Variante. Dieses Ergebnis konnte bestätigt werden. 2.3 D ARSTELLUNG (S ECOND PASS ) 18 Ein Photon Rekursiv Die erste Variante die implementiert wurde, ist die von Jensen (Abbildung 11). Diese bekommt einen Schnittpunkt übergeben, traversiert den kd-tree der Photon Map und speichert die gefundenen Photonen in einem Array. Wenn im Suchradius mehr als k zu suchende Photonen liegen, wird das Array in einen Heap umgewandelt, so dass in diesem nur die k-nächsten Photonen enthalten sind. Ein Photon Iterativ Christensen gibt in [Chr02] einen iterativen Algorithmus (Abbildung 12) als Ersatz für den von Jensen formulierten rekursiven Algorithmus an und berichtet von bis zu 25% Geschwindigkeitssteigerung. Die Schwierigkeit bei der Formulierung eines iterativen Algorithmus liegt darin, dass der rekursive Algorithmus doppelt rekursiv ist. An jedem Knoten im kd-tree muss entschieden werden, ob der linke oder rechte Teilbaum besucht werden muss. Wenn einer von beiden besucht wurde, kann es jedoch sein, dass auch der andere Teilbaum noch besucht werden muss, je nach maximaler Entfernung der im bisherigen Teilbaum gefundene Photonen. Bei der Implementierung in DREAM konnte die von Christensen beschriebene Geschwindigkeitsverbesserung von bis zu 25% der iterativen Variante gegenüber der rekursiven Variante bestätigt werden. Es wurden jedoch auch Parameter gefunden, bei denen die iterative Variante langsamer ist. Vier Photonen Rekursiv ohne SIMD Dieser Algorithmus entstand als Vorstufe zum “Vier Photonen Rekursiv mit SIMD”-Algorithmus. Im Gegensatz zu diesem besitzt er keinen SIMD-Heap, sondern verwendet vier separate Heaps zum Sammeln der k-nächsten Photonen. Die Schwierigkeit bei der Entwicklung eines Traversierungsalgorithmus zum parallelen finden von k-nächsten Photonen liegt darin, das der ursprüngliche Algorithmus doppelt rekursiv ist. Beim Abstieg im kd-tree werden entsprechend der aktuellen Entfernungen zum Schnittpunkt entweder der linke oder der rechte Teilbaum weiter traversiert. Dies ist noch kein Problem. Beim Aufstieg jedoch wird anhand des bis jetzt am weitesten entfernten Photons entschieden, ob man an einer Stelle, an der man den linken Teilbaum untersucht hat, auch noch den rechten besuchen muß, oder umgekehrt. Dabei ist die Reihenfolge, ob man zuerst den linken oder rechten Teilbaum traversiert, wichtig. Wenn man bei der Suche nur von einem Schnittpunkt ausgeht, ist dies auch kein Problem. Wenn man nun für vier Schnittpunkte die k-nächsten Nachbarn sucht, hat man mehr Kombinationsmöglichkeiten den Baum zu traversieren. Dann kann es nämlich vorkommen, dass für einige Schnittpunkte zuerst im linken und dann im rechten Teilbaum gesucht werden muß, wohingegen es für andere Schnittpunkte genau der umgekehrte Fall ist. So kommt 2.3 D ARSTELLUNG (S ECOND PASS ) 19 es durchaus vor, dass erst der linke, dann der rechte, und schließlich nochmals der linke Teilbaum traversiert werden muß. Diese Tatsache macht auch unmittelbar klar, dass eine Traversierung des kd-tree mit SIMD Hilfsmitteln keinesfalls eine Vervierfachung der Geschwindigkeit mit sich bringen kann. Vier Photonen Rekursiv mit SIMD Eine noch weitergehende SIMD Integration stellt dieser Algorithmus dar. Dabei wird zusätzlich noch der Heap für SIMD optimiert. Es werden nicht vier separate Heaps verwendet in denen jeweils eine teilsortierte Liste mit Photonen abgelegt ist. Stattdessen gibt es einen Heap in dem vier Listen nebeneinander abgelegt sind. So befinden sich in einem SIMD Heap Element jeweils ein Element der vier Listen. Der jeweils erste, zweite, dritte und vierte Wert in einem SIMD Element ist Element der ersten, zweiten, dritten und vierten teilsortierten Liste. Illuminance Estimate bei Precomputed Illuminance Wird zur Darstellung Precomputed Illuminance verwendet (in der Regel nur bei gleichzeitiger Verwendung von Final Gathering), werden für jeden Schnittpunkt nicht die k-nächsten Photonen, sondern nur das nächste Photon bestimmt und dessen precomputedIlluminance verwendet. Christensen empfiehlt in seinem Paper, das Skalarprodukt zwischen der Oberflächennormale und der bei dem Photon gespeicherten Normale zu bilden, und bei Werten unterhalb eines Schwellwerts (z.B. 0,9) nach einem weiteren Photon zu suchen, dessen Normale ähnlicher ist. In meiner ersten Implementierung wurden für jeden Schnittpunkt eines Final Gathering Rays die 5 nächsten Photonen gesucht. Wurde kein Photon gefunden, wurde eine Beleuchtungsstärke von 0 zurückgegeben. Werden Photonen gefunden, werden sie der Reihe nach auf ihre Normale geprüft. Die Precomputed Illuminance vom ersten Photon, dessen Normale innerhalb des Schwellwerts liegt, wird zurückgegeben. War bei allen gefundenen Photonen die Normale ungünstig, wurde ein normales Illuminance Estimate durchgeführt. Bei meinen Tests mit der Cornell-Box war die Normale der ersten 5 Photonen in ca. 2,5% der Fälle ungünstig. Ich versuchte nun, in jedem Fall das erste Photon zu verwenden, unabhängig von dessen Normale. Es stellte sich heraus, das sich das Ergebnisbild nur sehr gering von dem der ersten Implementierung unterscheidet (siehe dazu Abbildung 6). Die Renderingdauer verkürzte sich jedoch auf weniger als die Hälfte (Auflösung: 512x512, 4 Final Gathering Rays pro Schnittpunkt, ca. 350000 Photonen in der globalen Photon Map, mit Precomputed Illuminance): 2.3 D ARSTELLUNG (S ECOND PASS ) 20 • Mit Berücksichtigung der Normalen: – direkte Visualisierung der Photonen: 1.86s – mit Final-Gathering: 18.9s • Ohne Berücksichtigung der Normalen: – direkte Visualisierung der Photonen: 1.26s – mit Final-Gathering: 7.2s Es muß jedoch beachtet werden, dass diese Optimierung sehr von der Szene abhängt. Bei der Cornell-Box funktioniert sie. Man stelle sich jedoch eine Fläche vor, auf deren einer Seite Photonen liegen auf der anderen jedoch nicht. Diese “dunkle” Seite ist diffus und wird von einem Strahl getroffen, der Photonen einsammelt unabhängig von der Normalen. Man sammelt nun Lichtstrom ein, der eigentlich nicht vorhanden ist, und macht einen Fehler. Man kann sich also Szenen ausdenken, die völlig falsch beleuchtet sind, wenn die Normale nicht berücksichtigt wird. 2.3.2 Final Gathering Wenn Final Gathering verwendet wird, was zur Laufzeit umgeschaltet werden kann, wird für jeden Schnittpunkt eines Primär-/Sekundärstrahls eine beliebige Anzahl an Final Gathering Rays erzeugt. Die finalGather Methode erhält ein VectorPacket mit Schnittpunkten und weitere notwendige Parameter. Für diese vier Schnittpunkte wird wiederum ein VectorPacket mit vier neuen Richtungen gesampled, die cosinusgewichtet in den vorderen Halbraum verteilt sind. Mit diesen neuen Richtungen werden neue Strahlen erzeugt, durch die Szene gesendet und beim Schnitt mit einer diffusen Oberfläche die Leuchtdichte bestimmt. Das Versenden der Final Gathering Rays wird beliebig oft durchgeführt, und dabei wird die ermittelte Leuchtdichte aufsummiert. Zum Schluss wird die Leuchtdichte noch durch die Anzahl der Strahlen geteilt, mit der Farbe der Oberfläche, die vom Primär-/Sekundärstrahl getroffen wurde, multipliziert, und zurückgegeben. 2.3 D ARSTELLUNG (S ECOND PASS ) 21 Abbildung 6: Behandlung der Normalen bei Precomputed-Illuminance Das obere Bild zeigt die indirekte Beleuchtung, wenn beim Einsammeln der Precomputed Illuminance die Oberflächennormale berücksichtigt wird und ggf. mehrere Photonen betrachtet werden. Beim mittleren Bild wurde die Normale vernachlässigt und immer das nächste Photon verwendet (Helligkeit um +50 erhöht). Das untere Bild ist die Differenz der beiden Bilder, dessen Kontrast um +85 erhöht wurde. Ein subjektiver Unterschied ist zwischen den beiden Bildern nicht festzustellen. 22 3 Ergebnisse 3.1 Evaluation der Beleuchtungsqualität Durch die Erweiterung von DREAM um das Photon Mapping Verfahren konnte, die Beleuchtungsqualität, und damit die Qualität der Bilder die Dream produziert, verbessert werden. Dies wurde durch mehrere Änderungen bzw. Erweiterungen erreicht, die in dieser Studienarbeit vorgestellt wurden: • Physikalisch korrektere direkte Beleuchtung • Ergänzung einer globalen Beleuchtungssimulation durch Photon Mapping • Erhöhung der Qualität des Photon Mapping durch Final Gathering In Abbildung 7 ist eine Gegenüberstellung der Ergebnisbilder mit und ohne die genannten Änderungen und Erweiterungen zu sehen. Man kann das typische, durch die indirekte Beleuchtung verursachte, Color-bleeding an der Decke erkennen. Außerdem sind die von der spiegelnden und transparenten Kugel geworfenen Schatten nicht mehr absolut dunkel sondern erhellt, und unterhalb der Glaskugel ist außerdem eine Caustic deutlich zu erkennen. 3.2 Evaluation der Performance Die Evaluation der Performance gestaltete sich außerordentlich schwierig. Je nach verwendetem Betriebssystem, Compiler oder Anzahl der Prozessoren wurden Messeergebnisse erreicht, die erwartet wurden, oder sie waren das extreme Gegenteil. Bei der ersten Messreihe sind zu den Zahlenwerten auch noch die Ergebnisbilder angegeben um sich einen Eindruck von dem Testfällen machen zu können. Die zweite Messreihe war auf maximale Performance ausgelegt, um die verschiednene Implementierungen zu vergleichen. Die beiden Testreihen können nicht miteinander vergleichen werden und es macht auch wenig Sinn wie man an den wiedersprüchlichen Zahlenwerten erkennen kann. 3.2.1 Messreihe 1 Im Folgenden sind die Messergebnisse der verschiedenen Implementierungen aufgelistet. Es wurde nur die Global Photon Map ausgewertet, dabei bedeutet 650.000 P, dass 650.000 Photonen in der Photon Map gespeichert waren. Das C steht für die Anzahl der eingesammelten Photonen für ein Luminance Estimate, das R steht für den Suchradius. 3.2 E VALUATION DER P ERFORMANCE 23 Abbildung 7: Vergleich Beleuchtungsqualität vorher/nachher Das obere Bild zeigt die Cornell-Box gerendert durch die ursprüngliche DREAM Variante. Im unteren Bild ist die gleiche Szene unter Verwendung von pysikalisch korrekterer direkten Beleuchtung, Photon-Mapping und Final-Gathering zu sehen. 3.2 E VALUATION DER P ERFORMANCE 1 P. Rekursiv 1 P. Iterativ 4 P. Rekursiv o. SIMD 4 P. Rekursiv m. SIMD 650.000 P, C: 500, R: 2 44s 45s 46s - 24 65.000 P, C: 50, R: 2 4,9s 4,8s 5,3 - Tabelle 2: Messergebnisse ohne Precomputed Irradiance 1 P. Rekursiv 1 P. Iterativ 4 P. Rekursiv o. SIMD 4 P. Rekursiv m. SIMD 650.000 P, C: 500, R: 2 1,4s 1,0s 1,7s - 65.000 P, C: 50, R: 2 0,96s 0,78s 1,0s - Tabelle 3: Messergebnisse mit Precomputed Irradiance Die Angegebenen Zeiten in Sekunden geben die Gesamtdauer für das Rendern eines Frame an. Dabei wurde nur die indirekte Beleuchtung berechnet, also keine direkte Beleuchtung mit Schatten, Reflexionen oder Transmissionen. Das Rendern eines Frames ohne Effekte, also auch ohne indirekter Beleuchtung, was nur dem Tracen der Primärstrahlen bis zum ersten Schnittpunkt entspricht, dauert 0,28 Sekunden. Die Ergebnisse wurden auf einem Single Athlon 64 3200+ mit dem Visual Studio .NET 2003 Compiler ermittelt. Die Implementierung von 4 Photonen Rekursiv mit SIMD war zu dem Zeitpunkt noch nicht verfügbar. Aus diesen Messergebnissen kann man erkennen, dass unter bestimmten Umständen die Iterative Variante schneller ist als die rekursive Variante. Außerdem schein es, als ob die Variante die 4 Photonen gleichzeitig einsammelt langsamer ist, als die Variante bei der immer nur ein Photon eingesammelt wird. Deutlich zu sehen ist, das durch Precomputed Illuminance ein starker Geschwindigkeitszuwachs erreicht werden kann, insbesondere wenn viele Photonen verwendet werden. 3.2.2 Messreihe 2 Die folgenden Ergebnisse wurden auf einem Dual-Xeon System mit jeweils 3GHz und dem Intel-Compiler unter Linux ermittelt. Es wurden die Implementierungen “1 Photon Iterativ” vs. “4 Photonen Iterativ” verglichen, sowie der Einfluss der verschiedenen Effekte: Schatten, Reflexion und Transmission und deren Kombination. Es wurde kein Precomputed Illuminance verwendet. 3.2 E VALUATION DER P ERFORMANCE 25 Abbildung 8: Bilder zu den Messergebnissen In der linken Spalte sind die Bilder ohne Precomputed Illuminance, in der der rechten Spalte mit Precomputed Illuminance berechnet worden. Es ist nur die indirekte Beleuchtung zu sehen. In der obere Zeile waren 650.000 Photonen in der globalen Photon Map, in der unteren Zeile 65.000 Photonen. (Die Helligkeit der Bilder wurde für den Druck erhöht +50) 3.2 E VALUATION DER P ERFORMANCE 1 P. Iterativ direkt 1 P. Iterativ mit Schatten 1 P. Iterativ mit Reflextion 1 P. Iterativ mit Transmission 1 P. Iterativ mit Sch., Refl., Trans. 4 P. Rekursiv mit SIMD 4 P. Rekursiv ohne SIMD mit Schatten 4 P. Rekursiv ohne SIMD mit Reflexion 4 P. Rekursiv ohne SIMD mit Transmission 4 P. Rekursiv ohne SIMD mit Sch., Refl., Trans. 26 1 CPU 0,34 0,33 0,31 0,23 0,16 0,30 0,29 0,27 0,28 0,23 2CPUs 0,66 0,64 0,60 0,41 0,28 0,45 0,44 0,40 0,42 0,35 Tabelle 4: Messreihe 2 100.000 Photonen in der Photon-Map, kein Precomputed-Illuminance 1 P. Iterativ direkt 1 P. Iterativ mit Schatten 1 P. Iterativ mit Reflexion 1 P. Iterativ mit Transmission 1 P. Iterativ mit Sch., Refl., Trans. 4 P. Rekursiv mit SIMD 4 P. Rekursiv ohne SIMD mit Schatten 4 P. Rekursiv ohne SIMD mit Reflexion 4 P. Rekursiv ohne SIMD mit Transmission 4 P. Rekursiv ohne SIMD mit Sch., Refl., Trans. 1 CPU 1,22 1,09 1,09 0,99 0,66 1,10 0,99 0,97 0,98 0,70 2CPUs 2,19 1,97 1,98 1,80 1,24 1,62 1,51 1,45 1,45 1,13 Tabelle 5: Messreihe 2 10.000 Photonen in der Photon-Map, kein Precomputed-Illuminance Diese zweite Messreihe läßt erkennen, dass DREAM auf zwei CPUs meistens erwartungsgemäß skaliert, d.h. es kann teilweise eine Verdoppelung der Geschwindigkeit beobachtet werden. Jedoch schwankt der Geschwindigkeitszuwachs bei diesen Messwerten teilweise enorm. Weiterhin kann man sehen, das in diesem Fall die Variante, bei der mit 4 Photonen gleichzeitig gearbeitet wird, scheller ist als die Variante bei der nur ein Photon eingesammelt wird. Außerdem kann man bei “1 P. Iterativ” erkennen, dass die Geschwindigkeit bei eingeschalteten Transmissionen wesentlich stärker einbricht als bei Reflexionen obwohl ein gleichhoher Geschwindgkeitsverlust zu erwarten wäre, wie dies bei “4 P. Rekursiv” der Fall ist. Dieses Phänomen kann nicht erklärt werden. 27 3.2.3 Zusammenfassung Die ermittelten Messwerte schwanken sehr stark. Man kann Parameter finden, bei denen sich DREAM verhält, wie man es erwartet. Dazu gehört z.B. eine Verdoppelung der Geschwindigkeit bei Verwendung von zwei CPUs statt einer. Es wurden jedoch auch Parameter gefunden, bei denen die Geschwindigkeit bei zwei CPUs langsamer wurde. Dieses Verhalten konnte auch durch intensive Tests nicht erklärt werden. Weiterhin wurden Parameter gefunden, die das Geschwindigkeitsverhalten beeinflussen wie man es nicht erwarten würde (siehe 3.2.2: Messreihe 2). Es kann jedoch definitiv gesagt werden, das Precomputed Illuminance die Geschwindigkeit deutlich erhöht. 4 Fazit Ziel dieser Studienarbeit war es, den Ray Tracer DREAM um Photon Mapping zu erweitern und durch Optimierungen zu beschleunigen. Dieses Ziel wurde erreicht, jedoch konnte die vollständige Implementierung der kdtree Traversierung mit SIMD nicht fertiggestellt werden. Es wurde die Darstellungsqualität verbessert und die Geschwindigkeitssteigerungen durch die verschiedenen Optimierungen dargelegt. Durch eine geeignete Wahl der Parameter können mit der erweiterten DREAM Variante interaktive Frameraten bei guter Darstellungsqualität erreicht werden. Dies kann man in Abbildung 9 sehen. Trotz aktivierter Effekte wie Schatten, Spiegelungen, Transmissionen und Photon Mapping mit Final Gathering konnten 1,07 FPS erreicht werden. 4.1 Ausblick Im Rahmen von interaktivem Ray Tracing kann man heute immer noch sagen: Für höhere Auflösung, bessere Bildqualität und höhere Frameraten braucht man schnellere oder mehr Hardware. Mittlerweile wurden die ersten Dualcore CPUs vorgestellt und in naher Zukunft wird mit Spannung die Vorstellung der ersten Cell Prozessoren erwartet. Gerade hochparallele Ray Tracer, zu denen auch DREAM gehört, profitieren deutlich von der Vielzahl an parallel arbeitenden Recheneinheiten. Außerdem wird die Plattformunabhängigkeit von DREAM eine schnelle Portierung auf die wahrscheinlich zuerst für die Spielekonsole “Playstation” erscheinenden Prozessoren ermöglichen. 4.1 A USBLICK 28 Abbildung 9: Interaktiv! 12921 Photonen in der Photon-Map, 798 in der Caustic-Map, Radius: 0,7, Max Photons: 500, mit Precomputed-Illuminance und Final-Gathering 4.1 A USBLICK 29 Abbildung 10: Photonenverteilung zu Abbildung 9 Anhang void PhotonMap::locatePhotonsRec(NearestPhotons* const np, const int index) const { //std::cout < < index < < std::endl; const Photon *p = &mPhotons[index] ; float dist1; if (index<mHalfStoredPhotons) { dist1 = np->pos[ p->plane ] - p->pos[ p->plane ]; if (dist1>0.0) { // if dist1 is positive search right plane locatePhotonsRec( np, 2*index+1); if ( dist1*dist1 < np->dist2[0] ) locatePhotonsRec( np, 2*index); } else { // dist1 is negative search left first locatePhotonsRec( np, 2*index); if ( dist1*dist1 < np->dist2[0] ) locatePhotonsRec( np, 2*index+1); } } CheckAddNearest(np, index); } Abbildung 11: Rekursiver Traversierungscode von Henrik Wann Jensen aus [Jen01] 4.1 A USBLICK 30 void PhotonMap::locatePhotonsIter(NearestPhotons* const np, const int index) const { int i = 1; int level = 0; // start at root node int camefrom; float dist1d; int treeDepth = (log((float)mStoredPhotons) / log(2.) ) + 1; float* dist1d_2 = (float*)alloca( sizeof(float)*treeDepth ); int* chosen = (int*)alloca( sizeof(int)*treeDepth ); // Move up and down the kd-tree until return (when past the root) while (true) { // Move down through the subtrees containing p until a leaf is reached while (i < mHalfStoredPhotons) { const Photon *p = &mPhotons[i] ; dist1d = np->pos[ p->plane ] - p->pos[ p->plane ]; dist1d_2[level] = dist1d * dist1d; i = 2*i; if (dist1d > 0.0) { ++i; // choose left/right child } chosen[level++] = i; } // Check this leaf photon, add it if it is among the nearest // so far, and update nearestDist2 CheckAddNearest(np, i); // Move up in tree until we reach a photon where we need to // check that photon and the other subtree do { camefrom = i; i = i/2; --level; // go to parent if (i == 0) return; // we passed the root: return } while (dist1d_2[level] >= np->dist2[0] || camefrom != chosen[level]); // Check this non-leaf photon, add it if it is among the // nearest so far, and update nearestDist2 CheckAddNearest(np, i); // Step into the other subtree i = chosen[level++]^1; } } Abbildung 12: Iterativer Traversierungscode aus [Chr02] A BBILDUNGSVERZEICHNIS 31 Abbildungsverzeichnis 1 2 3 4 5 6 7 8 9 10 11 12 Zweidimensionaler kd-tree . . . . . . . . . . . . . . . . . . . Datenstruktur eines Photons . . . . . . . . . . . . . . . . . . . Vergleich: Mit/Ohne Final-Gathering . . . . . . . . . . . . . Lichtstrom und Beleuchtungsstärke . . . . . . . . . . . . . . Quadratisch abnehmende Beleuchtungsstärke . . . . . . . . Behandlung der Normalen bei Precomputed-Illuminance . . Vergleich Beleuchtungsqualität vorher/nachher . . . . . . . Bilder zu den Messergebnissen . . . . . . . . . . . . . . . . . Interaktiv! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Photonenverteilung zu Abbildung 9 . . . . . . . . . . . . . . Rekursiver Traversierungscode von Henrik Wann Jensen aus [Jen01] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Iterativer Traversierungscode aus [Chr02] . . . . . . . . . . . 4 5 6 11 13 21 23 25 28 29 29 30 Einige Bilder wurden in Adobe Photoshop nachbearbeitet, in der Form, dass die Helligkeit und/oder der Kontrast für den Druck verstärkt worden sind. Dies ist dann bei den Bildern angegeben. Die Helligkeit und der Kontrast können dabei um -100 und +100 verändert werden. L ITERATUR 32 Literatur [Jen01] Jensen, H. W. 2001. Realistic Image Synthesis Using Photon Mapping. Natrick, Massachusetts: A. K. Peters. [Pha04] Pharr, M., Humphreys, G. 2004. Physically based Rendering. Elsevier. [Chr00] Christensen P. H., 2000. Faster Photon Map Global Illumination. Journal of Graphics Tools, 4(3), 1-10 [Abe05] Geimer, M., Abert, O. 2005. Interactive ray tracing of trimmed bicubic bézier surfaces without triangulation. In WSCG’2005. [Gei03] Geimer M., Müller S., 2003. A cross-platform framework for interactive ray tracing. In Proceedings of Graphiktag 2003, Frankfurt/M., September 2003. Gesellschaft für Informatik. [Bär04] Bärz, R. 2004. Parallelisierung von Ray Tracing Berechnungen in einem heterogenen Netzwerk. Studienarbeit Universität Koblenz. [Wal04] Wald, I., Günther, J., Slusallek, P., 2004. Balancing Considered Harmful - Faster Photon Mapping using the Voxel Volume Heuristic -. EUROGRAPHICS 2004 Volume 23 (2004), Number 3 [Chr02] Christensen P. H., Jensen, H. W., Kato, T., Suykens, F. 2002. A Practical Guide to Global Illumination using Photon Mapping. Siggraph 2002 Course 43. [Hai87] Haines, E. 1987. A Proposal for Standard Graphics Environments. IEEE Computer Graphics ans Applications, vol. 7, no. 11, November 1987, pp. 3-5.