Let us start with a little calculus. We would like to apply a cloud texture to our beautiful planet Earth in our super cool
solar system demo. The texture that we have is a 1539K size jpg file with a resolution of 4096 x 2048. As we wish to obtain a
transparent effect, we will load the RGBA float which is one of the available formats in Demoniak3D.
The question is: what is the size occupied by the texture in the graphics card memory?
With the RGBA Float format, each canal is coded onto a float. The float is a classic means for designating a real number.
A float is 4 bytes in size. Therefore a pixel or even better, a texel (texture element) is coded on 4 x 4 = 16 bytes. Finally,
the entire texture will occupy 4096 x 2048 x 16 = 134317728 bytes, that is to say about 128 Mb... On a standard 3D card, equipped
with a graphics memory of 128 Mb, this is rather large. More especially if the graphic memory is not entirely reserved for stocking
textures (for more precision concerning this last assertion, look at the respective graphics controller tutorial:
Graphics Controllers).
Four letters represent the solution to this tricky problem:
S3TC
S3TC has been the standard for the compression of texture for quite a while. The term S3TC signifies S3 Texture Compression.
S3TC is an algorithm for compression which possesses a number of variations, better known under the names of
DXT1,
DXT3
and
DXT5.
S3TC defines a class of algorithms for hardware compression and more especially for decompression hardware. In order to
be able to benefit from this, it is imperative that the graphics card supports S3TC compression. To check this, a rapid look
at
HardwareInfos will inform us. The card supports S3TC if, in the list 'OpenGL GPU Capabilities', one finds [+]S3TC. Another way of verifying is to show
the list of OpenGL extensions (OpenGL Extensions List button) and to find the extension
GL_EXT_texture_compression_s3tc.
Generally, a card supporting the S3TC in OpenGL, will also support it in Direct3D.
But what does the texture compression really offer us? The obvious benefit that texture compression provides is that a given amount
of texture data can be stored using much less memory, which may attain a ratio of 1 to 10.
S3TC texture compression allows more and larger (more detailed) textures to be stored in a smaller memory area and, at the same time,
significantly decreases the bandwidth required to access them, which is the real strength of compressed texture files: loading is direct.
There are no more long processes for texture file decoding and conversion into the best adapted pixel format for using it.
The standard file format for stocking compressed textures is the
DDS format. DDS comes from
Direct Draw Surface and
bears its name very well because the content of a DDS file is the direct copy (the name of the file format excepted) of the texture contained in
the graphic controller memory. This explains the rapidity of the DDS file loading, even for high resolution textures (4096 x 2048 for
example).
Another advantage is the presence, in the texture file, of
mipmaps. Mipmaps are copies of the base texture
(which are also part of the set of mipmaps), but for which the dimensions are successively divided by 2. If the base texture
(or mipmap 0) is size 2048x1024, the mipmaps (mipmaps 1 to n) will have the following sizes: 1024x512, 512x256, 256x128, 128x64,
64x32, 32x16, 16x8 and 8x4 if one generated 8 mipmaps. The term
mipmapping comes from the latin expression
multum in parvo
(many things in a small place), permits the graphic card to automatically chose the right mipmap in consideration of the distance between
the camera and the texture to be shown. The mipmapping algorithm may be resumed thus: the choice of the mipmap to be
shown (0, 1, ... 8) is proportional to the distance between the camera and the texture.
Mipmapping is very useful because it permits the reduction of visual defects to a large extent (noise in the texture) and
diminishes the delivery time. Just that! To visualise the reduction of the visual defects load
code sample 15
in Demoniak3D and compare the right and left surfaces. It is evident. The left-hand side is textured using mipmapping and the right-hand
side only has a simple texture.
Fig. 1 - Code Sample 15In the DDS file, the different mipmaps are already in the right format and of course are already compressed. This means that the
global loading time of a texture and its mipmaps is very rapid. To be convinced, make the test using the
DXTViewer.
DXTViewer is a tool which allows to see compressed S3TC textures. It also lets you know whether a given graphic card supports texture
compression.
DXTViewer is delivered with two test textures. The first is in JPG format and the second in DDS format. First load
earth_4096x2048.jpg (by simply clicking on OK in the Texture Loading Options box) and note the loading time which takes a number of
seconds (between 5 and 10 sec.). Now load earth_4096x2048_DXT1.dds. The loading is practically immediate!
Fig. 2 - DXTViewerNow let us see a concrete example with the elaboration of the Earth. For this, download the
code sample 100 and
load it into Demoniak3D. This code sample uses textures in large dimension in order to be realistic: 4096 x 2048 for the surface of
the Earth and 2048 x 1024 for the clouds.
Fig. 3 - Code Sample 100 - Earth seen from a distanceFigure 3 shows the Earth as seen from a distance, whereas figure 4 shows the Earth seen nearby. From a distance, the Earth is
shown without visual defects, and from nearby the details are preserved.
Fig. 4 - Code Sample 100 - Earth seen nearbyThe code of the CS100 does not present any particular difficulty. The texture of the Earth is shown in the following texture node:
<texture name="earth_tex" filename="data/earth_4096x2048_DXT1.dds"
filtering_mode="TRILINEAR" anisotropy="8.0" />
For the earth’s surface, the demo uses a compressed texture following the DXTI scheme. This type of compression is particularly
well adapted if the texture does not need an alpha component. DXT1 applies to RGB textures. For the cloud layer, it is another cup
of tea as one must manage transparency. Transparency is created using alpha blending and to do this we need a texture with an alpha
canal. But what should the alpha canal contain? In order to answer this question, let us have a look at the cloud texture:
Fig. 5 - Code Sample 100 - cloud textureThe aim is to have complete transparency for the black zones (alpha=0.0), to have no transparency for the very cloudy zones
(alpha=1.0) and partial transparency for the zones where the cloud layer is not thick (alpha>0.0 and alpha<1.0). Seeing that we
use a compressed texture format, it is not possible with Demoniak3D to dynamically modify the contents of the alpha channel. Therefore the
texture must be delivered with the correctly initialised alpha channel. In order to do this, we will use the DXTViewer, which will
make it possible to create this compressed texture containing correct values of an original texture file (clouds.bmp).
Start loading the texture clouds.bmp in the DXTViewer. Then choose the texel format (texel = texture element) RGBA Float and
choose Create Opacity Map. The latter option permits the initialisation of the value of the alpha channel as one requires.
An
opacity-map from the Demoniak3D point of view, is a texture whose alpha channel is the arithmetic mean of the three rgb channels.
Exactly what we need!
Fig. 6 - DXTViewer - Texture Loading OptionsOnce the texture loaded on the graphic controller, DXTViewer shows the compression format: DXT5. This format is the most widely
used when compressing textures featuring an alpha chnel. Now we only need to save the texture on the hard disk. To do this, we will
use the only format which is proposed by the DXTViewer, that is to say the O3TC format. This format, except for the file format heading,
is comparable with the DDS format. Now that we have our compressed cloud texture, we need only to load it using the following code:
<texture name="clouds_tex" filename="data/clouds_DXT5.o3tc"
filtering_mode="TRILINEAR" anisotropy="8.0" />
The transparency effect is obtained by activating the blending (mixture of colours) within the mesh node as this mesh will
receive the cloud textures with the blending_params element as shown by the code hereunder:
<mesh name="clouds_mesh" render="TRUE" shape_type="SPHERE"
lighting="TRUE" auto_spin="TRUE" texturing="TRUE"
back_face_culling="FALSE" >
<blending_params active="TRUE"
src_factor="BLENDING_FACTOR_SRC_ALPHA"
dst_factor="BLENDING_FACTOR_ONE_MINUS_SRC_ALPHA" />
<sphere stacks="60" slices="60" radius="51.0" />
<position x="0.0" y="0.0" z="0.0" />
<orientation pitch="90.0" />
<attach_material name="clouds_mat" />
<texture material_name="clouds_mat"
texture_name="clouds_tex"
texture_unit="0" />
<spin_values x="1.0" y="1.0" z="1.0" />
<vertices_color r="1.0" g="1.0" b="1.0" a="1.0" />
</mesh>
Choosing the BLENDING_FACTOR_SRC_ALPHA and BLENDING_FACTOR_ONE_MINUS_SRC_ALPHA blending factors leads to obtain this variable
transparency. Refer to the following tutorial to get further explanations on how to use these blending factors:
Blending.
nVidia proposes a set of tools for manipulating DDS files amongst which an export plugin for Photoshop (which
can also be used with PaintShopPro but I have not yet had the time to test it). This plugin is really useful for generating DDS
files containing mipmaps. For example, you may choose the compression type (DXT1, DXT3 ou DXT5), or else the number of mipmaps.
This set of tools is available at the following address:
NVIDIA DDS PLug-in.