Skip to main content

Using Quantization with 3D Models

The WEB3D_quantized_attributes extension to glTF offers reasonable compression with little to no overhead for decompression. This meets the needs of 3D Tiles in Cesium perfectly because the 3D Tiles engine frequently downloads new tiles based on the view. Quantized 3D model files means smaller files, faster downloads, and less GPU memory usage with no performance degradation.

All about Quantization

The WEB3D_quantized_attributes extension is based on Mesh Geometry Compression for Mobile Graphics, by Jongseok Lee, et al.

Usually model attributes such as positions and normals are stored as 32-bit floating-point numbers. Quantization takes those attributes and stores them as 16-bit integers represented on a scale between the minimum and maximum values. This means that the attribute data can be stored in half the amount of space!

The decompression is done by a simple matrix multiplication in parallel in the vertex shader on the GPU.

Model Quantization in Cesium

Quantization works best on models whose file size is composed mostly of quantizable attributes, such as positions and normals. So files that have complex geometry tend to benefit the most.

To illustrate this, I’ve included a synopsis using two models in the glTF sample models repository.

2 Cylinder Engine

A geometry-heavy model donated to the glTF sample models repository by Okino Polytrans Software.

Statistics

ImageOriginalQuantizedCompression
File Size (Raw)1,872 KB1,222 KB34.7%
File Size (gzip)590 KB502 KB14.92%

Raw File Size Breakdown

OriginalQuantizedCompression
glTF JSON (.gltf)116 KB120 KB-3.44%
Binary Data (.bin)1,753 KB1,099 KB37.31%
Shaders (.glsl)3 KB3 KB0%
Total1,872 KB1,222 KB34.72%

gearbox_original

Original

gearbox_quantized

Quantized

Cesium Milk Truck

A texture-heavy model donated to the glTF sample models repository by the Cesium team.

Statistics

ImageOriginalQuantizedCompression
File Size (Raw)1,036 KB988 KB4.63%
File Size (gzip)926 KB919 KB0.76%

Raw File Size Breakdown

OriginalQuantizedCompression
glTF JSON (.gltf)19 KB18 KB5.26%
Binary Data (.bin)111 KB64 KB42.34%
Shaders (.glsl)4 KB4 KB0%
Textured Images902 KB902 KB0%
Total1,036 KB988 KB4.63%

milk truck original

Original

milk truck quantized

Quantized

As expected, the model with more geometry benefits more from this compression, but even the model whose file size is mostly impacted by texture benefits from what is effectively free compression.

The reason the data doesn’t shrink down all the way to 50% is because a portion of the binary data buffer is made up of indices that cannot be quantized.

Applying gzip to models shrinks the gap between the quantized and non-quantized file sizes, but ultimately the quantized models still have a size advantage over their non-quantized counterparts and use less GPU memory.

There are some slight changes in the size of the glTF JSON itself. This is due to restructuring of the data accessors during quantization as well as the addition of a few properties enabling quantization. These steps are a result of the gltf-pipeline implementation.

The gltf-pipeline project contains an open-source implementation of quantization that can be used to compress your glTF models.

Compatibility with Existing Compression

We already use two techniques for compressing normal and texture coordinate attributes in Cesium. Normal vectors are oct-encoded using the technique described in A Survey of Efficient Representations of Independent Unit Vectors, by Zina H. Cigolle, et al. This compresses three 32-bit floating-point numbers down to two bytes, a roughly 83% compression, so this approach is preferable to quantization of normals.

The other technique stores two 32-bit floating-point numbers representing texture coordinates into a single 32-bit floating-point number. Like quantization, this also results in roughly 50% compression, so either technique can be used with similar results.

Unfortunately, quantization cannot be used to further compress these attributes. It can only be applied to floating-point attributes so it cannot be used on the byte oct-encoded normals, and even though the texture coordinate compression does store its value into a float, attempting to apply quantization on top of it produces some interesting results.

milk truck compressed and quantized

This is what happens when you try to quantize already-compressed texture coordinates.

This happens for two reasons: the first is that quantization is a lossy compression; the second is that compressed texture coordinates are not necessarily mapped linearly. Quantization will produce a decompressed value close to the original, but it won’t necessarily be the same value [A].

Thus our approach is to quantize positions, oct-encode normals, and either quantize or compress texture coordinates [B].

The statistics for oct-encoding normals and quantizing attributes for the 2 Cylinder Engine model are shown below.

Statistics

ImageOriginalQuantizedCompression
File Size (Raw)1,872 KB988 KB47.22%
File Size (gzip)590 KB457 KB22.54%

Raw File Size Breakdown

OriginalQuantizedCompression
glTF JSON (.gltf)116 KB102 KB12.07%
Binary Data (.bin)1,753 KB881 KB49.74%
Shaders (.glsl)3 KB5 KB-40%
Total1,872 KB988 KB47.22%

gearbox_original

Original

gearbox_quantized

Quantized

The shader modification required for oct encoding normals does increase the size of the shaders, but it isn’t much compared to the size of the model as a whole.

Model Quantization in 3D Tiles

3D Tiles is an open format for streaming massive heterogeneous 3D geospatial datasets.

With support for quantized attributes in Cesium, the glTF in the Batched 3D Model (b3dm) and Instanced 3D Model (i3dm) tile formats can be quantized for faster downloads and less GPU memory usage with no performance hits.

The data used in the benchmarks and screenshots below is from CyberCity 3D’s Washington DC data set. The zoom benchmark is an average of the frames per second while zooming into the city, causing additional tiles to be loaded, as shown below.

city_zoom

The models used here already have their normals oct-encoded, so the compression represents the gain from quantizing only the positions of the models.

Northwest Cleveland Park

The table below shows the file size breakdowns and compression statistics for the batched 3D model of Northwest Cleveland Park in Washington, D.C. The files are broken up into level-of-detail hierarchies.

Statistics

File Size (raw)Total5.92 MB5.29 MB10.64%
Average328 KB294 KB10.37%
0/0/0.b3dm164 KB123 KB25.00%
1/0/0.b3dm279 KB232 KB16.85%
1/0/1.b3dm428 KB378 KB11.68%
1/1/0.b3dm278 KB222 KB20.14%
1/1/1.b3dm556 KB499 KB10.25%
2/0/0.b3dm365 KB348 KB4.66%
2/0/1.b3dm287 KB261 KB9.06%
2/0/2.b3dm205 KB191 KB6.82%
2/1/0.b3dm315 KB293 KB6.98%
2/1/1.b3dm334 KB306 KB8.38%
2/1/2.b3dm268 KB249 KB7.09%
2/1/3.b3dm207 KB196 KB5.31%
2/2/0.b3dm436 KB385 KB11.69%
2/2/1.b3dm431 KB378 KB12.30%
2/2/2.b3dm227 KB205 KB9.69%
2/3/0.b3dm425 KB376 KB11.53%
2/3/1.b3dm369 KB323 KB12.47%
2/3/3.b3dm346 KB327 KB5.49%
ImageOriginalQuantizedCompression
File Size (Raw)Total5.92 MB5.29 MB10.64%
Average328 KB294 KB10.37%
0/0/0.b3dm164 KB123 KB25.00%
1/0/0.b3dm279 KB232 KB16.85%
1/0/1.b3dm428 KB378 KB11.68%
1/1/0.b3dm278 KB222 KB20.14%
1/1/1.b3dm556 KB499 KB10.25%
2/0/0.b3dm365 KB348 KB4.66%
2/0/1.b3dm287 KB261 KB9.06%
2/0/2.b3dm205 KB191 KB6.82%
2/1/0.b3dm315 KB293 KB6.98%
2/1/1.b3dm334 KB306 KB8.38%
2/1/2.b3dm268 KB249 KB7.09%
2/1/3.b3dm207 KB196 KB5.31%
2/2/0.b3dm436 KB385 KB11.69%
2/2/1.b3dm431 KB378 KB12.30%
2/2/2.b3dm227 KB205 KB9.69%
2/3/0.b3dm425 KB376 KB11.53%
2/3/1.b3dm369 KB323 KB12.47%
2/3/3.b3dm346 KB327 KB5.49%
Total1.321.22 MB7.58%
ImageOriginalQuantizedCompression
File Size (gzip)Total1.32 MB1.22 MBCompression
Average73.56 KB67.72 KB7.94%
0/0/0.b3dm49 KB42 KB14.29%
1/0/0.b3dm68 KB61 KB10.29%
1/0/1.b3dm97 KB88 KB9.28%
1/1/0.b3dm70 KB61 KB12.86%
1/1/1.b3dm124 KB114 KB8.06%
2/0/0.b3dm76 KB73 KB3.95%
2/0/1.b3dm63 KB58 KB7.94%
2/0/2.b3dm46 KB43 KB6.52%
2/1/0.b3dm67 KB63 KB5.97%
2/1/1.b3dm71 KB67 KB5.63%
2/1/2.b3dm59 KB55 KB6.78%
2/1/3.b3dm45 KB43 KB4.44%
2/2/0.b3dm96 KB88 KB8.33%
2/2/1.b3dm95 KB87 KB8.42%
2/2/2.b3dm52 KB48 KB7.69%
2/3/0.b3dm94 KB86 KB8.51%
2/3/1.b3dm81 KB74 KB8.64%
2/3/3.b3dm71KB68 KB4.23%

The zoom benchmark averaged ~52 FPS over 10 seconds for both quantized and non-quantized data sets running in Chrome 51.0.2704.84 on Windows (Intel® Core™ i7-4980HQ Quad-Core @2.80GHz and AMD Radeon R9 M370X).

Entire Washington, D.C. Data Set

The whole Washington D.C. data set was quantized in this run. For brevity’s sake, I’m not going to include the level-of-detail hierarchy breakdown, just the overall statistics.

Statistics

ImageOriginalQuantizedCompression
File Size (Raw)367 MB318 MB13.35%
File Size (gzip)85.5 MB75.4 MB11.81%

The zoom benchmark averaged ~50 FPS over 10 seconds for both quantized and non-quantized data sets.

So, as with the individual models, applying the gzip does bring the quantized and non-quantized file sizes closer, but the city datasets still see a solid ~10% drop in file size and reduced GPU memory usage. Building models with more complex geometry appear to benefit more from the compression.

This can be confirmed by looking at the Northwest Cleveland Park tiles. 0/0/0.b3dm compressed the most, while 2/0/0.b3dm compressed the least.

0/0/0.b3dm

dc_quantized

2/0/0.b3dm

2/0/0.b3dm is a neighborhood with very simple house models, while 0/0/0.b3dm has buildings with more complex geometry.

The b3dm tiles include an additional field not found in normal glTF, a per-attribute uint16 Batch ID used to uniquely identify each building, which cannot be quantized and does contribute to the overall file size.

Conclusions

This is a very promising addition to glTF and to Cesium’s implementation of 3D Tiles. The zooming benchmark was unhindered by the quantization, and in the renderings there is visually no difference. A 10% drop in file size for some of these large city datasets will be a welcome addition to the growing Cesium and 3D Tiles community.

The Cesium implementation of glTF WEB3D_quantized attributes can be found in Model.js in the Cesium GitHub repo.

For the Interested Reader

A. Quantizing Compressed Texture Coordinates

This is the texture coordinate compression algorithm we use in Cesium:

var x = textureCoordinates.x === 1.0 ? 4095.0 : (textureCoordinates.x * 4096.0) | 0;
var y = textureCoordinates.y === 1.0 ? 4095.0 : (textureCoordinates.y * 4096.0) | 0;
return 4096.0 * x + y

Quantization decodes to values close to the original, but not necessarily ones that are exactly the same. The trouble here is that compressed texture coordinates that are numerically close are not necessarily close spatially once they get decompressed. This creates the distortions shown above.

B. Trade-offs between Quantization and Texture Coordinate Compression

Quantization and texture coordinate compression ideally result in 50% compression. So which one is better?

That ends up being a tough question to answer. They are both decoded by fairly simple GPU operations, so the decode performance should be a moot point. What about precision?

Compression will always preserve 12 bits of precision. The current quantization implementation doesn’t do any chunking (splitting up the model into multiple quantized parts to keep precision high), so the precision is dependent on the area being quantized.

If the texture coordinates cover a single square unit, quantization preserves 16 bits of precision and is superior to compression. At 256 square units they break even at 12 bits of precision, and if the texture coordinates cover a larger area than that, compression takes the lead in precision.

In reality, either is probably fine for most use cases.