Category | Compression Format | Alpha Support | R Support | G Support | B Support | Bit Depth per Channel (Uncompressed) | Total Bit Depth per Pixel (Uncompressed) | Compressed Bits per Pixel (bpp) |
Default (DXT1/5, BC1/3 on DX11) | DXT1 | No | Yes | Yes | Yes | 8 bits (R, G, B) | 24 bits | 4 bpp |
DXT5 | Yes | Yes | Yes | Yes | 8 bits (R, G, B, A) | 32 bits | 8 bpp | |
Normalmap (DXT5, BC5 on DX11) | BC5 | No | Yes | Yes | No | 8 bits (R, G) | 16 bits | 8 bpp |
Masks (no sRGB) | DXT1 / DXT5 | DXT1: No DXT5: Yes | Yes | Yes | Yes | DXT1: 8 bits (R, G, B) DXT5: 8 bits (R, G, B, A) | DXT1: 24 bits DXT5: 32 bits | DXT1: 4 bpp DXT5: 8 bpp |
Grayscale (R8 RGB8 sRGB) | G8 | No | No | Yes | No | 8 bits (G) | 8 bits | 8 bits (Uncompressed) |
Displacement Map (8 / 16bit) | G8 / G16 | No | No | Yes | No | G8: 8 bits (G) G16: 16 bits (G) | G8: 8 bits G16: 16 bits | G8: 8 bits G16: 16 bits (Uncompressed) |
Vector Displacement Map (RGB8) | B8G8R8A8 | Yes | Yes | Yes | Yes | 8 bits per channel (B, G, R, A) | 32 bits | 32 bits (Uncompressed) |
HDR (RGB, no sRGB) | FloatRGBA | Yes | Yes | Yes | Yes | 32 bits float per channel (R, G, B, A) | 128 bits | 128 bits (Uncompressed) |
User Interface 2D (RGBA) | B8G8R8A8 | Yes | Yes | Yes | Yes | 8 bits per channel (B, G, R, A) | 32 bits | 32 bits (Uncompressed) |
Alpha (no sRGB, BC4 on DX11) | BC4 | No | Yes | No | No | 8 bits (R) | 8 bits | 4 bpp |
Distance Field Font (R8) | G8 | No | No | Yes | No | 8 bits (G) | 8 bits | 8 bits (Uncompressed) |
HDR Compressed (RGB, BC6H, DX11) | BC6H | No | Yes | Yes | Yes | Varies (HDR data) | Varies | 8 bpp |
BC7 (DX11, optional A) | BC7 | Optional | Yes | Yes | Yes | 8 bits per channel (R, G, B, optional A) | 24-32 bits | 8 bpp |
Understanding Bits Per Pixel (bpp)
"bpp" stands for bits per pixel, which represents the amount of data used to store each pixel in a texture. In uncompressed formats, this is straightforward—the bits per pixel are divided evenly among the channels (e.g., Red, Green, Blue, Alpha). However, in compressed formats, bits are allocated using complex algorithms that compress data across blocks of pixels, making per-channel bit depths less direct.
DXT1 vs. DXT5 (Default Textures):
DXT1:
Alpha Support: No (or 1-bit alpha)
Channels: R, G, B
Uncompressed Bit Depth: 24 bits per pixel (8 bits × 3 channels)
Compressed Bit Depth: 4 bpp
DXT5:
Alpha Support: Yes
Channels: R, G, B, A
Uncompressed Bit Depth: 32 bits per pixel (8 bits × 4 channels)
Compressed Bit Depth: 8 bpp
BC5 (Normal Maps):
Alpha Support: No
Channels: R, G (used for normal vectors)
Uncompressed Bit Depth: 16 bits per pixel (8 bits × 2 channels)
Compressed Bit Depth: 8 bpp
BC4 (Alpha Masks):
Alpha Support: No (but used for single-channel data)
Channels: Typically R or G
Uncompressed Bit Depth: 8 bits per pixel
Compressed Bit Depth: 4 bpp
G8 / G16 (Grayscale and Displacement Maps):
Alpha Support: No
Channels: G
Uncompressed Bit Depth: G8: 8 bits; G16: 16 bits per pixel
Compressed Bit Depth: Uncompressed formats (no further compression)
B8G8R8A8 (Vector Displacement Maps & UI Textures):
Alpha Support: Yes
Channels: B, G, R, A
Uncompressed Bit Depth: 32 bits per pixel (8 bits × 4 channels)
Compressed Bit Depth: Uncompressed format
FloatRGBA (HDR Textures):
Alpha Support: Yes
Channels: R, G, B, A
Uncompressed Bit Depth: 128 bits per pixel (32 bits float × 4 channels)
Compressed Bit Depth: Uncompressed format
BC6H (HDR Compressed):
Alpha Support: No
Channels: R, G, B (HDR data)
Uncompressed Bit Depth: Varies (depends on HDR precision)
Compressed Bit Depth: 8 bpp
BC7 (High-Quality Compression):
Alpha Support: Optional
Channels: R, G, B, (optional A)
Uncompressed Bit Depth: 24 bits (without alpha) or 32 bits (with alpha)
Compressed Bit Depth: 8 bpp
Understanding Compressed Formats:
Block Compression: Formats like DXT, BC4-BC7 compress textures in blocks (typically 4×4 pixels).
Variable Bit Allocation: Bits are not evenly divided among channels or pixels; instead, they represent color endpoints and indices that reconstruct the image during rendering.
Compression Efficiency: These formats reduce texture size in memory and improve performance without significantly compromising visual quality.
Differences Between Similar Settings:
Vector Displacement Map vs. User Interface 2D (Both Use B8G8R8A8):
Vector Displacement Map:
Purpose: Stores precise displacement vectors (X, Y, Z) for modifying surface geometry.
Requirement: Uncompressed to preserve exact values; compression artifacts can distort geometry.
User Interface 2D:
Purpose: Displays crisp UI elements like icons and text.
Requirement: Uncompressed to maintain sharpness and clarity; even minor compression artifacts are noticeable.
Default Textures vs. Masks (Both Can Use DXT1/DXT5):
Default Textures:
Usage: General textures where standard sRGB gamma correction is applied.
Compression: Uses sRGB color space.
Masks (no sRGB):
Usage: Grayscale masks for blending or masking operations.
Compression: sRGB is disabled to prevent gamma correction, ensuring linear color values.
Grayscale Textures vs. Distance Field Fonts (Both Use G8):
Grayscale Textures:
Purpose: Black and white masks, height maps.
Data: Single-channel intensity values.
Distance Field Fonts:
Purpose: Scalable fonts with smooth edges.
Data: Precise control over glyph edges; relies on accurate single-channel data.
Normal Maps (BC5) vs. Alpha Masks (BC4):
Normal Maps (BC5):
Channels: Two channels (R and G) representing surface normals.
Compression: 8 bpp optimized for gradient data.
Alpha Masks (BC4):
Channels: Single channel (often R).
Compression: 4 bpp suitable for opacity information.
HDR Uncompressed (FloatRGBA) vs. HDR Compressed (BC6H):
HDR Uncompressed:
Precision: Highest possible (32-bit floats per channel).
Usage: Critical when maximum dynamic range and precision are required.
HDR Compressed (BC6H):
Precision: High dynamic range with compression.
Usage: Balances memory usage with HDR support; suitable when slight precision loss is acceptable.
Why Derive Normal Z does not work with all formats, and why it's important to use the right texture packing compression setting:
Normal maps store surface normals in texture channels to simulate detailed surface geometry without increasing mesh complexity. A normal vector has three components: X, Y, and Z, and is typically normalized (its length is 1). In tangent space normal maps:
X component is stored in the Red channel.
Y component is stored in the Green channel.
Z component is often reconstructed in the shader to save memory.
when using RG channels from a texture in BC5, BC3 derive normal Z works but with BC7 it needs this
float Input1 = R;
float Input2 = G;
float2 Appended = float2(Input1, Input2);
float2 Multiplied = Appended 2;
float2 Subtracted = Multiplied - 1;
float2 MultipliedBySelf = Subtracted Subtracted;
float MaskR = MultipliedBySelf.r;
float MaskG = MultipliedBySelf.g;
float OneMinusMaskR = 1 - MaskR;
float FinalSubtract = OneMinusMaskR - MaskG;
float SquaredRoot = sqrt(FinalSubtract);
float3 AppendX = float3(Subtracted, SquaredRoot);
return AppendX;
Both are linear color texture type
BC5 Compression Format
Designed for Two-Channel Data: BC5 is optimized for two-channel textures, making it ideal for normal maps storing X and Y components.
High Precision: Each channel (R and G) is compressed separately using techniques similar to BC4, preserving high fidelity.
Data Range: When sampled, the texture returns values in the [0, 1] range, which are linearly mapped to [-1, 1] in the shader.
Standard Method to Derive Z Component (Works with BC5):
float2 normalXY = tex2D(normalMap, texCoords).rg * 2.0 - 1.0;
float normalZ = sqrt(1.0 - dot(normalXY, normalXY));
float3 normal = float3(normalXY, normalZ);
BC7 Compression Format
Designed for High-Quality Color Data: BC7 is intended for high-quality compression of color images with optional alpha.
Complex Compression: Uses multiple modes, partitions, and bit allocations, which can introduce slight inaccuracies.
Data Range and Precision:
Possible Artifacts: Due to its compression scheme, BC7 can introduce minor errors in the decompressed values.
Data Handling: Values may not map perfectly to the expected range after decompression.
Why the Difference Occurs
Compression Artifacts and Precision Loss:
BC5: Maintains high precision for the R and G channels, so the standard method works reliably.
BC7: Compression may introduce slight deviations in the R and G values, leading to potential inaccuracies when reconstructing Z.
Negative Values Inside sqrt():
Standard Method Risk: Minor inaccuracies can cause the expression 1.0 - dot(normalXY, normalXY) to become negative, resulting in sqrt() of a negative number (NaN).
Need for Additional Calculations:
Adjusting for Inaccuracies: The provided code carefully computes each step to prevent negative values and ensure valid results.
Explicit Computation: Breaking down the calculation helps manage the precision issues introduced by BC7.
What are BCn?
Introduction to Block Compression (BCn) Formats
Definition: BC stands for "Block Compression". BCn formats compress texture data for efficient real-time rendering on GPUs.
Block Structure:
Operate on 4×4 pixel blocks.
Each block is self-contained with all data needed for decoding.
Fixed block sizes: either 8 or 16 bytes, depending on the format.
Compression Ratios:
Achieve 4:1 or 8:1 compression ratios for 8-bit RGBA images.
GPU Optimization:
Designed for fast, random access required by GPUs.
Fixed-size blocks allow easy calculation of any pixel's location.
Self-contained blocks enable decompression of only required portions.
Locality of texture sampling is leveraged through the 4×4 block structure.
General Concepts
Limited Color Variation:
Small areas (4×4 blocks) often have limited color variation.
Color Palettes:
Each block has a small palette (typically a few colors).
Pixels are indexed into this palette.
Endpoints and Indices:
Colors are assumed to lie along a line in RGB space.
Only the endpoints of this line are stored.
Intermediate colors are interpolated between endpoints.
Block Data:
Each block contains:
Endpoints: Define the color line segment.
Indices: Per-pixel references into the palette.
Limitations of BCn Formats
Color Representation:
Poor quality when more than two distinct, non-linear colors are in a block.
Struggles with blocks containing red, green, and blue together.
Gradient Representation:
Smooth gradients can exhibit banding due to limited precision.
Normal Maps:
Standard BCn formats may not adequately represent normal maps.
Specific BCn Formats
BC1 (Also Known as DXT1)
Data Type: RGB with optional 1-bit alpha.
Block Size: 8 bytes (0.5 bytes per pixel).
Color Precision: Endpoints in RGB 5:6:5 format.
Palette Size: 4 colors.
Use Cases:
Standard color maps without smooth gradients.
Cutout textures requiring 1-bit alpha (e.g., fences, vegetation).
Limitations:
Poor for smooth gradients due to low color precision.
Potential for dark fringes with bilinear filtering on cutout textures.
Degeneracy and 1-bit Alpha in BC1
Degeneracy Breaking:
The order of endpoints triggers different modes.
Two modes: Four-color palette or three-color palette with transparency.
Transparency Handling:
Supports 1-bit alpha by designating one palette entry as transparent.
No color information stored in transparent areas.
BC4
Data Type: Grayscale (single-channel).
Block Size: 8 bytes (0.5 bytes per pixel).
Palette Size: 8 grayscale values.
Higher Quality:
Full 8-bit endpoints and larger palette improve quality over BC1 for grayscale images.
Use Cases:
Height maps.
Gloss maps.
Font atlases.
Any grayscale texture.
BC2 (Rarely Used)
Data Type: RGB with explicit 4-bit alpha per pixel.
Block Size: 16 bytes (1 byte per pixel).
Limitations:
Only 16 levels of alpha leading to severe banding.
No endpoint-and-index compression for alpha channel.
Current Relevance:
Generally obsolete due to better alternatives like BC3.
BC3 (Also Known as DXT5)
Data Type: RGBA.
Block Size: 16 bytes (1 byte per pixel).
Components:
RGB stored using BC1 compression.
Alpha stored separately using BC4 compression.
Use Cases:
Textures requiring full alpha channel.
Combining color with grayscale maps (e.g., gloss or specular maps).
BC5
Data Type: Two-channel data (e.g., XY components of normal maps).
Block Size: 16 bytes (1 byte per pixel).
Components:
Consists of two BC4 blocks (one for each channel).
Advantages:
Better fidelity for normal maps compared to BC1.
Separate endpoints and indices per channel.
Use Cases:
Tangent-space normal maps.
Any two-channel texture data.
BC6
Data Type: RGB half-precision floating-point (HDR images).
Block Size: 16 bytes (1 byte per pixel).
Features:
Supports HDR content natively.
Multiple modes for flexibility.
Partitioning allows multiple line segments per block.
Advanced Compression:
Uses delta compression for endpoints.
Use Cases:
High Dynamic Range (HDR) images.
Replacing less efficient HDR encoding methods.
Data Type: RGB or RGBA.
Block Size: 16 bytes (1 byte per pixel).
Features:
High-quality compression for complex color images.
Multiple modes and partitioning for adaptability.
Supports smooth gradients and fine color variations.
Advanced Compression:
Utilizes P-bits for endpoint precision.
Offers options for shared or separate indices for color and alpha.
Use Cases:
High-quality color textures.
Textures requiring full alpha with minimal quality loss.
Advanced Features in BC6 and BC7
Per-Block Modes:
Modes change palette size, endpoint storage, and number of line segments.
First few bits of each block specify the mode.
Partitioning:
Blocks can have multiple line segments via predefined partition patterns.
Improves quality for blocks with colors not fitting a single line in RGB space.
Compression Techniques:
Degeneracy Breaking: Saves bits by enforcing certain bit patterns and swapping endpoints when necessary.
Delta Compression (BC6): Stores one endpoint precisely, others as lower-precision deltas.
P-bits (BC7): Shared least-significant bits to improve endpoint precision without extra storage.
Hardware Requirements:
Supported by Direct3D 11-level GPUs and above.
Compression is more complex and time-consuming due to advanced features.
Comparison Table of BCn Formats
Format | Data Type | Data Rate (bytes/pixel) | Palette Size | Line Segments | Use Cases |
BC1 | RGB + optional 1-bit alpha | 0.5 | 4 colors | 1 | Standard color maps, cutout textures |
BC2 | RGBA with 4-bit alpha | 1.0 | 4 colors + 16 alpha levels | 1 | (Obsolete) |
BC3 | RGBA | 1.0 | 4 colors + 8 alpha | 1 color + 1 alpha | Textures with full alpha |
BC4 | Grayscale | 0.5 | 8 grayscale values | 1 | Height maps, gloss maps, font atlases |
BC5 | Two-channel (e.g., normal maps) | 1.0 | 8 per channel | 1 per channel | Tangent-space normal maps |
BC6 | RGB half-precision floating-point | 1.0 | 8–16 | 1–2 | HDR images |
BC7 | RGB or RGBA | 1.0 | 4–16 | 1–3 | High-quality color maps with alpha |
Key Takeaways
BC1: Best for simple color textures without smooth gradients or full alpha.
BC3: Preferred for textures requiring full alpha channels.
BC4/BC5: Ideal for grayscale images and normal maps, offering higher quality in the same or less space.
BC6: Enables efficient storage of HDR images on compatible hardware.
BC7: Provides high-quality compression for complex textures with minimal artifacts, suitable for next-gen graphics.