The answer : Compression… VTC!
If something is too big and uses up too much memory then
there is always a way out called compression. NVIDIA probably did the
same math as I did and realized that implementing simple uncompressed
3D textures is a big no-no. Doing this would be like implementing a
useless feature, unless memory prices drop like a rock. Now,
the issue with compression is, as always, how do you do it ?
Texture Compression is not new, we already have various formats for compressing
2D textures. We have S3TC (DXTC), FXT1 and VQ (Vector Quantisation). The first two
techniques have compression ratio’s of up to 8:1 while VQs compression
ratio is resolution dependent (the higher the resolution the higher the
compression, goes up to 25:1).
There are some rules we need to keep in mind when selecting a compression
technique for textures. The main issue is that this we need real-time
access to these textures, so any technique we use must have a very, very
fast de-compression system. This means that complex, yet very powerful,
systems like Wavelets or JPEG are out of the question. They compress with
a fantastic ratio, but the decompression is slow. Another issue is that
texels must be individually available, so we can’t use a technique that
requires the decompression for the whole or a larger part of the texture.
So we need direct fast access to very specific texels using our technique.
The existing techniques are based on 2 principles, well actually one principle
known as a look-up table. But there are 2 different approaches to it.
The first approach used by S3TC and the more advanced (and visually better)
FXT1 spilts the texture in blocks, 4 by 4 texel blocks. For each of these
block a small lookup table is made, this lookup table contains 2 color
value (so an RGB(A) color). The individual texel colors are defined by
a mix/blend of these 2 base colors- which blend is determined by some
parameters. More details about this technique can be found here.
VQ works differently but is also lookup table bound. Instead of creating
small lookup tables for small blocks in the image, a global lookup table
is used. Actually the best way to explain this is as follows. Imagine
the texture map as big puzzle existing of small 2 texel by 2 texel ( or
even 3x3) puzzle-pieces. Using clever maths you can find puzzle pieces
that are almost identical, so instead of storing all the puzzle pieces,
some can be used several times. So the basic idea is to create a pool
of puzzle pieces (lets say 256 pieces) that are used to form the final
texture. The compression lies in the re-use of the same puzzle piece at
various locations. This principle is used a lot in compression of still
images and even video. Videologic's PowerVR chip supports this technique
and its used with great success in the Sega Dreamcast console. You can
read more about VQ here.
Now,
both these principles can be extended to 3 dimensional textures. The S3TC,
FXT1 principle of small zones with a small local lookup table can be extended
to small cubic zones inside the 3D texture. Each small cube gets some
base colors and the lookup value give each cubic texel a color based on
a blend of the base colors. The problem with this is that you need to
find some setup which has a good byte size. S3TC and FXT1 use block with
a total size of 64-bits (or even 128bits), a cubic extension should maintain
this size or move to 128-bit/256bit. These values are needed to make efficient
use of bandwidth (read in 128-bit or a multiple of that at every clock
tick). Finding such a setup should not be too difficult.
VQ can also be extended. Instead of 2D puzzle pieces we can use small
cubic volumetric puzzle pieces. The same idea applies: re-use of the puzzle
“blocks†delivers the compression.
At
this moment it is not known how the VTC compression works. Beyond 3D will
try to find out how it works and a detailed analysis of the quality
of this technique will be provided as soon as possible.
One thing to keep in mind is that a massive compression ratio is needed
to make 3D textures usable. The extra dimension does introduce more relations
between neighboring pixels, these added links can result in better compression.
Feel free to speculate about techniques and ratio’s in our
forum.
Another solution to the problem is the use of procedural 3D textures. Personally, I prefer this solution since procedural textures hardly use any memory and have an almost infinite resolution. Sounds cool, no? So what is it...
Procedural
textures are a bit like mathematical textures. Instead of providing a
true map saying this pixel has this color, you provide a mathematical
description of how a texture looks. For example, a checkered texture can
be generated very easily using mathematics (think about it). Now, procedural
textures on their own are worth a full article (and we plan to do this
soon) so I won’t go into details. Suffice to say, almost
all natural textures can be generated using mathematics, even the stripe
patterns of a zebra or tiger can be generated using a mathematical function.
The infinite resolution is a result of the mathematical basis of this
system (e.g. a sine has infinite accuracy too!). The low storage comes
from the fact that you only need to store the small program that mathematically
describes the texture (this is much smaller than true pixel stored textures).
This technique is used successfully in 3D ray tracers. Actually, procedural
textures is what make movies like Toy Story 2 look so cool.
The final and easy way out is, of course, to revert to using low
resolution 3D textures only. The big question with this solution is: "Is
it visually acceptable?".