ATI tackled the problem of normal-maps compression and has developed a new format of compression to solve this thorny problem:
the 3Dc format. For a more detailed explanation on how the information is coded in the 3Dc format, see the following paper:
3DcWhitePaper.pdf.
The 3Dc normal-map compression works only on the ATI Radeon X800 and higher graphics
controllers.
At the OpenGL level, the 3Dc format is accessible via the GL_ATI_texture_compression_3dc extension:
Fig. 10 - The GL_ATI_texture_compression_3dc extension in HardwareInfosA new internal format of pixel must be declared:
#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837.
Except that, nothing special, the 3Dc being an usual DDS file, the loading is done like the DXT5. The 3Dc format uses the following
new FOUR_CC: ATI2.
That said, let us see in concrete terms what it would be like (since the time we hear about this format...). The principle of 3Dc format use
is the same than the swizzled DXT5 format: from 2 coordinates x and y stored in the compressed texture, we re-calculate
on fly the z coordinate in the shader:
//----- DDS file: reverse y texture coodinate.
vec2 uv = texCoord.xy;
uv.y *= -1.0;
vec3 bump;
bump.xy = (texture2D(normalMap, uv).ra * 2.0) - 1.0;
bump.z = sqrt(1.0 - dot(bump.xy, bump.xy));
The compressed data in the DDS format are Y-reversed compared to the other file image formats, so we have to invert in the shader
the Y coordinate:uv.y *= -1.0;.
Now, load the file bump_map_compressed_3Dc.xml into Hyperion:
Fig. 11 - Compression using ATI 3DcThe result is eloquent: the quality of uncompressed normal-map with renormalization is back. Really classy!
Normal-maps with 3Dc compression can be created with the DXTViewer or with the following
tool provided by ATI: The Compressonator.
The compression is done using Compress / ATI 3Dc Compression menu and by selecting the ATI2 format:
Fig. 12 - ATI - The Compressonator
Update: March 16, 2006:
The swizzled-DXT5 (or DXT5-xGxR) can also be created with the ATI's Compressonator tool:
Fig. 13 - Compression using the DXT5-xGxR formatThe pixel shader is the following:
//----- DDS file: reverse y texture coodinate.
vec2 uv = texCoord.xy;
uv.y *= -1.0;
vec3 bump;
bump.xy = (texture2D(normalMap, uv).ag * 2.0) - 1.0;
bump.z = sqrt(1.0 - dot(bump.xy, bump.xy));
And the result, available in the bump_map_compressed_DXT5_xGxR.xml file is shown here:
Fig. 14 - Compressed bump map (DXT5-xGxR)The interest of that format is that it is supported by any S3TC-complient graphics controller. But the better is coming.
Indeed, the ATI's 3Dc format can be created using a second method:
Fig. 15 - Compression with the 3Dc ATI2N alternate xy swizzled formatAnd this format is really handy since it uses the same pixel shader than the swizzled-DXT5 xGxR format. That means that according to
the hardware capabilities (3Dc support or not), we will be able to use the same pixel shader simplifying in passing the code management:
//----- DDS file: reverse y texture coodinate.
vec2 uv = texCoord.xy;
uv.y *= -1.0;
vec3 bump;
bump.xy = (texture2D(normalMap, uv).ag * 2.0) - 1.0;
bump.z = sqrt(1.0 - dot(bump.xy, bump.xy));
For the details, see the bump_map_compressed_3Dc_ATI2N_XY_swizzle.xml file.