-
Notifications
You must be signed in to change notification settings - Fork 302
UASTC HDR 6x6 Support Notes
Basis Universal now supports a powerful GPU-native HDR photo codec capable of handling both scene-referred and display-referred content at competitive bitrates—typically around 1.2–3.0 bits per pixel for storage/transmission, and 3.56 bpp (ASTC HDR) or 8 bpp (BC6H) in GPU memory. Both the encoder and transcoder work well in the browser (using WASM), with optional support for WASM multithreading.
As of Dec. 2024, the system supports encoding to, and transcoding from, two additional high quality formats. The first is 100% standard ASTC HDR 6x6 (3.56 bits/pixel or texel, RGB only) with or without RDO (Rate-distortion optimization), and the second is a custom variable block size compressed intermediate format that is rapidly transcodable to ASTC HDR 6x6. Both formats can also be rapidly transcoded to BC6H in real-time, or to a variety of uncompressed pixel formats for GPU devices or API's that don't support ASTC HDR or BC6H.
The ASTC HDR 6×6 codec operates in a scene-referred, linear-light color space using half-float RGB data, and supports a maximum encodable value of 65,216.0 per channel due to ASTC HDR format limits. Unlike display-referred systems that encode tone-adjusted imagery for specific display devices, this codec preserves full scene-linear luminance information, making it resilient to exposure adjustments, compositing, and physically-based rendering. The encoder is perceptually optimized using advanced visual models to guide rate-distortion decisions, ensuring high visual fidelity even at aggressive compression levels. While designed for scene-referred workflows, the codec is equally capable of handling display-referred HDR content, as well as LDR/SDR content upconverted to HDR (typically 80–100 nits or candela per sq. meter).
This encoder has been extensively tested and refined on a wide range of positive half-float HDR and upconverted LDR/SDR photographic content. It goes to great lengths to reduce block artifacts, which can be more noticeable at 6x6 vs. 4x4 pixel block sizes. Internally it operates in the ICtCp HDR colorspace (with support for values exceeding 10,000 nits), and utilizes the delta E ITP color difference metric (or see here). It's also our first encoder to heavily utilize SSIM and a perceptual saliency map to guide compression decisions. Here's a comparison showing the quality difference between ARM's astcenc encoder vs. ours.
Our future plans include extending this compressor to support a more powerful intermediate format by adding entropy coding and more effective weight grid compression, to also support other ASTC HDR block sizes, and an optional alpha channel.
The two new formats:
-
basis_tex_format::cASTC_HDR_6x6: 100% standard ASTC HDR 6x6 (3.56 bits/texel), with or without RDO (Rate-distortion optimization). RDO support in this mode is fairly basic at the moment, as most of our implementation effort was focused on the custom intermediate format. Only RGB inputs are currently supported (ASTC HDR 6x6 supports alpha, but BC6H doesn't.) -
basis_tex_format::cASTC_HDR_6x6_INTERMEDIATE: A custom compressed intermediate format which can achieve lower bitrates (roughly 1.2-3 bits/texel). Internally, this custom variable block size format is designed to be rapidly transcodable to the fixed block size ASTC 6x6 HDR format. It is roughly 20% smaller than an equivalent ASTC HDR 6x6 encoding followed by LZMA.
The compressor can write both .basis and .KTX2 files in these two texture formats, although .KTX2 is now our default file format. Both formats internally utilize the same 75 mode ASTC HDR compressor, which supports upsampled ASTC weight grids, 1-3 subsets, single or dual planes, and Color Endpoint Modes (CEM's) 7 and 11.
Note that .KTX2 files utilizing our custom intermediate format for ASTC 6x6 HDR (basis_tex_format::cASTC_HDR_6x6_INTERMEDIATE) are currently only readable using our library/tools (as of 2/2025). We're still working with Khronos on the exact header ID's we use in this mode. This doesn't apply to basis_tex_format::cASTC_HDR_6x6 files (RDO), which closely follow the existing .KTX2 specification which already supports RDO encoding+Zstd supercompression.
The transcoder can output the following GPU texture or pixel formats from either type of ASTC 6x6 HDR texture (standard or intermediate):
- ASTC HDR 6x6 (3.56 bits/texel): RGB only.
- BC6H (8 bits/texel) - Real time transcoded/encoded. The
basisu_decode_flags::cDecodeFlagsHighQualitydecode flag controls max BC6H quality (1 or 2 subsets). - RGB half float (48 bits/texel)
- RGBA half float (64 bits/texel, A is always 1.0)
- RGB9E5 (32 bits/texel). A shared exponent format supported by some GPU's. Also see here.
Note these map directly to low-level codec configuration settings in basis_compressor_params (in encoder/basisu_comp.h):
-
-hdr_6x6or-hdr_6x6i: Sets the codec to 6x6 HDR or 6x6 HDR intermediate mode, at the default comp level (2). Both LDR/SDR and HDR input images can be compressed to 6x6 HDR. For LDR/SDR inputs, the image will be upconverted to HDR first.
Note the "comp level" setting controls the quality vs. encoding speed tradeoff, which is not to be confused with "lambda", which is the bitrate (file size) vs. quality tradeoff.
-
-lambda X: Controls the bitrate (file size) vs. quality (distortion) tradeoff (Lagrangian multiplier). If X=0 (the default), the compressor optimizes for highest achievable quality (at the current comp level). Higher values of X progressively lower quality, but reduce bitrate.
For HDR inputs, lambda values between 100-3,000 or so work well. For LDR/SDR inputs, values between 500-50,000 work well.
-
-hdr_6x6_level Xorhdr_6x6i_level X: Sets the codec to 6x6 or 6x6 intermediate mode, at the specified comp level X, where X ranges from [0,12]. The comp level X controls the quality vs. encoding speed tradeoff, where 0=fastest, but lowest quality, and higher levels increase the quality but lower encoding speed. Comp level 12 is exhaustive and impractically/extremely slow.
The comp level setting controls the maximum number of ASTC modes and partition patterns that may be evaluated for each block.
-
-rec_2020: Indicates the input image uses the Rec. 2020 color gamut, vs. the default Rec. 709 color gamut. This setting controls how the input image is internally transformed into the ICtCp colorspace. -
-hdr_6x6_jnd X: Enable "Just Noticeable Difference" (JND) mode during rate-distortion optimization, for potentially high compression gains. Good values for X to try are .5-2.0. Works best on LDR/SDR inputs. If set too high, noticeable artifacts/noise can be introduced into smooth image areas. Disabled by default. -
-hdr_ldr_no_srgb_to_linearand-hdr_ldr_upconversion_nit_multiplier X: These settings control the LDR/SDR to HDR upconverter. -hdr_ldr_no_srgb_to_linear disables sRGB to linear conversion (i.e. it's assumed the LDR input image is already in linear light), and -hdr_ldr_upconversion_nit_multiplier X controls how the normalized [0,1] linear RGB values are converted to luminance in nits (candela per sq. meter). The default nit multiplier setting is 100 nits. (Typical SDR monitors range from 80-100 nits. Some systems/API's use a multiplier of 80 nits.) -
Other misc. low-level parameters:
-hdr_6x6_comp_levels X Y or -hdr_6x6i_comp_levels X Y: Directly sets the low-level 6x6 HDR codec's base and maximum internal compression vs. encoding comp levels, where X and Y range from [0,4]. Use instead of the higher level -hdr_6x6_level or -hdr_6x6i_level parameters.
-hdr_6x6_brute_force_pats, -hdr_6x6_extra_pats: Controls how partition patterns are chosen.
-hdr_6x6_no_gaussian: Disable Gaussian filtering fallback passes on blocks with low SSIM's (faster).