Original Post
Hi; I have been trying to cover my terrain mesh with a normal map for a long time now. I firstly tried regular tangent space normal maps; but the GeoMipMapping and GeoMorphing algorithms I am using proved it to be useless. (The vertex normals change between LOD levels, causing terrible popping artifacts.) Therefore I decided to use object space normal mapping instead. My terrain mesh consists of 1025x1025 vertices and for the normal mapping to be meaningful, the normal map texture must be huge in my case. For this purpose I am using a 4096x4096 sized texture holding an object space normal in its every texel. This texture covers the whole terrain, providing detail and light information. Of course, I needed to compress this huge texture, in pure ARGB format with its mip-map levels,it eats up to 80 MB of video memory! For DXT normal map compression, I found the following articles: developer.nvidia.com/object/real-time-normal-map-dxt-compression.html developer.nvidia.com/object/bump_map_compression.html ati.amd.com/developer/NormalMapCompression.pdf There are two approaches to the DXT5; in the first one, I put the x component of the vectors into the alpha channel, the y component into the green channel and the z component into the blue channel. In the pixel shader, I renormalize the vectors. The problem here is the banding artifacts, there are 32 different possibilities of directions in a 4x4 DXT block, but still the rough banding transitions between DXT blocks are visible. The second option is to derive the z component of the normal in the pixel shader. Although I use object space normal mapping, it is guaranteed that the z components of the normals will point into the positive direction. The reason is that on the terrain, there will never be a surface which will face towards the underground. I get the z by normal.z=sqrt(1.0 - (normal.x*normal.x +normal.y*normal.y) ). This method works almost fine, the banding is nearly non-existent, but sometimes the term (normal.x*normal.x +normal.y*normal.y) becomes greater than 1.0 and the sqrt operation gets totally messed up. The result is small-paper burn like stains on the terrain. Theoretically, (normal.x*normal.x +normal.y*normal.y) must be always smaller than 1 because of the normalized vectors. I believe this problem stems from the DXT compressor's way of building DXT blocks. (I use the D3DXCreateCubeTextureFromFileEx function of the DirectX runtime to build DXT5 format texture.) What should I do in this situation? I want to use the second method but the (normal.x*normal.x +normal.y*normal.y)>1 issue is a nuisance. How can I get rid of this problem? Thanks in advance