Is there a way to ‘compress’ the voxel colors ? right now I store a color for each voxel. I keep track of them in a array. However, it’s a lot of data. I was hoping you would know a way to reduce the number of colors I need to keep track of. Like how voxel position data is reduced by using slabs (instead of storing each voxel separated ).
I’m using slabs for my models, but If I have a cube of 64x64x64 I still need to store 19432 color indexes. Which I find too much (I’m programming for mobile/handheld systems with not much memory).
Hopefully you know something. Thanks for your time,
Hugo
Ñuño Martínez at
Re: Alternative for storing voxel color information
You may try to compress it. Ken used RLE which is simple and fast. You can try other algorithms as Huffman or LZ77 but they're too much complex.
Reduce "color depth" is a good idea also. 32bits per voxel (bpv) is too much for 64x64x64 voxeled objects. 16bpv will reduce it to a half and paletted 8bpv (as VOX format) should be enough in most cases.
Edited by Ñuño Martínez at
0xC0DE at
Thanks for the tip on RLE. That's the kind of answer I was looking for! :)
about the color depth, I only store a index number that correspons with the color from the palette (instead of storing r,g,b for each color). So color depth,etc isn't a problem.
Awesoken at
RLE is a good choice. I use it for both Voxlap and Slab6. Another method is to store 1 bit per voxel for determining solid vs. air - 32KByte for a 64^3 model. Then to store colors, you use a hash table. This method requires fast bit scan instructions (such as BSF/BSR on x86) to find the surfaces quickly. A 3rd method is to use a compressed octree. Unfortunately, I have no experience with octrees so I can't comment on its practicality.
Ñuño Martínez at
Awesoken said at
A 3rd method is to use a compressed octree. Unfortunately, I have no experience with octrees so I can't comment on its practicality.
I think I can help here.
An octree is similar than a binary-tree but you use 8 nodes ("oct" is 8 in Latin). It isn't too complex. You have a "box" wich contains the object. Then divide this box in 8 smaller boxes and each of them in 8 more until each box is 1 voxel whide. The compression cames because if a box is empty, then the smaller boxes that contains are empty too so it is not necessary to store them. In a similar way if a box is "interior" then all boxes that contains are "interior" too, so its not necessary to store them. You can build this structure in this way (pseudo code):
OCTREE_NODE = RECORD boxes: ARRAY [1..8] OF OCTREE_NODE; empty: BOOLEAN; interior: BOOLEAN; color: INTEGER; END;
Octrees are used often for fast collision detection. Most ray-tracers used it. I think that it's not a good structure for voxels because it's hard to tell how to draw an object this way, but it can be used to detect "voxel-per-voxel" colisions.
Edited by Ñuño Martínez at
Zelex at
What about ray-casting? Seems pretty straight forward to me? Oct-trees are related to RLE compression wise so the sizes of the data should be comparable. The big question is, is an oct-tree in its uncompressed form comparable to a RLE coded volume? This is important because if it is not, then the RLE format is superior as it can stay compressed in memory and still be used in runtime.
A compressed oct-tree form has its child information stored as bits with the layout in memory implicitly derived (depth first, etc..). So insead of "int children[8]" per node, you have "unsigned char childMask".
Zelex at
So, in an Oct-tree's compressed form, for every non-empty voxel (and immediate neighbors in its 2x2x2 block) it consumes 1.15 bits. Does anybody have any numbers on the average compression per-visible voxel in RLE?
Hazard at
I'm not storing colors at all in my approach. instead i use materials. Each material is identified by a 1 byte ID, resulting in 255 materials (and 0 for empty voxels). the material ID is stored for each voxel (no matter if surface or interior) and compressed in a slab-like way. since you'll most likely have large patches of the same material, compression is pretty high. colors are generated procedurally or from a texture as needed. you are also able to define the behaviours for each material individually to make materials that are indestructable or can only be destroyed by specific types of weapons. even effects like per-voxel-health can be done this way. just create something like 10 materials (each one a little bit darker than the previous one) and define the material bahaviour to switch to the next material when damaged and destroy it after the last material in the row is reached.
Zelex at
So, a follow-up here.
Assuming the voxelstein level is a 1024x1024x512 grid. The level consumes 56591876 bytes. Then we can calculate the number of bits per voxel (including empty space and color information) as 56591876 * 8 / (1024*1024*512) = 0.84 bits per voxel. I'll attempt to parse the format when I get the time to find the amount of non-empty space so I can get a more useful calculation here.