Ich habe eine naive Implementierung eines diffusen / emittierenden Materialpfad-Tracers (Lochkamera) und sehe, dass eine sehr große Anzahl von Abtastwerten pro Pixel erforderlich ist, um zu konvergieren - wie wahrscheinlich in Millionenhöhe - und habe mich gefragt, ob dies für einen "naiven" Pfad-Tracer normal ist Implementierungen?
Hier sind 10.000 Samples pro Pixel:
Und hier ist ein Bild mit 10.000 Seiten pro Sekunde unter Verwendung von kosinusgewichteten Hemisphärenproben als Vergleich:
Für jedes Pixel mache ich das:
- Wirf einen Strahl in die Szene für das Pixel (beginnend in der nahen Ebene, von der Richtung der Kamera bis zur Position des Pixels in der nahen Ebene).
- Wenn ein Objekt getroffen wird, berechne ich eine einheitliche Zufallsrichtung in der durch die Normalen definierten Halbkugel und fahre fort.
- Auf jeder Ebene gebe ich emittierend + (2 * Punkt (normal, bounceRayDir) * ColorFromBounceRay * DiffuseColor / pi) zurück.
- Wenn nichts von einem reflektierten Strahl getroffen wird, kehre ich schwarz zurück.
- Ich arbeite mit 3 Gleitkomma-Farbkanälen, wobei die Absicht ist, dass 0-1 0-255 in der endgültigen Ausgabe uint8 pro Farbkanal entspricht.
- Ich erlaube max. 5 Bounces.
Nachdem ich alle Samples für das Pixel gemittelt habe, konvertiere ich es von HDR zu LDR:
- Für jeden Farbkanal mache ich eine Gammakorrektur: channel = powf (channel, 1.0f /2.2f)
- Ich multipliziere dann den Kanalwert mit 255, klemme ihn von 0-255 und wandle ihn für die endgültige Pixelfarbe auf uint8 um.
Der Quellcode ist hier im Folgenden zu sehen. Es enthält windows.h für Bitmap-Header, hat aber ansonsten keine nicht standardmäßigen Header und keine Bibliotheksabhängigkeiten: https://gist.github.com/anonymous/0dc9f7f5abf15f8fdb9aa84ecfcf67d5
quelle
Antworten:
Ohne explizite Lichtabtastung würde ich eine sehr langsame Konvergenz erwarten.
Jeder Pfad, der nicht vor dem Beenden auf die Lichtquelle trifft, ist nutzlos (trägt Null bei). Da Sie eine kleine Lichtquelle haben, wird die überwiegende Mehrheit der Pfade diese nicht treffen. Es wäre interessant, Ihrem Tracer einige Statistiken hinzuzufügen, um zu sehen, wie viele Pfade Null gegen Null zurückgeben. Ich würde vermuten, dass 99 bis 99,9% von ihnen Null sind, sodass Sie nur eine nützliche Stichprobe von etwa 100 bis 1000 verfolgten Pfaden erhalten.
Eine naive Pfadverfolgung ist beispielsweise mit einem Himmelslicht sinnvoller, von dem fast jeder Pfad erwartet werden kann.
quelle
Ja, das ist zu erwarten. Der Unterschied zwischen Ihren beiden Bildern ist der Unterschied zwischen der Verwendung und Nichtverwendung von Wichtigkeitsabtastungen.
Das erste Bild zeigt deutlich mehr Rauschen als das zweite. Dies liegt daran, dass der Code nicht die Halbkugelproben durch Verwendung der Kosinusgewichtung in Richtung der Normalen vorspannt, sondern gleichmäßig über die Halbkugel abtastet und dann Strahlen, die näher an der Normalen liegen, weniger reflektiertes Licht gibt. Da dies das Punktprodukt verwendet, ist dies auch eine Kosinusgewichtung:
Es wird nur der Beitrag jedes Strahls gewichtet, anstatt die Anzahl der Strahlen in jeder Richtung zu gewichten.
Das zweite Bild ist weniger verrauscht, da es nicht viele Proben auf nahezu senkrechten Strahlen verschwendet, die nur sehr wenig zum Bild beitragen. Das Bild konvergiert bei genügend Samples immer noch zum gleichen Ergebnis - der Ansatz im zweiten Bild wird nur viel früher erreicht.
Der Effekt ist in beiden Fällen gleich:
Die Langzeitsumme ist in beiden Fällen dieselbe, aber Ansatz 1 beinhaltet viele Strahlen mit vernachlässigbarem Beitrag, die immer noch genauso viel Berechnung erfordern wie jeder andere Strahl, wodurch der größte Teil der Berechnungszeit verschwendet wird.
Beachten Sie, dass selbst mit dieser Beschleunigung die Konvergenz für Szenen mit kleinen, hellen Lichtern oder wenn Teile der Szene nur über schmale Pfade zugänglich sind , sehr langsam ist. Im Allgemeinen jede Szene, in der es Regionen gibt, für die nur ein enger Winkelbereich den größten Teil des Lichts beiträgt.
quelle