Tuesday, August 29, 2017

Is voxel data bigger than polygon data

We just got some fresh measurements that I would like to share.

Voxels and polygons are alternative forms of storing and visualizing 3D information. They are pretty much equivalent in terms you could represent the same information, the key difference is there are penalties attached to each method.

For instance, if you want to change the world in real-time, like making holes, cutting pieces or merging different shapes, voxels are likely to outperform polygons. The same applies if you want to merge layers of procedural content in real time. This is fast because voxels are a much simpler representation of the content. If you were doing this with polygons, you must use more complex and slower methods.

On the other hand, polygons can represent and reproduce some surfaces more economically. This is the reason why the graphics industry adopted polygons so early.

One aspect where we can do an apple-to-apple comparison is data size. The experiment would be this: Get a fairly large scene, store it both as voxels and polygons, and see which dataset is larger. We would be measuring the final size of the package, that is, how much data you need to download to have a complete scene.

This is what we did. We used Ben's work-in-progress scene, which features a massive citadel. The following video shows a character running around this place. You do not have to watch all this to realize it is a pretty big place:


(Please ignore the rough edges in the video, this is an un-optimized test aimed to get a feeling of the scale of the place.)

Everything you see there is voxel content. There are no props or instances. This is all unique geometry, forming a watertight mesh:


Here are the core stats about the scene:

54,080,225 triangles
2,203,456,000 voxels

This is the first takeaway. It takes 2 billion voxels to represent the same content as 54 million polygons. You need 40 times more voxels than polygons.

Is the voxel dataset 40 times the size of the polygon dataset?

That, you guessed, depends on how much smaller a voxel is than a polygon, also what is the overhead in storing them. Let's talk about that.

We store meshes as:
  • a list of vertex coordinates (3 x 32bit float)
  • a list of faces, where each face is three indices into the vertex list (3 x 32bit int)
  • a list of UV pairs, one per each vertex in a face (2 x 32bit float)
  • a list of material identifiers, one per each face (16 bit)
For the entire scene, the final compressed version of this data is 527 MB.

Voxels, on the other hand, store:
  • attributes (empty, has material, has UV, etc. 8bit int)
  • one 3D point (3 x 8bit float)
  • up to 12 UV entries with surface properties (each 64bit)
  • inner material (16bit int)
The compressed final version of the voxel data is 1,210 MB.

It seems the voxel data takes twice the space. This somehow feels right, considering everything we have heard about voxels versus polygons, it is no surprise voxels take twice the space as polygons for the same content.

But there is a little problem with this test. It is not really apples-to-apples. Here is why:

The polygon version of the content captures only the visible surfaces. That is when the solid materials meet air. These are the portions of the model you can actually see.

The voxel version of the content also captures hidden surfaces. While you cannot see these initially, they may become exposed later due to changes made by the viewer to the scene, for instance, while destroying or building things.

This image shows why these two sets of surfaces are different:


The red arrows point to surfaces that appear in the voxel set but are not included in the polygon set.

Luckily for us, we can change the contour rules and also produce these surfaces in the polygon dataset. After a collecting a new set of stats for this new configuration, the new polygon count is 122,470,300 triangles. Once this is compressed, the final storage is 1,105 MB.

Now, this has come very close to the voxel database size. Does this make any sense?

What is maybe most surprising is that we expected the sizes to be different. In both cases, we are capturing surfaces. Even if they are fully volumetric, voxels only really get "busy" around surfaces. This is not much different than polygons.

Of course, there are nuances in how the information is compressed. In each case, we could be using tailored compression schemes. But at this point, this will be producing diminishing returns, and the ratio between voxel data and polygon data is not likely to change much.

If you have questions or opinions about these measurements, I'd love to discuss them. Just post a comment below.