- Yves "Jack" Albuquerque
Unity 2D shader for mobile/TV
Unity is really smart in several stuffs. Unity is awesome in choose a good compression format, it works by analising what channels are available and then taking the "most compatible" format for that target platform. Most guys just use the default importing settings and have good results. However, this also can lead to some undesirable result. The surprise comes when someone figure out the huge size of the compiled file some months after the project starts. Sometimes the amont of RAM being used is also a signal that something is going on.
A good way to deal with that is set the importing settings manually. First thing is change all your importing settings from image files to Advanced. Make sure that Mip Maps are absutelly necessary before go on as it add about a third of the regular size. Mip Maps are really awesome if you'll have an image in diferent sizes on your screen, but if you are using a sprite, and it appear at a single size, maybe you should consider turn it off.
But let's deal with the compression. If you look over the web, you'll find something like "use ETC format for Android", "Use PVRTC format for iOS" and "Use DXT for desktop platforms". Good general rules as it garantee the device compatibility but, as we can see, some problems can arises from it.
You can find about the size-format relationship here. Following our dev instinct, we can say that smaller formats had wrost quality than the larger ones. Makes sense but is not always true. Also this wrost quality can sometimes be seamless.
Let suppose that your use is a very discrete one, like some secondary particle effect or a bullet that cross your screen in about 1 sec. Well, you probably should look to the smallest fomat. Maybe some 2 bit or 4 bit format is the wisest choice.
If you need a ok quality and your image don't use Alpha channel or don't need a smooth edge, you really should look to the 4-bit formats as ETC.
On the other hand, if you need quality and smooth edges, you`ll need an expensible format but this don't means that you need some kind of 32-bit true color or something like that. Most times a 8 bit-formats can deal with a pretty good result.
If you're executing a test following the above rules, you'll probably see some awesome results but before you become too excited, let me say something: If your GPU is not compatible with some of those formats, usually, it will not stop working or returns a error. It will just pay the price to decompress the texture, which is, most time, somewhat expensive. That's why, for instance, most Android developers just say: Use ETC (ETC is not ETC2) as this format is supported by all target android devices.
Ok, now you know that you can reduce your files and knows that you really need to be sure what formats you're suppose to use, let's see some advanced stuff.
If you are targeting iOS, you're on the PVRTC world. Probably wandering if you should use a 2 bit or a 4 bit format and if you need the Alpha channel. The PVRTC 2-bit without Alpha looks ok for small things but this PVRTC 2bit with Alpha sucks (but you can use for some particle effects or minor effects). PVRTC 4-bit without Alpha works fine even for major assets but the PVRTC 4-bit with Alpha isn`t good enough for your main character. And, well, there's no other options until 16 bit.
If you a targeting Android, there's a bunch of options. If you are developing just to Power VR systems (Probably not your case), you can even use the PVRTC format as on iOS. If you are targetting OPEN GL ES (GLES) 3.0 or supperior (Excluding Low-end devices), you should use ETC2. If your target is just the top devices (OpenGL releases after 2012-august or something supperior to DX11.3) you probably should use ASTC. But if you need some jack of all trades format, you really need to use ETC-4bit and the main problem here is that you just have RGB channels (No Alpha).
The problem is even worst if you are doing a 2D game and creating sprites. Unity-users usually packs their sprite into a single texture by giving a "Packing tag". An awesome solution for several reasons but unfortunately, this throw away all our work so far since the texture pack has it`s own format (RGBA 16bit) so to ensure some benefits here, make sure that you're not packing the compressed sprites.
Also, remember that you need the texture size to be POT (Power fo Two) in order to use Sprites. (Reescaled textures to POT don't compress to ETC) .
New 2D Unity tools enables a Sprite Pack in ETC format spliting Alpha channel from the regular base. This will be a boost on 2D development. While this's not a real thing built-in in Unity, you can use some custom shaders intead of the built-in sprite shaders in non-packed sprites.
To help you with this task I've uploaded two sprite shaders ready-to-use to the programming gallery.
The first one is a composition using a regular RGB and an Alpha channel. Is really easy to use.
First, duplicate your image. Then change your importing settings so one image will use some RGB format (as ETC) and the other one Alpha 8. Yep, we'll create a mask here taking the Alpha value from another image file.
Alpha 8 is too much for an Alpha channel isn't? No problem. You can also use two RGB images, being the second image a mask (R is our maks, G and B does nothing here but I promisse some really cool shaders using it in some next post). On this case, you will need to open and edit the second image putting your Alpha Channel on the red channel. If you're using Photoshop, maybe your transparency don't use Alpha channel so you probably need to create an appropriate Alpha Channel.
Just replace the material used in your sprite by some new material using one of these solutions and plug your textures.
That's all folks.
"Leggimi lettore se ti diletti di me, perché son rarissime volte rinato al mondo."