Skip to main content

Terrain Quantization

In Cesium 1.17, which will be released on January 4, 2016, we have reduced the amount of GPU and CPU memory used by terrain. The overall amount of CPU memory used has been reduced by up to 40%. Once a mesh is created for the quantized mesh or height map terrain data, it is uploaded to the GPU for rendering, but also kept in CPU memory for picking. The mesh is now compressed using quantization.

Quantization is the process of constraining a set of values to a smaller set of values. In short, the smaller the range of a value, the fewer the number of bits needed to represent that value before there is any noticeable error.

The image above shows a terrain tile enclosed in an oriented bounding box. Instead of representing the terrain vertices in Earth-fixed coordinates, we can represent them in the coordinate frame of the oriented bounding box. Now the terrain vertices are in the range of the maximum and minimum corners of the box. The smaller the box is, the fewer number of bits are needed to store a vertex.

Once it is determined if a mesh can be quantized, each vertex is transformed to the box’s frame and scaled to be in the range [0, 1]. Essentially, each vertex is multiplied by a matrix. Then the attributes are packed into as few floating-point numbers as possible. For information on packing vertex attributes, see the Vertex Compression blog post.

Here's the amount of memory used for a mountainous view with the camera at a height of 3,600 meters and a pitch of -15 degrees:

memoryuncompressed (Cesium 1.16)compressed (Cesium 1.17)
CPU428,552K224,368K
GPU252,024K216,600K

Here's the amount of memory used for a flat view with the camera at a height of 490 meters and a pitch of 0 degrees:

memoryuncompressed (Cesium 1.16)compressed (Cesium 1.17)
CPU426,096K231,200K
GPU192,020K189,776K

Of course there are minor trade-offs that impact CPU and GPU performance. The terrain vertices are decompressed on the fly when picking a tile, and each vertex has to be decompressed on the GPU for rendering.

Currently, there is only one level of compression. In the future, we can add different levels of compression at different levels of the quadtree.