Zuerst. Schreiben wir, was wir über jedes Voxel wissen:
voxel = (x, y, z, color) // or some other information
Allgemeine Lagerung
Der allgemeine Weg ist einfach:
set of voxels = set of (x,y,z, color)
Beachten Sie, dass das Triplett (x, y, z) jedes Voxel eindeutig identifiziert, da Voxel ein Punkt im Raum ist und auf keinen Fall zwei Punkte einen Platz einnehmen (ich glaube, es handelt sich um statische Voxeldaten).
Für einfache Daten sollte es in Ordnung sein. Es handelt sich aber keineswegs um eine schnelle Datenstruktur.
Das Rendern erfolgt AFAIK mit dem Scanline-Algorithmus. Toms Hardware-Artikel über Voxel enthält ein Bild des Scanline-Algorithmus .
Schnelle Suche
Wenn eine schnelle Suche erforderlich ist, ist die schnellste Datenstruktur für die Suche Hash (auch Array, Karte ... genannt). Also muss man daraus Hasch machen. Naiv wollen wir also nur den schnellsten Weg, um ein beliebiges Element zu erhalten:
array [x][y][z] of (color)
Dies hat O (1) zum Nachschlagen des Voxels nach x-, y-, z-Koordinaten.
Das Problem ist, dass der Platzbedarf O (D ^ 3) ist, wobei D der Bereich jeder x-, y- und z-Zahl ist (vergessen Sie die reelle Zahl, denn wenn es Zeichen wären, die einen Bereich von 256 Werten haben, gäbe es 256 ^ 3 = 2 ^ 24 == 16 777 216 Elemente im Array).
Aber es kommt darauf an, was Sie mit Voxeln machen wollen. Wenn Rendern das ist, was Sie wollen, dann ist es wahrscheinlich dieses Array, was Sie wollen. Aber das Problem der Lagerung bleibt immer noch ...
Wenn die Lagerung das Problem ist
Eine Methode ist die Verwendung der RLE-Komprimierung im Array. Stellen Sie sich eine Voxelscheibe vor (eine Voxelmenge, bei der Voxel einen konstanten Koordinatenwert haben ... wie zum Beispiel eine Ebene mit z = 13). Ein solches Stück Voxel würde wie eine einfache Zeichnung in MSPaint aussehen . Ich würde sagen, das Voxelmodell belegt normalerweise einen Bruchteil aller möglichen Plätze (D ^ 3-Raum aller möglichen Voxel). Ich glaube, dass "nimm ein Paar aus einem Triplett von Koordinaten und komprimiere die verbleibende Achse" den Trick machen würde (zum Beispiel nimm [x] [y] und komprimiere für jedes Element alle Voxel auf der z-Achse bei gegebenem x, y. sollte es 0 bis wenige Elemente geben, würde RLE hier gut tun):
array [x][y] of RLE compressed z "lines" of voxel; each uncompressed voxel has color
Eine andere Methode zur Lösung des Speicherproblems wäre, anstelle eines Arrays die Baumdatenstruktur zu verwenden:
tree data structure = recursively classified voxels
for octrees: recursively classified by which octant does voxel at (x,y,z) belong to
- Octree, wie von Nick erwähnt. Es sollte Voxel komprimieren. Octree hat sogar eine anständige Geschwindigkeit für das Nachschlagen, ich denke, es ist ein O (log N), wobei N die Anzahl der Voxel ist.
- Octree sollte in der Lage sein, anständig beliebige Voxeldaten zu speichern.
Wenn Voxel eine vereinfachte Höhenkarte sind, können Sie genau das speichern. Oder Sie können Parameter für Funktionen speichern, die die Höhenkarte generieren, oder sie prozedural generieren ...
Und natürlich können Sie alle möglichen Ansätze kombinieren. Aber übertreiben Sie es nicht, es sei denn, Sie testen, dass Ihr Code funktioniert und messen, dass er WIRKLICH schneller ist (es lohnt sich also, ihn zu optimieren).
TL; DR
Anders als Octrees ist RLE-Komprimierung mit Voxeln, Google "Voxlap", "Ken Silverman" ...
Ressourcen
Es gibt eine Liste von Ressourcen und Diskussionen darüber, wie ein schneller Voxel-Renderer erstellt werden kann, einschließlich Artikel und Quellcode .