ASTC Texture Compression

From OpenGL Wiki
Jump to: navigation, search
ASTC Texture Compression
ARB extension KHR_texture_compression_astc_hdr, KHR_texture_compression_astc_ldr

Adaptable Scalable Texture Compression (ASTC) is a form of Texture Compression that uses variable block sizes, rather than a single fixed size. ASTC is designed to effectively obsolete all (or at least most) prior compressed formats by providing all of the features of the others plus more, all in one format.

S3 Texture Compression
ASTC has better peak signal-to-noise than DXT3/5 at the same block size. But because of ASTC's variable block size, ASTC can also beat DXT1's 4-bits-per-pixel, going as far down as 0.89bpp. At similar bitdepths, ASTC provides better visual quality than DXT1.
BPTC Texture Compression
BPTC provides two features: improved image quality for Normalized Integer formats and floating-point compression. ASTC also covers both normalized integer and floating-point compression. It gives more or less equivalent image quality for the same bitrate, but it can also achieve higher compression if you are willing to sacrifice some image quality.
Red Green Texture Compression
ASTC provides a single-channel and two-channel version, equivalent to RGTC's formats. A vital feature of RGTC, the reason to use it instead of DXT5, is that the two channels are uncorrelated with one another. The gradient used for one channel has no relation to the gradient used for the other.
ASTC provides both correlated and uncorrelated two-channel compression.
One feature of RGTC missing from ASTC (directly at least) is support for signed, normalized integer values. This can be approximated however by biasing the data (pre-compression) by 127 (assuming that you properly removed all -128 values from your data), to make it unsigned. Then, in the shader, multiplying the result sampled from the texture by 2 and subtracting 1 to reconstitute the signed value.

Of course, the downside is that ASTC is not widely available at present. It is available as an OpenGL extension, but it is not core OpenGL functionality.

Also, note that the ASTC extension is written against OpenGL ES 3.0, not desktop OpenGL. This means that some of its functionality is limited, relative to desktop GL.

Variable block sizes

Block size

(WxH)

BPP
4x4 8.00
5x4 6.40
5x5 5.12
6x5 4.27
6x6 3.56
8x5 3.20
8x6 2.67
10x5 2.56
10x6 2.13
8x8 2.00
10x8 1.60
10x10 1.28
12x10 1.07
12x12 0.89

Compression formats used for textures are based on compressing specific blocks of pixels. This makes it easy for hardware to tell what has to be decompressed to get at a specific texel, which is a frequent operation in texture accessing.

Most compression formats have a fixed size of blocks. S3TC, BPTC, and RGTC all use 4x4 pixel blocks. The byte sizes can be different based on different variations of the format. DXT1 in S3TC uses 8-byte blocks, while DXT3/5 use 16-byte blocks.

ASTC is a bit different. The algorithm is designed to be able to work against a large range of block sizes in terms of pixel footprints. However, the amount of space a block takes up is always 16-bytes. Therefore, the number of bits per pixel that ASTC takes up is determined by the block size used. So the 4x4 version of ASTC, the smallest block size, takes up 8 bits per pixel, while the 12x12 version takes up only 0.89bpp.

The range of blocks ASTC offers (for 2D compression) is to the left.



Color channels

Most compressed formats offer a fairly limited array of color channel support. BPTC's normalized integer support provides 4 channels, always. The various RGTC formats only allow for 2 channels. And so forth.

ASTC is much more flexible. It supports from 1 to 4 channels, and it allows the user to control whether certain channels are correlated or not. What is meant by "correlated" is that the two channels will be tied to the same gradient. Correlating channels makes the data smaller, but it also means that there can be a degree of bias, where a particular gradient in a block provides more accuracy to one channel than another.

Correlating channels is often useful for color data (or at least, it's usually not too bad). However, for data like normals, it may well result in rather ugly results.

ASTC provides the following color channel possibilities:

  • Single channel (analogous to Red-only RGTC).
  • Two channels, correlated.
  • Two channels, uncorrelated (analogous to Red/Green RGTC).
  • Three channels, all correlated (analogous to DXT1).
  • Three channels, with the third uncorrelated from the first two.
  • Four channels, all correlated.
  • Four channels, with the fourth uncorrelated from the first three (analogous to DXT3/5).

While these are important elements of an ASTC compressed image, the specific details of correlation are selected on a per-block basis. So even if you request two correlated channels the compressor may decide that, for certain blocks, the uncorrelated version will result in a better output. Or even for all of them. The same is true if you request two uncorrelated channels; if the compressor decides that the picture quality will be better with correlation on a block, then it will use that.

This is quite useful for improving compression quality. If you have a texture that uses alpha to cut a hole in the middle, the parts outside of this will have a constant alpha of one. So the ASTC compressor can treat those blocks as a 3-channel block (since the alpha for those is 1.0). By contrast, in DXT3 or 5, you would be wasting most of the 64-bits reserved for the alpha block. ASTC can recover those bits, using them for improved color compression quality.

One difference between ASTC and RGTC is that the one and two channel formats are not red and green; they are "luminance" with alpha. Luminance in this case means that the RGB color channels will all be the same value. If there is only one channel (luminance only), then the alpha will be 1.0.

If you prefer the RGTC presentation of one or two channel formats, you can use texture swizzling to move the channels to red and green.

Also, for the three-channel blocks, the alpha in those cases will always be 1.0.

Colorspace

Color data can be considered linear or in the sRGB colorspace. The latter will mean that fetching from the texture in the shader will perform sRGB-to-linear color conversion operations. Note that this conversion is not affected by the number of channels used, so you can use a single-channel compressed image with sRGB conversion. Also, only the 3 color channels will undergo sRGB conversion when used; the alpha is always assumed to be linear.

ASTC can also compress floating-point data outside of the [0, 1] range. These represent HDR (high-dynamic range) compression. Like BPTC, HDR values are restricted to only non-negative floating-point values. Unlike BPTC however, HDR compression works with any of the different channel versions specified above. So you can have one or two channel floating-point compression.

Like color channels, HDR is handled on a per-block basis. So if a particular block of color data does not actually use the HDR range, it can be compressed with LDR, with no impact on the result.

When encoding four channels in HDR, the alpha can be encoded in LDR or HDR. Again, this is handled on a per-block basis, rather than as an assumption of the format.

OpenGL image formats

As shown in the previous sections, ASTC images have a number of variables for their formats. However, almost all of these variables are specified per-block, rather than for the image as a whole. Whether floats larger than 1.0 are allowed is not a per-image property; it's a per-block property. An HDR-compressed ASTC image is simply one where blocks can return values larger than 1.0.

The same goes for the number of channels provided; this is a per-block property. So any individual ASTC image could have one block use only one channel, while another uses 3.

This makes the OpenGL image format rather unusual. With RGTC, for example, the image format you use specifies the number of channels returned. With ASTC, all ASTC image formats provide the same number of channels: RGBA. So even if you compress an image with one channel in every block, you use the same OpenGL image format you would if you had compressed an image with full RGBA channels.

With BPTC, you pick an image format based on the channel properties: normalized integer or floating-point. With ASTC, you simply don't care. That is a per-block property which is handled at compression time. So the format does not specify if floating point values are greater than 1.0.

There are only two properties of an ASTC compressed image that are per-image (and therefore part of the format) rather than being per-block. These properties are block size and sRGB colorspace conversion. ASTC does allow for flexible block sizes, but not within an image; the entire image must be compressed with the same block compression. And sRGB colorspace conversion is something that happens after decompression.

Thus, this extension provides a large suite of formats, with the only variance being colorspace and block size. The format enumerators are of the form:

 GL_COMPRESSED_[Colorspace]​_ASTC_[BlockSize]​_KHR

Colorpsace​ can be "RGBA​" or "SRGB8_ALPHA8​". BlockSize​ must be one of the valid block sizes from the table above, named with "width​xheight​".

Dimensions

Note: The ASTC extension is... unclear as to exactly how ASTC compressed images work in desktop OpenGL. Because it was written against OpenGL ES 3.0, it does not mention many elements of desktop GL, such as 1D textures and the like. Clarifications on these elements are in the process of being compiled, but are not available at this time.

Unavailable features

The ASTC format defines additional functionality which has not yet been exposed to OpenGL. Specifically, it has the concept of volumetric compression, where the blocks are 3-dimensional blocks rather than two-dimensional blocks.

See also