This content was automatically converted from the project's wiki Markdown to HTML. See the Basis Universal GitHub wiki for the latest content.
.basis/.KTX2 files support both UASTC LDR 4x4 and ETC1S texture data. In UASTC mode, there is no extra lossless compression applied apart from UASTC itself in .basis files, so the raw UASTC .basis file sizes are quite large (8-bpp). This is not true for .KTX2 files, which support additional lossless Zstandard supercompression layered on top of the lossy UASTC texture data.
The encoder supports an optional Rate-Distortion Optimization (RDO) mode, which reduces the entropy of the output lossy UASTC texture data by conditioning it for better lossless LZ compression. This trades off quality for fewer LZ compressed bits, in an intelligent way that tries to increase the probability/density of close (low distance) LZ matches. In our experiences, we've seen bitrates (using Deflate) ranging between 2-7bpp, with the typical usable bitrate being around 5-7bpp. With the current RDO encoder, the sweet spot is around 5-6 bpp.
A previously unused field in .basis files indicates the internal
universal texture format (ETC1S or UASTC). See
basis_file_header::m_tex_format. UASTC files reuse all the
existing ETC1S file structures. There are no codebooks in UASTC mode, so
a bunch of header fields (like m_total_endpoints,
m_endpoint_cb_file_ofs, etc.) are zero. The helper method
basisu_transcoder::get_tex_format() can be used to
determine the texture format of a .basis file.
The transcoder API transparently supports both ETC1S and UASTC files.
The UASTC code was added to the transcoder in
transcoder/basisu_transcoder.cpp. It can optionally be
disabled by setting the BASISD_SUPPORT_UASTC preprocessor
macro to 0.
There are three ways of accessing the new UASTC functionality:
Use the command line tool to encode UASTC .basis files using the
-uastc, -uastc_rdo_l, and -uastc_level options. Then use
basisu_transcoder::transcode_image_level() and
transcode_slice() which transparently support both ETC1S
and UASTC files. This is the way web developers use the system, by
compiling the transcoder's .cpp file to WebAssembly.
A lowlevel class, basisu_lowlevel_uastc_transcoder,
was added with a single method that transcodes UASTC data to GPU texture
data in any format:
basisu_lowlevel_uastc_transcoder::transcode_slice().
Internally, this is what
basisu_transcoder::transcode_image_level() uses on UASTC
.basis files.
You could roll your own file format and just call this helper to transcode the UASTC data.
transcoder/basisu_transcoder_uastc.h declares the UASTC
transcode functions, and basisu_uastc_enc.h declares the
UASTC encode functions.Note that before using any encoder functions you
must call basisu_encoder_init().
Similarly, before calling any transcoder functions you must call
basist::basisu_transcoder_init().
The two functions pack_uastc() and
uastc_rdo() are used for encoding individual blocks (with
no RDO), or groups of blocks with RDO. They are very simple to use. You
call them with a pointer to 4x4 RGBA pixel blocks, and flags/options,
and you get back packed 128-bit UASTC blocks.
The key lowest-level block transcoder functions defined in
basisu_uastc_enc.h are:
transcode_uastc_to_bc1(),
transcode_uastc_to_bc3(),
transcode_uastc_to_bc4(),
transcode_uastc_to_bc5(),
transcode_uastc_to_bc7(),
transcode_uastc_to_astc(), etc.
Note that we will be optimizing
transcode_uastc_to_etc2_eac_r11() and
transcode_uastc_to_etc2_eac_rg11() to be roughly 2-2.5x
faster. We targeted too high a quality for EAC R11/RG11. We will also be
further optimizing UASTC->ASTC and UASTC->BC7. I would expect ~2x
faster without using any SIMD.