1# Effective ASTC Encoding 2 3Most texture compression schemes encode a single color format at single 4bitrate, so there are relatively few configuration options available to content 5creators beyond selecting which compressed format to use. 6 7ASTC on the other hand is an extremely flexible container format which can 8compress multiple color formats at multiple bit rates. Inevitably this 9flexibility gives rise to questions about how to best use ASTC to encode a 10specific color format, or what the equivalent settings are to get a close 11match to another compression format. 12 13This page aims to give some guidelines, but note that they are only guidelines 14and are not exhaustive so please deviate from them as needed. 15 16## Traditional format reference 17 18The most commonly used non-ASTC compressed formats, their color format, and 19their compressed bitrate are shown in the table below. 20 21| Name | Color Format | Bits/Pixel | Notes | 22| -------- | ------------ | ---------- | ---------------- | 23| BC1 | RGB+A | 4 | RGB565 + 1-bit A | 24| BC3 | RGB+A | 8 | BC1 RGB + BC4 A | 25| BC3nm | G+R | 8 | BC1 G + BC4 R | 26| BC4 | R | 4 | L8 | 27| BC5 | R+G | 8 | BC1 R + BC1 G | 28| BC6H | RGB (HDR) | 8 | | 29| BC7 | RGB / RGBA | 8 | | 30| EAC_R11 | R | 4 | R11 | 31| EAC_RG11 | RG | 8 | RG11 | 32| ETC1 | RGB | 4 | RGB565 | 33| ETC2 | RGB+A | 4 | RGB565 + 1-bit A | 34| ETC2+EAC | RGB+A | 8 | RGB565 + EAC A | 35| PVRTC | RGBA | 2 or 4 | | 36 37**Note:** BC2 (RGB+A) is not included in the table because it's rarely used in 38practice due to poor quality alpha encoding; BC3 is nearly always used instead. 39 40**Note:** Color representations shown with a `+` symbol indicate non-correlated 41compression groups; e.g. an `RGB + A` format compresses `RGB` and `A` 42independently and does not assume the two signals are correlated. This can be 43a strength (it improves quality when compressing non-correlated signals), but 44also a weakness (it reduces quality when compressing correlated signals). 45 46# ASTC Format Mapping 47 48The main question which arises with the mapping of another format on to ASTC 49is how to handle cases where the input isn't a 4 component RGBA input. ASTC is 50a container format which always decompresses in to a 4 component RGBA result. 51However, the internal compressed representation is very flexible and can store 521-4 components as needed on a per-block basis. 53 54To get the best quality for a given bitrate, or the lowest bitrate for a given 55quality, it is important that as few components as possible are stored in the 56internal representation to avoid wasting coding space. 57 58Specific optimizations in the ASTC coding scheme exist for: 59 60* Encoding the RGB components as a single luminance component, so only a single 61 value needs to be stored in the coding instead of three. 62* Encoding the A component as a constant 1.0 value, so the coding doesn't 63 actually need to store a per-pixel alpha value at all. 64 65... so mapping your inputs given to the compressor to hit these paths is 66really important if you want to get the best output quality for your chosen 67bitrate. 68 69## Encoding 1-4 component data 70 71The table below shows the recommended component usage for data with different 72numbers of color components present in the data. 73 74The coding swizzle should be applied when compressing an image. This can be 75handled by the compressor when reading an uncompressed input image by 76specifying the swizzle using the `-esw` command line option. 77 78The sampling swizzle is what your should use in your shader programs to read 79the data from the compressed texture, assuming no additional API-level 80component swizzling is specified by the application. 81 82| Input components | ASTC Endpoint | Coding Swizzle | Sampling Swizzle | 83| -------------- | ------------- | -------------- | ------------------ | 84| 1 | L + 1 | `rrr1` | `.g` <sup>1</sup> | 85| 2 | L + A | `rrrg` | `.ga` <sup>1</sup> | 86| 3 | RGB + 1 | `rgb1` | `.rgb` | 87| 4 | RGB + A | `rgba` | `.rgba` | 88 89**1:** Sampling from `g` is preferred to sampling from `r` because it allows a 90single shader to be compatible with ASTC, BC1, or ETC formats. BC1 and ETC1 91store color endpoints as RGB565 data, so the `g` component will have higher 92precision. For ASTC it doesn't actually make any difference; the same single 93component luminance will be returned for all three of the `.rgb` components. 94 95## Equivalence with other formats 96 97Based on these component encoding requirements we can now derive the the ASTC 98coding equivalents for most of the other texture compression formats in common 99use today. 100 101| Formant | ASTC Coding Swizzle | ASTC Sampling Swizzle | Notes | 102| -------- | ------------------- | --------------------- | ---------------- | 103| BC1 | `rgba` <sup>1</sup> | `.rgba` | | 104| BC3 | `rgba` | `.rgba` | | 105| BC3nm | `gggr` | `.ag` | | 106| BC4 | `rrr1` | `.r` | | 107| BC5 | `rrrg` | `.ra` <sup>2</sup> | | 108| BC6H | `rgb1` | `.rgb` <sup>3</sup> | HDR profile only | 109| BC7 | `rgba` | `.rgba` | | 110| EAC_R11 | `rrr1` | `.r` | | 111| EAC_RG11 | `rrrg` | `.ra` <sup>2</sup> | | 112| ETC1 | `rgb1` | `.rgb` | | 113| ETC2 | `rgba` <sup>1</sup> | `.rgba` | | 114| ETC2+EAC | `rgba` | `.rgba` | | 115| ETC2+EAC | `rgba` | `.rgba` | | 116 117**1:** ASTC has no equivalent of the 1-bit punch-through alpha encoding 118supported by BC1 or ETC2; if alpha is present it will be a full alpha 119component. 120 121**2:** ASTC relies on using the L+A color endpoint type for coding efficiency 122for two component data. It therefore has no direct equivalent of a two-plane 123format sampled though the `.rg` components such as BC5 or EAC_RG11. This can 124be emulated by setting texture component swizzles in the runtime API - e.g. via 125`glTexParameteri()` for OpenGL ES - although it has been noted that API 126controlled swizzles are not available in WebGL. 127 128**3:** ASTC can only store unsigned values, and has no equivalent of the BC6 129signed endpoint mode. 130 131# Other Considerations 132 133This section outlines some of the other things to consider when encoding 134textures using ASTC. 135 136## Decode mode extensions 137 138ASTC is specified to decompress into a 16-bit per component RGBA output by 139default, with the exception of the sRGB format which uses an 8-bit value for the 140RGB components. 141 142Decompressing in to a 16-bit per component output format is often higher than 143many use cases require, especially for LDR textures which originally came from 144an 8-bit per component source image. Most implementations of ASTC support the 145decode mode extensions, which allow an application to opt-in to a lower 146precision decompressed format (RGBA8 for LDR, RGB9E5 for HDR). Using these 147extensions can improve GPU texture cache efficiency, and even improve texturing 148filtering throughput, for use cases that do not need the higher precision. 149 150The ASTC format uses different data rounding rules when the decode mode 151extensions are used. To ensure that the compressor chooses the best encodings 152for the RGBA8 rounding rules, you can specify `-decode_unorm8` when compressing 153textures that will be decompressed into the RGBA8 intermediate. This gives a 154small image quality boost. 155 156**Note:** This mode is automatically enabled if you use the `astcenc` 157decompressor to write an 8-bit per component output image. 158 159## Encoding non-correlated components 160 161Most other texture compression formats have a static component assignment in 162terms of the expected data correlation. For example, ETC2+EAC assumes that RGB 163are always correlated and that alpha is non-correlated. ASTC can automatically 164encode data as either fully correlated across all 4 components, or with any one 165component assigned to a separate non-correlated partition to the other three. 166 167The non-correlated component can be changed on a block-by-block basis, so the 168compressor can dynamically adjust the coding based on the data present in the 169image. This means that there is no need for non-correlated data to be stored 170in a specific component in the input image. 171 172It is however worth noting that the alpha component is treated differently to 173the RGB color components in some circumstances: 174 175* When coding for sRGB the alpha component will always be stored in linear 176 space. 177* When coding for HDR the alpha component can optionally be kept as LDR data. 178 179## Encoding normal maps 180 181The best way to store normal maps using ASTC is similar to the scheme used by 182BC5; store the X and Y components of a unit-length normal. The Z component of 183the normal can be reconstructed in shader code based on the knowledge that the 184vector is unit length. 185 186To encode this we need to store only two input components in the compressed 187data, and therefore use the `rrrg` coding swizzle to align the data with the 188ASTC luminance+alpha endpoint. We can sample this in shader code using the 189`.ga` sampling swizzle, and reconstruct the Z value with: 190 191 vec3 nml; 192 nml.xy = texture(...).ga; // Load normals (range 0 to 1) 193 nml.xy = nml.xy * 2.0 - 1.0; // Unpack normals (range -1 to +1) 194 nml.z = sqrt(1 - dot(nml.xy, nml.xy)); // Compute Z, given unit length 195 196The encoding swizzle and appropriate component weighting is enabled by using 197the `-normal` command line option. If you wish to use a different pair of 198components you can specify a custom swizzle after setting the `-normal` 199parameter. For example, to match BC5n component ordering use 200`-normal -esw gggr` for compression and `-normal -dsw arz1` for decompression. 201 202## Encoding sRGB data 203 204The ASTC LDR profile can compress sRGB encoded color, which is a more 205efficient use of bits than storing linear encoded color because the gamma 206corrected value distribution more closely matches human perception of 207luminance. 208 209For color data it is nearly always a perceptual quality win to use sRGB input 210source textures that are then compressed using the ASTC sRGB compression mode 211(compress using the `-cs` command line option rather than the `-cl` command 212line option). Note that sRGB gamma correction is only applied to the RGB 213components during decode; the alpha component is always treated as linear 214encoded data. 215 216*Important:* The uncompressed input texture provided on the command line must 217be stored in the sRGB color space for `-cs` to function correctly. 218 219## Encoding HDR data 220 221HDR data can be encoded just like LDR data, but with some caveats around 222handling the alpha component. 223 224For many use cases the alpha component is an actual alpha opacity component and 225is therefore used for storing an LDR value between 0 and 1. For these cases use 226the `-ch` compressor option which will treat the RGB components as HDR, but the 227A component as LDR. 228 229For other use cases the alpha component is simply a fourth data component which 230is also storing an HDR value. For these cases use the `-cH` compressor option 231which will treat all components as HDR data. 232 233- - - 234 235_Copyright © 2019-2024, Arm Limited and contributors. All rights reserved._ 236