# How on earth do you get decent color out of 2BPP?

I've been looking into PowerVR textures, and have run into several textures that are apparently 2 bits per-pixel. This, frankly, boggles my mind. How does one get even half way decent color preservation when you only have 4 possible states per pi per pixel? I would love any resources out there that talk about the compression behind such a feat. Thanks!

• With JPG, you can get a decent color with under 1BPP :) – Ivan Kuckir Nov 19 '17 at 15:49

PVRTC 2BPP encoding, as introduced in this paper divides an image into 8x4-texel blocks, and compresses each block such that only two RGB colors are stored for each thirty-two texel block.

None of the thirty-two texels stores a color of its own - each texel stores only information about how to blend between the two RGB colors of its 8x4-texel block.

If the source image has an 8x4 texel block with a rainbow of 32 colors in it, PVRTC 2BPP compression will do a very poor job of maintaining its quality, because in PVRTC 2BPP each 8x4 texel block has only two RGB colors to blend with.

• Fascinating! Thank you very much. Sadly, I'm having a lot of trouble loading the paper you linked to. Maybe it's hosted on Amazon's EC2? ;) – Toji Apr 22 '11 at 4:37

Texture compression does not compress pixels. It compresses blocks of pixels. When an individual pixel is referenced, the GPU computes which block represents the pixel. Then it processes the whole block to get the color of that pixel.

An example

Lets assume the block size is 4x4 pixels on an RGB texture. Uncompressed, each block consumes 4x4x3 = 48 bytes in texture memory.
Now the compression algorithm will calculate the average for each channel (RGB) and store it with the block ( 3 bytes). Now lets give each pixel 2 bits to adjust the average so that the pixel is closer to its original color. Thats another 4x4x2x3/8 = 12 bytes.
The total bytes used by this newly invented compressor is 15 bytes per block, a compression ratio of 31.25%.

My mythical compressor uses 7.5 bpp. That isn't as good as the 2 bpp pvrtc can achieve, but now you have rough idea on how 2 bbp might be achieved.

update:
I just looked at the wikipedia page for pvrtc. It looks like pvrtc doesn't use traditional block based compression. Here is paper that describes the way block based compression works and how pvrtc differs. Of particular note: Block based filters can produce decent looking images using 4bpp (no alpha), whereas nvrtc can do so with 2bpp.

@Toji, the site the paper is on is a bit temperamental but it worked for me this morning. Failing that, if you have access to ACM/SIGGRAPH, it's hosted here. Strangely, it was also on the IMG/PowerVR developer website (free registration) but I can't seem to find the right section. :-(

[UPDATE] It is still on the IMG site here[/UPDATE]

@bmcnet: PVRTC does not break the texture into blocks like, say, ETC or S3TC. FWIW, I did experiment with block-based textures but I couldn't find a way to pack enough data into self-contained blocks and still get the results I wanted. Instead, it's a bit more of a 'global' texture compression system. It has 2 low resolution images which it bilinearly upscales to the target res, and then mixes these together on a texel-by-texel basis.