Blog Archive
-
Recent Posts
Labs: PVRTC PowerVR Texture Compression
April 7, 2011 by Sensei
Categories: Labs
One of the more confusing areas of development for iOS a developer may come across is PowerVR Texture Compression (PVRTC).
What is it?
PowerVR Texture Compression is a great technology developed by Imagination Technologies. They make the graphics chips in Apple’s iOS devices, and the chips come with this technology along with many others. Uncompressed images are big. Images, normally, must be uncompressed to be used on your graphics card. So a 512×512 jpg on your computer may only take up 100KB on your hard drive, when you display it, it takes up about 1 Megabyte of space in your video card.
Think of PVRTC as jpg for your video card. Instead of uncompressing that jpeg and sending a megabyte over to your video card, you can take a .pvr image and send it over, and it does not need to be uncompressed. PVR compressed images have a very specific, fixed compression. They can either be 4-bit, or 2-bit. 4-bit images take up 1/8th of the space of an uncompressed image, and 2-bit images take up only 1/16th.
Why would you use it?
On an iOS device, you do not get a lot of memory to play with. By using PVRTC you can fit 8 or 16 images in where you would normally only fit one uncompressed image. If you’re animating sprites, that is a huge benefit. If you have large images, you might have to use this feature in order to fit all your images into the graphics card.
When would you use it? (and more importantly when would you not?)
PVRTC is lossy, really lossy. Its like a jpeg at a quality of 40. But there are still many applications for this. Anything that is animated won’t need perfect detail, as its always moving. Particle effects, background effects, and other small animations can benefit. While PVRTC is lossy, its not that bad when the object is photographic. Large photographic images will look fine with PVRTC.
I would recommend staying away from using PVRTC on anything that isn’t animated or huge. Avoid using PVRTC when you have static images that are the focus of your content. Your hero and enemies that are the main focus of your levels should probably stay uncompressed.
How do you use it?
Apple has a ‘texturetool’ command line utility. It blows. Avoid it. Use the PowerVR tool ‘PVRTexTool’. I have seen people mention that there is no Mac version. This is incorrect. You can get mac, linux, and windows binaries here.
Quality Comparisons texturetool vs. PVRTexTool
(click for larger image) |
(click for larger image) |
I won’t go into the details of the different modes, but these are really the *only* compression options available. Where does PVRTexTool win out? transparency. PVRTexTool can preprocess an image before compressing, meaning it can premultiply the alpha. This provides a huge quality improvement on images that have alpha. I also could not get texturetool to output a working alpha channel. If you don’t have alpha, there will be little difference between the two programs.
This is an example of a large image that has no alpha. In a game environment, i think it would be difficult to notice the compression on a 4-bit image. On a 2-bit image it is much more noticable. But the savings on size are humongous!
Is there a performance improvement?
My limited tests say no. My test of iTorque2D showed an amazing memory improvement, but no real change in performance. I maybe saw a tiny performance increase, but its hard to say. But the numbers on memory are hard to argue with:
These are screenshots from OpenGL ES Driver info captured in Instruments. The small number is the frame number captured, and the large number is the number of resource bytes used.
The images used in PVRTC must be powers of two and square. Normal textures must be power of two, and can be non-square. So in order to make my tests I modified my 512×128 images to be 512×512 and my 256×128 images to be 256×256. That is a 400% and 200% increase in size. But you can see that the memory usage actually *decreased* by 3.8 Megabytes! That is a 15% decrease.
How do I compress my images?
The PVRTexTool gui is quite useful for getting started. Its an X11 app, so its a bit quirky on Mac. It is important to go to Edit->Preprocess.. and check ‘Pre-multiply Alpha’ and click ‘PreProcess’ if you are using alpha.
Specifically for iTorque2D, here is my project file to help you out. In the projectFiles/game/data/levels/datablocks/*.cs files you will want to remove the image extension from your .png/.jpg files. You’ll want to do the same from the projectFiles/game/managed/datablocks.cs file also.
Shell Scripts
And here are some shell scripts that have made my life easier. These automate the above GUI settings.
pvrTexTool:
#!/bin/bash # Generates 4-bit perceptual pvrs. # Example usage for a file called BlackNinja.png # pvrTexTool BlackNinja # Can take multiple files: # pvrTexTool file1 file2 file3 for file in "$@" do ~/Downloads/PVRTexTool/PVRTexToolCL/MacOS_x86/PVRTexTool -i $file.png -f PVRTC4 -p -pvrtciterations 8 -premultalpha -q 5 done
pvrTexToolPreview
#!/bin/bash # creates png previews for what the compressed texture will look like. # This does not create a .pvr file! ~/Downloads/PVRTexTool/PVRTexToolCL/MacOS_x86/PVRTexTool -i $1.png -d -f PVRTC4 -p -pvrtciterations 8 -premultalpha -q 5 -o $1_4bit_perceptual.png ~/Downloads/PVRTexTool/PVRTexToolCL/MacOS_x86/PVRTexTool -i $1.png -d -f PVRTC4 -p -pvrtciterations 8 -premultalpha -q 2 -o $1_4bit_linear.png ~/Downloads/PVRTexTool/PVRTexToolCL/MacOS_x86/PVRTexTool -i $1.png -d -f PVRTC2 -p -pvrtciterations 8 -premultalpha -q 5 -o $1_2bit_perceptual.png ~/Downloads/PVRTexTool/PVRTexToolCL/MacOS_x86/PVRTexTool -i $1.png -d -f PVRTC2 -p -pvrtciterations 8 -premultalpha -q 2 -o $1_2bit_linear.png