KHR_draco_mesh_compression provides advanced compression for mesh geometry.

For models where geometry is a significant factor (>1 MB), Draco can reduce filesize by ~95% in many cases. When animation or textures are large, other complementary compression methods should be used as well. For geometry <1MB, the size of the WASM decoder library may outweigh size savings.

Be aware that decompression happens before uploading to the GPU — this will add some latency to the parsing process, and means that compressing geometry with Draco does not affect runtime performance. To improve framerate, you'll need to simplify the geometry by reducing vertex count or draw calls — not just compress it. Finally, be aware that Draco compression is lossy: repeatedly compressing and decompressing a model in a pipeline will lose precision, so compression should generally be the last stage of an art workflow, and uncompressed original files should be kept.

A decoder or encoder from the draco3dgltf npm module for Node.js (or elsewhere for web) is required for reading and writing, and must be provided by the application.

Encoding options

Two compression methods are available: 'edgebreaker' and 'sequential'. The edgebreaker method will give higher compression in general, but changes the order of the model's vertices. To preserve index order, use sequential compression. When a mesh uses morph targets, or a high decoding speed is selected, sequential compression will automatically be chosen.

Both speed options affect the encoder's choice of algorithms. For example, a requirement for fast decoding may prevent the encoder from using the best compression methods even if the encoding speed is set to 0. In general, the faster of the two options limits the choice of features that can be used by the encoder. Setting --decodeSpeed to be faster than the --encodeSpeed may allow the encoder to choose the optimal method out of the available features for the given --decodeSpeed.

Example

import { NodeIO } from '@gltf-transform/core';
import { DracoMeshCompression } from '@gltf-transform/extensions';

import draco3d from 'draco3dgltf';

// ...

const io = new NodeIO()
    .registerExtensions([DracoMeshCompression])
    .registerDependencies({
        'draco3d.decoder': await draco3d.createDecoderModule(), // Optional.
        'draco3d.encoder': await draco3d.createEncoderModule(), // Optional.
    });

// Read and decode.
const doc = io.read('compressed.glb');

// Write and encode.
doc.createExtension(DracoMeshCompression)
    .setRequired(true)
    .setEncoderOptions({
        method: DracoMeshCompression.EncoderMethod.EDGEBREAKER,
        encodeSpeed: 5,
        decodeSpeed: 5,
    });
io.write('compressed.glb', doc);

Hierarchy

  • Extension
    • DracoMeshCompression

Properties

extensionName: "KHR_draco_mesh_compression" = ...
prereadTypes: PropertyType[] = ...
prewriteTypes: PropertyType[] = ...
readDependencies: string[] = ...

Methods

  • dispose(): void
  • Disables and removes the extension from the Document.

  • isRequired(): boolean
  • Indicates to the client whether it is OK to load the asset when this extension is not recognized. Optional extensions are generally preferred, if there is not a good reason to require a client to completely fail when an extension isn't known.

  • Indicates to the client whether it is OK to load the asset when this extension is not recognized. Optional extensions are generally preferred, if there is not a good reason to require a client to completely fail when an extension isn't known.

  • register(): void
  • Performs first-time setup for the extension. Must be idempotent.

Function symbol, f(📦) → 📦, where the argument and output are a box labeled 'glTF'.

Made by Don McCurdy TypeDoc documentation Copyright 2021 under MIT license