How to improve PVRTC Quality

Hi ,

My GPU is sgx544 (GLES2.0), use pvr as texture input, sometimes I got low quality pvr image when convert the image from png to pvr. (PVRTC II 4bpp)

I already set the encoding mode to “Best Quality”, if it’s can’t avoid because of compressed data, is there other suggestion to improve the quality of image?

I see RGBA4444 is much better, but the format seems not support in the spec, please correct me if i am wrong.

RGBA8888 will cosume too much CPU& GPU resource in the platform, i don’t want to use the format.

Based on the above scenario, is there anything else I can do? Very grateful if i can get some advice.

Hi Axel,

Welcome to the PowerVR Developer Forum!
Could you please let us know the PVRTexTool version that you are using for encoding the textures ?
Also, it would be helpful if you could share us your reference png texture.

Best Regards,
Nagnath

Hi Nagnath,

Base on tda2p.

PVRTexTool version: 4.2.0, please check the png in attachment.

issue , there are many impurities in pvrtc like grids.

original png
bt_setting2

Hi Axel,
Thanks for sharing the images and info.

I could see the impurities/artefacts that you are talking about in the generated PVRTCII 4BPP Linear transcoded image. One thing I could notice is the input texture is NPOT. That doesn’t allow us to transcode to the PVRTC 1 as it expects the dimensions to be POT. Though I am not the right person to comment on the intended behaviour here on the observed quality. But I’m guessing NPOT makes some difference for PVRTC 1/2 compression results. Let me check with the team and get back to you on this and what could be the best possible compression format here.

And btw, after I locally resized the texture to 128x128 which makes it POT and allows PVRTC 4BPP sRGB compression and the results looked much better.

Note : Also, I could see you are using the older version of PVRTexTool. We have our new texture tool released and you can download it from here.
Thank you for your patience.

Best Regards,
Nagnath

Hi Nagnath,
Thank you for your reply,

I did several sets of experiments on the comparison of linear, sRGB and POT, NPOT. Please check the result as below,

PVRTexTool version: 4.2.0

case 1: 120x120 , 128x128 linear

case 2: 120x120, 128x128 sRGB

PVRTexTool version: 5.5.0

case 1: 120x120 , 128x128 linear

case 2: 120x120, 128x128 sRGB

all the case choose “best quality”, PVRTC II 4BPP

The color will be change a lot compare with original png when use the linear mode in the latest versioin (version: 5.5.0).

POT or NPOT seems didn’t affect quality too much, but sRGB or linear will.
I would be very grateful if you have any more suggestions for me.

Addtional, can you give me a demo that how to load pvr with sRGB format in opengles? thank you!

Hi Axel,

Thank you for sharing your observations on the different experiments you carried out.
And yes, I could confirm it locally that NPOT or POT doesn’t make much difference on the output quality when transcoding to PVRTC formats. But altering the color spaces does have an impact.

Usually, the textures provided to the OpenGL/ES is assumed to be in sRGB color space and the HW automatically handles the necessary sRGB to linear conversion while accessing/sampling the texture. This is usually free of cost. Generally, it is recommended to keep the colorspace intact from the original source texture. This basically ensures the gamma correction remains intact and hence preserve the color accuracy when representing the texture. You can very much use the PVRTC II 4BPP sRGB format for your requirement here.

One of the possible reasons for the artefacts that are visible in PVRTexTool GUI when converted to the linear space could be due to our PVRTexTool glitch for this specific case. As I couldn’t observe it with other textures sRGB->Linear converted PVRTC II textures. I shall get this checked with the tools team internally.

Also, when I was checking for the other possible formats that you could use here, an alternate option could be to use RGBA4444 which is comparatively having less memory footprint and delivering reasonable quality and accuracy w.r.t RGBA8888 variant.

Addtional, can you give me a demo that how to load pvr with sRGB format in opengles? thank you!

For loading this, we basically need to pass in the right glInternalFormat while loading the texture using glCompressedTexImage2D. The internal format should be GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT. For more information on how to load pvr in OGLES, you could refer to our PowerVRSDK sample, OpenGLESBumpmap.

Hope this helps. Kindly let us know in case you have any further questions.

Best Regards,
Nagnath

Hi Nagnath,

RGBA4444 can meet the requirment, but i didn’t find the format was supported in spec of tda2p platform. Could you please help me to confirm this?

If the format is support, how can i load this kind of texture, the sample code i used like below
GLCheck(glTexImage2D(
static_cast(GL_TEXTURE_2D),
static_cast(0),
static_cast(GL_RGBA),
static_cast(120),
static_cast(120),
static_cast(0),
static_cast(GL_RGBA),
static_cast(GL_UNSIGNED_SHORT_4_4_4_4),
pxlData));

I got incorrect effect
rgb4444

Hi Axel,

For RGBA4444, it’s quite tricky for us to say because usually what the HW supports is different to what the API might support (driver) that you are running on currently. But looking at the output makes me think that it might be supporting RGBA4444. The sample code looks about right to load the texture. But there’s just one small thing you could try changing, for the internalFormat, which is the 3rd parameter, could you try GL_RGBA4 as base internal format which goes as per the Khronos reference glTexImage2D - OpenGL 4 Reference Pages for RGBA4444 data format or GL_RGB as base internal format as it says in the table.

And for PVRTC II 4BPP sRGB, did you get a chance to try this format with the above-mentioned method to load the compressed texture? This should ideally work for you. Let us know in case you are facing any difficulties.
I tried loading the texture while adding this texture to our SDK’s OpenGLESBumpMap sample and it worked fine.

If the texture is monochromatic, you could use a single channel texture format like L8 where you basically sample the texture in pixel shader as usual and copy the .r component to gl_FragColor.rgb and keep alpha 1 shown below,

float luminance = texture2D(tex, texCoords).r;
gl_FragColor = vec4(luminance, luminance, luminance, 1.0);

or if you have alpha requirement you could experiment with dual channel formats where you could store your monochromatic color value and alpha values separate.

One thing which I noticed while trying older version of the PVRTexTool, which you could find in the installer, PowerVRSDKSetup-2019_R1.exe from the same downloads page. The PVRTC II 4BPP Linear converted image looks way closer to what you see with the original source image. The color shift is also minimal compared to the 5.5.0 version. This might be due to an issue with the encoder in the latest version of PVRTexTool because when I tried loading this texture in the sample it was showing the same artifacts. I shall be reporting this issue internally to understand why the output looks different and why it produces those artifacts as compared to the older version.

I am attaching the converted PVRTC II 4BPP Linear & sRGB from the 2019 version for your reference. Also, attaching a screenshot from our PVRCarbon which is a capture taken from the OpenGLESBumpMap sample on our PowerVR enabled device to show how the texture input looks like after loading it.

Best Regards,
Nagnath
2019R1.zip (78.1 KB)

Hi Nagnath,

I try GL_RGBA4 as Internal Format, it works, i got the correct image.
I didn’t try the sRGB, cuz i still can see some impurities in the picture when using the format.
Anyway, we found a format that can be meet our requirement and tested successfully, thank you very much, it really helped me a lot!

Regarding the comparison of file size, each pixel of PVRTC4bpp occupies 4 bits, and each pixel of RGBA4444 occupies 2 bytes, which is about 4 times more. Please let me know if my understanding is wrong.

Hello Axel,

Glad to hear that it worked!

And yes, your understanding is correct. The choice on which format to go with could be driven on several factors. If you are memory bound and memory usage is critical then we suggest using PVRTC. But we need to keep in mind that it’s a lossy compression format so it might generate unavoidable artefacts and compromise on quality or detail due to the limited number of bits per channel. For elements like UI/ icons we would usually expect high quality so this might not be the right choice. Alternate formats like RGBA4444 might be more suitable depending upon the platform’s support of texture formats.

Best Regards,
Nagnath