# Export guidelines

> Learn how to export optimized models with the lightest file size using GLB, Draco and KTX2 compression.

## Why focus on export file size?

After preparing, repairing, and optimizing your 3D models, the final step is exporting them in a format optimized for your target platform. Export file size directly impacts:

* **Load times** - Smaller files download and load faster, especially critical for web applications
* **Bandwidth costs** - Reduced file sizes lower hosting and transmission costs
* **User experience** - Faster initial loading improves perceived application performance
* **Mobile support** - Smaller files are essential for devices with limited bandwidth or storage

The GLB format with Draco compression provides the best combination of compatibility, file size reduction, and runtime performance for real-time applications.

> **Note:**
>
> **Don't compare file sizes across different formats** - A STEP or CATIA file before import and optimization may be smaller than the exported FBX or GLB file, but this comparison is meaningless. [BREP files](./3d-models) store parametric representations using mathematical formulas (curves, surfaces, equations), while [mesh files](./3d-models) store discrete vertex positions, normals, and UV coordinates to represent the same geometry. This is similar to comparing vector graphics to raster images, or SVG to PNG - they fundamentally represent data differently. The file size increase is expected and necessary for real-time rendering.

## 1. Prepare your model for export

Before exporting, ensure your model has been properly optimized. The more you optimize before export, the lighter your final file will be.

### Reduce polygon count

Lower polygon counts directly reduce file size. The mesh geometry data (vertices, normals, UVs) is typically the largest component of exported files.

Use decimation and occluded geometry removal to reduce triangle count while preserving visual quality.

[Optimization guidelines](./optimization-guidelines): Learn how to reduce polygon count through decimation and occluded geometry removal.


> **Note:**
>
> Each triangle reduction directly translates to smaller file size. A 50% polygon reduction typically results in approximately 40-45% file size reduction.

### Reduce the number of unique meshes

The number of unique meshes in your scene affects file size. Mesh data must be stored for each unique geometry.

**Use instancing to reduce unique mesh count** - Instancing is one of the most effective ways to reduce file size. When multiple objects share the same mesh (instances), only one copy of the mesh data needs to be stored in the exported file.

[Repair instances](/asset-transformer-sdk/2026.4/api/python/algo_functions.md#convertsimilarpartoccurrencestoinstancesfast): Recreate instances to reduce unique mesh count.


> **Tip:**
>
> Instancing is particularly effective for repeated elements like bolts, screws, or architectural components. A scene with 1000 bolts using instancing stores only one bolt mesh instead of 1000, dramatically reducing file size.

> **Important:**
>
> **Avoid merging meshes** - While merging can reduce draw calls, it destroys instances and actually **increases file size** because each merged mesh must store duplicate geometry data. Merging also increases memory usage and can prevent culling optimizations. Preserve instances whenever possible for the smallest export file size.

See the [optimization guidelines](./optimization-guidelines) for detailed information on polygon reduction and mesh optimization techniques.

## 2. Export to GLB format

The GLB (binary glTF) format is the recommended export format for real-time applications, especially web-based 3D experiences. GLB offers:

* **Industry standard** - Supported by all modern web browsers and 3D engines
* **Efficient binary format** - Geometry, textures, and animations in a single file
* **Draco compression support** - Built-in support for mesh compression
* **PBR materials** - Physical Based Rendering material support
* **Animation support** - Skeletal animations and morph targets

> **Tip:**
>
> For Unity projects, use the [glTFast package](https://github.com/atteneder/glTFast) to load GLB files quickly in both Editor and at Runtime. glTFast provides high-performance GLB/glTF import with full support for Draco mesh compression and KTX2 texture compression, making it ideal for loading the optimized GLB files exported from Pixyz.

### Basic GLB export

Use [io.exportScene](/asset-transformer-sdk/2026.4/api/python/io_functions.md#exportscene) to export your optimized model to GLB format:

```python
# Export the entire scene to GLB
io.exportScene("output/optimized_model.glb")
```

## 3. Enable Draco compression

[Draco compression](https://google.github.io/draco/) is a mesh compression technology that dramatically reduces file size for GLB exports. Draco compresses vertex positions, normals, texture coordinates, and other mesh attributes.

> **Important:**
>
> Draco compression can reduce GLB file sizes by **70-90%** compared to uncompressed GLB files, with minimal visual quality loss.

### How Draco compression works

Draco uses quantization and entropy coding to compress mesh data:

1. **Quantization** - Reduces precision of vertex attributes (positions, normals, UVs) from 32-bit floats to fewer bits
2. **Entropy encoding** - Compresses the quantized data using efficient encoding algorithms
3. **Decompression** - The client (browser, engine) decompresses the mesh at load time

The result is significantly smaller files with a small, one-time decompression cost during loading.

### Enable Draco export

To export GLB files with Draco compression, enable the `ExportGLTFDraco` module property before exporting:

```python
# Enable Draco compression for GLB export
core.setModuleProperty("IO", "ExportGLTFDraco", "True")

# Export with Draco compression enabled
io.exportScene("output/compressed_model.glb")
```

### Draco compression settings

Draco compression can be fine-tuned using module properties. These settings control both the compression level and the quantization precision for different vertex attributes:

```python
# Enable Draco compression
core.setModuleProperty("IO", "ExportGLTFDraco", "True")

# Set compression level (0-10, default: 7)
core.setModuleProperty("IO", "GLTFDracoCompressionLevel", "7")

# Configure quantization bits for vertex attributes
core.setModuleProperty("IO", "GLTFDracoQuantizationPosition", "11")      # Position (default: 11)
core.setModuleProperty("IO", "GLTFDracoQuantizationNormal", "8")         # Normals (default: 8)
core.setModuleProperty("IO", "GLTFDracoQuantizationTexCoord", "10")      # UVs (default: 10)
core.setModuleProperty("IO", "GLTFDracoQuantizationVertexColor", "8")    # Vertex colors (default: 8)
```

[Module Properties Reference](../preferences): See the complete list of available module properties and their default values.


**Compression level guidelines:**

| Level | Compression speed | File size | Use case                            |
| ----- | ----------------- | --------- | ----------------------------------- |
| 0-3   | Fastest           | Larger    | Quick iterations, testing           |
| 4-7   | Balanced          | Good      | Production use (recommended)        |
| 8-10  | Slowest           | Smallest  | Final delivery, maximum compression |

> **Tip:**
>
> Start with compression level 7 (default) for a good balance between file size and compression time. Only increase to 8-10 for final deliverables where file size is critical.

### Quantization guidelines

Quantization reduces attribute precision to save space. Choose appropriate bit depths based on your quality requirements:

**Position quantization:**

* 11 bits - Default, good balance for most models
* 14 bits - Higher precision for detailed models
* 8-10 bits - Maximum compression, acceptable for low-precision models

**Normal quantization:**

* 8 bits - Default, sufficient for smooth lighting in most cases
* 10 bits - Higher quality normals for detailed surfaces
* 6-7 bits - Maximum compression with potential lighting artifacts

**UV quantization:**

* 10 bits - Default, good balance for most textures
* 12 bits - Higher precision for detailed textures
* 8 bits - Maximum compression, acceptable for simple textures

**Vertex color quantization:**

* 8 bits - Default, standard color precision

> **Note:**
>
> Higher quantization bits = better quality but larger file size. Lower quantization bits = more compression but potential visual artifacts. The defaults (Position: 11, Normal: 8, UV: 10, Vertex Color: 8) provide a good balance for most use cases.

## 4. Optimize textures for export

Textures can significantly increase file size. While Draco compresses mesh geometry, textures require separate optimization.

### Reduce texture resolution

Lower resolution textures using [material.resizeImage](/asset-transformer-sdk/2026.4/api/python/material_functions.md#resizeimage) reduce file size dramatically:

```python title="Python"
# Resize all images to a maximum resolution

# Get all images in the scene
images = material.getAllImages()

# Define maximum texture size
MAX_SIZE = 2048

# Resize each image if it exceeds the maximum size
for image in images:
    width, height = material.getImageSize(image)
    width = size["width"]
    height = size["height"]

    # Check if resizing is needed
    if width > MAX_SIZE or height > MAX_SIZE:
        # Calculate new dimensions while maintaining aspect ratio
        if width > height:
            new_width = MAX_SIZE
            new_height = int((height / width) * MAX_SIZE)
        else:
            new_height = MAX_SIZE
            new_width = int((width / height) * MAX_SIZE)

        # Resize the image
        material.resizeImage(image, new_width, new_height)

```

| Resolution | Use case                        | File size impact |
| ---------- | ------------------------------- | ---------------- |
| 4096x4096  | Desktop, high-end applications  | Very large       |
| 2048x2048  | Desktop, VR, high-quality web   | Large            |
| 1024x1024  | Mobile, standard web            | Medium           |
| 512x512    | Low-end mobile, distant objects | Small            |

### Use KTX2 texture compression

[KTX2](https://www.khronos.org/ktx/) with [Basis Universal](https://github.com/BinomialLLC/basis_universal) compression is the recommended texture format for GLB exports. KTX2 provides GPU-compressed textures that dramatically reduce file size while maintaining good visual quality.

**Why use KTX2 for GLB exports:**

* **Dramatically smaller files** - 70-90% texture size reduction compared to PNG/JPEG
* **GPU-ready format** - Textures can be uploaded directly to GPU without decompression
* **Universal compatibility** - Transcodes to platform-specific formats (ETC, BC, ASTC) at runtime
* **Complements Draco** - Draco compresses geometry, KTX2 compresses textures
* **glTF standard** - Part of the official glTF 2.0 specification

> **Important:**
>
> Using KTX2 textures with Draco mesh compression provides the best possible file size reduction for GLB exports. This combination is specifically designed for web and real-time applications.

#### Enable KTX2 texture export

Set the texture export format to KTX2 before exporting:

```python
# Enable KTX2 texture format for GLB export
core.setModuleProperty("Material", "ExportTextureFormat", "KTX2")

# Configure KTX2 quality (1-255, default: 128)
# Lower values = smaller files, lower quality
# Higher values = larger files, better quality
core.setModuleProperty("Material", "KtxQuality", "[128, 1, 255]")

# Configure KTX2 compression level (1-5, default: 2)
# 1 = Fastest compression, larger files
# 5 = Slowest compression, smallest files
core.setModuleProperty("Material", "KtxCompression", "[2, 1, 5]")
```

**KTX2 quality guidelines:**

| Quality | File size | Visual quality | Use case                       |
| ------- | --------- | -------------- | ------------------------------ |
| 255     | Largest   | Excellent      | High-fidelity visualization    |
| 128     | Medium    | Good           | Production use (recommended)   |
| 64      | Small     | Acceptable     | Web, mobile with size priority |
| 32      | Smallest  | Low            | Maximum compression needed     |

**KTX2 compression level guidelines:**

| Level | Speed   | File size | Use case                          |
| ----- | ------- | --------- | --------------------------------- |
| 5     | Slowest | Smallest  | Final delivery, maximum reduction |
| 2-3   | Medium  | Good      | Production use (recommended)      |
| 1     | Fastest | Larger    | Quick iterations, testing         |

> **Tip:**
>
> Start with quality 128 and compression level 2 for a good balance. For web applications where file size is critical, try quality 64-96 with compression level 4-5.

> **Note:**
>
> KTX2 is specifically designed for GLB/glTF exports. For other formats (FBX, OBJ, USD), use PNG for textures with alpha channels and JPEG for color-only textures.

### Alternative texture formats

If not using KTX2, choose the appropriate format based on your export format:

**PNG** - Lossless compression, supports transparency

```python
core.setModuleProperty("Material", "ExportTextureFormat", "PNG")
core.setModuleProperty("Material", "PngCompression", "[6, 0, 9]")  # 0-9, higher = smaller
```

**JPEG** - Lossy compression, no transparency, smaller than PNG

```python
core.setModuleProperty("Material", "ExportTextureFormat", "JPEG")
core.setModuleProperty("Material", "JpegQuality", "[85, 0, 100]")  # 0-100, higher = better
```

[Export Textures](../io/export-textures): Learn more about texture export formats and settings.


### Remove unused textures

Delete textures that aren't actually used in your scene:

```python
# Merge duplicated images
scene.mergeImages()
# Remove unreferenced images
scene.cleanUnusedImages()
```

## 5. Export workflow example

Here's a complete workflow that combines optimization and export with Draco compression:

```python title="Python"
# Export to GLB with Draco and KTX2 compression for lightweight files

# Merge duplicated images
scene.mergeImages()

# Remove unreferenced images
scene.cleanUnusedImages()

# Resize all images to maximum 2048x2048
MAX_SIZE = 2048
images = material.getAllImages()
for image in images:
    width, height = material.getImageSize(image)
    if width > MAX_SIZE or height > MAX_SIZE:
        if width > height:
            new_width = MAX_SIZE
            new_height = int((height / width) * MAX_SIZE)
        else:
            new_height = MAX_SIZE
            new_width = int((width / height) * MAX_SIZE)
        material.resizeImage(image, new_width, new_height)

# Enable Draco compression for mesh geometry
core.setModuleProperty("IO", "ExportGLTFDraco", "True")

# Enable KTX2 compression for textures
core.setModuleProperty("Material", "ExportTextureFormat", "KTX2")

# Export to GLB format with Draco and KTX2 compression enabled
io.exportScene("optimized_model.glb")

```

## File size comparison

Here's what you can expect from following these guidelines:

| Export configuration                            | Relative file size | Use case                |
| ----------------------------------------------- | ------------------ | ----------------------- |
| FBX (unoptimized)                               | 100%               | Baseline                |
| GLB (unoptimized, no compression)               | 80%                | Better than FBX         |
| GLB (optimized, no compression)                 | 40%                | Mesh optimization only  |
| GLB (unoptimized, Draco only)                   | 25%                | Compression without opt |
| GLB (optimized, Draco only)                     | 10-15%             | Good file size          |
| GLB (optimized, Draco + KTX2) **← Recommended** | 5-10%              | Best file size          |

> **Important:**
>
> Combining optimization + Draco compression + KTX2 textures typically achieves **90-95% file size reduction** compared to uncompressed, unoptimized exports. This is the recommended configuration for web and mobile applications.
