noobtuts

Unity Textures

Foreword

Unity has a great texture system. It's straight forward to use, but there are a few important things to know about it in order to create high quality games.

Test Scenario

To test a few things, we will create a new Project, create a new script called Tex.cs and attach it to the Main Camera. The script looks like this:

using UnityEngine;
using System.Collections;

public class Tex : MonoBehaviour {

    public Texture2D t = null;

    void OnGUI() {
        GUI.DrawTexture(new Rect(0, 0, t.width, t.height), t);
    }
}

We will also need a test texture, so let's use a "make a game" logo:
make-a-game-logo

After attaching the script to the camera and adding the texture to the project, all we have to do is drag the texture into the Tex script's "t" variable like this:
tex-script-t-variable

If we press play, we see the following:
texture-default

It looks weird. The picture is slightly unsharp and the aspect ratio doesn't really fit. It looks stretched, but why?

Texture Dimensions

Our logo has a size of 300x100 px, this is the reason for our first problem. Unity always loads textures with a power of two size (examples: 2x2, 4x4, 8x8, 16x32, 128x256, 512x1024, 2048x2048 and so on...). If our texture doesn't have a power of two size then Unity scales it so it has a power of two size, that's why it looks so stretched.

The simple rule is always use power of two textures if they should look good.

The question is, why is Unity doing that? Such a sophisticated game engine, yet we can't use all sizes. The reason is that older graphic cards only supported textures with a power of two size. And since Unity games should run on as many computers as possible, they just force a power of two size.

Let's create a new logo with the size of 512x128 px (which are powers of two) and see how it looks after we press play:
texture-power-of-two
Nothing is stretched, it looks perfectly fine.

Texture Compression

Usually people stop thinking about textures as soon as they understood the power of two concept. But there is more.

Unity has a Quality Settings feature like we know it from all the other games. It can be used to set the graphics to Fastest, Fast, Simple, Good, Beautiful or Fantastic. Now the thing about the Quality System is that in some cases Unity adjusts the quality automatically even though we didn't tell it to adjust the quality (the Quality system can be used with scripting). The best example is when we build games for the web or for phones. Those platforms can't handle Fantastic graphics, that's why Unity sets them to Fastest (or similar) instead.

Here is how our 512x128 texture looks on a phone or a web browser at the moment (with Fastest setting):
texture-power-of-two-fastest

Uah!

First off: this is good. If the texture would be attached to a player's hat or something like that, we wouldn't really see a quality difference since it's just a little detail in a 3D world anyway. The only difference that we would see is a fps increase, which is great. The Quality System does an excellent job, the problem is that we didn't configure our texture properly.

Let's select our texture in the Project area and take a look in the inspector:
texture-in-inspector
The important thing is the Texture Type. Here is what we need:

If we select GUI for Texture Type and press Apply, this is what we get on phones and web browsers:
texture-power-of-two
Perfectly clean and sharp!

Now this doesn't mean that we should use the GUI type for everything. If we do that, we will end up with serious performance problems. Just use GUI when it's really necessary for a texture to look highest quality no matter which platform or Quality Setting is selected.

Render Textures

This was about all there is to know about Textures in Unity. One more thing though: we might stumble upon Render Textures every once in a while. Those are basically placeholders. They are used in combination with an extra camera in our scene. We still see the world through our Main Camera, but the extra camera renders the world from where it sees it into the Render Texture.

The best usage example is a Rear-View mirror in a car game. In that case the extra camera would be behind the car, and the Rear-View mirror would be the Render Texture.

Note: Render Textures can slow down your game's performance very quickly.