# KTX2 Compressed Textures

> Learn advanced texture compression with KTX2 support in Babylon.js.

Source: https://doc.babylonjs.com/features/featuresDeepDive/materials/using/ktx2Compression

## Introduction

![Compression](https://doc.babylonjs.com/img/resources/gpu_compressed_textures/compression_cesar.webp)

Using GPU compressed textures is becoming more and more important in the computer graphics / gaming world because it allows you to use more assets within the same memory budget and provides better performance by reducing cache misses on the GPU side.

Note that we are speaking about **GPU compressed textures**, meaning textures that remain compressed on the GPU. That's different from a `.png` or `.jpg` file, for example, which also holds compressed data but must be expanded before being sent to the GPU.

## Working with compressed texture formats

![Container](https://doc.babylonjs.com/img/resources/gpu_compressed_textures/container.webp)

There are a number of compression formats used by the industry (ASTC, DXT, PVRTC, etc), and depending on your device it will generally support only a (small) subset of them : see [the table here](https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/mutliPlatTextures#khronos-texture-container-format--ktx-files) for more details. So, to support a wide range of devices, you would need to provide your assets in multiple different formats and Babylon.js would choose the right one depending on the capability of the target device.

It can be a bit tedious to generate and maintain so many formats for a given asset, so **container files** have been created. These files can either contain multiple formats of the same asset or be transcodable to multiple formats. Because this is the subject of this article, we are going to deal with the **KTX2 container file format**.

## KTX2 container

![KTX2](https://doc.babylonjs.com/img/resources/gpu_compressed_textures/ktx2.webp)

**KTX** stands for **Khronos Texture Container** and the current incarnation is [v2.0](http://github.khronos.org/KTX-Specification/#basisu_gd) (we won't discuss version 1), and the associated file format extension is **.ktx2**.

This file does not in fact contain different formats of the same asset, but rather a **universal representation** of the data that can be transcoded to any format supported by the target device! We speak of **transcoding** instead of **expanding** because the data are not expanded per se; they are transformed into another compressed format, one supported by your target device (the universal representation is itself compressed).

Currently, the universal representation is generated by using a compression algorithm known as [Basis Universal](https://github.com/BinomialLLC/basis_universal#basis_universal), or **BasisU** for short, created by a company named Binomial. This algorithm supports two modes :

- **ETC1S** : original low/medium quality mode, produces lower file sizes. Works best on images, photos, map data, or albedo/specular/etc. textures, but does not work as well on data that are not true color data (like normal maps, metallic/roughness maps, etc.)
- **UASTC** : high quality mode, can be used on any type of texture, even for non-color data maps

On top of this compression, the data can be further compressed in the UASTC case by using a [Zstandard](https://facebook.github.io/zstd/) compression scheme. Note, however, that this additional compression pass can lead to smaller `.ktx2` file sizes but not smaller GPU compressed textures! The data compressed with Zstandard will be expanded on the CPU side and then transcoded to a GPU texture.

Note that `.ktx2` files can also store GPU-compressed non-universal data, but as far as Babylon.js is concerned, it only deals with the ETC1S and UASTC universal compression schemes listed above.

## Babylon.js support for .ktx2 files

![KTX2](https://doc.babylonjs.com/img/resources/gpu_compressed_textures/breeze.webp)

On the **Babylon.js** side, using such files is a breeze: just create a Texture instance that points to the `.ktx2` file you want to use, as you would with any other standard picture format (`png`, `jpg`, etc.)!

The KTX2 format is also used in the **glTF** world by means of the [KHR_texture_basisu extension](https://github.com/KhronosGroup/glTF/pull/1751) : this extension simply enables you to use .ktx2 files for the images used by your .gltf/.glb files and is supported by Babylon.js.

The KTX2 implementation of Babylon.js is developed as an external package (the [KTX2 decoder](https://github.com/BabylonJS/Babylon.js/tree/master/ktx2Decoder)) designed to be small (the minified .js file is less than 22kb) and efficient. Depending on the universal representation of the data in the .ktx2 file and the compressed formats supported by the target device, the right module is used for the transcoding. Whenever possible, the [Universal Texture Transcoders](https://github.com/KhronosGroup/Universal-Texture-Transcoders) (UTT) are used, as they are both very fast and small. For transcoding formats not supported by the UTTs (yet), the [MSC Basis Transcoder](https://github.com/KhronosGroup/KTX-Software/releases) module is used instead.

_Note_ : you may have already encountered or heard of **.basis** files. Those files use the same compression scheme as `.ktx2` files, but this format is not backed by any standards committee, unlike the KTX2 format. So, you should prefer the latter, as it will become the de-facto standard.

## Tools

![Tools](https://doc.babylonjs.com/img/resources/gpu_compressed_textures/tools.webp)

Now that you know why you should use `.ktx2` files, you will need to actually generate them!

Khronos provides [command line tools](https://github.com/KhronosGroup/KTX-Software/releases) that you can use to generate, check, and dump `.ktx2` files:

- **toktx.exe** is the primary tool, used to generate .ktx2 files from .png, .jpg files. There are a handful of options, just type **toktx.exe** to display them
- **ktxinfo.exe** will display useful data in human readable form about a .ktx2 file
- **ktx2check.exe** will check that your .ktx2 file is a valid file
- **ktxsc.exe** will allow you to update some parameters of an existing .ktx2 file (change the compression scheme, add a Zstandard compression, etc)

_Happy compressing!_

![KTX2](https://doc.babylonjs.com/img/resources/gpu_compressed_textures/compression.webp)
