CodingCat hat geschrieben:Endlich vollständige Beleuchtung (mit Schatten) in den Reflexionen. Ja, das Aliasing und die Normals sind grausig.
Noch weniger als eine Woche bis zur Abgabe der Arbeit, deshalb vorerst keine weiteren Ausführungen.

Zurück ans Schreiben ...
So, Bachelorarbeit ist, wie bereits andernorts erwähnt, abgegeben, ich darf wieder programmieren. ;)
Halbzeit der Verbesserungen und Optimierungen, doppelte Framerate: (Reflexionen stark übertrieben)
Hoffen wir dass die zweite Halbzeit genauso gut läuft. An dieser Stelle endlich eine kurze Zusammenfassung des aktuellen Vorgehens. Ich arbeite mittlerweile auf einem regulären Strahlengitter, das die gesamte Szene enthält. In diesem Strahlengitter sind pro Zelle alle Strahlen eingetragen, welche diese Zelle durchlaufen. Das Ray Tracing ist damit prinzipiell ein einfacher linearer Renderdurchlauf der gesamten Szene, wie bei normaler Rasterisierung, nur dass ich nicht zweidimensional rasterisiere, sondern in das Strahlengitter voxelisiere. Für jedes generierte Voxelfragment schaue ich dann im Strahlengitter einfach alle Strahlen nach, welche die jeweilige Gitterzelle durchlaufen.
In dieser reinen Form ist das Verfahren jedoch nicht umsetzbar, weil jeder Strahl locker 100 Gitterzellen durchläuft, die niemals alle Links auf den jeweiligen Strahl speichern können. Also nutze ich einen weiteren linearen Renderdurchlauf der Szene, um eine grobe Voxelapproximation der Szene aufzubauen (das geht flott, ca. 2 ms). Mit dieser Voxelapproximation kann ich dann das Strahlengitter auf jene Gitterzellen begrenzen, welche tatsächlich von Geometrie bewohnt sind. Damit landet man bei ca. 20 Links pro Strahl, immer noch ne Menge Speicher.
Der nächste Schritt ist ein Multi-Pass-Verfahren, das das Strahlengitter nur teilweise aufbaut (die Voxelapproximation wird von allen Strahlen schichtweise abgetragen, ähnlich wie bei Depth Peeling). Pro Schicht von Geometrie wird ein extra Tracing-Pass durchgeführt, ein großer Teil der Strahlen trifft bereits in der ersten Schicht. Damit profitiert man wie in klassischen Ray-Tracing-Verfahren mit echter (aber meist statischer) Raumaufteilung von der Szenenverdeckung. Ich habe das ganze mit einer einfachen Heuristik auf 3 Passes reduzieren können, wobei jeder Strahl im Schnitt maximal 3 Dreiecke trifft und vor allem pro Pass nur maximal 3 Links emittiert. Der Speicherbedarf wird so tragbar. Dies ist meine aktuelle Implementierung.
Als nächstes werde ich versuchen, die einfache Voxelapproximation durch eine genauere, aber dennoch kompakte Approximation der Geometrie zu ersetzen.
Der ein oder andere fragt sich jetzt vielleicht noch: Warum das Ganze? Es gibt in der Tat bereits wesentlich schnellere Ray-Tracing-Implementierungen auf der GPU, die von Geometrie-Bäumen oder auch Geometrie-Gittern Gebrauch machen. Diese erfordern jedoch meines Wissens nach alle wahlfreien Zugriff auf die gesamte Szenengeometrie und lassen sich somit nur schwerlich in aktuelle Real-time Rendering Pipelines integrieren. Obendrein geht damit der Bedarf eines wahlfreien Zugriffs auf Materialien und insbesondere Texturen einher. Das Verfahren, das ich hier konstruiere, ist direkt in eine ganz normale Deferred Shading Rendering Pipeline integriert, ohne globale Puffer für die Szenengeometrie und unter Verwendung eines ganz normale Objekt- bzw. Batch-basierten Objekt- und Materialsystems.
Nachtrag: Das, was vorhin im ersten Bild zu sehen war, waren gar keine Race-Artefakte, sondern das klassische Mailboxing-Problem. Wieder ein Bug weniger. :)