Captain Peter Hager for sending me his A340 as a nice test case for texture compression. Peter (like many aircraft authors) has never been very happy with the artifacts introduced by DXT compression.
First the basics: DXT1-5 are a series of texture compression formats. They store the same number of pixels in a smaller number of bytes via clever encodings of the pixels.
When your image has no alpha channel, the savings from DXT1 compression are 8:1. (Modern graphics cards store RGB images in 32 bits for alignment, so the 4-bits-per-pixel DXT encoding is an 8:1 savings, not the 6:1 you’d expect on paper.) RGBA images take 8 bits per pixel, for a 4:1 savings. That’s as much as reducing the image size by a factor of 2 in each dimension.
DDS is an image format that contains a compressed image. DDS files load faster (because the image is already compressed), look better (because the image is compressed using a slower, higher quality process before sim load) and let you pick the DXT algorithm choice. (In some cases, the choice between DXT3 or DXT5 matters!) However, once an image is compressed into a DDS file, the pixels lost in compression never come back – DXT is a lossy compression format! (This is just like saving a JPG as a PNG – if the JPG quality was too low, the PNG will contain the same blocky artifacts that the JPG had.)
Compression is useful for more than just saving VRAM – because the amount of data needed to texture a given pixel is smaller (4 bits per pixel instead of 32) compressed textures can speed up framerate if the memory bus between the GPU and its own VRAM is congested.
Now let’s look at some pictures.
This is the Swiss Air livery at extreme res, uncompressed, sourced from a PNG. This is our reference image for how good the original image can look before we start trading off quality for VRAM.
This is the same image, extreme res, texture compression on, sourced from a PNG. It just looks awful. The graphics card has done the compression, and it has done a fast job, not a high quality job. (In the driver’s defense, X-Plane asks for a fast compression rather than a high quality one to avoid slowing the sim down.)
This is also compressed!!! But in this case the livery was pre-compressed using XGrinder/DDSTool (which in turn uses libSquish). DDSTool sets libsquish for maximum quality and then takes quite a while to grind each texture, but the results are better use of those compressed bits. (DXT is a lossy compression, so more compute time can find a better use of the finite quality available in the compressed texture.)
Finally, this is the uncompressed texture at “very high” res – that is, taken down one resolution level. Compare this image to the compressed one above. For an alpha-blended texture, the trade-off is one “size” increment (2x smaller on both sides for 4x VRAM savings) vs. compression. I submit that the compressed version is a better way to save VRAM than down-sizing.
Have Your Cake and Eat It in X-Plane 10
In X-Plane 9 you had to make a trade-off: ship a compressed image in a DDS file and have the very best look be extreme res compressed or ship a PNG file, and have the texture look terrible when texture compression is on. You can see from the above images what the options looked like.
In X-Plane 10 you can do both. If you ship a DDS and a PNG file, X-Plane will load the PNG file when texture compression is off and the DDS file when it is on. The result is a pre-compressed texture for users who need texture compression and an uncompressed texture for those who can afford the VRAM.
VRAM and Memory
One last note on texture resolution for users: most drivers use virtual address space to load textures, and thus texture memory eats into X-Plane’s 2/3/4 GB address space limit. Therefore with high VRAM cards (e.g. a 3 GB card) it probably isn’t possible to absolutely max out texture res until we go 64 bit. For example, on the Mac (where the driver uses a lot of address space and we only get 3.5 GB) running the sim on extreme + uncompressed texture res will almost always run you out of memory.
One thing I have noticed from looking at user’s settings and our own machines is that the textures resolution selector goes in pretty big jumps. Each resolution change cuts VRAM by 75%, so if you are over VRAM (and having performance problems because of that), the next setting down will probably leave VRAM unused.
So I have a todo item to look at putting incremental texture resolutions in that derez the scenery but not the airplane, for example, to hit some in-between points. In that context, we may be able to support mixed compression, where some airplane elements remain uncompressed, but the scenery is compressed.
The recommended practice for developers remains the same:
- If your textures look better without compression, ship DDS and PNG files, and pre-compress using XGrinder/DDSTool.
- If your textures don’t improve much by running uncompressed, ship only DDS files, pre-compressed with XGrinder/DDSTool.
One Exception: Orthophotos
There is one exception to the X-Plane 10 practice of shipping both DDS and PNGs: if you are using orthophotos via either a .pol or .ter with the LOAD_CENTER directive, use DDS and only DDS.
LOAD_CENTER causes your images to be reloaded at high or low res depending on the distance from the user’s aircraft to the image; this can save a lot of VRAM by reducing resolution where the user cannot see the detail. Because DDS contains pre-resized images, it is much more efficient than PNG for load center; I therefore recommend DDS-only for orthophotos.