- December 10, 2011 at 9:59 pm #30708
I am using the pvr tex tool to compress textures with alpha and i have come across a problem, i will take a very simple example to explain my problem.
I have a texture with some white clouds on a blue background.
The blue background zone is fully transparent.
When i use the pvr tex tool to compress this texture, the resulting image RGB is black where the alpha = 0. this is not what i expect, i want the RGB to stay blue as the original texture.
The problem is that with a black color in transparent zones, when i apply this texture on a 3D Plane, some filtering occurs. Thus resulting with a black border around the clouds.
As artists we usually put a blue background so that the border is blue and not black around the clouds when filtering occurs;
This happens when i compress the texture in normal, high and best quality mode.
Strangely, in Fast compression method, the pvr tex tool keeps the Blue color in transparent zones. Due to this behavior, we have better result with Fast compression than Best quality method.
Is there some way to force the pvr tex tool to not put Black in fully transparent zones ?
If not, can someone explain me the logic behind this ?
JeffDecember 12, 2011 at 8:54 am #35306
This is something that got put into the last PVRTC compressor, it’s supposed to be accompanied by a “bleed” step to counteract this problem, but this has somehow been disabled. The idea being that if the alpha==0 areas can be used to store arbitrary colours to make the actually visible areas look better.
Until I get a fix out for this, one way you could get around the problem is to pre-multiply your textures. This will also save a cycle in your shader and it could give you better quality output from PVRTC.
TobiasDecember 12, 2011 at 5:46 pm #35307
Using premultiplied textures resolved the issue indeed 🙂 thanks!
Now i have to work a little bit on our pipeline so that we can use the premultiplied alpha technique on all our transparent textures 🙂January 4, 2012 at 4:24 pm #35308
I have another problem with PVR Compression.
As you advised, i am now using Premultiplied Alpha textures with a specific Shader.
Before compressing a texture in PVRTC i preprocess it to Premultiply its alpha.
Normally a premultiplied texture should be Completely black where the alpha is fully transparent. This is Ok before Compression.
But on some textures, after the compression, i get some white artifacts where my alpha is completely transparent
With such textures in game, when the appropriate shader is applied, i get white border caused by the artifacts.
Here is an example with a very simple texture :
A number with a black border. (without the black border i don’t get the glitches).
I don’t understand why the PVR compression add these glitches on some textures. In my opinion, these zones should be completely black to save texture space, instead, these artifacts add some texture information where there should not be…
This is annoying because the quality of the final ingame texture is not very good. As showed in the example, there are lot of white borders.
JeffJanuary 4, 2012 at 4:53 pm #35309
Is there any chance you could send me the original texture in that example? It does seem weird that it’s putting artifacts at those locations, can I also ask are you using 2bpp or 4bpp, and what the build version of your PVRTexTool is? (Help -> About…)
Texture compression methods (like PVRTC) are typically a fixed rate scheme, meaning that a given amount of data always encodes for a certain number of pixels. So unlike file compression, which is variable rate, no space can be saved when there is a large chunk of identical data. The reasons for this are due to needing random access to any given pixel without having to decode the whole thing – texture compression is there to save bandwidth, not storage space.
Due to the nature of PVRTC, it does sometimes have trouble with UI elements such as the one you’ve presented, it’s typically best with gradients in things like photos and materials. However, the location of the artifacts in your texture do look avoidable, so once I’ve reproduced the bug I’ll try to find out what’s going on.
TobiasJanuary 4, 2012 at 5:53 pm #35310
Hi Tobias, thanks for the very fast reply 🙂
I use this version of PVRTextTool:
v3.23(SDK build 2.09.29.0677) Uses the Fox Toolkit version 1.6.37
Here is the original texture file that i used in the example :
I open it in the PVR TextTool
PreProcess to Pre-Multiply Alpha
Encode the texture in PVRTC 4BPP, BEST Quality
Then i can see the white artifact around the black border of the number.
When using 2BPP the result is worse. the artifacts are larger.
In Fast Compression mode the artifacts are larger to.
Best High and Medium seems to be the same.January 4, 2012 at 8:17 pm #35311
Premultiplied alpha with PVRTC is unacceptable because the compressed alpha channel can’t match what was multiplied into RGB. Value artifacts exist within borders, and black areas exist outside of them.
When is the fix going to be out? I’m not willing to live with the lowest quality setting, which is the only one of the four that isn’t affected by the bug.
Also, what is this about shader instructions? I’ve never found any blend mode to have any effect on performance over any other. The fragment shader itself should look identical with or without premultiplied textures. Jessy2012-01-04 21:31:42January 5, 2012 at 7:59 am #35312
The problem seems to basically stem from the small size of the texture coupled with the sharp borders due to it being a UI element – if you increase the size of the texture to 128×128, you’ll see a marked improvement. Whether this is something you could do as a workaround however depends on your use case. You’d have to not use MIP-Mapping for example, as the lower MIP level would have the same problems.
Sadly this isn’t strictly a bug – it’s actually a limitation of the texture format. To get the quality it does, PVRTC’s information is decompressed from a large sample area. The artefacts you are seeing are due to the decompression using some of the same information as is used to decompress the white parts of the 8. Subsequently there’s a slight white taint to the surrounding areas. Typically this is actually a good thing (as mentioned, most textures have many smooth gradients), it’s just small UI elements like this that tend to suffer.
Saying that – the keyword there is small. Unless you have pages and pages of textures like this, you’re probably better off simply not compressing them. I’d suggest you use a dual channel format (e.g. GL_LUMINANCE_ALPHA) to save on as much bandwidth as possible.
This particular issue is something we’re planning to address with our next generation texture compression, but for now it’s likely something we’re unable to do much about I’m afraid 🙁
Tobias2012-01-05 08:09:56January 5, 2012 at 8:06 am #35313
As I mentioned in the reply to Jeff, this is because of how small the texture is and how sharp the transitions are in the colours.
Sadly no fix is likely to happen for this issue with regards to PVRTC-I, as it’s more a limitation of the format and there’s only so much working around it that the compressor can do. We do plan to address this with our next generation compression though.
Sorry I wasn’t particularly clear there – typically blending is highly optimised as it’s fixed functionality, though in theory pre-multiplication means one less thing for the GPU to do (the multiplication is already done). Whether this pans out in hardware is another matter as it could be that this makes little or no difference. However, in cases where two textures are being manually blended in a shader, you’d save a cycle by not doing the multiplication at run time.
TobiasJanuary 5, 2012 at 2:40 pm #35314
JessyMemberTobias wrote:Hi Jessy,As I mentioned in the reply to Jeff, this is because of how small the texture is and how sharp the transitions are in the colours. Sadly no fix is likely to happen for this issue with regards to PVRTC-I, as it’s more a limitation of the format and there’s only so much working around it that the compressor can do.
Thanks for the info, but I don’t see how this can be true. I just tested with this:
2048 x 2048
White in RGB
1024×1024 white square in the middle of an otherwise black alpha channel
FAST (Medium quality): identical to original
Any other setting: RGB matches the original Alpha; Alpha matches except for noise along the edge of the square
What doesn’t make RGB match: Reducing the contrast of the alpha channel by darkening the white square.
What does: Making the black in the alpha channel anything but.
This seems to be consistent with what you two have noted.
More pixels do not help. Reducing “sharp transitions” does not seem to help. If premultiplication is really only happening where alpha is black, that would be fine, if alpha were only used for opacity, but unfortunately that’s not the case. This method is a really bad match for me. I use PVRTC 4bpp RGBA, but generally not for opacity. It just doesn’t look good enough; the results of using a greyscale mask are much better:
lowp vec4 fragColor = texture2D(_MainTex, uv_RGB) * _Color;
// faster than swizzling a lowp vector
fragColor.a = dot(texture2D(_MainTex, uv_Mask).rgb, vec3(0,0, _Color.a));
gl_FragColor = fragColor;
The “Best” compression works very well with that, and 8 bits per pixel is totally acceptable for that quality. It would be nice if the shader could be faster, but it’s not a big deal. There are other times, though, when I have noisier textures, that I’d like to balance out the memory requirements of that method, by utilizing RGBA. But PVRTexTool can’t help me there. Please do what you can.Jessy2012-01-05 15:22:53January 5, 2012 at 3:32 pm #35315
Hmm, yes you’re right that shouldn’t be producing those artefacts. It might be that for the particular use case on that texture the artefacts might be solvable. You will possibly still get a slight halo – though it should be far less noticeable.
I’ve filed a bug (Internal BRN35584) and will get someone to look into it – it should hopefully make it into our next release (some time in the next few months). I may also be able to provide a preview version to you but that depends on when it gets fixed.
Tobias2012-01-05 15:33:09February 24, 2012 at 2:56 pm #35316
I also experience very bad artifacts on transparent borders when using the latest v3.23 version of the PVRTexTool (both GUI and CL) in the NORMAL, HIGH and BEST setting (FAST is fine).
If I use the previous version 3.20 it works fine in both FAST and NORMAL setting (tested at 8 PVRTC Iterations).
I preprocess the PNG with Pre-Multiply Alpha. For some reason the artifacts are not clearly visible in the PVRTexToolGUI when looking at the alpha channel, but they are extremely visible in the game on iPhone, don’t know why. Very weird but when using v3.23 everybody I asked thinks that the “FAST” setting provides by far the best image quality when compared to NORMAL, HIGH and BEST, so this must be some kind of bug.
I still have the old version, but maybe it is a good idea to publish a link to the old version of the tool until the bug is fixed? Using the NORMAL setting of v3.20 seems the best image quality for now.March 2, 2012 at 7:21 pm #35317
so there are bugs in the 2.9 SDK compressor?
if so I might stick with the 2.8 one for a while longerMarch 5, 2012 at 9:45 am #35318
Just as an update to this thread, the forced pre-multiplication problem has now been fixed for the next release. The minor haloing is still there but that’s near identical to the artefacts seen in 2.8. Other quality increases should mean that the next (2.10) release of the tools should provide better visual output than before. This release should be available shortly.
Schendstok, just for your information – the reason the artefacts don’t show up in the tool but do show up in game is due to PVRTexTool not previously having a pre-multiplied alpha mode, so the artefacts would have been multiplied twice, rendering them invisible in the tool. When using PVRTexTool’s pre-multiplication options, the next release will now show you a pre-multiplied view instead.