‚Gaussian Splatting‘ ist ziemlich cool
(aras-p.info)- Das 3D Gaussian Splatting-Paper der SIGGRAPH 2023 ist ein Ansatz, der fotobasierte Szenen in Millionen von 3D-Gaussians umwandelt und in Echtzeit rendert; auch eine Unity-Implementierung zum Visualisieren von Experimenten wurde veröffentlicht
- Die Szene wird nicht als Mesh, Voxel oder Distanzfeld dargestellt, sondern als Menge von Blobs im Raum mit Position, Rotation, nichtuniformer Skalierung, Opazität und Spherical-Harmonics-Koeffizienten
- Dieser Ansatz ist kein NeRF, und auch die offizielle Implementierung verwendet keine Fixed-Function-Rasterization-Pipeline, sondern zu 100 % CUDA-basiertes, gekacheltes Software-Rendering
- Die Unity-Implementierung braucht auf einer NVIDIA RTX 3080 Ti bei 1200x800 mit 23,8 ms länger als der offizielle Viewer mit 7,40 ms, ist aber in gewöhnlichem HLSL geschrieben und läuft daher auch auf dem Mac
- Die bicycle-Szene belegt auf der Festplatte 1,5 GB, umfasst etwa 6 Millionen Blobs und benötigt ungefähr 250 Byte pro Blob; damit sind nicht nur Performance, sondern auch Datengröße und GPU-Speicher wichtige Ziele für Verbesserungen
SIGGRAPH-2023-Paper und Unity-Experiment
- Das SIGGRAPH-2023-Paper 3D Gaussian Splatting for Real-Time Radiance Field Rendering stammt von Kerbl, Kopanas, Leimkühler und Drettakis
- Die Website zum Paper, der Source Code und die Datensätze sind öffentlich verfügbar, sodass sich Experimente und Reproduktionen direkt selbst ausprobieren lassen
- Das Unity-Experiment konzentriert sich darauf, bereits erzeugte Gaussian-Splat-„Modell“-Dateien zur Echtzeit-Visualisierung zu laden
- Die Implementierung ist unter aras-p/UnityGaussianSplatting veröffentlicht; weitere Experimente sollen folgen
- Ein weiteres interessantes Thema ist, ob sich die Datengröße reduzieren lässt; möglicherweise lassen sich frühere Experimente zur Float-Kompression dafür nutzen
Woraus besteht ein Gaussian Splat?
- Gaussian Splatting stellt 3D-Szenen nicht als Polygon-Mesh, Voxel oder Distanzfeld dar, sondern als Millionen von Partikeln
- Jedes Partikel, also jedes „3D Gaussian“, enthält folgende Informationen
- Position im 3D-Raum
- Rotation
- nichtuniforme 3D-Skalierung
- Opazität
- Farbinformationen
- Die Farbe wird nicht als einzelne Farbe gespeichert, sondern als Koeffizienten dritter Ordnung der Spherical Harmonics, sodass sie sich je nach Blickrichtung ändern kann
- Beim Rendern werden die Partikel nicht als langgezogene 3D-Kugeln gezeichnet, sondern als 2D Gaussian im Screen Space „gesplattet“
- Der Kern des Verfahrens ist, aus fotobasierten Szenen eine Menge von Blobs mit Skalierung und Farbe zu erzeugen und diese schnell zu rendern
Weder NeRF noch Fixed-Function-Rasterization
- Gaussian Splatting ist kein NeRF
- Es wird ausdrücklich darauf hingewiesen, dass kein „neuraler“ Bestandteil vorhanden ist
- Der Geschwindigkeitsvorteil kommt auch nicht daher, dass „Rasterization-Hardware der GPU verwendet wird“
- Die offizielle Implementierung nutzt keine Rasterization-Pipeline
- Sie ist zu 100 % in CUDA implementiert
- Die Performance der offiziellen Implementierung stammt also nicht aus Fixed-Function-Rasterization, sondern aus gekacheltem Software-Rendering, das Millionen skalierter Partikel effizient verarbeitet
- Ein gekachelter „Software“-Rasterizer auf der GPU ist allerdings als Konzept nicht völlig neu
Verbindung zu älteren Technikbausteinen
- Gaussian Splatting selbst steht in Verbindung mit Arbeiten wie EWA Splatting aus den Jahren 2001 bis 2002
- Dabei werden skalierte und ausgerichtete Blobs im Raum platziert, ihre Projektion auf den Bildschirm berechnet und anschließend Gauß-Formen im Screen Space verarbeitet
- Das Spiel Ecstatica von 1994 ist ein ungewöhnliches Beispiel für einen Ellipsoid-basierten Renderer
- Spherical Harmonics werden in der Physik seit Jahrhunderten verwendet und wurden in der Computergrafik um das Jahr 2000 durch Arbeiten von Ravi Ramamoorthi und Peter-Pike Sloan weithin bekannt
- Ein frühes Beispiel in der Grafik könnte Ray tracing volume densities von Kajiya & Von Herzen aus dem Jahr 1984 sein
- Eine hilfreiche Zusammenfassung findet sich auf Patapom’s page
- Point-Based Rendering ist ebenfalls ein altes Forschungsfeld
- Partikelsysteme werden seit Langem in VFX und zur Darstellung nichtfester Phänomene eingesetzt
- The Use of Points as a Display Primitive ist eine Arbeit von 1985
- Surfels ist ein Paper von 2000
- Auch die Demoscene und Echtzeit-VFX-Tools haben nichttraditionelle Rendering-Ansätze verwendet
- Beispiele sind Fairlight & CNCDs Agenda Circling Forth, Ceasefire (all falls down..) und Number One / Another One
- Notch ist ein Echtzeit-VFX-Tool mit Funktionen zum Erstellen, Simulieren und Anzeigen von punkt- und blobbasierten Objekten
- fogleman/primitive ist ein Beispiel für ein Tool aus dem Jahr 2016, das Bilder als Menge primitiver Formen darstellt
- „Dreams“ von Media Molecule nutzte einen splat-basierten Renderer; die veröffentlichte Version scheint eine Kombination mehrerer Techniken zu sein
- Alex Evans’ Vortrag „Learning from Failure“ ist bei SIGGRAPH 2015 und Umbra Ignite 2015 zu finden
- Gekachelte Rasterization für Partikel gibt es mindestens seit Gareth Thomas’ Holy smoke! Faster Particle Rendering using Direct Compute aus dem Jahr 2014
- Wenn der Bildschirm in Kacheln aufgeteilt wird und die Arbeit innerhalb jeder Kachel erfolgt, lässt sich der Speicherverkehr reduzieren
- Solche Ansätze stehen auch im Zusammenhang mit der Funktionsweise vieler mobiler GPUs; frühe PowerVR-Designs reichen bis 1996 zurück, Pixel Planes 5 sogar bis 1989
Aktueller Stand von UnityGaussianSplatting
- aras-p/UnityGaussianSplatting ist eine Implementierung eines Visualisierers für Gaussian-Splat-Modelle
- Der aktuelle Zustand lässt sich ungefähr als „funktioniert, aber ist nicht schnell“ beschreiben
- Beim Rendern der bicycle-Szene auf einer NVIDIA RTX 3080 Ti mit 1200x800 ist der Performance-Unterschied groß
- Offizieller Viewer: 7,40 ms, 135 FPS
- Unity-Implementierung: 23,8 ms, 42 FPS
- Etwa 4-mal langsamer
- Auch das Sortierverfahren beeinflusst den Performance-Unterschied
- Die Unity-Implementierung verwendet einen relativ einfachen GPU-Bitonic-Sort
- Die offizielle Implementierung nutzt einen CUDA-Radix-Sort auf Basis des OneSweep-Algorithmus
- Auch der Rasterization-Ansatz ist unterschiedlich
- Die offizielle Implementierung verwendet einen in CUDA geschriebenen gekachelten Ansatz
- Die Unity-Implementierung rendert jeden Splat über die normale GPU-Rasterization-Pipeline als Screen-Space-Quad
- Die Unity-Implementierung hat dafür Vorteile bei der Portabilität
- Der Code ist in gewöhnlichem HLSL innerhalb von Unity geschrieben und läuft daher auch auf dem Mac
- Auf einem Apple M1 Max wird dieselbe Szene mit 108 ms und 9 FPS gerendert
- Beim GPU-Speicher scheint die Unity-Implementierung derzeit sparsamer zu sein
- Offizieller Viewer: 4,8 GB
- Unity-Implementierung: 2,2 GB
- In den Werten ist auch der vom Unity Editor belegte Speicher enthalten
Datengröße und Speichernutzung
- In Diskussionen über Gaussian Splatting stehen oft Renderqualität und Geschwindigkeit im Vordergrund, aber auch Datengröße und Speichernutzung sind große Probleme
- Die bicycle-Szene belegt auf der Festplatte 1,5 GB
- Die Szene besteht aus etwa 6 Millionen Blobs
- Jeder Blob benötigt ungefähr 250 Byte
- Zur Laufzeit wird zusätzlicher Speicher für Sortierung, gekacheltes Rendering und Ähnliches benötigt
- Die „Dreams“-Präsentation enthält Ideen, die beim Verkleinern der Daten helfen könnten
1 Kommentare
Kommentare auf Hacker News
Die Formulierung, man habe „neural“ vermieden, obwohl man Gradient Descent und differenzierbares Rendering verwendet, klingt etwas selbstgefällig.
Konzeptionell ähnelt es NeRF: Es optimiert eine datengetriebene Repräsentation, die aus Bildern Variablen für eine 3D-Szene approximiert. Der Unterschied scheint zu sein, dass NeRF das gesamte Lichttransport-Funktional als Radiance Field modelliert, während hier offenbar nur die Randbedingungen modelliert werden, an denen Licht auftrifft.
Da das Ziel ein anderes ist, ist eine einfachere Repräsentationsbasis plausibel, und die Ergebnisse sehen gut aus. Aber es ist schade, wenn es so dargestellt wird, als sei schon das Vermeiden neuronaler Netze an sich lobenswert. Neuronale Netze werden nicht nur benutzt, weil sie im Trend liegen, sondern weil sie tatsächlich leistungsfähige Funktionsapproximatoren sind; außerdem ist die Bandbreite dessen, was man „neuronales Netz“ nennt, sehr groß.
Das ist nur mein Eindruck vom Ton der Einleitung des Blogposts und kann sich vom Paper selbst unterscheiden.
Dadurch wirkt er leichter verständlich und scheint sich einfacher in andere 3D-Software wie Editoren oder Renderer integrieren zu lassen; auch Animationen scheinen möglich. Ein Black-Box-Funktionsapproximator, der eine ganze Szene auf einmal beschreibt, wirkt nicht skalierbar oder elegant.
Allerdings weiß man bei neuronalen Netzen oft selbst dann, wenn das Problem gut modelliert ist, nicht, wie das trainierte Modell tatsächlich funktioniert; wegen des Datenbedarfs und des wiederholten Neutrainings stoßen sie beim Bau langfristiger Lösungen an Grenzen.
Hier möchte ich wohlwollend annehmen, dass die Autoren keinen kleinen Kulturkampf anheizen wollten, sondern einen freundlichen Scherz gemacht haben.
Jeder gerenderte Pixel ist eine gewichtete Summe der Beiträge unbegrenzter, blickrichtungsabhängiger Gaußfunktionen; daher stimmt die Unterscheidung nicht, NeRF modelliere ein Radiance Field und dieses Verfahren nur Randbedingungen.
Wenn man außerdem bedenkt, dass NeRF im Richtungsraum eine niedrig-rangige Darstellung mit Kugelflächenfunktionen verwendet hat, ist es fast eher 3D+α; da stellt sich die Frage, warum man zur Rekonstruktion einer Funktion so niedriger Dimensionalität ein neuronales Netz wählt.
Bei der Inferenz muss das neuronale Netz für jedes Pixel wiederholt entlang des Sehstrahls abgetastet werden; komprimierte Repräsentationen von Light Fields sind in der Grafik schon lange ein Thema, daher wirkt dieser Teil ziemlich unbeholfen.
Später entfernte Plenoxels das „Ne“ aus NeRF und steigerte Trainings- und Inferenzleistung deutlich, und Nvidias Instant NeRF holte mit einem kleinen neuronalen Netz, in das ausgefeilte Eingabe-Embeddings interpoliert werden, ein Stück weit auf: https://nvlabs.github.io/instant-ngp/assets/mueller2022insta...
In der Grafiktechnik werden neuronale Netze vor allem zur Rekonstruktion spärlicher Daten eingesetzt, insbesondere zur Rauschunterdrückung; das ist ein hochdimensionales Problem und wirkt daher naheliegend. Trotzdem schlagen sie handgeschriebene Algorithmen nur selten deutlich; kleine neuronale Netze für Kompression scheinen hingegen Zukunft zu haben.
In der Grafik gibt es viele Funktionsapproximationen, sodass neuronale Netze dort ihren Platz haben. Die behandelten Funktionen sind aber meist besser verständlich und kontrollierbar, anders als in Bereichen wie dem Verstehen natürlicher Sprache, wo von Hand entwickelte algorithmische Lösungen nahezu unmöglich sind.
Viele Gespräche enden bei AI = schlecht, CRYPTO = schlecht. Das Problem ist nicht, dass die Gegenposition falsch wäre, sondern dass man, wenn man zuerst das Fazit festlegt und dann aufhört zu denken, keine Möglichkeit mehr hat zu merken, ob die eigenen Gedanken völliger Unsinn sind.
Wirklich beeindruckende Arbeit.
Im Artikel werden punktbasiertes Rendering und Partikelsysteme erwähnt; in neueren Spielen habe ich das Gefühl, dass es eine subtile Verschiebung hin zu einem neuen Partikelstil gibt, der stärker punktorientiert ist als Texturfragmente und sich zugleich wie ein physikalisches System verhält.
Beispiele sind Hogwarts: https://www.gamespot.com/a/uploads/original/1816/18167535/40..., Forspoken: https://oyster.ignimgs.com/mediawiki/apis.ign.com/project-at..., Starfield: https://dotesports.com/wp-content/uploads/2023/08/temple-loc..., AC6 und FF16.
Gemeinsam ist ihnen, dass sie wie farbige, transparente Punktpartikel mit Physik wirken; besonders auf Konsolen scheint das genutzt zu werden, um günstige Effekte auf der GPU zu erzeugen, ohne die CPU zu belasten. Falls sich jemand in der Spieleentwicklung damit auskennt, würde mich das interessieren.
Ohne Fluid-Simulation sieht ein punktbasiertes Partikelsystem einfach wie Feuerwerk aus. Der nächste Schritt war dann, dass jedes Partikel eigenständig Physik wie Impuls oder Wind hatte und als kleines Textur-Billboard gerendert wurde; bis vor relativ kurzer Zeit wurde das für Explosionen oder Rauch verwendet.
Inzwischen sind Hardware und Physikalgorithmen so gut geworden, dass man Fluid-Simulationen, bei denen Partikel miteinander interagieren, in Echtzeit laufen lassen kann, und die Effekte, die man jetzt sieht, scheinen in diese Richtung zu gehen.
In einer 3D-Spielwelt hat es konzeptionell und strukturell viele Vorteile, nur mit echten 3D-Primitiven zu arbeiten, und Punkt-Sprites lassen sich fast wie unendlich kleine 3D-Objekte behandeln.
Fügt man dagegen 2D-Sprites in eine 3D-Szene ein, müssen sie bei teilweiser Transparenz von hinten nach vorne sortiert werden, passen schlecht zum Z-Buffer, kollidieren mit GPU-freundlichen Batch-Reihenfolgen, dringen in 3D-Oberflächen ein und verraten leicht, dass sie 2D sind.
Um solche Probleme zu lösen, haben sich über die Zeit viele Kompromisse angesammelt: Screen-Door-Transparenz, Shader, die ändern, wie in den Z-Buffer geschrieben wird, Alpha-Tests, Alpha-to-Coverage und so weiter.
In VR fallen 2D-bildbasierte Renderings innerhalb einer 3D-Szene noch stärker negativ auf als auf einem einzelnen Bildschirm, und dass es sich um flache Billboards handelt, ist viel deutlicher zu erkennen. Nimmt man all diese Gründe zusammen, gibt es genug Anlass, sich von 2D-Textur-Sprite-Effekten in 3D-Szenen lösen zu wollen.
Durch den Trend im AI-Bereich scheint es auch teilweise damit zusammenzuhängen, dass GPUs sich mit RT-Cores, Tensor-Cores usw. in Richtung einer Art „GPU mit reduziertem Befehlssatz innerhalb der GPU“ entwickeln.
Vor einigen Jahren hat NVIDIA einen Kernel geschrieben, der SE(3)-Kernel auf Tensor-Cores verlagert; es wäre nicht überraschend, wenn sich das in Teilen auch auf den Kugelflächenharmonik-Anteil des Gaussian Splatting übertragen ließe, sowohl bei der Kompression als auch zur Laufzeit: https://developer.nvidia.com/blog/accelerating-se3-transform...
Da Gaussian Splatting im 3D-Raum immer einen Trägerbereich hat, dürfte es ziemlich effizient sein, und selbst eine grobe, schnelle Transformation kann am Ende recht gute Ergebnisse liefern.
Auch schöne Wirbel aus leuchtenden Punkten lassen sich damit relativ leicht bauen. In Unreal Engine gibt es vermutlich etwas Ähnliches, aber ich habe damit nicht viel eigene Erfahrung.
Ich glaube nicht, dass sie dort ihren Ursprung haben, aber diese Demo ist der erste Meilenstein, den ich benennen kann.
Als das Siggraph-Paper erstmals erschien, war ich wirklich gespannt.
Ich habe aus hunderten Winkeln Fotos von den Zimmern gemacht, in denen ich ungefähr die letzten zehn Jahre gewohnt habe, weil ich sie irgendwann in 3D rekonstruieren wollte; Gaussian Splatting ist die erste Technik, bei der ich das Gefühl habe, dass sie diese Räume nahezu realistisch wiedergeben kann.
Wenn die Tools weiter ausgereift sind, freue ich mich sehr darauf, die alten Zimmer noch einmal zu durchstreifen und in Nostalgie zu schwelgen.
Da ich mich in dem Bereich nicht gut auskenne, ist das vielleicht eine naive Frage, aber solche Videos sehen wirklich beeindruckend aus.
Soweit ich es verstehe, sind die Szene oder das Radiance Field immer statisch und die Beleuchtung ist gebacken. Ich frage mich, ob es sich in eine Richtung weiterentwickeln kann, in der man die Beleuchtung dynamisch ändern und sogar Bewegung unterstützen kann.
In einem Radiance Field gibt es keine Konzepte wie Lichtemission, Reflexion oder Absorption; alles ist zu einem einzigen Wert „übertragenes Licht“ zusammengefasst. In diesem Sinne ist ein Radiance Field eher ein 3D-Foto.
Um das zu ändern, müsste man per Inverse Rendering oder Photogrammetrie die Positionen der Lichtquellen, Oberflächen, Materialien usw. schätzen und anschließend wieder klassisches Path Tracing verwenden.
Eine andere Richtung wäre nicht Animation, sondern Video: Man könnte das Radiance Field über die Zeit fortlaufend erfassen und die Ähnlichkeiten zwischen Frames komprimieren, um zeitliche Konsistenz zu erreichen.
Man kann auch mehrere davon aneinanderhängen, um Animationen zu erzeugen: https://twitter.com/8Infinite8/status/1699460316529090568
Für Relighting gibt es viele NeRF-Varianten, die das unterstützen; daher scheint es auch möglich, Materialparameter der Splats zu optimieren.
Wenn in einer Innenraumszene zum Beispiel ein Tisch einen dunklen Schatten auf den Boden wirft, versteht NeRF Lichtquellen und Schatten noch nicht. Es kann also nicht wissen, ob der Boden schwarz ist, ob ein weißer Boden vom Schatten des Tisches verdeckt wird oder ob sich im Schatten ein blauer Stanford Bunny versteckt.
3D-Scanning-Rigs, die kleine Objekte wie menschliche Gesichter erfassen, lösen das, indem sie die Beleuchtung manipulieren und die BRDF direkt sampeln. Wenn man die Beleuchtung nicht manipulieren kann, lässt sich die BRDF zwar schätzen, aber nur begrenzt.
Nachträglich Animation hinzuzufügen kann einfach sein, aber um die Animation selbst zu erfassen, braucht man mehrere Kameras oder muss, weil es um Menschen geht, auf Schätzungen wie neuronale Netze zurückgreifen, die sich die Gegenseite vorstellen und ergänzen.
Intel hatte vor einigen Jahren ein Projekt, bei dem eine Szene mit mehreren Kameras erfasst wurde, sodass man in der Nachbearbeitung die Kameraposition ändern konnte. Es schien wohl auf Übertragungen von American Football abzuzielen, aber von einer tatsächlichen Veröffentlichung habe ich nichts gehört. Man braucht mehrere Kameras wie bei Matrix.
Mit anderen Worten: Man würde die Daten je nach Tageszeit animiert machen. Der Datenbedarf kann groß werden, aber mit Interpolationsmethoden ist es vielleicht nicht allzu schlimm.
Wenn eine statische Szene 2 GB hat, dürfte eine grobe Näherung für verschiedene Tageszeiten mit weniger als 16 GB möglich sein und sich auf modernen GPUs rendern lassen. Danach ist es eine Frage von ein paar Jahren Optimierung, während man darauf wartet, dass Leistung auf H100-Niveau im Consumer-Bereich ankommt.
Es ist immer spannend, wenn Wissenschaft die Erwartungen der Science-Fiction übertrifft.
In diesem Fall musste ich sofort an das Braindance-Konzept aus Cyberpunk 2077 denken: die Möglichkeit, sich innerhalb der visuellen Erinnerung einer anderen Person zu bewegen, soweit diese Person die Szene wahrgenommen hat.
Wenn man die Kamera an eine andere Stelle als den ursprünglichen Blickpunkt bewegt, zerfällt das Sichtfeld zu einer Art Haufen dreidimensionaler Pixel. Das ähnelt dem Blob-Konzept hier, sieht aber überraschenderweise deutlich weniger ausgefeilt aus als in diesem Paper.
https://steelseries.com/blog/how-to-braindance-cyberpunk-207...
Splatting im Volume Rendering ist eine ziemlich alte Technik. Es gibt das Paper „SPLATTING: A Parallel, Feed-Forward Volume Rendering Algorithm“ von Westover, Lee Alan, Juli 1991.
Letzteres scheint niemand verbergen zu wollen, und Ersteres wirkt nicht zutreffend.
Ich weiß nicht, woher diese Einsicht kam, aber damals lebte ich in der Nähe von Boston und hatte kleine Kinder.
Ich freue mich auf die erste nativ optimierte WebGPU-Implementierung von 3DGS-Rendering.
Außerdem bin ich gespannt, wie man die Szenendaten effizient komprimiert und dekomprimiert.
Ich habe ein paar Notizen zu dieser Frage in einem Zulip-Thread hinterlassen: https://xi.zulipchat.com/#narrow/stream/197075-gpu/topic/Gau...
Kürzlich habe ich ein Video gesehen, das zeigt, wie man Gaussian Splatting verwendet: Getting Started With 3D Gaussian Splats for Windows (Beginner Guide) - https://www.youtube.com/watch?v=UXtuigy_wYc
Mich interessiert der aktuelle Stand von Structure from Motion
Wenn man ein Video eines Raums hat, würde ich gern wissen, wie man es heute tatsächlich in eine 3D-Szene umwandelt.
Genau das ist der Input für den in diesem Paper beschriebenen Prozess der Szenenrekonstruktion.
Soweit ich weiß, hat sich der grundlegende SfM-Ansatz in den letzten etwa zehn Jahren nicht stark verändert; er lässt sich als Extraktion von Bildmerkmalen wie SIFT, heuristisches Matching, Bundle Adjustment und Entfernen von Ausreißern zusammenfassen.
Die übliche Photogrammetrie ist die Antwort, und auch das Interesse an sowie die praktische Nutzbarkeit von NeRF-artigen Ansätzen nehmen allmählich zu.
Allerdings überrascht es, dass zusätzliche räumliche Beziehungen, die sich allein daraus ableiten lassen, dass es ein Video ist, nicht stärker beachtet werden. Die Einschränkung, dass sich die Kamera zwischen Frames nur auf bestimmte Weise bewegen kann, ließe sich vermutlich für die Schätzung der Kamerapose nutzen.
Es gibt die Idee, auf den gesplatteten Gaußverteilungen Marching Cubes laufen zu lassen, um ein Mesh zu extrahieren, aber ich glaube, ich habe noch keinen tatsächlichen Anwendungsfall davon gesehen.
Ende der 90er habe ich mit Blobs Voxel-Isoflächen gerendert.
Ich habe in einem vollständigen 3D-Voxel-Array die Oberflächen-Voxel gescannt, die Normalen über den lokalen Dichtegradienten berechnet und dann auf einen von 240 Werten quantisiert.
Anschließend habe ich mithilfe einer Tabelle von Verschiebungsvektoren Ketten von Oberflächen-Voxeln erstellt; die meisten Voxel bestanden aus 2 Byte: einem Verschiebungsindex relativ zum vorherigen Voxel und einem Index für den Normalenvektor.
Die Beleuchtung für die 240 Normalenvektoren wurde vorab berechnet und in einer Lookup-Tabelle abgelegt, und die Software konnte sehr schnell kleine farbige Kreise in den Z-Buffer malen.
Der große Wermutstropfen damals war, dass keine Perspektive möglich war. Weil die Verschiebungsvektoren für jeden Frame in den Bildschirmraum transformiert wurden, lief es darauf hinaus, einen Blob zu malen, zu versetzen, die Farbe nachzuschlagen und wieder zu malen. Es gab einen Verschiebungswert, der das Ende einer Kette und die Speicherung der nächsten absoluten Position markierte, aber die meisten Voxel waren 2 Byte groß.