Section 2: Texture Formats and GPU Compression

Unreal Engine supports various formats for the pixels color data. These are described below:

  • 8bit GreyScale: 1 byte per pixel
  • 16bit GreyScale: 2 bytes per pixel
  • 16bit float GreyScale: 2 bytes per pixel (UE5.1 and up)
  • 32bit float GreyScale: 4 bytes per pixel (UE5.1 and up)
  • 8bit RGBA: 4 bytes per pixel, one each for Red,Blue,Green and Alpha
  • 8bit RGBE: 4 bytes per pixel – HDR format, one byte each for RGB and a shared Exponent
  • 16bit RGBA: 8 bytes per pixel, 16bit values each for RGBA
  • 16bit Float RGBA: 8 bytes per pixel – HDR, 16bits each for RGB with 16bit Exponent
  • 32bit Float RGBA: 16 bytes per pixel – HDR float format (UE5.1 and up)

Each of the texture formats is designed for optimal use with different types of textures.

Diffuse textures contain Red,Green and Blue to describe their image so they get stored in CPU memory as 8bit or float RGBA. When passed to the GPU through the texture streamer, they are in either an 8bit DXT5 (BC5) format, a Float16 HDR format using 16bit floats for each color or a compressed format called BC1 (Block Compression version 1) which reduces the color data to 16bit (5bit Red, 6bit Green, 5bit Blue) while computing its compressed blocks (this is the default).

BC5 and Float16 use considerably more GPU memory to store the texture than BC1 – for instance, a 2048×2048 texture with BC1 compression has a resource size of 2.67Mb – using BC5 compression, it’s resource size is 21.3Mb and using Float16 is 42.67Mb.

There is also a compressed HDR format which has a resource size of 5.3Mb for the 2048×2048 texture – the HDR format does alter the color or data though so isn’t really useful for maps such as the Roughness or Opacity.

Normal maps are stored with BC5 compression in the GPU – this gives full 8 bits per channel which is important for normals.

Metallic, Opacity, Roughness and AO maps are greyscale (1 channel) and are usually stored in CPU memory as 8bit RGBA but in the GPU they’re compressed with BC4 compression which works with 8bit channel data. This allows these maps to have more detail than if they were stored in a packed channel with BC1… but by how much in real life?

It can be handy to understand how these BC compression systems work (but not essential) – there is an excellent article here that explains them in an easy-to-read and detailed way:
https://www.reedbeta.com/blog/understanding-bcn-texture-compression-formats/

Below is a comparison of a material using the original 8bit GPU data from a BC4 compressed texture besides one using 5bits of a BC1 compressed texture

BC4
BC1
Difference

As you can see there is a difference, but it’s not really noticeable by eye (I had to ramp up the texture brightness of the DiffMap to over 500 to see it) and comparing them pixel by pixel shows only 1.25% of the pixels on screen had changed, those pixels having less than 40% variation per channel (max – red:15%,green:17%,blue:37%).