The engine uses zstd+bc7 compressed cubemap textures for faster processing in shaders and lower file sizes.
A nice primer on compressed textures: https://www.reedbeta.com/blog/understanding-bcn-texture-compression-formats/
Preparing
Get a package from https://github.com/KhronosGroup/KTX-Software/releases
You should get a bag of binaries named like ktx*, copy them to your ~/.local/bin.
Now you can convert and compress textures in one go by piping ktx create to ktx transcode.
Converting
If you have electricity/time to spare, throw in
--uastc-quality 4 --uastc-rdooptions.
Albedo maps / regular textures.
Those are typically srgb and should remain as that. Use bc7 codec.
ktx create \
--encode uastc \
--assign-tf srgb \
--format R8G8B8A8_SRGB \
--generate-mipmap \
source.png \
- | \
ktx transcode \
--target bc7
--zstd 22 \
- \
output.ktx2Cubemaps
The key thing here is the file order in input.
ktx create \
--encode uastc \
--assign-tf srgb \
--format R8G8B8_SRGB \
--generate-mipmap \
--cubemap \
{right,left,top,bottom,front,back}.png \
- | \
ktx transcode \
--target bc7
--zstd 22 \
- \
output.ktx2
For HDR maps you actually should use the bc6h codec, but it is rarely available.
Normals / linear textures
This one may need some fiddling. Depending on the original format and encoding you may have to convert it to a linear colorspace or not. Try different settings and see.
Using sRGB-encoded textures (get to linear space in the shader):
ktx create \
--encode uastc \
--assign-tf srgb \
--generate-mipmap \
--format-
source.png \
- | \
ktx transcode \
--target bc7
--zstd 22 \
- \
output.ktx2Using linear-encoded texture (no conversion) and 2-channel maps (recover z in the shader):
ktx create \
--encode uastc \
--assign-tf srgb \
--convert-tf linear \
--format R8G8_UNORM \
--normalize \
--generate-mipmap \
source.png \
- | \
ktx transcode \
--target bc5 \
--zstd 22 \
- \
output.ktx2Raw
You can skip compression altogether by transcoding into one of the r8 | rg8 | rgb8 | rgba8 formats.
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 the tools results in a crash or something likewise bad and you won’t be bothered with that.