Image compression of grayscale images

In realtime graphics grayscale images are often used as masks in shader and particle effects. In many cases (lensflares or vector masks for example) compression artifacts can become a problem.

The following table is a comparison between a few of the compression schemes present in current UDK builds. (The images are closeups of a shader using the textures, click for a bigger view.)

This TC_Grayscale compression simply drops the green, blue and alpha channels so the result is the untouched red component.

 

Advantages: There are no DXT compression artifacts.

Disadvantages: Can not store multiple masks in a single texture.

TC_Grayscale G8 Image compression of grayscale images Image compression of grayscale images MaskCompression01

TC_Default produces a DXT1 encoded texture. It reduces fidelity in 4×4 pixel blocks.

 

Advantages: Can store three masks with the same (small) memory footprint.

Disadvantages: Compression artifacts might be unacceptable on clip art/vector style images or smooth gradients.

TC_Default DXT1 Image compression of grayscale images Image compression of grayscale images MaskCompression02

Doubling the resolution of the previous image helps maintaining the sharp edges but there are still ugly blocking at certain places.

Gradients look much better although gamma correction can affect the result.

TC_Default DXT1 double resolution Image compression of grayscale images Image compression of grayscale images MaskCompression03

At 4x the resolution of the original image, it starts to look really sharp with only a few errors in the contours.

The change in gradient quality is barely visible, probably isn’t worth the extra memory usage by itself.

TC_Default DXT1 4x resolution Image compression of grayscale images Image compression of grayscale images MaskCompression04

The TC_NormalmapUncompressed scheme stores the red and green channels uncompressed and derives the blue (Z) component in the pixel shader (+2 instructions).

 

Advantages: Can store two masks in the same texture, no DXT compression artifacts.

Disadvantages: Each texture sampler increases the pixel shader’s instruction count by 2 or 4 if the texture values are remapped to the [0,1] range.

TC_NormalmapUncompressed V8U8 Image compression of grayscale images Image compression of grayscale images MaskCompression05

After choosing the V8U8 compression, UDK automatically halves the resolution in order to keep size the same as with DXT1. (This is why the previous image is 128×128.)

A 512×512 imported image ended up being 256×256, same size as the 512×512 DXT1 compression. The decreased resolution certainly shows but at least the quality is consistent throughout the image. It would work much better for distance fields than DXT1.

TC_NormalmapUncompressed V8U8 double resolution Image compression of grayscale images Image compression of grayscale images MaskCompression06

So the bottom line is that the ideal compression method depends on several factors: the content of the image, the memory and shader instruction limitations and workflow considerations.