← Back to Blog guide

GLTF extensions for game assets: KHR_draco, EXT_mesh_gpu_instancing, and engine support

By BitSoul Team7/1/2026Updated 8/1/20265 min read48 views
GLTF extensions for game assets: KHR_draco, EXT_mesh_gpu_instancing, and engine support

Every GLB file you download from BitSoul's marketplace is already GLTF 2.0 under the hood — but vanilla GLTF is just the baseline. Extensions are where the format gets genuinely useful for game production: mesh compression that cuts transfer sizes by 80 %, per-instance transform data that lets a single draw call scatter a thousand props, and material variants that swap skins without extra geometry. The problem is that engine support is fragmented and poorly documented. This guide maps what's actually implemented, what still requires manual workarounds, and how to bake the right extensions into your export pipeline.

What GLTF extensions are and why they matter for game pipelines

GLTF separates the core spec from optional features through a formal extension system. A file declares which extensions it uses in the `extensionsUsed` array and which are non-negotiable in `extensionsRequired`. Importers that don't recognise a required extension must reject the file; optional extensions can be silently ignored.

For game developers, this matters because it means a single `.glb` file can carry compressed geometry, instancing hints, and material variants — all without breaking importers that don't support those features. You build one asset, tag it correctly, and let each engine pick up what it understands.

What GLTF extensions are and why they matter for game pipelines — illustrated

The extension landscape breaks into three practical tiers for game artists:

| Tier | Extensions | Status |
|------|-----------|--------|
| Broadly supported | `KHR_materials_unlit`, `KHR_texture_transform` | Unity, UE5, Godot 4 |
| Widely supported | `KHR_draco_mesh_compression`, `KHR_materials_variants` | Unity (via package), Godot 4 native, UE5 plugin |
| Limited / experimental | `EXT_mesh_gpu_instancing`, `KHR_mesh_quantization` | Godot 4 only (partial), manual in Unity/UE5 |

KHR_draco_mesh_compression — shrink assets for faster loads

Draco is Google's open-source mesh compression library. When the `KHR_draco_mesh_compression` extension is applied, vertex buffers are replaced with a Draco-encoded bitstream that typically shrinks geometry data 70–90 % compared to uncompressed GLTF. For a 500-polygon prop, the difference is barely measurable; for a dense environment mesh with 200 k triangles, you can drop from 8 MB to under 1 MB.

KHR_draco_mesh_compression — shrink assets for faster loads — illustrated

Exporting with Draco from Blender

Blender's built-in GLTF exporter supports Draco natively since Blender 3.3. Enable it under Export → GLTF 2.0 → Geometry → Compression:

```python
# Via bpy for batch export
import bpy

bpy.ops.export_scene.gltf(
filepath="/output/prop.glb",
export_format='GLB',
export_draco_mesh_compression_enable=True,
export_draco_mesh_compression_level=6, # 0–10; 6 is a good default
export_draco_position_quantization=14, # bits; 14 = near-lossless
export_draco_normal_quantization=10,
export_draco_texcoord_quantization=12,
)
```

Quantization trade-offs: lower bit counts = smaller files but visible vertex snapping. For props viewed from 5+ metres, 10-bit position quantization is often acceptable; for hero assets or characters, stay at 14 bits or higher.

Engine support

```bash
# Pre-decompress for UE5 (requires @gltf-transform/cli)
npx @gltf-transform/cli decompress input_draco.glb output_plain.glb
```

EXT_mesh_gpu_instancing — scatter props with a single draw call

`EXT_mesh_gpu_instancing` embeds per-instance transform data (translation, rotation, scale) directly in the GLTF buffer. A single mesh node can describe thousands of placed instances with one accessor — an approach that maps cleanly to GPU instanced rendering and dramatically cuts CPU draw-call overhead.

EXT_mesh_gpu_instancing — scatter props with a single draw call — illustrated

The extension works by adding an `extensions` block to a mesh node that references three `VEC3`/`VEC4` accessors for TRS data:

```json
{
"name": "rocks_scattered",
"mesh": 0,
"extensions": {
"EXT_mesh_gpu_instancing": {
"attributes": {
"TRANSLATION": 1,
"ROTATION": 2,
"SCALE": 3
}
}
}
}
```

Engine support

Engine support matrix: Unity, Unreal Engine 5, and Godot 4

The table below covers extensions relevant to assets from BitSoul's marketplace. "Native" means the built-in importer handles it without plugins.

| Extension | Unity (GLTFast) | Unreal Engine 5 | Godot 4 |
|-----------|----------------|-----------------|---------|
| `KHR_draco_mesh_compression` | ✅ v6+ | ❌ (glTFRuntime plugin) | ✅ native |
| `KHR_mesh_quantization` | ✅ v6+ | ❌ | ✅ native |
| `KHR_materials_variants` | ✅ v6+ | ❌ (plugin) | ✅ native |
| `EXT_mesh_gpu_instancing` | ✅ v6.2+ | ❌ | ⚠️ partial |
| `KHR_texture_transform` | ✅ | ✅ | ✅ |
| `KHR_materials_unlit` | ✅ | ✅ | ✅ |
| `KHR_lights_punctual` | ✅ | ✅ | ✅ |

Recommended export presets by target engine

For Godot 4 or Unity (GLTFast): Export from Blender with Draco enabled at level 6, position quantization 14 bits, texture transform if you use tiling. Tag `extensionsRequired` only for Draco.

For Unreal Engine 5: Export standard GLB without Draco. Use `gltf-transform` to strip unsupported extensions before import, or work from a pre-optimised FBX for the UE5 pipeline until Epic ships native Draco support.

For multi-engine distribution: Keep two exports — a Draco-compressed GLB for Godot/Unity and a plain GLB for UE5. Name them `prop_draco.glb` and `prop.glb` respectively.

Getting started with GLTF extensions today

Most assets on BitSoul's marketplace ship as plain GLB without extensions applied — which means maximum compatibility across all importers. Apply Draco compression as a post-process step in your own pipeline using `gltf-transform compress`:

```bash
npm install -g @gltf-transform/cli
gltf-transform compress --draco.method edgebreaker input.glb output_draco.glb
```

Check what extensions a file currently declares before importing:

```bash
python3 -c "
import struct, json, sys
with open(sys.argv[1], 'rb') as f:
f.read(12) # skip header
chunk_len = struct.unpack('<I', f.read(4))[0]
f.read(4) # chunk type JSON
data = json.loads(f.read(chunk_len))
print('extensionsUsed:', data.get('extensionsUsed', []))
print('extensionsRequired:', data.get('extensionsRequired', []))
" your_asset.glb
```

Understanding which extensions your target engine actually supports — not just which ones the exporter can produce — is the most reliable way to avoid silent import failures and unexpected runtime behaviour.

---

*This post is part of the Ultimate Guide to Free 3D Game Assets — BitSoul's complete reference for formats, texturing, rigging, optimization, and engine integration.*

Tags: game-assets optimization unity unreal godot 3d-models workflow

Skip the modelling — download it instead

A free BitSoul account gets you 2 game-ready models every month plus 25 AI Engine credits to generate one of your own, no card required. Clean topology, PBR textures, and GLB downloads that drop straight into Unreal, Unity, Godot or Blender — plus OBJ and 3D-printable STL export.

Create a free account → Browse 846 models