PVRTexLib - RGB banding when Alpha is low

When compressing textures with alpha, there is a very noticeable quality difference between areas with high vs low alpha values.  I can understand the theory that transparent areas don't need as much rgb detail.  But, that theory breaks down when in practice I am trying to pack a scalar shader parameter into the alpha channel --such as glossiness.  Areas with high glossiness look great, but areas with low glossiness end up blurry and banded.

In future releases, I would greatly appreciate an option to disable this behavior in the compressor.  Or better yet, if you open-source the compressor, I will happily add the option for you to merge or reject at your leisure.

Below is an intentionally extreme example to illustrate the behavior.  The alpha channel is either 0 or 255.  The large area with solid 0 alpha has very poor quality rgb compression.  This was compressed "Fast".  "Best" looks significantly better, but still exhibits the issue.


Hi Corysama,

Your image shows you having a rough average error of somewhere

between 0 and 13 on in most areas, and the worst case of banding seems to show a rough error of around 11 between two sections. At the top-end this is quite

significant, but reflects the fact that you’re using the fast

compressor. Could you post the original image so that I can look at this in greater detail? Errors in the fast compressor are somewhat expected, as this is really only designed for quick iteration during development. For deployment we recommend at least the normal compressor, so I’d like to look into the errors that come from that to see if anything can be improved.

Unfortunately the thing you mention about less RGB data being needed when alpha is present is not simply something that can be “turned off”. To encode RGBA data into the same number of bits as for RGB data, some RGB precision has to be lost to accomodate the extra channel, which is probably the reason you’re seeing the banding. The harder you allow the compressor to run, the better it will be able to hide this. I’m afraid that currently we have no plans to release our compressor as open source.



Hiya Tobias,

It is totally expected that a 4-bit RGBA file will have less rgb information than a 4-bit RGB file.  What is surprising is that given a single RGBA file where the top half has solid 1.0 alpha and the bottom half has solid 0.0 alpha, the top half will have significantly better rgb quality than the bottom half even though the complexity of the alpha channel is the same in both halves.  This manifests as both banding and blurring where the alpha value is low.  You can see this in my example above where the pixels outside of the solid-0-alpha box have good quality rgb, but the pixels inside of the box have poor quality rgb –in the same image.  I’ll try to whip up another illustration tomorrow.

Meanwhile, I’m far from an open-source zealot.  But, from where I’m standing it seems that keeping your compressor closed is very counter-productive for your team and your company.  That’s why I plan to nag you about it approximately once a year until you cave.  Tongue

So, it appears that RGBA PVRTC special-cases blocks with 100% alpha so that they have good rgb-quality.  But, if the block isn’t a==255 it is stuck with crappy rgb quality.  This is great for blending textures.  Unfortunately, it means that packing scalar parameters into the alpha channel isn’t really viable with PVRTC.  More texture reads it is then.  If this is a feature of the compressor, I’d be really happy to be able to turn it off.  But, at this point I expect it’s a feature of the format.

In the example below, the top image is NORMAL-compressed with alpha masking off to show the banding.  The bottom is BEST-compressed with alpha masking on to show the alpha.  I’ve added blue labels to illustrate that the 95% alpha region in the top-left has the same poor quality rgb as the 0% and 5% alpha regions.  That’s the kicker.  In this experiment, I was expecting the 95% region to have better rgb quality than the 5% region, but it’s doesn’t.  Science!


Hi Corysama,

I think the misunderstanding is that PVRTC is tied
to RGB or RGBA in a single texture. In actual fact, what most people
don't realise is that PVRTC can have a mix of RGB and RGBA blocks in a single
texture - they can exist side by side. So the "special cases" are
actually blocks without any alpha. The quality isn't tied to the "alpha
complexity", it's just that when a given area is opaque, the compressor
will simply not encode an alpha channel. This proves to be a simple and
highly effective optimisation.

As you've mentioned, the way this
works is great for blended textures, which is the majority of uses of
the alpha channel. Whilst PVRTC will try to pack something else in there
if it's provided, it is impossible to guarantee the exact same quality
between an opaque area and a transparent one, due to the lower amount of
data available.



Tobias2012-09-05 11:31:08

One more follow-up for the benefit of anyone reading this.  There is apparently another threshold when the alpha value is <= 8/255.  The image below is the RGB of the result of compressing then decompressing RGBA pvrtc 4-bit, NORMAL quality.  The RGB is a photoshop “clouds” render and the alpha has 4 (not 3) stripes of 255, 254, 9, and 8 descending.  The background alpha is 0.  Note that the RGB in areas with 0 or 8 alpha has turned completely black, but the stripe with 9 alpha is OK.

I'm still using the old PVRTex lib and decompression from just before the recent rewrite.  This only happens with the lib.  I can't repro with PVRTexTool.  I haven't verified that this is visible on device yet.  So, I don't know for certain if the effect is from is the compression or the decompression code.  FAST compression does not show the black-out effect.

Hi corysama,

This was a problem with the compressor where it was forcing its own pre-process pass on near-transparent RGB data. This has been fixed in later versions of the compression code, hence you don’t see it in the tool version, and any new releases shouldn’t suffer this issue.

FYI this is actually a problem with the compressor - the rgb data was in fact wiped out, so you’d see this on device too.