Saturday, January 23, 2021

How to benchmark or use the UASTC encoder in the Basis Universal library

UASTC is a subset of LDR ASTC 4x4, 4x4 block size, always 8bpp, and very high quality. If your engine/product/benchmark supports BC7 or LDR ASTC 4x4, trying out our UASTC encoder/transcoder (without using .basis or .KTX2 at all) is pretty simple:

Compile/link in the Basis Universal encoder and transcoder .cpp files (or put them into libs). Call basisu_encoder_init() at startup.

To encode 4x4 blocks to the 8bpp UASTC format, call encode_uastc():
https://github.com/BinomialLLC/basis_universal/blob/master/encoder/basisu_uastc_enc.h

To decode UASTC blocks to raw 32bpp pixels, call

bool unpack_uastc(const uastc_block& blk, color32* pPixels, bool srgb);

Set the "srgb" flag to always false right now, because that's what the UASTC encoder assumes it will be set to. (We're fixing this for the Feb. release.)

Or you can call transcode_uastc_to_bc7() or transcode_uastc_to_astc(), then unpack those blocks yourself (ASTC will always be equal or higher quality than BC7 because UASTC is a pure subset of LDR 4x4 ASTC):

https://github.com/BinomialLLC/basis_universal/blob/master/transcoder/basisu_transcoder_uastc.h

There's an optional RDO post processor in there too that you can call on arrays of UASTC blocks, but it's pretty basic right now. See uastc_rdo().

The advantage of UASTC is that you can transcode it at run-time to basically any texture format. There are very high quality transcoders to BC1-5, ETC1/2, BC7, etc. It even supports PVRTC1. The disadvantage is a slight drop in quality vs. best BC7/ASTC, but not much, and slower encoding. We even throw in a free RDO encoder (as a simple post processor) for UASTC.