Understanding DirectX Block Compression BC1 to BC7

Block compression (BC) is a family of lossy texture compression formats supported natively by DirectX and modern graphics hardware. By dividing images into uniform 4x4 pixel grids and encoding them into fixed-size data blocks, these formats dramatically reduce video memory (VRAM) consumption and memory bandwidth while allowing the GPU to sample and decompress texels on the fly. This article explains the memory mechanics of GPU block compression and details how DirectX formats BC1 through BC7 encode color, alpha, and vector data.

How Block Compression Operates in DirectX Memory

Uncompressed textures store color values per pixel sequentially in memory, requiring 32 bits per pixel (bpp) for standard RGBA8 formats. Block compression processes the texture in discrete, non-overlapping tiles of 4x4 pixels (16 texels total).

Instead of variable-length compression algorithms like JPEG or PNG, block compression uses a fixed memory footprint for each 4x4 block: either 64 bits (8 bytes) or 128 bits (16 bytes). Because the byte size per block is constant, the GPU can access any texel at coordinates \((x, y)\) in \(O(1)\) time by calculating the exact byte offset in memory using simple bit shifts:

\[\text{Block Index} = \left(\left\lfloor\frac{y}{4}\right\rfloor \times \left\lfloor\frac{\text{Width}}{4}\right\rfloor\right) + \left\lfloor\frac{x}{4}\right\rfloor\]

\[\text{Memory Address} = \text{Base Address} + (\text{Block Index} \times \text{Block Size in Bytes})\]

Once addressed, the hardware texture unit decodes the 16-pixel block directly in the cache.


The Formats: BC1 Through BC7

BC1 (Formerly DXT1)

  • Block Size: 64 bits per 4x4 block (4 bits per pixel).
  • Target Data: Three-channel RGB color, with optional 1-bit (cutout) alpha.
  • Encoding Mechanism:
    • Stores two 16-bit reference colors in RGB 5:6:5 format (32 bits total).
    • Stores a 32-bit lookup table composed of sixteen 2-bit indices (one per pixel).
    • The hardware generates two intermediate colors by interpolating between the two endpoints. If the numerical value of Color 0 is greater than Color 1, the intermediate colors are weighted at 2/3 and 1/3 intervals. If Color 0 is less than or equal to Color 1, the format creates one intermediate 1/2 blended color and reserves the fourth index value for full transparency (black/transparent alpha).

BC2 (Formerly DXT3)

  • Block Size: 128 bits per 4x4 block (8 bits per pixel).
  • Target Data: RGB color with sharp, explicit alpha.
  • Encoding Mechanism:
    • Uses 64 bits to store an explicit 4-bit alpha value directly for each of the 16 pixels.
    • Uses the remaining 64 bits to store RGB color data identically to BC1 (without the 1-bit transparency mode).
    • Because alpha is not interpolated, BC2 works best for decals and assets with hard, distinct transparency edges rather than smooth gradients.

BC3 (Formerly DXT5)

  • Block Size: 128 bits per 4x4 block (8 bits per pixel).
  • Target Data: RGB color with smooth, gradient alpha.
  • Encoding Mechanism:
    • Uses 64 bits for color, identical to the standard color encoding in BC1.
    • Uses 64 bits for alpha: two 8-bit alpha endpoints (16 bits) followed by sixteen 3-bit indices (48 bits).
    • The GPU calculates either four or six intermediate alpha steps between the two endpoints depending on their relative values, resulting in smooth transitions suitable for glass, smoke, and soft-edged foliage.

BC4

  • Block Size: 64 bits per 4x4 block (4 bits per pixel).
  • Target Data: Single-channel grayscale (roughness, metallic, height, or gloss maps).
  • Encoding Mechanism:
    • Uses the same mathematical scheme as the alpha channel in BC3.
    • Encodes two 8-bit endpoints (16 bits) and sixteen 3-bit interpolation indices (48 bits).
    • DirectX supports both unsigned normalized (BC4_UNORM) and signed normalized (BC4_SNORM) variants.

BC5 (Formerly 3Dc / ATI2N)

  • Block Size: 128 bits per 4x4 block (8 bits per pixel).
  • Target Data: Two-channel data (primarily tangent-space normal maps).
  • Encoding Mechanism:
    • Stores two separate BC4 blocks back-to-back: one 64-bit block for the red channel and one 64-bit block for the green channel.
    • For normal maps, the red and green channels represent the \(X\) and \(Y\) vectors. The shader reconstructs the \(Z\) component using the identity \(Z = \sqrt{1 - X^2 - Y^2}\), saving memory while maintaining higher precision than packing normals into BC1 or BC3.

BC6H

  • Block Size: 128 bits per 4x4 block (8 bits per pixel).
  • Target Data: High Dynamic Range (HDR) images with RGB channels using half-precision floating-point numbers (16-bit floats).
  • Encoding Mechanism:
    • Uses complex mode-based partitioning to divide the 4x4 grid into one or two subsets.
    • Endpoints are delta-encoded and compressed using varying bit depths depending on the chosen mode.
    • Supports both signed (BC6H_SF16) and unsigned (BC6H_UF16) dynamic range values, eliminating color banding in environment maps, skyboxes, and emissive materials.

BC7

  • Block Size: 128 bits per 4x4 block (8 bits per pixel).
  • Target Data: High-quality Standard Dynamic Range (SDR) RGB or RGBA textures.
  • Encoding Mechanism:
    • The most versatile format in the suite, BC7 features 8 distinct modes determined by a mode bit at the beginning of the payload.
    • Modes define how the block is partitioned (into 1, 2, or 3 subsets), the bit-depth of the RGB(A) endpoints, whether alpha data is present, and whether secondary index tables are applied.
    • By adapting its internal configuration to each block's specific color gradients and edge angles, BC7 minimizes block artifacts, edge bleeding, and banding common to BC1 and BC3.