Texture compression

The engine uses zstd+bc7 compressed cubemap textures for faster processing in shaders and lower file sizes.

Alternatively, you can skip compression altogether and use toktx instead.

You may wish to do so when:

  • Banding may appear if the image has a lots of smooth gradients.
  • GPU codecs operate on 2x2 blocks. It may turn out your image has an unlucky alignment resulting in massive loss of precision.
  • Compression codec may misinterpret data in semi-transparent images.
  • Using basisu results in a crash or something likewise bad and you won’t be bothered with that.

Using KTX format is important however and you get mipmaps for free.

Since KTX is merely a metadata format, it contains raw bitmap data and requires an extra file compression step to prevent files from growing huge. The engine can deal with any zstd-compressed files transparently to other codecs so you can have best of both worlds.

1. Apply GPU compression

Use patched Basis Universal tool: https://gitlab.com/dpwiz/basis_universal

Due to https://github.com/BinomialLLC/basis_universal/issues/227

You can skip this and use a recent mainstream basisu binary and just delete extra files after transcoding.

For flat textures:

basisu \
  -mipmap \
  -uastc -uastc_level 4 \
  \
  flat.png

Use -linear when compressing things like normal maps.

For cubemaps:

Use online converter if you need to get PNG input images: https://jaxry.github.io/panorama-to-cubemap/

basisu \
  -mipmap \
  -tex_type cubemap \
  -uastc -uastc_level 4 \
  right.png left.png top.png bottom.png front.png back.png # the order is important

2. Transcode to KTX format

basisu -unpack -ktx-only -format-only 6 right.basis

To upgrade from v1 KTX+Zstd containers simply unpack them and follow along.

zstd -d *.ktx.zst

Caveat: if your source was written in sRGB format, you will need to change the format from 0x91 to 0x92 in resulting KTX2 file.

3. Apply file compression

First, convert to KTX2 container, which allows supercompression.

ktx2ktx2 *.ktx

Then apply Zstd supercompression to the block data. Unlike using whole-file compression, this leaves metadata open for inspection.

ktxsc -z 19 *.ktx2

Some clean up…

rm right_*.png *.ktx

Ready, ship your .ktx2 file!

mv \
  right_transcoded_cubemap_BC7_RGBA_0.ktx2 \
  ../../../resources/cubemaps/env.ktx2
Links to this page