Part 6 - Compressed Textures

By Richard Davey on 25th November 2016   @photonstorm

Phaser CE All code shown here requires Phaser CE, version 2.7.0 or above.

Compressed Texture support was added to Phaser CE. The feature allows you to use PVRTC, DDS, ETC1 and S3TC texture formats in your games.

Using compressed textures allows the GPU to decode, and access, the texture data much faster than traditional image compression schemes such as JPEG. iOS devices in particular benefit greatly from using PowerVR Texture Compression (PVRTC). The resulting textures take up less memory than their traditional counterparts, and when it comes to iOS, every bit of memory helps!

It's also possible to achieve better compression rates in some cases:

image

Lots of popular tools export compressed textures, including Texture Packer, PVRTexTool, DirectX Texture Tool and Mali Texture Compression Tool.

Supported Texture Formats

The supported texture compression formats are: PVRTC, S3TC and ETC1.

The supported file formats are: PVR, DDS, KTX and PKM.

The formats that support all 3 compression algorithms are PVR and KTX.

PKM only supports ETC1. And DDS only supports S3TC for now.

Creating Compressed Textures

In this example we'll use Texture Packer to create our compressed texture. When starting Texture Packer be sure to pick either the JSON (Hash) or JSON (Array) formats, and not the Phaser format, or the option will be hidden from you.

Add all the sprites to your atlas as usual:

image

And if you look carefully, in the Texture panel on the right there are drop-down lists for 'Texture format' and 'Pixel format`. These should be changed to whatever you need, and then exported.

Load your textures

To use compressed textures they need to be loaded via Phaser.Loader. You use the same call as before (load.image), but instead pass it a new formats object:

function preload () { 

    game.load.image('factory', {
        etc1: 'assets/factory_etc1.pkm',
        s3tc: 'assets/factory_dxt1.pvr',
        pvrtc: 'assets/factory_pvrtc.pvr',
        truecolor: 'assets/factory.png'
    });

    //  The old way is also still supported:
    game.load.image('factory', 'assets/textures/factory.png');
}

The truecolor property points to a standard PNG file, that will be used if none of the compressed formats are supported by the browser / GPU.

The first format Phaser comes across that the GPU supports will be the one loaded, falling back to good-old PNG / JPG if specified.

Internally it will then parse the compressed texture, extract the data needed from it, and set it up so that WebGL can use it. All you will need to worry about is providing the files and slightly tweaking your loader calls, everything else happens behind the scenes.

Compress for mobile

If you're targeting mobile browsers specifically, then compressed textures can have a dramatic impact. Despite the name ('compressed') the files it generates are not always smaller than standard PNGs, but when they hit the GPUs memory, that is when they come to life.

As with most things it's a trade-off (file size and / or workflow complexity vs. performance), but at least in Phaser CE you have the option.