My Account


RSS
oZone3D.Net RSS Feeds»RSS 2.0 Feeds

Blogs
»Demoniak3D Blog
»JeGX's Infamous Lab

Sponsors



Link to Us

oZone3D.Net 100% Realtime 3D

»All Links

Web Partners

www.geeks3d.com
www.benchmarkhq.ru
www.tdt3d.com
www.steph3d.net
www.g-truc.net
www.worldpcspecs.com


Banners Exchange

www.jmax-hardware.com
cgindia.blogspot.com
grapejuice.c.la
www.game-lab.com


Links Exchange

»CYGAD's 3DXtra

Search
Google
Web
oZone3D.Net

Visitors Map

 
Normal Map Compression
Renormalization
Swizzled DXT5 - ATI 3Dc

By Jerome Guinot aka 'JeGX' - jegx [at] ozone3d (dot) net

Initial draft: March 11, 2006
Update: March 16, 2006


[ Index ]

Introduction | Page 2 | Page 3 | Page 4 | Conclusion

»Next Page







1 - Introduction

2 - Renormalisation

3 - Generating the Z component or Swizzled DXT5

4 - ATI 3Dc

5 - Conclusion

6 - Structure of the O3TC format and OpenGL Demo

7 - Further Resources

8 - Downloads




Required knowledge

1 - Introduction

The compression of texture S3TC is a destructive compression (with losses) rather like the jpg format, destructive in the sense that a part of the information contained by the non compressed texture is definitely lost after compression. For textures containing color data (color-map or classical image) this loss of information is not a problem, but for textures containing normal vectors (normal-map) this could be more problematic. We are going to see the problems caused by texture compression with normal maps and some techniques to resolve these problems.

Figure 1 shows the rendering of the accompanying project (available at the bottom of the page). We will use the Demoniak3D platform in order to test the various techniques to render the normal-maps.


Fig. 1 - Overall view

The different project files use the following vertex/pixel shader, written in GLSL (OpenGL Shading Language), to create the bump mapping:

OpenGL.org

[Vertex_Shader]
varying vec3 lightVec; 
varying vec3 viewVec;
varying vec2 texCoord;
attribute vec3 tangent; 
void main(void)
{
	gl_Position = ftransform();
	texCoord = gl_MultiTexCoord0.xy;
	
	vec3 n = normalize(gl_NormalMatrix * gl_Normal);
	vec3 t = normalize(gl_NormalMatrix * tangent);
	vec3 b = cross(n, t);
	
	vec3 v;
	vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
	vec3 lVec = gl_LightSource[0].position.xyz - vVertex;

	v.x = dot(lVec, t);
	v.y = dot(lVec, b);
	v.z = dot(lVec, n);
	lightVec = v;

	vec3 vVec = -vVertex;
	v.x = dot(vVec, t);
	v.y = dot(vVec, b);
	v.z = dot(vVec, n);
	viewVec = v;
}

[Pixel_Shader]
varying vec3 lightVec;
varying vec3 viewVec;
varying vec2 texCoord;
uniform sampler2D normalMap;
void main (void)
{
	vec3 lVec = normalize(lightVec);
	vec3 vVec = normalize(viewVec);
	
	vec3 bump = texture2D(normalMap, texCoord).xyz * 2.0 - 1.0;
	
	float diffuse = max( dot(lVec, bump), 0.0 );
	float specular = pow(clamp(dot(reflect(-lVec, bump),vVec),
					 0.0, 1.0), 
					 gl_FrontMaterial.shininess );
	vec4 vAmbient = gl_LightSource[0].ambient * 
					gl_FrontMaterial.ambient;
	vec4 vDiffuse = gl_LightSource[0].diffuse * 
					gl_FrontMaterial.diffuse * 
					diffuse;	
	vec4 vSpecular = gl_LightSource[0].specular * 
					 gl_FrontMaterial.specular *
					 specular;	
	
	gl_FragColor = vAmbient + (vDiffuse + vSpecular);	
}

This shader will serve as the reference for the demo’s different XML files. The variations will be found in the pixel shader along the following line:

vec3 bump = texture2D(normalMap, texCoord).xyz * 2.0 - 1.0;

Now let us make a closer analysis. To do this, load into Demoniak3D the xml bump_map_uncompressed_non_normalized.xml file. The rendering should be the same as figure 2:


Fig. 2 - Uncompressed and non-normalized bump map

Then load the xml bump_map_compressed_non_normalized.xml file. This code loads a compressed normal-map (bulge_DXT5.o3tc) with the O3TC format.

For information, do not forget that the 03TC format possesses practically the same characteristics as the DDS format. It supports the DXT1 and DXT5 compression and the mipmaps, in short, the essential elements for texture compression. The O3TC format is created with the DXTViewer tool. See part 4 for more information on O3TC format. A normal-map in DDS format will give the same result. The shader used is always the same.


Fig. 3 - Compressed bump map (DXT5)

We clearly see the damage due to compression. The specular highlights are very ugly, a sort of grid pattern has appeared. The grid pattern is due to the DXT algorithm which uses internally blocks of 4 x 4 pixels. Picture 4 clearly shows such a block. The large rectangle marks the block and the small rectangle marks a pixel. This picture was obtained by suppressing the bilinear filtering by default: it suffices to insert the filtering_mode="NONE" attribute in the texture element.


Fig. 4 - Block of 4 x 4 pixels used in the DXT1 and DXT5 algos

It is not really very visible in picture 4, but perform the test by disabling the texture filter and you will easily see the blocks.







[ Index ]

Introduction | Page 2 | Page 3 | Page 4 | Conclusion

»Next Page







Language:


Demoniak3D
Current Version: 1.23.0
»Demoniak3D
»Download
»Libraries and Plugins
»Demos
»Online Help - Reference Guide
»Codes Samples


GPU Caps Viewer
Current Version: 1.5.2
»GPU Caps Viewer
»GPU DB Submissions


FurMark
Current Version: 1.4.0
»FurMark
»Benchmark Submissions


PhysX FluidMark
Current Version: 1.0.0
»PhysX FluidMark
»Benchmark Submissions


Announces

Shop at CheckCost UK.Find Software products like Windows, Antivirus Software, Video Editing & more.


Modul8: real time video mixing and compositing



Geeks3D News
Page generated in 0.092303991317749 seconds.