## Help converting normals from global space to tangent space

Apprentice
Posts: 5
Joined: 2007.10
Post: #1
Hi, I'm developing a simple normal map generator. One that takes two meshes, one lowpoly and one highpoly and creates a normal map for the lowpoly. (Yes I know that there exists such things already, but I'm doing it just for the kicks )

The result when rendering a global space normal map is quite satisfying but when it comes to the tangent space one it get's worse. I can't seem to get a grip on how to generate a tangent space normal map using the smoothed normals of the lowpoly model. I can however generate one that looks decent for the hard normals but such a normal map just isn't good enough for anything

This is how I was thinking when using the hard normals:

Where all the vectors are normalized and the two tangents are parallell to their corresponding edge of the triangle. The normal is ofcourse the hard normal of the triangle. (The T is the transformation matrix which I would use to transform the global space normals to tanget space.)

For the smoothed normals I was thinking of generating a matrix for every pixel of the global space map where I use the interpolated smoothed normal as the normal and the same tangents and uv vectors as before. I would like some input on that method before implementing it though.

Any input is greatly appreciated.
Member
Posts: 72
Joined: 2006.10
Post: #2
Someone correct me if I am wrong, but shouldn't your three axises form an orthonormal coordinate system?

- Sohta
Apprentice
Posts: 5
Joined: 2007.10
Post: #3
I think, you are right about that.

I've actually thought about making the vectors orthonormal but it feels like the results would differ quite a bit depending on which vector I choose as the first and second base vector.

Perhaps I'm just making a faulty assumption.
Luminary
Posts: 5,143
Joined: 2002.04
Post: #4
If they're not orthonormal the matrix won't be (purely) a rotation matrix.
Member
Posts: 72
Joined: 2006.10
Post: #5
Alright, it's been a while since I did any of that stuff, but here goes:

IIRC, your tangent vector is the direction that will match the u axis of your texture coordinate minus its projection on the normal vector (normalizing the end result). Your "second tangent" (normally referred to as the binormal) has to be the cross product of the tangent and the normal (in order to preserve the orthonormality). You have the choice of precalculating that value, or generate it in your shader (depending on where your bottleneck is).

- Sohta
Moderator
Posts: 102
Joined: 2003.07
Post: #6

Article

-CarbonX
Apprentice
Posts: 5
Joined: 2007.10
Post: #7
Sohta: Yeah... that sounds like a reasonable plan. One thing I got to thinking about, when I was just about to try it, was this.

To get the tangent which is pointing in the direction of the U-coordinate one could use the inverse of my matrix T and use it on the vector [1, 0, 0]. After that, if one has a matrix for every pixel you would use inv(T) on the vector [0, 0, 1].
Using a perfectly constructed UV-map one would get the bitangent using inv(T) on [0, 1, 0]. (This would result in the a transformation of the I-matrix which again iresults in inv(T).)

So I was thinking, is it really the correct way to actually build a orthonormal matrix? Wouldn't a transformation matrix be more "correct" if one wants to convert to a local coordinate system?

Thanks for the input