Inverted tangent normal map

Started by
3 comments, last by unrealer2 13 years, 5 months ago
Hello all-knowing coding gods;) (thats NOT ironic)



I think our problem is easy to see in the picture above. We don't knwo why our engine inverts the normal map on the left hand side whereas for example xNormal renders a perfect smooth surface. The normal map is just the same for both parts of the model an the seam is the symmetry axis.

Anyone an idea? Something is wrong with baking the tangent spaced normal map to the model :(
Advertisement
You might just need to invert a single axis since one might use a right-hand coordinate system and the other one a left-hand coordinate system. Also some tangent spaces are defined BTN (x: Binormal, y: Tangent, z: Normal) and others TBN (x: Tangent, y: Binormal, z: Normal). You might need to switch them.
The reason is your tangent space is different than that used by xNormal for baking. Different "how" is anybody's guess.

It might be the case that you're exporting to a format that has no tangents, and xNormal is calculating them itself. Or, your engine is ignoring the tangents in the data and substituting its own.

There are many ways to arrive at a "plausible" tangent basis, but it's important that the renderer uses precisely the same basis as was used for baking the normal map, otherwise it will reconstruct a different normal.
Looks like in your engine you're not generating the binormal, but rather doing cross( vNormal, vTangent ).
It also looks the left side is has the same UVs as the right side.

When both things happens, the binormals of one of it's sides will be in the opposite (wrong) direction. The solution to this is either put the binormals in the vertex buffers, or use vTangent.xyzw, and write w = 1.0 almost always, and w = -1.0 where binormals are reversed.

Also another cause could be wrongly loading the normal map into the shader.
Some generators assume positive values XYZ go from [127; 255], while other generators assumes XY [127; 255] and Z [0; 255]. Check xNormal settings and documentation to see which convention is using when generating the maps.

If the normal map is in DDS format, check that if you're using a signed format (like U8V8) you don't do myXYZ = (texture * 2.0) - 1.0f (because that's done automatically for you). Same in reverse: check your shader isn't expecting a signed format and you're supplying the texture in an unsigned format.

Cheers
Dark Sylinc


Thank you! Now we are using the bitangents of the imported mesh and everything works fine.

This topic is closed to new replies.

Advertisement