# How to Use gltfpack Command-Line Options for glTF Optimization: A Complete Guide

> Master gltfpack command-line options to optimize glTF assets. Discover quantization, compression, and simplification techniques with this comprehensive guide.

- Repository: [Arseny Kapoulkine/meshoptimizer](https://github.com/zeux/meshoptimizer)
- Tags: how-to-guide
- Published: 2026-07-11

---

**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`](https://github.com/zeux/meshoptimizer/blob/main/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`](https://github.com/zeux/meshoptimizer/blob/main/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`](https://github.com/zeux/meshoptimizer/blob/main/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`](https://github.com/zeux/meshoptimizer/blob/main/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 `.obj` extensions)
- **`-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 setting `Settings::compress = true`
- **`-cc`**: Activates higher-ratio compression via `Settings::compressmore = true`
- **`-cz`**: Uses the KHR_meshopt_compression extension through `Settings::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) via `Settings::pos_bits`
- **`-vn N`**: Sets normal/tangent bits (1–16) via `Settings::nrm_bits`
- **`-vt N`**: Sets texture coordinate bits (1–16) via `Settings::tex_bits`
- **`-vc N`**: Sets vertex color bits (1–16) via `Settings::col_bits`

For position storage formats:
- **`-vpi`**: Integer positions (default; sets `pos_float = false; pos_normalized = false`)
- **`-vpn`**: Normalized positions (sets `pos_float = false; pos_normalized = true`)
- **`-vpf`**: Floating-point positions (sets `pos_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 via `Settings::texture_quality`
- **`-ts R`**: Scales texture dimensions by ratio R (0–1) via `Settings::texture_scale`
- **`-tl N`**: Limits maximum texture size to N pixels via `Settings::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.5` for 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`**: Retains `extras` JSON 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:

```bash
gltfpack -i model.gltf -o model_opt.gltf

```

Enable Khronos compression while preserving scene hierarchy:

```bash
gltfpack -c -ce khr -kn -i model.gltf -o model_opt.glb

```

Convert textures to high-quality UASTC and generate tangents:

```bash
gltfpack -tu -tq 10 -gt -i model.gltf -o model_opt.gltf

```

Reduce texture resolution by 50% and enforce power-of-two dimensions:

```bash
gltfpack -ts 0.5 -tp -i model.gltf -o model_opt.gltf

```

Aggressive mesh simplification to 30% of original triangles:

```bash
gltfpack -si 0.3 -sa -i model.gltf -o model_opt.gltf

```

## Summary

- **gltfpack** maps command-line arguments to a `Settings` structure in [`gltf/gltfpack.h`](https://github.com/zeux/meshoptimizer/blob/main/gltf/gltfpack.h) (lines 120–180), with parsing logic in [`gltf/gltfpack.cpp`](https://github.com/zeux/meshoptimizer/blob/main/gltf/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`](https://github.com/zeux/meshoptimizer/blob/main/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.