We’re having some issues with high memory use of our app on Android devices. We use Unity’s sprite packer for packing our UI sprites into atlases. On iOS this is very efficient, since each 2048x2048 atlas only takes up ~2 MB of memory when loaded in at runtime. This is using the “RGBA Compressed PVRTC 4 bits” compression. However, using the same compression on Android, each 2048x2048 atlas takes up ~16 MB of memory, which is rather problematic, especially on old Android devices with little memory.
Now, what we’ve tried is to use other compression methods on Android. I’ve found various posts and articles suggesting to use “RGB Compressed ETC 4 bits” and then using the “split alpha channel” method. This works in editor and the sprite atlas does also get reduced to ~2 MB at runtime on Android devices, but unfortunately it also causes all UI to turn magenta.
Another method was to use “RGB + 1-bit Alpha Compressed ETC2 4 bits”. This one doesn’t turn pink when used on Android devices, but obviously soft edges of sprites become rather ugly and even worse, it’s only on newer devices that it actually results in reduced memory load. On older devices, this compression method still takes up 16 MB of use for each 2048x2048 atlas.
What is the best way to reduce texture load on Android devices? I know there’s probably no general answer to this, but I’ve read so many different suggestions based on different Unity versions that I don’t know what to trust anymore. There’s always the option of reducing texture size (which is what we do currently), but that looks bad on high end devices. There’s also the option of having different atlases for different devices, but that doesn’t seem to be something Unity easily handles and would end up becoming rather cumbersome to maintain. We’re using Unity 2017.2.0p3 by the way.
Hi!
A 2048x2048 texture using 16 MB of memory means it gets decompressed when the application is loading, and also that the compression format is not supported by the device.
PVRTC is good for iOS, since all the device support it. On Android the situation is not that shiny 
ETC1 is supported by most devices, but doesn’t support alpha channel. The “split alpha” option creates two textures, one with RGB information and one with alpha information, both in ETC1 format.
ETC2 is supported by a smaller range of devices (it is required by OpenGL ES3 standard, as far as I remember, so all devices without OpenGL ES3 support are likely to not have it). If one-bit alpha is not enough for you, you can use “RGBA compressed ETC2 8 bit” format. A 2048x2048 texture would occupy 4MB in this case.
As for the UI that turns magenta - what UI system and what shaders are you using?
Thanks for your fast reply. First of all, I’ve created a simple project to test these things and I am just using Unity’s own UI system, with whatever shaders is used in that, as well as the (legacy) Sprite Packer. It should be mentioned that if I don’t use the legacy sprite packer, but the new one, sprites doesn’t turn magenta, but they still look bad (repeating pixels around the edges).
I have also been trying out the “RGBA compressed ETC2 8 bit”, as you suggest, but again, it’s only on newer devices that we get the advantage of the low memory atlases. On older devices - Samsung Galaxy 3 Tab Lite (Android 4.4.4) in this case - the atlases are still 16 MB when using this compression type.
All ETC2 modes would be restricted to the newer devices, regardless of what exact format is being used.
Could you post a screenshot please?
Sorry about the late reply. Below are screenshots of what the result is like (sorry for the terrible ‘art’
):
This is what it’s supposed to look like:
The camera renders to a solid, white background so everything white is basically transparent in the sprites. Now, this is what it looks like if I do tight packing:
And if I do non-tight packing, I get this:
It’s probably even intended, or at least expected, since it also happens in editor. In any case, it doesn’t seem to change the fact that there is no compression that - on old, low end Android devices - will make a 2048x2048 atlas take up any less than 16 MB. Or 4 MB in case of a 1024x1024 atlas. Is that correct?