draco-gltf
Load and save full glTF scenes with Draco-compressed geometry.
draco-gltf is a thin bridge between gltf
(gltf-rs), which models the whole glTF scene — materials, textures, nodes,
animations, skins, lights, and arbitrary extensions — and the Draco crates:
- decode uses
draco-coreto decompressKHR_draco_mesh_compressiongeometry; - encode reuses
draco-io's document-preserving compressor core, so the compression logic lives in exactly one place — while reading the geometry to compress through gltf-rs, so it depends ondraco-iowith only its writer, never its glTF reader.
It exists because neither side does the whole job alone: gltf-rs does not decode
Draco (its validator even rejects a Draco asset, since
KHR_draco_mesh_compression is a required extension it does not implement),
while the Draco crates intentionally do not model the rest of a glTF scene.
[]
= "0.1"
Load a scene and decode geometry
let scene = import?;
// The full scene is available through the gltf-rs API.
println!;
// Decode the Draco-compressed geometry.
for in scene.draco_primitives
# Ok::
Transparent reading
If you would rather not deal with Draco at all, decompress_in_place replaces
every Draco primitive with plain geometry, after which the normal gltf-rs reader
works on the whole document:
let mut scene = import?;
scene.decompress_in_place?; // Draco primitives become ordinary geometry
for mesh in scene.document.meshes
# Ok::
Compress a scene back to Draco
let scene = import?;
let bytes = compress?;
write?;
# Ok::
compress preserves everything the geometry change does not touch — materials,
textures, images, nodes, animations, skins, extras, and unknown extensions. It
runs draco-io's shared document-preserving compressor core, decoding the
geometry to compress straight from the gltf-rs accessors through draco-io's
reader-agnostic decode_geometry. So there is a single compression path, and
draco-gltf depends on draco-io with only its gltf-writer feature — not its
glTF reader (gltf-rs already parses the document).
Validation
gltf-rs's own validator rejects Draco assets outright (it treats
KHR_draco_mesh_compression as an unsupported required extension). import
therefore runs Draco-aware validation: full gltf-rs validation with only the
expected Draco errors filtered out (the unsupported-extension error, and the
"missing bufferView" on accessors whose data comes from the Draco stream). A
structurally invalid asset — out-of-range indices, malformed accessors — is
still rejected. The validation is also panic-safe: gltf-rs 1.4's validator can
panic on a primitive that references an out-of-range accessor, so validate
pre-checks those references and returns a controlled Error::Validation before
the panic can happen (this holds even on wasm targets built with
panic = "abort", where catch_unwind would not). Use
draco_gltf::validate(&document) to check a document you built yourself.
WebAssembly
draco-gltf works on wasm32 for native-Rust web apps that want the full glTF
scene model in the browser. Use the byte API — [import_slice], [compress],
and [Import::decompress_in_place] — since the filesystem [import] is
native-only. Fetch the glTF/GLB bytes (and any external resources) yourself and
pass them in. For plugging a Draco decoder into a JavaScript glTF loader instead
(three.js, babylon, …), use draco-core directly.
Features
image(default): decode embedded/external images into pixels via gltf-rs, exposing them asImport::images. This pulls theimagecrate (PNG/JPEG codecs), which is the largest part of the build. Disable it withdefault-features = falsewhen you only need geometry and the scene model — e.g. on wasm, where the host usually decodes textures. Without it, images are not decoded,Import::imagesis absent, and a small built-in loader resolves buffers (data URIs and the GLB BIN chunk; external files only with a base path). Measured size-optimized wasm: ~384 KB → ~279 KB gzip withoutimage.
glTF 2.1
These crates target glTF 2.0. glTF 2.1 (announced 2026, backward-compatible) is not implemented yet, but a 2.1 asset is handled safely — 2.0 content is supported, new scene-level content is preserved, and attributes using new 2.1 component types are kept verbatim rather than corrupted. See GLTF_2_1.md.
Where it sits
| Crate | Role | depends on gltf-rs |
|---|---|---|
draco-core |
raw .drc bitstream |
no |
draco-io |
container plumbing + document-preserving compressor | no |
draco-gltf |
full-scene load/save bridging gltf-rs ↔ Draco | yes (only here) |
If you only need raw .drc or geometry-level glTF I/O, use draco-core /
draco-io directly and skip the gltf-rs dependency.
License
Apache-2.0.