Sunday, April 29, 2012

Texturing for Games - Basics

Texturing in video games is a slightly different animal than for film or rendered projects.  There are a couple of requirements to keep in mind and we'll go over why they are so restrictive.

1. Memory Footprint - The larger the texture the more memory it takes up

Of all the assets you import, textures take up more memory than most.  One of the surest ways to reduce over-all memory usage (from assets) is to reduce texture sizes.  This is pretty basic and obvious as a whole, but i want to treat the topic with a little more finesse than "Use smaller textures!".

So your standard asset now a-days will have, let's say, a diffuse(color) map, a spec, normal, and mayhaps an emissive.  Along with these you will end up with various masks and specialty textures related to specific assets. By default habit we end up usually starting with a diffuse texture then building the rest from there.  This often ends with each of these maps being the same resolution even though they shouldn't necessarily.

This is a very dynamic subject that must be checked on a per asset basis but here is some general info as I have found.  The basic idea is to try each separate mask as multiple resolutions until you get what you need to get the look you want with minimal texture resolutions.  There are many tricks that we can do to REALLY reduce texture sizes and texture lookups but that will be for later posts.

Example Time:


  • Diffuse on my character is a 1024x0124, i like the look and stick with it
  • I generate a spec map out of this but my spec needs little detail so i find that i can import it as a 512 and not get any compression issues.
  • My normal map requires some detail for pores and such but in general it needs little.
    At this point i usually end up with a detail normal (pores and such) that i overlay onto a specific normal for my character.  Now usually this wouldn't be very efficient but i use this normal on many characters so i only have to import it once.  So i have 2 textures, a universal 256x256 detail and a 512x512 normal map but only the 512 is character specific.
  • My characters armor has emissive(glow/incandescence)  for some sweet running lights.  On average emissive textures can be much lower res due to the nature of how they are handled.  Emissive textures are interesting cases solely because often they will use very small sections of a UV layout and texture sheet.  Some engines deal with this in different ways (Unreal Engine 3 has a nifty export tool to just export that important parts and it does some shader magic to make them line up), but otherwise we do our own tricks involving special UV channels to stress important areas specifically. In the end i get a 256 emissive texture.
  • By reducing these sizes instead of just going with the first resolution i chose i am using a little over half as much memory as my original sizes would have.

2. "Power of 2" rule - Textures have specific resolutions

So we talk about texture sizes in these specific sizes, each one being a power of 2 (starting with 2 and multiplying each result by 2 again).  The reason we do this is for some programming mumbo jumbo related to shifting bits around but we don't care much about that.  I will point out some things associated with it that are good to know in general though.

Some game engines do not require a power of 2 texture!  This seems like total awesome freedom at first but when we look at it closer we find there are problem with this!

Any texture that is imported, compressed, and built for use in game will be power of 2 eventually.  The engine itself will convert your texture to work properly which may result in some problems.  Essentially it is adding empty (black) space around the edge of your texture until it reaches the next power of 2.

Example: A 545x580 will end up being a 1024x0124!

So this is an extreme example but very important.


  1. That is all wasted space, why not fill it or increase your UV layout to match and get some free texture space back?
  2. This sort of thing leads to misjudging available memory usage/etc which may be important.
  3. In some engines, this conversion is done at RUN TIME! This means that when that texture is loaded into memory it has to up-convert it, which causes noticeably slower load times.
  4. Mipmaps may be corrupted.  Mipmaps are essentially smaller versions of the texture for use in LODs.  Like with reducing texture sizes in any program you get blurring between pixels.  When your pixels lay at the edge or similar colors it is not always noticeable but imagine your bright red pixel now has a bunch of solid black padding around it.

3. Compression - Post-import textures are converted for use in the game engine, resulting in various compression types. LOD, etc

This is just a quick note on compression.  Some engines do some hardcore compression to your textures and sometimes the only solution is to make sections bigger.  This is something you need to learn through intimate late nights with your chosen engine.  As a quick example, unreal ueses DXT compression mostly and it is just plain mean to dark gradients.

4. MultiTexture  per-channel masks

Sometimes an asset may have several black and white masks used for any number of specific circumstances.  If these masks don't mind certain compression risks they can each be stored into a single texture, taking advantage of the red, green, and blue channels as their own textures.  This takes up the amount of memory a single texture would for a total of 3 masks.

5. Alpha channels

Based on your game engine, compression on Alpha channels may be handled differently.  Some engines will double the texture sizes when an alpha channel is added because they assume you want less compression on them.


No comments:

Post a Comment