I’ve read that regular DXT compression is not suitable for normal maps, and that’s why DXT5n was invented. But when I look in OpenGL documentation, I only see GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, nothing for normal maps. So how do I load compressed normal maps??

dxt5n? Never heard about it and I can’t find any valuable information. I know that swizzled dxt5 or 3dc compression are commonly used to for normal maps compression, though 3dc is only supported on ATI hardwares.

I read on some NVIDIA page that 3Dc can be loaded as RGTC in OpenGL.

Edit: http://developer.nvidia.com/object/real-time-normal-map-dxt-compression.html

Yes that gives you one more chance to be able to load 3dc compressed texture if your hardware supports the GL_EXT_texture_compression_latc extension. But I do not not if it is widely supported.

IMO 3dc is worth to try since all quite recent ati hardware should support the GL_ATI_texture_compression_3dc extension and nvidia ones should support the GL_EXT_texture_compression_latc one which has a reason to live only on non-ati hardwares.

DXT5n is DXT5. The only difference is, that you swizzle the x,y,z channels differently for better quality. Maybe you even discard one of them and recalculate it in the shader, don’t know the details anymore.

You don’t need additional hardware support for it, it only means, that you use DXT5 in a way that gives best results for normalmaps.


Chicken scratches from the past on that:

“Also, if you’re using tangent-space normal maps, you only need to store two components: X and Y (z = sqrt( 1-xx-yy )). Store them in alpha and green for best accuracy. Often referred to as DXT5N or DXT5NM (normal map) format, where specifically A=X, G=Y, sometimes setting R & B to Y.”

Yeah, you can do object-space normal maps too, but the quality of course isn’t as good.

See the “Normal Map Compression” chapter in <u>ShaderX2: Section 2 – Rendering Techniques</u>, which you can download using this link. Also see this Normal Map Compression whitepaper from ATI. Also search for DXT5 in Engel’s An HLSL Primer for Developers.

Nowadays you’d prefer LATC2 for tangent-space normal map compression (essentially ATI’s old 3Dc) as you get 2 8-bit exemplars and 3-bit per-texel interpolants per block, vs. DXT5 where you only get this for alpha but have to deal with at most 6-bit exemplars (green) and 2-bit per-texel interpolants.

How do I detect if a dds file is 3Dc/LATC/RGTC? NVIDIA’s texture tools documentation says they support these formats, but I don’t have Photoshop to try creating a file and see what it puts in the header if they are specified…

Same as your last post about sRGB, check out the dds headers:

Good luck then if you have to supports simultaneously DX10 and DX9. Look at the fourcc value when reading DX9 dds files.

Sticking to non-DX10,
I see in an NVIDIA dds loader that 3Dc uses a four-CC value of ATI2
Can I assume then if the four-CC is that that I can straight-load it as GL_COMPRESSED_RG_RGTC2? i.e. glCompressedTextureImage2DEXT(_id, GL_TEXTURE_2D, mipLevel, GL_COMPRESSED_RG_RGTC2, mipW, mipH, 0, sz, image->GetData() + mipOffset);
where the data has been fread in the same way as with DXT formats?
And is there any file format that stores GL_COMPRESSED_RED_RGTC1? There is a four-CC of ATI1, but I haven’t found any definition of this format, I just see in code that the block size is half of ATI2. Could it be what I’m looking for?

By the way, dwMipMapCount is defined at MS’ site as “Number of mipmap levels, otherwise unused.” That doesn’t explain if the base layer is counted!

I’m not a D3D guy, but I believe the DX10 format codes for LATC1 and LATC2 (aka RGTC1/RGTC2) are BC4 and BC5.

…though you said non-DX10. I don’t think these are supported on pre-DX10 hardware on the NVidia side at least (i.e. pre-GeForce 8). So prob won’t find a cross-vendors LATC1/RGTC1 D3D analog.

By the way, dwMipMapCount is defined at MS’ site as “Number of mipmap levels, otherwise unused.” That doesn’t explain if the base layer is counted!

Yes, it is confusing:

  • if there are no mipmaps (single image), dwMipMapCount == 0
  • if there are mipmaps, dwMipMapCount == total number of mipmaps images
    That’s for 2d images anyway, knowing MS, I would not be surprised if it is totally different for cubemap or volume textures.