Texture Compression Update
We’ve previously had quite limited options for texture compression for our platforms.
The ones we’ve had have been mostly focused on mobile platforms (ETC1 and Pvrtc1).
Now we’ve updated our pipeline to support ASTC, ETC2, BCx and RGTC formats.
To do this, we use a library called Basis Universal from Binomial.
What does it do?
Traditionally, textures are compressed on the development machine, into a format that (hopefully) is supported on the target user machine. However, if the target machine doesn’t support that format, you have to mitigate that somehow (e.g. separate bundles).
Basis Universal instead compresses into a generic format that gets shipped with the game.
When the game runs, we check what hardware compression formats are supported, and then ask the basis library to transcode the compressed basis texture into the hardware format we want.
That way you can use the same bundle for multiple versions (e.g. old and new android devices)
Texture Profiles
The way it works is that you choose a texture format (say TEXTURE_FORMAT_RGBA
) for a set of textures.
Then you choose the compression type.
If you chose DEFAULT
, which means no compression, you’ll get the format you asked for at runtime and the data will be uploaded to the GPU uncompressed. This might be good if you wish to upload a new version of the texture at runtime.
If you chose BASIS_UASTC
, the texture will be compressed into a .basis
file (internally), with possible mipmaps.
Fallback strategy
Note that the texture format you specified, will now act as the fallback format, in case the graphics card didn’t support any suitable compressed formats.
You can see the actual code here
The current fallback strategy is fixed, and it favors quality over size (e.g. ASTC over Pvrtc1).
Performance
The size of the compressed texture stored on disc will be 1 byte per pixel. Also note that we have LZ4 compression on the entire game archive, so the actual size is a little bit smaller still.
To compress faster, the texture compiler itself uses up to 8 threads to compile the texture.
A big (commercial) project with ~1.5gb of textures takes ~15 minutes on my machine.
I also happen to know that the authors of Basis Universal are working on improving both the size of the compressed textures, and also the compression speed with ~2-3 times in the next few months.
At runtime, the texture will transcode into the final format before uploading to the GPU. This step takes ~5-15ms per texture. It is currently done on the loader thread, but one of the next tasks is to move the transcoding work to the texture upload thread.
Also, don’t forget to check the texture sizes at runtime using our Web Profiler!
It’s an easy way to see if the textures were uploaded to a hardware supported compression format on your device.
WebP
For engine size (and performance) reasons, the previous compression format WebP has been removed.
For backwards compatibility, we convert the compression type like so
* WEBP -> DEFAULT
* WEBP LOSSY -> BASIS_UASTC
Notes
Note that I’m also working on upgrading our OpenGL backend to support OpenGLES 3 and WebGL 2.
This is needed in order to support ETC2 on Android, and ASTC on iOS. I expect this work to be done in a few days.
Interestingly enough, the Android devices I have tested on, already support ASTC, so that’s something you can test right now.
Feedback
We’d love to hear your experience with this feature, and to see if there are any issues that pop up.
You can get the build from the Alpha Download Page.