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| BC6 | 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 channel RGBA input. ASTC is a 50container format which always decompresses in to a 4 channel RGBA result. 51However, the internal compressed representation is very flexible and can store 521-4 channels 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 channels 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 channels as a single luminance channel, so only a single 61 value needs to be stored in the coding instead of three. 62* Encoding the A channel 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 channel data 70 71The table below shows the recommended channel usage for data with different 72numbers of color channels 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 channel 80swizzling is specified by the application. 81 82| Input Channels | 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` channel will have higher 92precision. For ASTC it doesn't actually make any difference; the same single 93channel luminance will be returned for all three of the `.rgb` channels. 94 95## Equivalence with other formats 96 97Based on these channel 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| BC6 | `rgb1` | `.rgb` | 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 channel. 119 120**2:** ASTC relies on using the L+A color endpoint type for coding efficiency 121for two channel data. It therefore has no direct equivalent of a two-plane 122format sampled though the `.rg` channels such as BC5 or EAC_RG11. This can 123be emulated by setting texture channel swizzles in the runtime API - e.g. via 124`glTexParameteri()` for OpenGL ES - although it has been noted that API 125controlled swizzles are not available in WebGL. 126 127# Other Considerations 128 129This section outlines some of the other things to consider when encoding 130textures using ASTC. 131 132## Encoding non-correlated channels 133 134Most other texture compression formats have a static channel assignment in 135terms of the expected data correlation. For example, ETC2+EAC assumes that RGB 136are always correlated and that alpha is non-correlated. ASTC can automatically 137encode data as either fully correlated across all 4 channels, or with any one 138channel assigned to a separate non-correlated partition to the other three. 139 140The non-correlated channel can be changed on a block-by-block basis, so the 141compressor can dynamically adjust the coding based on the data present in the 142image. This means that there is no need for non-correlated data to be stored 143in a specific channel in the input image. 144 145It is however worth noting that the alpha channel is treated differently to 146the RGB color channels in some circumstances: 147 148* When coding for sRGB the alpha channel will always be stored in linear space. 149* When coding for HDR the alpha channel can optionally be kept as LDR data. 150 151## Encoding normal maps 152 153The best way to store normal maps using ASTC is similar to the scheme used by 154BC5; store the X and Y components of a unit-length normal. The Z component of 155the normal can be reconstructed in shader code based on the knowledge that the 156vector is unit length. 157 158To encode this we therefore want to store two input channels and should 159therefore use the `rrrg` coding swizzle, and the `.ga` sampling swizzle. The 160OpenGL ES shader code for reconstruction of the Z value is: 161 162 vec3 nml; 163 nml.xy = texture(...).ga; // Load normals (range 0 to 1) 164 nml.xy = nml.xy * 2.0 - 1.0; // Unpack normals (range -1 to +1) 165 nml.z = sqrt(1 - dot(nml.xy, nml.xy)); // Compute Z, given unit length 166 167In addition to this it is useful to optimize for angular error in the resulting 168vector rather than for absolute color error in the data, which improves the 169perceptual quality of the image. 170 171Both the encoding swizzle and the angular error function are enabled by using 172the `-normal` command line option. 173 174## Encoding sRGB data 175 176The ASTC LDR profile can compress sRGB encoded color, which is a more 177efficient use of bits than storing linear encoded color because the gamma 178corrected value distribution more closely matches human perception of 179luminance. 180 181For color data it is nearly always a perceptual quality win to use sRGB input 182source textures that are then compressed using the ASTC sRGB compression mode 183(compress using the `-cs` command line option rather than the `-cl` command 184line option). Note that sRGB gamma correction is only applied to the RGB 185channels during decode; the alpha channel is always treated as linear encoded 186data. 187 188*Important:* The uncompressed input texture provided on the command line must 189be stored in the sRGB color space for `-cs` to function correctly. 190 191## Encoding HDR data 192 193HDR data can be encoded just like LDR data, but with some caveats around 194handling the alpha channel. 195 196For many use cases the alpha channel is an actual alpha opacity channel and is 197therefore used for storing an LDR value between 0 and 1. For these cases use 198the `-ch` compressor option which will treat the RGB channels as HDR, but the 199A channel as LDR. 200 201For other use cases the alpha channel is simply a fourth data channel which is 202also storing an HDR value. For these cases use the `-cH` compressor option 203which will treat all channels as HDR data. 204 205- - - 206 207_Copyright © 2019-2022, Arm Limited and contributors. All rights reserved._ 208