This article covers how we can achieve better visual textures for games while still keeping to low memory footprints, thanks to efficient management of the visual results of texture compression. We will learn in-depth what type of visual results we can expect, and examines the use of the hardware DXT compression method. [Please note that the example textures can be clicked on to see higher-resolution versions of each example.]
Handy tools for this study:
To view, load, and save DDS textures, the following tools and resources are handy.
Developer.Nvidia.com has a set of tools for Photoshop to create and save DDS / normal maps.
WTV Viewer and DDS Thumbnail Viewer (provided by NVIDIA) are small and fast viewers that allows you to scroll through the folder images in explorer view and see the alpha of the DDS.
www.irfanview.com lets you quickly and easily read, scroll through and thumbnail the DDS images.
As we go through this article, we will be using NVIDIA's DDS Photoshop tool, as seen in Figure 1.0.
Please note that there are several other programs out there, including freeware, that will do the same task, perhaps with a better or worse result. As NVIDIA's DDS tool is commonly used within the industry, we will base the result from this article around its quality output.
DXT / Compression:
Throughout this article we will mainly concentrate on DXT1, as it the most useful format due to its effective memory size - a 1024*1024 texture is only 603KB in size. With a compression ratio of 1:8, DXT1 keeps the memory size low by using an algorithm that divides up the texture into 4x4 pixel blocks, where each block only stores 2 unique colors in the combined 3 channels from a 65k palette. If you careated a 16bit TGA texture with the same resolution, it would be 2.4MB in size.
Creating mods and games for PCs, we often have the fortune of large amounts of memory available, but creating art for low-spec machines, or even some next-gen consoles, is a whole different matter. We need to be more aware of how we use the memory available, and how we achieve the best quality for our textures. Knowing more about how DXT compression works, it can benefit you to use smaller-sized uncompressed textures, rather than increasing the texture size to compensate for the DXT compression and remaining within the same memory footprint.
As you most likely have seen, if you use a heavily compressed JPG, the texture becomes blurry, smeared and blocky. DXT has its similar blocky problems, as it will affect up the image in what can be seen as an uncontrolled way, something that can have devastating negative visual impact on our textures. We need to be aware and verify our output when saving out a normal black and white image as in Figure 1.1, where the original from Photoshop looks white and crisp the result after saving it as DDS could create something we see in Figure 1.2.
what happens with a small and simple texture like Figure 1.2, what
result can we expect from a larger, more complex in-game texture?
Let us start by looking at some areas where the DXT (and especially DXT1) format have problems:
Although not a true development example, this will still show how the compression can distort the result of your textures and alphas. When using heavily contrasted edges and lines within DXT, the variation in anti-aliasing can create blocks around the edges of the object. As we can see from Figure 1.3, there are two drawn circles. The left one has been antialiased by Photoshop while the right one has manually been adapted to retain its aliasing with a set of selective chosen gradients. We can then seeFigure 1.4, which shows the output from DXT1. To visualize the edge bleeding more clearly, we have intensified this image's saturation and brightness.
|Figure 1.3||Figure 1.4|
As we can see, the difference between the two circles are very obvious after the compression. The conclusion would be that using less anti-aliasing to smooth out high contrast edges and using reduced variation of colors can result in better remained visual sharpness in the texture.
Unique information in each channel:
Each 4x4 block within the texture shared by all channels can only withhold 2 unique colors. When trying to use each separate channel for unique information, the compression will distort the information of the combined result, resulting in almost unuseable information. Therefore, artists should refrain from using DXT in these occasions, due to its limitations for this purpose.
Blocky texture content:
If we study textures that rely heavily on gradient content, we can clearly start to notice the limitations of the 4x4 block compression method. Let's look at a light map, where the information is vital to define where the light is on the object, and how smooth the transition would be.
Comparing Figure 1.5 and 1.6, where Figure 1.5 is the original uncompressed data, we can clearly see that information gets distorted with the compressed DXT1 compression in Figure 1.6. To achieve higher quality, we can try various things:
- Use DXT3 or 5, with increased memory footprint.
- Increase the resolution of the textures, making each 4x4 block smaller.
- Limit the colors from the available palette in the original image.
- Choose an uncompressed format.
The concept and solution is very simple - the cleaner we keep the texture with the fewer variations, the better it's going to look. Let's take a closer look at an example where we will experience banding and pixelation, and see how we can improve on the final result.
16-bit Compression DXT1:
As mentioned earlier, DXT1 textures rely on 65k (16-bit) color information. Creating textures that involve large gradient variation will mean reduced quality and texture banding problems. Let's look at the result from a compressed gradient palette.
Comparing figure 1.7 and 1.8, we can see that the 16.8 million color gradient information from the original is fairly well-preserved in the compressed 65k texture version.
But let's take a look at a more practical development example. Using assets from Battlefield 2: Special Forces BFHQ, we will take a look at the visual quality when saved as DXT1 for minimal memory usage. The image is used in a menu screen, and it appears fairly up-close in an 800*600 resolution, so any large differences will be visible.
To achieve a different result, we will reduce the banding by applying a dither / noise filter on the image. This is something we can do very precisely, so we only put the filter where the gradient information is within the texture, and where we cannot paint in to keep the same uniform color. This method will add noise to the gradient, and prevent some of the banding appearing when using filtering inside the game. Doing this, we will need to filter out the area that needs to be adapted and apply monochromic noise, blended as soft light, with the following routine:
Filter out the area with painting selection mask, as seen in Figure 1.14:
- Create / Paint Selection Mask
- Add New Layer as 'Soft Light'
- Fill with color 128,128,128
- Add Monochromic Noise.
- Blend and tweak opacity of layer for best result.
Although not the most accurate blending, it gives you the option of less banding, and more variation in the interplay between the colors. Remember that a lot of noise will make the image look very pixelated, and less could create an ugly pattern, due to the fact that DXT selectively removes some of the noise in its 4x4 compression blocks. Keep the solid areas as clean as possible.
Whether you appreciate the blocky, banding, or pixelated output, remember that it is what you see in the game that counts. When image filtering is applied, having a bit of noise will make a large difference. The main problem is that there is no ultimate solution for the DXT1 compression and palette limitations.
Looking at Figure 1.17, 1.18 and 1.19, we can clearly see the difference when we are close to them. But let's take another look at the iamges - you will notice that the DDS compressed images seem to have a slightly different background color, and don't appear to have the same gray intensity as the original. Something happened when we exported the colors, and by using the eyedropper on the gray area behind the character in Figure 1.18 or Figure 1.19, we can verify that the background is no longer as gray as it was in the original 1.17. It has become slightly pink aswe saved it. Let's address this problem next.
Figure 1.14– Selection mask in PS
Figure 1.17– Original 32BIT TGA
Figure 1.18– DXT1
Figure 1.19– DXT1, w/ Noise
Green / Red DXT1 Compression Color Changes:
Working with the DXT image format, you may find it has a bad habit of changing the colors to favor large areas of green and red, even when you are compressing a clean, simple texture. Going back, looking at Figure 1.1 and 1.2 you can here see that the once-white background image became green after saving as DXT.
We can easily fix this by adjusting the original image from Photoshop before we save it out to DXT. Studying the saved image, we can determine what area is causing the worst color changes, and where we would need to adapt the colors, as shown in Figure 1.21.
Tweaking the original Photoshop file, we mask out the area as Figure 1.22, and add a combined color that has less of the changed color in it before we save again as Figure 1.23.
|Figure 1.21– DXT1, pink background||Figure 1.22– Masked area.||Figure 1.23- Filled BG green|
|Figure 1.24– Original 32BIT TGA||Figure 1.25– Final DXT1.|
As the result, the gray background appears more in line with the original, and we have managed to reduce the file size by using DXT1, but have been able to maintain as much visual quality as possible from the original texture. Compare Figure 1.24 and 1.25 for the final result.
Production Texture Analysis:
Let us now take this a step further, as we will look at a more complex real-world example. We will study the result from the AK47 texture we created in the book Game Art: Creation Direction and Careers. As we zoom into the texture, we'll look at how the colors and the compression are changing the texture, before and after it has been saved as a DXT1. During this process, we will also keep an eye on the histogram, as it will reveal what happens with the colors in the texture.
|Figure 1.26– original 32-bit TGA image|
Looking at the original Photoshop file in Figure 1.26, the image has an even gray intensity, and a red color dominates the texture.
|Figure 1.27– DDS saved image, take notice of the jagged histogram that represents the now 65k palette|
Studying the DXT1 Compressed image, we can see that it contains considerably fewer colors, making the histogram look more jagged. However, it's so far so good, as when we look at the textures, the difference is minimal. If we could stop the gamer from seeing the texture at a closer rangem this quality would be good enough. This isn't always possible, though, so let's zoom into the texture and study what happened when we compressed the texture.
|Figure 1.28– Original 32BIT TGA image||Figure 1.29– Compressed DDS|
The original image in Figure 1.28 still shows a wide range of colors within this cropped area, while the compressed image in Figure 1.29 shows that the colors within the area are definitely not what they once were.
Comparing the histogram from Figure 1.28 and 1.29, we can see that the green channel of the compressed image has fewer intense green pixels, yet they are more of them than the other colors in this area. Let us now study this in more detail, by continuing to zoom into the texture, and selecting a few pixels to see what the RGB value tells us.
Figure 1.30– Original TGA pixels are gray
Figure 1.31– Blocky 4x4 Compression with green pixel.
Figure 1.30 and 1.31 clearly shows you the limitations of the DXT 4x4 compression and the color changes. Up close, we can see that we did not just lose a lot of detail due to the compression method, but we also received a lot of green and pink artifacts. This ended up distorting the final visual quality of the image.
more precise, we can use the Eyedropper tool under the black square in
the original image in figure 1.30, where it shows an area of 6 pixels
with various amounts of 43/43/43 grays. The same area in the compressed
DXT in Figure 1.31 shows us that is has become one large area of a more
green-tinted color – 41/44/41. Using the earlier discussed method to
improve on this texture could benefit the final visual result.
When creating textures, the more contrast and variation we have within the texture and 4x4 pixels areas, the larger problems we will have when trying to keep the final result. When adding extra details as dirt and scratches in the textures, we should ask ourselves:
- When is it time to stop adding details, as the only result would be lost production time?
- What is our resolution of the texture of the final texture, how large is each 4x4 block going to be, and what type of detail would that support?
- What areas would risk showing up as pink and green spots within the game, and how can I improve on it before I save out the texture?
- When creating your textures, try keep them clean and free from a lot of close contrast in colors, gradients, and details.
- Knowing the 4x4 limitations, variation is not always good for the texture. Much of the fine details added to the texture can end up in lost production time, as it all disappears when the texture is compressed.
- Be aware of the limitation of the DXT compression ratio. If your objects / textures needs to be viewed up close DXT might not be what you want to use. It could be wiser to limit your color palette and use a non-compressed hardware DDS format instead.
- DXT1 is a 16 bit format. When you save it, you will lose information in your color palette. Beware of how you blend the information; using noise is one way distribute the colors, helping to remove banding.
[Images from BF2: Special Forces are used with courtesy from DICE. Additional material available at http://www.riccardlinde.com/ddsarticle.html.]