Voxel Cone Tracing-Experiment
Forumsregeln
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.
Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.
This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.
Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.
This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
- Schrompf
- Moderator
- Beiträge: 5093
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Voxel Cone Tracing-Experiment
Jetzt als eigenes Thema:
ConeTracing. Wie RayTracing, aber der Strahl, den man traced, hat jetzt ein Volumen. Beim RayTracing kriegt man einen Treffer oder nicht. Beim Cone Tracing wird analytisch ausgerechnet, wieviel der Cone-Grundfläche vom getroffenen Szenenelement verdeckt wird, und traced die Cone dahinter weiter.
Warum ist das cool? Zum Einen weil man bestimmte Problemstellungen, die Einflüsse aus einem Gebiet aufsummieren müssen, mit einer oder wenigen Cones lösen kann, wofür andere hunderte Rays abfeuern müssen. Und zum Anderen weil man beim Abklappern der Szene je nach Dicke des Kegels bereits bei detailreduzierten Versionen mit dem Tracen aufhören kann.
Beispiel: Ich kann für den Sonnenschatten einen Kegel Richtung Sonne abfeuern. Der Kegel weitet sich entlang seines Weges auf und berechnet auf dem Weg anteilig alles rein, was er trifft. Ich kriege damit also penumbra-korrekte Schatten, die mit der Entfernung zum Occluder immer weicher werden.
Anderes Beispiel: Global Illumination. Ich schicke nur ein paar wenige Cones los, die schnell aufweiten. Damit werden beim Tracing automatisch die detailreduzierten Riesen-Voxel verwendet, anstatt im Sparse Voxel Tree weiter in Richtung der detaillierten Einzelvoxel abzusteigen.
---
Mal wieder am Cone Tracing weitergebaut. Gibt jetzt korrekte LOD-Farben in allen Tiefenstufen, so dass man die LOD-Übergänge nur noch in Bewegung als Rollrasen vor sich sieht. Und es gibt jetzt ne korrekte Tiefensortierung zusätzlich zur SignBit-Vorsortierung. Es hat sich nämlich herausgestellt, dass std::sort drastisch schneller ist, wenn es mit vorsortierten Daten arbeitet. Wir reden hier mal locker vom Dreifachen bei Sortierung von ~100 int64.
Vor allem aber sorgt eine korrekte Tiefensortierung jetzt dafür, dass das zufällige Aufblitzen von hinteren Voxeln mit drastisch abweichenden Farben vorbei ist. Und damit ist das Bild endlich so stabil und aliasing-frei, wie es die Methode eigentlich liefern sollte. Ist halt aber immer noch knackelangsam, fürchte ich. An Sekundärstrahlen is eigentlich gar nicht zu denken, aber nur deswegen mach ich den Mist eigentlich. Grmpf. Naja, schaumermal, wie weit ich das noch treibe. Gibt theoretisch noch einiges an Optimierungspotential, aber es hat halt die ganze Zeit den Beigeschmack von "fruchtlos".
ConeTracing. Wie RayTracing, aber der Strahl, den man traced, hat jetzt ein Volumen. Beim RayTracing kriegt man einen Treffer oder nicht. Beim Cone Tracing wird analytisch ausgerechnet, wieviel der Cone-Grundfläche vom getroffenen Szenenelement verdeckt wird, und traced die Cone dahinter weiter.
Warum ist das cool? Zum Einen weil man bestimmte Problemstellungen, die Einflüsse aus einem Gebiet aufsummieren müssen, mit einer oder wenigen Cones lösen kann, wofür andere hunderte Rays abfeuern müssen. Und zum Anderen weil man beim Abklappern der Szene je nach Dicke des Kegels bereits bei detailreduzierten Versionen mit dem Tracen aufhören kann.
Beispiel: Ich kann für den Sonnenschatten einen Kegel Richtung Sonne abfeuern. Der Kegel weitet sich entlang seines Weges auf und berechnet auf dem Weg anteilig alles rein, was er trifft. Ich kriege damit also penumbra-korrekte Schatten, die mit der Entfernung zum Occluder immer weicher werden.
Anderes Beispiel: Global Illumination. Ich schicke nur ein paar wenige Cones los, die schnell aufweiten. Damit werden beim Tracing automatisch die detailreduzierten Riesen-Voxel verwendet, anstatt im Sparse Voxel Tree weiter in Richtung der detaillierten Einzelvoxel abzusteigen.
---
Mal wieder am Cone Tracing weitergebaut. Gibt jetzt korrekte LOD-Farben in allen Tiefenstufen, so dass man die LOD-Übergänge nur noch in Bewegung als Rollrasen vor sich sieht. Und es gibt jetzt ne korrekte Tiefensortierung zusätzlich zur SignBit-Vorsortierung. Es hat sich nämlich herausgestellt, dass std::sort drastisch schneller ist, wenn es mit vorsortierten Daten arbeitet. Wir reden hier mal locker vom Dreifachen bei Sortierung von ~100 int64.
Vor allem aber sorgt eine korrekte Tiefensortierung jetzt dafür, dass das zufällige Aufblitzen von hinteren Voxeln mit drastisch abweichenden Farben vorbei ist. Und damit ist das Bild endlich so stabil und aliasing-frei, wie es die Methode eigentlich liefern sollte. Ist halt aber immer noch knackelangsam, fürchte ich. An Sekundärstrahlen is eigentlich gar nicht zu denken, aber nur deswegen mach ich den Mist eigentlich. Grmpf. Naja, schaumermal, wie weit ich das noch treibe. Gibt theoretisch noch einiges an Optimierungspotential, aber es hat halt die ganze Zeit den Beigeschmack von "fruchtlos".
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
- Krishty
- Establishment
- Beiträge: 8319
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Langsam, okay. Aber dennoch a-fuckin-mazing!
Re: Showroom - Aktuelle Arbeiten und Projekte
Als jemand, der selbst auf 0,5m³ Voxel rumdümpelt muss ich ja sicher nicht erwähnen, dass das, was du machst, beeindruckend ist :D
Meine Meinung:
Hau einfach erstmal alles an Effekte rein, was dir einfällt. Wenns erstmal krass aussieht, gibt das viel Motivation. Dann macht das Optimieren gleich 3 mal so viel Spass. Es kann natürlich auch sein, dass es dann auf Max Grafik gar nicht so beeindruckend ist. Schließlich sind heutige Titel schon sehr realistisch. Da ist dann die Frage, wo du letztendlich hin willst. Ob dir dann der spezielle Look und die Möglichkeit, die dir eine Voxelengine bietet genug ist, oder ob es einfach nur ein hübsches Siteprojekt ist/bleibt. Beim Spiel Teardown war ja, nachdem die Technik stand, relativ schnell daraus ein Spiel gemacht worden, damit man den Hype, den die Techdemo in Videos gezeigt hat, genutzt werden konnte. Da sind die Voxel sogar grober als bei dir.
Meine Meinung:
Hau einfach erstmal alles an Effekte rein, was dir einfällt. Wenns erstmal krass aussieht, gibt das viel Motivation. Dann macht das Optimieren gleich 3 mal so viel Spass. Es kann natürlich auch sein, dass es dann auf Max Grafik gar nicht so beeindruckend ist. Schließlich sind heutige Titel schon sehr realistisch. Da ist dann die Frage, wo du letztendlich hin willst. Ob dir dann der spezielle Look und die Möglichkeit, die dir eine Voxelengine bietet genug ist, oder ob es einfach nur ein hübsches Siteprojekt ist/bleibt. Beim Spiel Teardown war ja, nachdem die Technik stand, relativ schnell daraus ein Spiel gemacht worden, damit man den Hype, den die Techdemo in Videos gezeigt hat, genutzt werden konnte. Da sind die Voxel sogar grober als bei dir.
- Schrompf
- Moderator
- Beiträge: 5093
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Danke, das freut mich sehr.
Tja, für echte Effekte müsste ich es auf der GPU abziehen. Und dafür müsste ich erstmal im 21sten Jahrhundert ankommen und Compute Shader-Support in mein Framework kriegen. Und damit fängt's erst an!
Sekundäre Cones für diffuse Reflektionen, Sonnenschatten, AO, GI usw. kann ich nicht im Cone selbst abfeuern. Denn durch die anteilige Verdeckung Voxel<->Kegel trifft ein Kegel meist mehrere Voxel, bevor er >99% Abdeckung erreicht hat. Gleichzeitig hat ein einzelner Voxel damit Anteile an den Ergebnissen mehrerer Kegel. Ich müsste also a) entweder in Kauf nehmen, dass ich jeden Secondary xmal trace - fäkalisch langsam - oder b) die Secondaries vorab pro Voxel ausführen und die Ergebnisse davon pro Voxel speichern. b) ist sogar Pflicht, wenn Du die Arbeit über mehrere Frames verteilen willst, was sich ja zumindest bei AO oder GI aufdrängt.
Also b) it is. Und allein in dieser Miniszene habe ich schätzungsweise bereits einige hundert Millionen Oberflächen-Voxel. "Mini", weil ich ja im richtigen VoxelSurvival-Spiel bereits nahezu unendliche Szenen und mehrere Dutzend Kilometer Sichtweite hatte. Ich kann also nicht einfach für jeden Voxel ein paar Werte zwischenspeichern. Außerdem kann ich nicht für jeden Voxel ein paar Werte jedes Frame berechnen, das wären Milliarden Cones zu tracen und ich müsste erstmal Minuten warten, bevor ich ein Bild sehe.
Die Lösung dafür ist so ein Paging Detail-System, wie ich es im richtigen Spiel habe: die Voxel in der Umgebung um die Kamera sind voll detailliert gespeichert, drumherum gibt's eine Hülle aus halber Auflösung bis zur doppelten Entfernung, darum ein Viertel Auflösung bis zur vierfachen Entfernung und so weiter. Und nur für diese Voxel werden dann Zwischenwerte gespeichert, und nur für diese Voxel werden Cones gecastet. Aber diese "kondensierte" Darstellung muss ich dann ja mit der Kamerabewegung nachpflegen. Blöcke werden je nach Bewegung verdoppelt oder halbiert, und dabei müssen dann ja die Temp-Werte der Voxel entsprechend mitgeführt werden. Sonst würden bei jeder Kamerabewegung die Blöcke vor der Kamera erstmal wieder schwarz auftauchen, bevor deren GI dann über mehrere Frames hinweg zum Ziel konvergiert.
Das alles muss ich irgendwann mal machen. Mach ich auch irgendwann mal. Aber schon beim Tippen hier vergeht mir die Lust, wenn ich sehe, was für eine Heidenarbeit das ist. Wo ich doch eh schon kaum Freizeit habe und sich auch noch die nächste Kita-Schließung am Horizont abzeichnet.
Vielleicht mach ich doch erstmal am Wurmspiel weiter.
Tja, für echte Effekte müsste ich es auf der GPU abziehen. Und dafür müsste ich erstmal im 21sten Jahrhundert ankommen und Compute Shader-Support in mein Framework kriegen. Und damit fängt's erst an!
Sekundäre Cones für diffuse Reflektionen, Sonnenschatten, AO, GI usw. kann ich nicht im Cone selbst abfeuern. Denn durch die anteilige Verdeckung Voxel<->Kegel trifft ein Kegel meist mehrere Voxel, bevor er >99% Abdeckung erreicht hat. Gleichzeitig hat ein einzelner Voxel damit Anteile an den Ergebnissen mehrerer Kegel. Ich müsste also a) entweder in Kauf nehmen, dass ich jeden Secondary xmal trace - fäkalisch langsam - oder b) die Secondaries vorab pro Voxel ausführen und die Ergebnisse davon pro Voxel speichern. b) ist sogar Pflicht, wenn Du die Arbeit über mehrere Frames verteilen willst, was sich ja zumindest bei AO oder GI aufdrängt.
Also b) it is. Und allein in dieser Miniszene habe ich schätzungsweise bereits einige hundert Millionen Oberflächen-Voxel. "Mini", weil ich ja im richtigen VoxelSurvival-Spiel bereits nahezu unendliche Szenen und mehrere Dutzend Kilometer Sichtweite hatte. Ich kann also nicht einfach für jeden Voxel ein paar Werte zwischenspeichern. Außerdem kann ich nicht für jeden Voxel ein paar Werte jedes Frame berechnen, das wären Milliarden Cones zu tracen und ich müsste erstmal Minuten warten, bevor ich ein Bild sehe.
Die Lösung dafür ist so ein Paging Detail-System, wie ich es im richtigen Spiel habe: die Voxel in der Umgebung um die Kamera sind voll detailliert gespeichert, drumherum gibt's eine Hülle aus halber Auflösung bis zur doppelten Entfernung, darum ein Viertel Auflösung bis zur vierfachen Entfernung und so weiter. Und nur für diese Voxel werden dann Zwischenwerte gespeichert, und nur für diese Voxel werden Cones gecastet. Aber diese "kondensierte" Darstellung muss ich dann ja mit der Kamerabewegung nachpflegen. Blöcke werden je nach Bewegung verdoppelt oder halbiert, und dabei müssen dann ja die Temp-Werte der Voxel entsprechend mitgeführt werden. Sonst würden bei jeder Kamerabewegung die Blöcke vor der Kamera erstmal wieder schwarz auftauchen, bevor deren GI dann über mehrere Frames hinweg zum Ziel konvergiert.
Das alles muss ich irgendwann mal machen. Mach ich auch irgendwann mal. Aber schon beim Tippen hier vergeht mir die Lust, wenn ich sehe, was für eine Heidenarbeit das ist. Wo ich doch eh schon kaum Freizeit habe und sich auch noch die nächste Kita-Schließung am Horizont abzeichnet.
Vielleicht mach ich doch erstmal am Wurmspiel weiter.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
-
- Establishment
- Beiträge: 426
- Registriert: 23.01.2013, 15:55
Re: Showroom - Aktuelle Arbeiten und Projekte
Wenn das Sortieren bei dir ein Engpass ist, schlage ich vor, mal einen anderen Sortieralgorithmus ins Auge fassen als das generische std::sort.
z.B. ska_sort. Das ist immernoch relativ generisch, verwendet aber einen Radix-Sort-Algorithmus der bei schönen nummerischen Schlüsseln ordentlich was rausholen kann.
Gibt dazu auch zwei gute Artikel und ein Video vom Autor, dass die Technik erklärt und viele Vergleichstests beinhaltet: https://probablydance.com/2016/12/27/i- ... -algorithm, https://probablydance.com/2017/01/17/fa ... thm-part-2, Youtube - C++Now 2017: M. Skarupke “Sorting in less than O(n log n): Generalizing and optimizing radix sort".
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Showroom - Aktuelle Arbeiten und Projekte
Und sich einfach mal diesen Vortrag geben, zur Unterhaltung.Spiele Programmierer hat geschrieben: ↑28.02.2021, 20:51Wenn das Sortieren bei dir ein Engpass ist, schlage ich vor, mal einen anderen Sortieralgorithmus ins Auge fassen als das generische std::sort.
z.B. ska_sort. Das ist immernoch relativ generisch, verwendet aber einen Radix-Sort-Algorithmus der bei schönen nummerischen Schlüsseln ordentlich was rausholen kann.
Gibt dazu auch zwei gute Artikel und ein Video vom Autor, dass die Technik erklärt und viele Vergleichstests beinhaltet: https://probablydance.com/2016/12/27/i- ... -algorithm, https://probablydance.com/2017/01/17/fa ... thm-part-2, Youtube - C++Now 2017: M. Skarupke “Sorting in less than O(n log n): Generalizing and optimizing radix sort".
https://www.youtube.com/watch?v=FJJTYQYB1JQ
Ich weiß nicht ob er mit Modern C++ Design oder wie das Buch heißt mehr geholfen oder mehr zerstört hat, ich habe es nicht gelesen. Aber der Vortrag ist sehr lustig, wenn ich mich richtig erinnere.
- Schrompf
- Moderator
- Beiträge: 5093
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Guck ich mir an, Danke. Aber wie gesagt: spätestens mit dem vorsortierten std::sort() ist der Tiefensort im Profiler auf 6% gesunken. Klarer Spitzenreiter mit ~85% ist jetzt die SVT-Traversierung und die darin enthaltene Abstandsprüfung Kegel gegen Bounding Sphere. Und letztere kann ich ja mit AVX256 für alle 8 Subnodes gleichzeitig machen, da ist noch ein bissl Magie versteckt. Danach wird's aber schwierig, noch mehr rauszuholen. Dann geht's an weiche Faktoren wie Cache-Effizienz, Sprungvermeidung und Latenzbetrachtung. Nuja, ich will's nicht zuweit treiben. Am Ende ist das auf der CPU ja nur ne Machbarkeitsstudie und die eigentliche Party soll auf jeden Fall auf der GPU steigen. Der muss ich aber mit ganz anderen Strategien kommen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Showroom - Aktuelle Arbeiten und Projekte
In einfachen Begriffen, sodass ich es auch verstehe, wo ist die Systemgrenze? Verstehe ich richtig, dass du die Voxel auf der CPU "verwaltest", aber das Raytracing macht schon die GPU, oder?Schrompf hat geschrieben: ↑28.02.2021, 22:40 Guck ich mir an, Danke. Aber wie gesagt: spätestens mit dem vorsortierten std::sort() ist der Tiefensort im Profiler auf 6% gesunken. Klarer Spitzenreiter mit ~85% ist jetzt die SVT-Traversierung und die darin enthaltene Abstandsprüfung Kegel gegen Bounding Sphere. Und letztere kann ich ja mit AVX256 für alle 8 Subnodes gleichzeitig machen, da ist noch ein bissl Magie versteckt. Danach wird's aber schwierig, noch mehr rauszuholen. Dann geht's an weiche Faktoren wie Cache-Effizienz, Sprungvermeidung und Latenzbetrachtung. Nuja, ich will's nicht zuweit treiben. Am Ende ist das auf der CPU ja nur ne Machbarkeitsstudie und die eigentliche Party soll auf jeden Fall auf der GPU steigen. Der muss ich aber mit ganz anderen Strategien kommen.
Oder sehen wir hier CPU-Raytracing?
Bestimmt ist es irgendwo schon erklärt, aber ich merke gerade an deinem Posting, dass ich nicht ganz aufgepasst habe.
Re: Showroom - Aktuelle Arbeiten und Projekte
Schrompf traced Cones. Ich hab's zuerst auch nicht verstanden warum, aber er hat die Vorteile aufm letzten Stammtisch erklärt. Eventuell macht es Sinn, wenn Du das in ein Projekt auslagerst und im Eingangspost die Vorteile/Beweggründe nochmal darlegst?
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Showroom - Aktuelle Arbeiten und Projekte
Mein veraltetes CUDA Wissen aus GT 9800 (?) Zeiten - also vor der Umbenennung in GTX und dreistellige Zahlen also zwei Namensschemata vor dem aktuellen - in Kombination mit dem was ich hier so mitbekomme sagt, dass es unwahrscheinlich ist, dass low-level Optimierungen für die CPU auf die GPU rübergerettet werden können.
Proof-of-concept auf der CPU schön und gut, aber hier scheint ziemlich viel Arbeit darein zu gehen, es auf der CPU schnell zu machen und ich vermute das kann man dann einfach wegwerfen, wenn man auf die GPU geht. Klingt schade.
- Schrompf
- Moderator
- Beiträge: 5093
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: Showroom - Aktuelle Arbeiten und Projekte
Das hier ist bisher reines CPU-Gebastel. Die meisten hier genannten Optimierungen sind für die GPU nicht anwendbar, aber die Grundgedanken wie "SOA anstatt AOS", "Sprungvermeidung" und ähnliche werden auch auf der GPU nutzen. Aber Du hast schon Recht, eigentlich sollte ich hier nicht zuviel Arbeit reinstecken, wenn die eigentliche Party am Ende eh auf der GPU steigt.
AVX256 macht mir tatsächlich auch Spaß :-)
Ich habe jetzt erstmal den Plan gefasst, das Paging der aktiven Voxel zu bauen. Das brauche ich für die GPU sowieso, und auch auf der CPU ermöglicht es ne Menge Sachen. Dann schaumermal. Und ich trenne den Thread hier wirklich mal ab, ist ja doch ein bissl was an Diskussion zusammen gekommen. Startbeitrag ist auch editiert.
AVX256 macht mir tatsächlich auch Spaß :-)
Ich habe jetzt erstmal den Plan gefasst, das Paging der aktiven Voxel zu bauen. Das brauche ich für die GPU sowieso, und auch auf der CPU ermöglicht es ne Menge Sachen. Dann schaumermal. Und ich trenne den Thread hier wirklich mal ab, ist ja doch ein bissl was an Diskussion zusammen gekommen. Startbeitrag ist auch editiert.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
-
- Establishment
- Beiträge: 426
- Registriert: 23.01.2013, 15:55
Re: Showroom - Aktuelle Arbeiten und Projekte
:D
Meines Erachtens ist das halt wirklich der große Unterschied zum GPU-Programmieren. Sie macht leider viel zu oft keinen Spaß! Die Landschaft ist so zersplittert, es gibt ständig Treiberprobleme mit irgendwelchen Karten, es ist völlig intransparent was die GPU wirklich macht/welcher Status gerade gesetzt ist, debuggen ist oft sehr schwierig bis unmöglich, die Architekturinformationen von den Herstellern sind extrem spärlich (insbesondere kein Agner), viele nützliche Dinge werden nicht von den APIs angeboten, man muss sich ein ausgeklügeltes Modell überlegen, um die Daten überhaupt laufend zur GPU zu bringen, u.s.w. u.s.f.
Die CPU arbeitet praktisch 100% determinisitisch und die Interna sind (bis zu einem gewissen Grad) sehr gut dokumentiert und die Varianz zwischen Herstellern sehr moderat. Es gibt keine Treiber und Shader-Compiler außerhalb deiner Kontrolle, die dein Werk vermießen, man muss sich nicht zwischen DirectX (nur Windows), CUDA (nur Nvidia) und OpenGL/OpenCL (ohwei) entscheiden. Wenigstens gibt es jetzt Vulkan, aber nervig ist es immernoch. Schon bis man überhaupt was am Bildschirm sieht. Beim ersten Versuch fast sicher eh ein schwarzer Bildschirm. Es ist immer ein Riesenspaß auf RenderDoc zu starren, bis man den Fehler errät...
Sorry, das ist jetzt etwas vom Thema abgedriftet.
Re: Voxel Cone Tracing-Experiment
Daher finde ich die Herangehensweise zuerst auf der CPU funktionierenden Code zu haben recht schlüssig. Den kann man dann "schön" -Stück für Stück- auf die GPU portieren.
Ist das heutzutage wirklich immer noch so schwierig mit dem Debuggen von GPGPU?
Ist das heutzutage wirklich immer noch so schwierig mit dem Debuggen von GPGPU?
Re: Voxel Cone Tracing-Experiment
Ich frage mich tatsächlich, wie das funktioniert. Wenn ich mir das 2D projiziert vorstelle, beginne ich mit einem Kreis, der keinen Radius hat. Und mit der Entfernung skaliert dieser immer größer (also der Kegel, dessen Grundfläche wächst umso weiter er verfolgt wird). Das man nun analytisch bestimmen kann, wie viel Fläche durch einen Voxelbereich weg genommen wird, kann ich mir noch vorstellen (auch wenn ich nicht weiß, wie es berechnet wird). Aber nun die Frage, wie verfolgt man das weiter? Denn letztendlich kommt man doch wieder zu dem Verdeckungsproblem, dass man beim 3D rendern durch Raytracing bzw. Rasterizing löst. Anders ausgedrückt, ich könnte mir vorstellen, wie es geht, wenn man diesen 2D Kreis nun in kleinere Segmente unterteilen könnte, und für jedes Segment entscheiden kann, ob es schon verdeckt ist oder nicht. Aber ohne das? Könnte man dann nicht auch analytisch ein Bild rendern?
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Voxel Cone Tracing-Experiment
Huh? Wenn du die Dimension um 1 reduzierst musst du dir ein Dreieck vorstellen, das in einer 2d Szene liegt und das Ergebnis ist die Farbe eines Punktes.Zudomon hat geschrieben: ↑01.03.2021, 18:53Ich frage mich tatsächlich, wie das funktioniert. Wenn ich mir das 2D projiziert vorstelle, beginne ich mit einem Kreis, der keinen Radius hat. Und mit der Entfernung skaliert dieser immer größer (also der Kegel, dessen Grundfläche wächst umso weiter er verfolgt wird). Das man nun analytisch bestimmen kann, wie viel Fläche durch einen Voxelbereich weg genommen wird, kann ich mir noch vorstellen (auch wenn ich nicht weiß, wie es berechnet wird). Aber nun die Frage, wie verfolgt man das weiter? Denn letztendlich kommt man doch wieder zu dem Verdeckungsproblem, dass man beim 3D rendern durch Raytracing bzw. Rasterizing löst. Anders ausgedrückt, ich könnte mir vorstellen, wie es geht, wenn man diesen 2D Kreis nun in kleinere Segmente unterteilen könnte, und für jedes Segment entscheiden kann, ob es schon verdeckt ist oder nicht. Aber ohne das? Könnte man dann nicht auch analytisch ein Bild rendern?
Re: Voxel Cone Tracing-Experiment
Hmmm... wäre das nicht schon um 2 Dimensionen reduziert? Da betrachtest du ja dann nur einen Spalt.Alexander Kornrumpf hat geschrieben: ↑01.03.2021, 19:03 Huh? Wenn du die Dimension um 1 reduzierst musst du dir ein Dreieck vorstellen, das in einer 2d Szene liegt und das Ergebnis ist die Farbe eines Punktes.
Also ich glaube, du betrachtest das Ganze von der Seite, dann wäre es ein Dreieck.
Eigentlich ist es aber ein kreisförmiges Bild. Wäre es kein Kegel, sondern eine Pyramide, dann hätte man ja tatsächlich ein View-Frustum.
Diese Bildfläche meinte ich mit 2D Kreis.
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Voxel Cone Tracing-Experiment
"das Ergebnis ist die Farbe eines Punktes." war nicht gut ausgedrückt von mir, weil das ja in 3d auch schon (für jeden einzelnen cone) so ist.Zudomon hat geschrieben: ↑01.03.2021, 20:11Hmmm... wäre das nicht schon um 2 Dimensionen reduziert? Da betrachtest du ja dann nur einen Spalt.Alexander Kornrumpf hat geschrieben: ↑01.03.2021, 19:03 Huh? Wenn du die Dimension um 1 reduzierst musst du dir ein Dreieck vorstellen, das in einer 2d Szene liegt und das Ergebnis ist die Farbe eines Punktes.
Also ich glaube, du betrachtest das Ganze von der Seite, dann wäre es ein Dreieck.
Eigentlich ist es aber ein kreisförmiges Bild. Wäre es kein Kegel, sondern eine Pyramide, dann hätte man ja tatsächlich ein View-Frustum.
Diese Bildfläche meinte ich mit 2D Kreis.
Ich denke die Dimensionsreduktion, die für die Anschauung am leichtesten ist, ist die wo du alle Zeilen des Bildes bis auf die Mittlere weglässt und von "Oben" auf das Resultat schaust. Ist jetzt ein bisschen albern, das weiter im Detail zu erklären, weil eigentlich klar ist, dass du ein Dreieck sehen musst, wenn du das mental machst.
Vielleicht verstehe ich auch was komplett falsch.
Re: Voxel Cone Tracing-Experiment
@Schrompf
Vielleicht kannst du, wo es ja gerade dein Themengebiet ist, noch was dazu sagen. Ich habe das Gefühl, dass meine Frage jetzt durch die anderen Posts untergegangen ist. Würde mich aber sehr interessieren, wie das funktionieren kann:
Falls auch für dich unklar ist, wie ich das meine, würde ich versuchen, das nochmal besser zu formulieren.
Vielleicht kannst du, wo es ja gerade dein Themengebiet ist, noch was dazu sagen. Ich habe das Gefühl, dass meine Frage jetzt durch die anderen Posts untergegangen ist. Würde mich aber sehr interessieren, wie das funktionieren kann:
Mit Kreis meine ich die Cone-Grundfläche die sich je nach Abstand immer weiter vergrößert.Zudomon hat geschrieben: ↑01.03.2021, 18:53Ich frage mich tatsächlich, wie das funktioniert. Wenn ich mir das 2D projiziert vorstelle, beginne ich mit einem Kreis, der keinen Radius hat. Und mit der Entfernung skaliert dieser immer größer (also der Kegel, dessen Grundfläche wächst umso weiter er verfolgt wird). Das man nun analytisch bestimmen kann, wie viel Fläche durch einen Voxelbereich weg genommen wird, kann ich mir noch vorstellen (auch wenn ich nicht weiß, wie es berechnet wird). Aber nun die Frage, wie verfolgt man das weiter? Denn letztendlich kommt man doch wieder zu dem Verdeckungsproblem, dass man beim 3D rendern durch Raytracing bzw. Rasterizing löst. Anders ausgedrückt, ich könnte mir vorstellen, wie es geht, wenn man diesen 2D Kreis nun in kleinere Segmente unterteilen könnte, und für jedes Segment entscheiden kann, ob es schon verdeckt ist oder nicht. Aber ohne das? Könnte man dann nicht auch analytisch ein Bild rendern?
Falls auch für dich unklar ist, wie ich das meine, würde ich versuchen, das nochmal besser zu formulieren.
- Schrompf
- Moderator
- Beiträge: 5093
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: Voxel Cone Tracing-Experiment
Die Frage ist durchaus naheliegend. Meine Cones haben entweder als Grundfläche entweder Kreis oder Rechteck. Die Primitives, deren Verdeckung ich berechnen will, sind dann Rechtecke, komische Rundblobs oder halt Dreiecke. Die Formeln für ein einzelnes Primitive vs. die Kegelgrundfläche habe ich teilweise schon ausgeformelt und in ShaderToy gebaut. In einer echten Szene geht's ja aber nach dem ersten Primitive weiter, wenn das nur einen Teil der Kegelgrundfläche verdeckt hat. Wie berücksichtigt man, dass ein Teil der Fläche des nächsten Primitives bereits durch vorherige Primitives verdeckt wurde? Die geht ja dann nicht mehr voll in die Verdeckungsberechnung gegen die Kegelgrundfläche ein?
Aktuell löse ich das Problem gar nicht. Ich tu einfach so, als wäre jedes Primitive vollständig unverdeckt von den vorherigen Primitives, würde also nur "neue" Verdeckung beitragen. Und für mein Experiment geht das erstmal prima. Ich habe da ja nur sehr dünne Kegel und die Primitives sind im Vergleich dazu deutlich größer. Daher kommt es da selten mehreren anteiligen Verdeckungen in Folge, und der Fehler ist gering.
Wenn ich jetzt aber weitermache und anfange, dickere Cones zu tracen, wird das Problem zu merken sein. Wenn ich zum Beispiel einen runden Kegel Richtung Sonne trace, würde ich bei korrekter Verdeckung ja automatisch penumbra-korrekte Schatten kriegen, also Schatten, die mit zunehmendem Abstand zu Schattenwerfer immer breiter öffnen und immer weicher werden. Und da werde ich das Problem akut kriegen, denn z.B. eine Hauswand besteht ja aus ner Menge Voxel hintereinander. Wenn ich den Sonnenschatten einer Hausecke haben will, kriege ich genau das Problem, dass viele Primitives in der selben Ecke meiner Kegelgrundfläche liegen und einander überdecken. Mit meiner Ignoranz kriege ich da wahrscheinlich übermäßig dunkle Teilschatten, die viel zu schnell zu Vollschatten übergehen.
Ich habe dafür noch keine echte Lösung. Tim Sweeney - der all meine hier dargestellten Ideen schon vor zehn Jahren auf Twitter präsentiert hat - hat sich nur für Dreiecke interessiert und wollte pro Cone einen kleinen BSP-Tree mitrechnen, um die Überdeckung perfekt einzuberechnen. Das erscheint mir ein bissl Overkill. Ich könnte mir stattdessen ein simples Bounding Rectangle vorstellen, was zumindest den UseCase "mehrere Primitives landen in der selben Ecke der Grundfläche" ganz gut abfedern könnte. Wenn man das Bounding Rect als "Vom Rand her einengend" formuliert, kriegst Du das sogar quasi umsonst, weil es nur den Wertebereich des Flächenintegrals weiter einschränkt. Oder man rastert die Grundfläche und zieht einen Mini-DepthBuffer ein. Du brauchst ja keine Tiefenwerte pro Teilfläche, sondern reine Anwesenheit reicht. Also tut es ein Bit pro Teilstück, oder halt 16x16 in einem AVX256-Register. Verdeckungsberechnung ist dann ne simple AND/OR-Operation und Bits zählen.
Ich werde hoffentlich bald zu diesem Problem kommen und dann berichten. Aber falls ihr Ideen habt, wie man das noch lösen könnte, immer gerne her damit.
Aktuell löse ich das Problem gar nicht. Ich tu einfach so, als wäre jedes Primitive vollständig unverdeckt von den vorherigen Primitives, würde also nur "neue" Verdeckung beitragen. Und für mein Experiment geht das erstmal prima. Ich habe da ja nur sehr dünne Kegel und die Primitives sind im Vergleich dazu deutlich größer. Daher kommt es da selten mehreren anteiligen Verdeckungen in Folge, und der Fehler ist gering.
Wenn ich jetzt aber weitermache und anfange, dickere Cones zu tracen, wird das Problem zu merken sein. Wenn ich zum Beispiel einen runden Kegel Richtung Sonne trace, würde ich bei korrekter Verdeckung ja automatisch penumbra-korrekte Schatten kriegen, also Schatten, die mit zunehmendem Abstand zu Schattenwerfer immer breiter öffnen und immer weicher werden. Und da werde ich das Problem akut kriegen, denn z.B. eine Hauswand besteht ja aus ner Menge Voxel hintereinander. Wenn ich den Sonnenschatten einer Hausecke haben will, kriege ich genau das Problem, dass viele Primitives in der selben Ecke meiner Kegelgrundfläche liegen und einander überdecken. Mit meiner Ignoranz kriege ich da wahrscheinlich übermäßig dunkle Teilschatten, die viel zu schnell zu Vollschatten übergehen.
Ich habe dafür noch keine echte Lösung. Tim Sweeney - der all meine hier dargestellten Ideen schon vor zehn Jahren auf Twitter präsentiert hat - hat sich nur für Dreiecke interessiert und wollte pro Cone einen kleinen BSP-Tree mitrechnen, um die Überdeckung perfekt einzuberechnen. Das erscheint mir ein bissl Overkill. Ich könnte mir stattdessen ein simples Bounding Rectangle vorstellen, was zumindest den UseCase "mehrere Primitives landen in der selben Ecke der Grundfläche" ganz gut abfedern könnte. Wenn man das Bounding Rect als "Vom Rand her einengend" formuliert, kriegst Du das sogar quasi umsonst, weil es nur den Wertebereich des Flächenintegrals weiter einschränkt. Oder man rastert die Grundfläche und zieht einen Mini-DepthBuffer ein. Du brauchst ja keine Tiefenwerte pro Teilfläche, sondern reine Anwesenheit reicht. Also tut es ein Bit pro Teilstück, oder halt 16x16 in einem AVX256-Register. Verdeckungsberechnung ist dann ne simple AND/OR-Operation und Bits zählen.
Ich werde hoffentlich bald zu diesem Problem kommen und dann berichten. Aber falls ihr Ideen habt, wie man das noch lösen könnte, immer gerne her damit.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.