Add ktx
This commit is contained in:
+235
@@ -0,0 +1,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._
|
||||
Reference in New Issue
Block a user