V220.127.116.11 Changelog - 12/12/2022
Added - BC Compression Support
GameGuruMAX Terrain Texture Formats: Dimensions have to be 2048x2048
*color = BC7 (not BC7 - sRGB)
*normal = BC5
*surface = BC1 (not BC1 - sRGB)
GameGuruMAX Grass Texture Formats: Dimensions have to be 1024x1024
*color = BC3 (not BC3 - sRGB)
*Please note these may change during MAX development
BC stands for “block compression”, and the BCn formats all operate in terms of 4×4 blocks of pixels. All images are sliced up into these small blocks, and each block is self-contained, the data to decode it is all in one contiguous chunk in memory. Moreover, the size of each compressed block is fixed either 8 or 16 bytes, depending on which BCn format is being used. This represents a 4:1 or 8:1 compression ratio, if the source image is in 8-bit RGBA format.
This standard layout is designed to make it easy for the GPU to use these formats for rendering. GPUs need to be able to quickly access any part of a texture, they don’t read the entire image sequentially, so streaming compression algorithms and those that have variable compression ratios are poorly suited for this application. The fixed block size makes it easy to locate the BCn block containing any given pixel, and the self-contained block data means that the GPU can decompress just the part of the image it needs to access.
Moreover, texture samples often exhibit locality in both dimensions, if one pixel from a texture is accessed, it’s likely that other pixels nearby in 2D will be accessed too. The 4×4 block structure supports this well, since it’s convenient to decompress all 16 pixels at once and then store them in the texture cache, where they can be efficiently reused for additional sampling operations.
The first three BCn formats are better known as DXT1, DXT3, and DXT5, respectively, but BCn (for n between 1 and 7) are the more up-to-date names for these formats.
BC1 stores RGB data. It technically supports an alpha channel, but the alpha is only 1-bit (that is, it must be either 0 or 255). It uses 8 bytes to store each 4×4 block, giving it an average data rate of 0.5 bytes per pixel. Each block consists of two color endpoints, which are stored in 2 bytes each, using RGB 5:6:5 format. The palette contains four entries generated from those endpoints, so the indices require 2 bits per pixel, making up the other 4 bytes of the block.
BC1 is a good choice for most standard-issue color maps, unless there’s a specific reason to use one of the other formats. One such reason could be that the image requires smooth gradients.
Rather than going through these formats in numerical order (which corresponds to the chronological order in which they were introduced, in successive generations of GPU hardware), I’m going to go in order from the simplest to most complicated. After BC1, BC4 is the next logical step.
BC4 stores a grayscale image—no RGB, just a single color channel—and uses 8 bytes per block. Its endpoints are one byte each, and it uses an eight-element palette, so it has 3 bits of indices per pixel.
BC4 is the same size as BC1, but it gives much better quality than BC1 when storing a grayscale image, due to both the expanded palette (eight elements instead of four) and the extended endpoint precision (8 bits instead of 5–6). This makes BC4 an excellent choice for height maps, gloss maps, and any other kind of grayscale texture.
BC2, BC3, and BC5
These formats are simply combinations of the previous two. BC3 stores RGBA data, using BC1 for the RGB part and BC4 for the alpha part, for a total block size of 16 bytes, or an average of 1 byte per pixel. It’s the most common format for textures that require a full alpha channel, and can also be used for packing a color texture together with any grayscale image, such as a height map or gloss map. Since the alpha is stored separately from the color, BC3 does not use the BC1 1-bit alpha mode in the color part.
BC5 is a two-channel format in which each block is just two BC4 blocks. This is very useful for tangent-space normal maps, if the the X and Y components are stored and the Z component is reconstructed in the pixel shader. Since each channel has its own endpoints and indices, normal maps, in which the X and Y components are often “doing different things”, so to speak—retain quite a bit more fidelity in BC5 than in BC1. The downside is that BC5 requires twice as much memory, at 16 bytes per block; this can also make it slower for shaders to access because more memory bandwidth is needed to get the texture to the shader cores. But this may be a price worth paying for the substantial increase in quality.
BC2 is a bit of an odd duck, and frankly is never used nowadays. It stores RGBA data, using BC1 for the RGB part, and a straight 4 bits per pixel for the alpha channel. The alpha part doesn’t use any endpoints-and-indices scheme, just stores explicit pixel values. But since each alpha value is just 4 bits, there are only 16 distinct levels of alpha, which causes extreme banding and makes it impossible to represent a smooth gradient or edge even approximately.
BC6 and BC7
The final two formats were introduced very recently, just within the last couple of years, and are only supported by D3D11+ level graphics hardware. They’re also vastly more complex than any of the other formats we’ve discussed. As a result of their newness, complexity, and hardware requirements, they’re not yet well supported in texture compression tools and libraries, and aren’t yet well-known or widely used.
Both of them consume 16 bytes per block, the same as BC3 and BC5. BC7 targets 8-bit RGB or RGBA data, and BC6 targets RGB half-precision floating-point data. BC6 is therefore the only BCn format that can natively store HDR images, and is an excellent replacement for RGBM and other HDR encodings that rendering programmers have heretofore used to shoehorn HDR data into compressed textures.
The reason BC6 and BC7 are so complicated is that they allow a variety of different modes that change the details of the format, such as the palette size and the way the endpoints are stored. Modes are specified by the first few bits of each block, so each block can effectively have a different format! This makes BC6 and BC7 very adaptable to the image contents, as they can choose the best mode for each individual 4×4 block. But the downside is that compressing to BC6 or BC7 is much more difficult and slow, since the compressor has many more options to try to achieve the best-quality representation of each block.
The different modes essentially trade off various features of the format. For example, they trade off endpoint precision versus index precision: some modes have larger palettes, but store the endpoints with fewer bits per component; other modes have higher-precision endpoints, but smaller palettes.
Another enhancement that BC6 and BC7 feature is the ability to have more than one line segment in each block. Now, some of the formats described previously—namely BC3 and BC5—have two line segments per block, but they use them for different channels—in BC3, color and alpha, or in BC5, the two grayscale channels. BC6 and BC7 introduce the concept of partitioning, which allows different line segments to be used for different pixels in the block.
Welcome to the real world!
Main PC - Windows 10 Pro x64 - Core i7-9700K @4.2GHz - 64GB DDR4 RAM - GeForce RTX 2070 SUPER 8GB - 2TB NVe, 1TB NVe, 2TB Hybrid Data Drive
Test PC - Windows 10 Pro x64 - Core i7-7700K @4.2GHz - 32GB DDR4 RAM - GeForce GTX 1060-6G 6GB - 1TB NVe SSD
Laptop - Helios 300 Predator - i7 7700HQ - 32GB - Nvidia GTX1060 6GB - 525GB M2 - 500 SSD - 17.3" IPS LED Panel - Windows 10 Pro x64
xRange No Nonsense Tools