Ich arbeite seit ner Weile hin und wieder am ConeTracing. Die Idee ist wie beim RayTracing, wo man Strahlen durch die Szene verfolgt und guckt, was sie treffen. Nur dass hier kein Strahl (eine unendlich dünne Linie) getraced wird, sondern ein Strahl mit Ausdehnung, ein Kegel, Englisch "Cone".
Beim RayTracing unterscheidet man Primary Rays, also die Strahlen von der Kamera in die Szene, um zu schauen, welche Szenenteile auf welchen Pixeln landen, und Secondary Rays, also Strahlen von Oberflächen der Szene in die Szene hinein. Letztere sind meist viel wüster gestreut als die wohlgeordneten Primary Rays, die halt wie die Pixel aufm Monitor artig nebeneinander im gleichen Abstand liegen.
Primary Rays macht niemand, Rasterizing wird prinzipiell immer schneller sein. In den Secondary Rays liegt die eigentliche Magie - man kann damit ganz plump Reflektionen einsammeln, globale Beleuchtungseinflüsse aus der Umgebung sammeln oder Schatten von Lichtquellen holen. Das Problem beim RayTracing ist, dass der Ray unendlich dünn ist. Alle genannten Techniken brauchen aber Licht aus großen Bereichen, also muss man beim RayTracing sehr viele Strahlen losschicken und deren Einflüsse gewichtet aufsummieren. Und selbst ne NVidia RTX 2080 schafft bei FullHD und 60fps mit Mühe und Not einen Ray pro Pixel. NVidia fängt da an, diesen einen Ray clever zu streuen, über mehrere Frames hinweg die Ergebnisse wiederzuverwenden und mit GANs das heftige Rauschen, dass man dabei bekommt, rauszurechnen. Ich dagegen will Strahlen mit Volumen (== Kegel) verschicken und will das Aufsummieren der Einflüsse im Kegel analytisch lösen.
Wir nehmen als Beispiel mal den Schatten der Sonne. Die Sonne ist am Himmel eine Scheibe, also eine Fläche. Ein Punkt auf dem Boden bekommt also Licht von der Sonne aus verschiedenen Richtungen: die Strahlen links auf der Sonnenscheibe und die vom oberen Teil der Sonnenscheibe und so weiter addieren sich und ergeben einen hellen Punkt auf dem Boden. Wenn der Weg zur Sonne frei ist, ist das alles kein Problem. Das Problem fängt an, wenn irgendwas Kleines einen Schatten wirft. Das kleine Hindernis verdeckt nur einen Teil der Sonnenscheibe, wir kriegen also auf diesem Bodenpunkt anteilig weniger Licht von der Sonne.
Mit RayTracing müsste man nun von Bodenpunkt aus viele Strahlen in Richtung Sonnenscheibe abfeuern und jeden Strahl ein bisschen streuen, so dass die ganze Sonnenscheibe gleichmäßig abgetastet wird. Wenn wir genügend Strahlen nehmen, kriegen wir anteilig raus, wieviel von der Sonnenscheibe durch das kleine Hindernis verdeckt wird, und wieviel dunkler es auf diesem Bodenpunkt dadurch wird.
Viele Strahlen? Kacke, nich. Wär doch viel cooler, wenn wir statt dem unendlich dünnen Strahl, der ja nur trifft oder nicht trifft, einen Kegel abschicken könnten, der anteilig auf das kleine Hindernis trifft. Und das habe ich versucht. Ich kann jetzt analytisch ausrechnen, wieviel von einem kreisrunden|rechteckigen Kegel durch ein Rechteck|Voxelblob|Dreieck verdeckt wird. Und das habe ich eingesetzt, um einen Haufen Cones durch meine alte Voxelwelt zu tracen. Sind erstmal nur die Primary Rays, weil die am einfachsten zu coden sind, aber theoretisch sollte es ja nicht dabei bleiben. Und das sieht so aus:
Komplett ohne Licht sieht alles reichlich gleichförmig aus, es sind halt nur die Primary Rays. Bei Primary Rays hat man auch nicht wirklich was davon, dass das jetzt Cones anstatt Rays sind. Der einzige Vorteil ist, dass es in Bewegung komplett frickelfrei ist, weil halt für jeden Pixel anteilig die Farbwirkung jedes Voxels einberechnet wird.
Und es ist aktuell komplett in Software, weil ich die leichter debuggen kann. Irgendwann soll das schon noch auf die Grafikkarte wandern, da wär's dann auch drastisch schneller. Hier auf der CPU könnte ich noch ein bissl was optimieren und vektorisieren, aber viel besser wird's im Groben und Ganzen nicht mehr.