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