Why you should use "Advanced texture type" more part 2 - Unity3D

Hey again,

Last time we talked alittle about what advanced texture type is in Unity. This time I will go deeper into the types of texture compression. But before we jump in xD I just want to say that this post is meant as a basic entry guide to the big world of texture compression, which I'm still beginner at and I'm exploring it with you. So let me know your feedback and what you think! And again this isn't meant to be detailed explanation of every thing. - if you want more details, I will add references below.

All the textures compression discussed here you will find them in Unity "advanced texture type" , with more detailed names. In order to make it easy for you to understand these names, I will add a little section at the end for that :) .

Let's start with what the need for texture compression is for. For example, you can open any png image on your pc (let's say it's a 1024x1024 size) you will find it around 1mb that's not bad, right ?

Well, the truth is most of these compression formats "png, jpg" aren't directly supported on the graphic cards, and once they are loaded into the game, they are decompressed into their full size - which is the RGB or RGBA format.
So truth is RGB and RGBA aren't a compression at all. They are the decompression which will take around 4mb with alpha channel if it's 1024x1024 size.
You enter a png image into your game with the size of 1mb. The user runs your game and this 1mb image decompresses in his graphic card to 4mb , this is bad xD

This is where other texture compression techniques come in place :

When considering texture compression, there are a few things that come in play:
   1. Small texture size.
This one is obvious. It depends on the compression type and your target quality that defines how far you decrease in size. This is also important because it decreases the memory bandwidth needed as less data has to get accessed while reading the texture during rendering and that's why in most cases it increases the performance.

   2. Fast Decompression.
Also this is an understandable point as the textures need to be decompressed on the fly .

   3. Fast random Access.
Well, imagine a single mesh (car model for example) covered with one texture. Only one side of this texture will be seen (UV mapping) so the texels  - or the part of the image that will be drawn - needs to be accessed fast.

Texture compression types :

The most used texture compression for pc and one of the oldest.
There are several types of DXT. The most notable (and used by unity) are DXT5  - which have alpha channel and provide around 75% less in size - and the DXT1  - with no alpha (as the one in unity). There is DXT1 with 1 bit alpha channel which mean that it's either fully transparent or fully opaque.

So what is the catch?

DXT can seriously decrease the image size and sometimes the effect of this won't be noticeable unless you zoom deeply in the images. But sometimes this compression can be really bad.
In order to explain when it's good, we will talk about how DXT works so bare with me xD

DXT splits your texture into segments each segment is 4 x 4 pixel which is 16 pixels for each segment let's imagine that this image is on the segments in our texture

Then what DXT do is it chooses the two extreme colors, which is the red (Top left corner) and black ( bottom right corner). Then it interpolates to get 2 colors in between, which means now we have 4 colors - the 2 extremes and another 2 that DXT interpolated ( the interpolated colors are something between the red and black). With this, 4 colors - which are called palette - are generated and all the 16 pixel will be linked to only one of these 4 colors. So all of these 16 pixels - which all have different colors or values - will be only 4 colors. Moreover, each pixel won't store the exact color value and it will just have an index in this palette and will save lots of size. This will turn the above image into this :

But the problem will arise when there are more varieties in colors in one segment for example:

Check this comparison image below and you will notice that outlines are the most damaged parts. So if your work has lots of outlines, it will be damaged severely.

One way to easy solve this is to increase the resolution. (Actually you will find this trick to work with most texture compression, and you will find a good decrease in size with very unnoticeable quality loss)

Ericsson Texture Compression is a texture compression format that operates on 4x4 blocks of pixels.
It's well known for being used for android devices and it's worth saying here that it's not supported on IOS. There is ETC 1 (no alpha channel ) and ETC 2 (either fully transparent or full opaque) and both take 4 bits per pixel.
There is ETC 2 RGBA 8 bits per pixel that has transparent channel.

ETC 1 : Supported on all Android devices with OpenGL ES 2.0 and above. Does not support alpha channel.
ETC 2 : Requires OpenGL ES 3.0 and above.
This texture compression won't be great at gradients and color contrasts areas in your images.

The most common (or for my knowledge the only) texture compression used for IOS. It's worth saying that you can use it for android or PC. It has great compression results. The artefacts come in the form of a slight blurriness. It's worth saying too that IOS demands the power of two images, and unity for example will always resize your image for the nearest power of two.

For a nice comparison with images between the above types check this blog :

A powerful new comer powered by Nvidia. Remember DXT, where it splits the images into segments 4x4 each? Well, ASTC is kind of similar but gives you the power to choose the size of blocks. So you can choose 4 x 4 or 10 x 10. The idea here is that you have more control of how large the size you want VS the quality you want.
It ranges from 8 bits per pixel (bpp) to less than 1bpp. This enables you to fine-tune the trade-off of space against quality.

There are a number of block size options available in the ASTC settings window. You can choose among these options and select the block size that best fits the assets. The larger the block sizes the higher the compression. Select large block sizes for textures that are not shown in great detail. For example, objects far away from the camera. And select smaller block sizes for textures that show more detail, like those closer to the camera.

The following table shows the compression ratio for the available ASTC block sizes in Unity for an RGBA 8 bits per channel texture with a 1024x1024 pixel resolution at 4 MB in size.

ASTC block size Size Compression ratio
4x4 1 MB 4.00
5x5 655 KB 6.25
6x6 455 KB 9.00
8x8 256 KB 16.00
10x10 164 KB 24.97
12x12 144 KB 35.93

Texture formats naming in unity :
(This is an optional part and is kinda a reminder for lazy people like me xD)
- In most types, you will find "RGB" at the beginning, meaning it has 3 color channels
- RGBA, meaning it also has an alpha channel
- Using the word compressed meaning yes xD compressed other than that it's not xD
- The number at then 2 bit , 4 bit or 8 bit .. etc . is the number of bits per pixel. The more they are the larger the size of the image is.
- Automatic: you leave texture compression selection to Unity.
- Crunched: newly introduced by Unity and it's amazing! It provides even less size with good quality but not supported for IOS.

Well, I hope you found some new information in this little post. There is still a lot to talk about and many things that I didn't get a chance to mention since I didn't want to complicate or lengthen the post. But please let me know your feedback or questions or anything in particular you are interested in.

References :

Again this awesome blog , I used many images for him so credits goes to him:

Written by :
Ahmed Mohi
Revisited by :
Ahmed Najeeb


Post a Comment

Popular posts from this blog

Service Locator design pattern for unity3D

Keys to Success Development Diary - Log #1