How to Use gltfpack Command-Line Options for glTF Optimization: A Complete Guide
gltfpack is the command-line front-end of the meshoptimizer library that optimizes glTF assets through quantization, compression, and scene simplification by mapping command-line flags to a Settings structure defined in gltf/gltfpack.h.
The gltfpack utility from the zeux/meshoptimizer repository provides a robust pipeline for reducing 3D asset file sizes while preserving runtime performance. Understanding how gltfpack command-line options translate into internal processing stages allows you to fine-tune optimization for web delivery, mobile VR, or high-fidelity desktop applications.
Understanding the gltfpack Architecture
The tool’s architecture follows a straightforward pipeline defined in gltf/gltfpack.cpp. The main() function (lines 1017–1045) handles argument parsing by iterating through argv and populating a Settings structure declared in gltf/gltfpack.h (lines 120–180). Depending on file extensions, it dispatches to parseGltf or parseObj (lines 1049–1055) before invoking the core process() function (lines 1053–1057).
The process() function orchestrates the optimization workflow, calling printMeshStats and printSceneStats when verbose flags (-v or -vv) are set. It then applies transformations guided by the Settings configuration, including quantization preparation via prepareQuantizationPosition and prepareQuantizationTexture (declared in gltfpack.h lines 166–176) before generating the final output.
Essential gltfpack Command-Line Options
All command-line switches directly map to fields in the Settings structure, controlling everything from vertex precision to texture encoding.
I/O and Basic Optimization
The fundamental flags specify input and output paths:
-i <file>: Sets the input path (accepts.gltf,.glb, or.objextensions)-o <file>: Specifies the output path (format inferred from extension)
By default, gltfpack applies integer quantization with 14-bit position precision. To adjust vertex precision or format, use the quantization flags described below.
Mesh Compression Settings
Control geometry compression through the Settings::compress* fields:
-c: Enables Draco-style mesh compression by settingSettings::compress = true-cc: Activates higher-ratio compression viaSettings::compressmore = true-cz: Uses the KHR_meshopt_compression extension throughSettings::compresskhr = true-ce khr|ext: Explicitly chooses between Khronos extension style (khr) or extensible mode (ext)
Vertex Quantization Controls
These flags populate quantization bit fields in the Settings structure, controlling attribute precision:
-vp N: Sets position bits (1–16) viaSettings::pos_bits-vn N: Sets normal/tangent bits (1–16) viaSettings::nrm_bits-vt N: Sets texture coordinate bits (1–16) viaSettings::tex_bits-vc N: Sets vertex color bits (1–16) viaSettings::col_bits
For position storage formats:
-vpi: Integer positions (default; setspos_float = false; pos_normalized = false)-vpn: Normalized positions (setspos_float = false; pos_normalized = true)-vpf: Floating-point positions (setspos_float = true)
Additional format flags:
-vtf: Forces floating-point texture coordinates (tex_float = true)-vnf: Forces floating-point normals (nrm_float = true)-vi: Enables interleaved vertex buffers (mesh_interleaved = true)
Texture Optimization
Control texture encoding and dimensions through the texture processing flags:
-tu: Encodes textures to KTX2 with UASTC (texture_ktx2 = true; texture_mode = UASTC)-tc: Encodes textures to KTX2 with ETC1S (texture_ktx2 = true; texture_mode = ETC1S)-tw: Encodes textures to WebP (texture_webp = true; texture_mode = WebP)-tq N: Sets compression quality 1–10 viaSettings::texture_quality-ts R: Scales texture dimensions by ratio R (0–1) viaSettings::texture_scale-tl N: Limits maximum texture size to N pixels viaSettings::texture_limit-tp: Resizes textures to power-of-two dimensions (texture_pow2 = true)-tfy: Flips Y-axis during BasisU compression (texture_flipy = true)-tr: Preserves original texture URIs instead of embedding (texture_ref = true)
Mesh Processing and Scene Optimization
Optimize scene structure and geometry complexity:
-gt: Generates tangent spaces (mesh_tangents = true)-mi: Converts mesh duplicates to GPU instancing (mesh_instancing = true)-mm: Merges duplicate meshes (mesh_merge = true)-mdd: Disables mesh deduplication (mesh_dedup = false)-si R: Simplifies meshes to R ratio of original triangles (e.g.,0.5for 50%)-sa: Enables aggressive simplification mode
Preservation Flags
Prevent gltfpack from removing specific data:
-kv: Keeps all vertex attributes (keep_attributes = true)-km: Preserves all material definitions (keep_materials = true)-ke: RetainsextrasJSON blocks (keep_extras = true)-kn: Preserves complete node hierarchy (keep_nodes = true)
Verbosity and Diagnostics
-v: Enables basic statistics (verbose = 1)-vv: Enables detailed statistics (verbose = 2)-h: Displays full usage information and exits
Practical gltfpack Usage Examples
Apply default optimization with integer quantization:
gltfpack -i model.gltf -o model_opt.gltf
Enable Khronos compression while preserving scene hierarchy:
gltfpack -c -ce khr -kn -i model.gltf -o model_opt.glb
Convert textures to high-quality UASTC and generate tangents:
gltfpack -tu -tq 10 -gt -i model.gltf -o model_opt.gltf
Reduce texture resolution by 50% and enforce power-of-two dimensions:
gltfpack -ts 0.5 -tp -i model.gltf -o model_opt.gltf
Aggressive mesh simplification to 30% of original triangles:
gltfpack -si 0.3 -sa -i model.gltf -o model_opt.gltf
Summary
- gltfpack maps command-line arguments to a
Settingsstructure ingltf/gltfpack.h(lines 120–180), with parsing logic ingltf/gltfpack.cpp. - Compression options (
-c,-cc,-cz,-ce) control whether Draco-style or KHR_meshopt_compression encoding is applied to geometry. - Quantization flags (
-vp,-vn,-vt,-vc) configure bit precision for vertex attributes, directly affecting memory usage and visual quality. - Texture flags (
-tu,-tc,-tw,-tq,-ts) support KTX2, WebP, and rescaling workflows for optimized texture delivery. - Scene processing (
-mi,-mm,-si) enables instancing, merging, and simplification to reduce draw calls and geometry complexity.
Frequently Asked Questions
What is the difference between -c and -cz in gltfpack?
The -c flag enables standard Draco-style mesh compression stored as a buffer extension, while -cz specifically uses the KHR_meshopt_compression Khronos extension format. According to the source code in gltfpack.cpp, -cz sets Settings::compresskhr = true, which produces glTF files compatible with the official Khronos extension rather than the legacy extensible format.
How do I prevent gltfpack from modifying my node hierarchy?
Use the -kn (keep nodes) flag to preserve the complete node hierarchy. This sets Settings::keep_nodes = true in the processing pipeline, preventing gltfpack from optimizing away empty nodes or flattening transforms during the scene optimization stage.
What quantization settings should I use for WebGL applications?
For WebGL deployment, use -vp 14 -vn 10 -vt 12 for balanced quality and size, or -vp 16 for maximum precision. The -vi flag enables interleaved vertex buffers, improving GPU cache coherency. These settings populate the Settings::pos_bits, nrm_bits, and tex_bits fields to compress vertex data while maintaining acceptable visual fidelity for real-time rendering.
Can gltfpack optimize existing glTF files without changing the file format?
Yes, gltfpack preserves the output format based on the file extension specified in -o. If you input a .gltf file and output to .gltf, it maintains the separate JSON/bin structure; outputting to .glb produces a binary glTF. Use -tr to preserve external texture references rather than embedding them, maintaining the original asset structure while still optimizing geometry and compression.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →