PDA

View Full Version : Transform to Tangent Space



Anybody
02-27-2004, 07:08 AM
Is there a possibility to perform a single vertex to tangent space? I heard there is a way to do this with the help of the texture coords, but I don't know how this should work.

Thanks for all your replies.

Dodger
02-27-2004, 09:51 AM
Transform a vertex to tangent space?
Usually, what this is done for is, to transform a light vector from world space into tangent space, in order to have it present in the same space that the normals from a normal map are in.

Technically, each vertex of a mesh is the origin of the tangent space of each vertex, so really, you can't transform a vertex into tangent space. Unless I'm misunderstanding what you're trying to do http://www.opengl.org/discussion_boards/ubb/wink.gif

jwatte
02-27-2004, 04:12 PM
That's right, tangent space only matters for normals, and possibly texture coordinates (if you do anisotropic stuff).

You provide a tangent basis to your shader by setting up one normal and one texture coordinate that's the normalized binormal, and one texture coordinate that's the normalized tangent. These, together, make up your tangent basis, which is the vector that you take the light vector through to get it in the space of the normal map. You can re-construct tangent from normal+binormal using a cross product if you have lots of fragment shader instructions available.

The typical code looks something like:

tangentLight.x = dot3( light, in.normal );
tangentLight.y = dot3( light, in.texcoord[1] );
tangentLight.z = dot3( light, in.texcoord[2] );
normal = tex2D( myNormalMap, in.texcoord[0] );
diffuse = clamp( dot3( light, normal ) ) * lightColor;

However, if you also want reflection mapping, you're probably better off bringing the normal map normal out to object space by using the inverse of that 3x3 tangent basis; either by changing the dot3 to a bunch of muls, or by inverting the matrix before stuffing it into the per-vertex attributes.

Anybody
02-29-2004, 06:55 AM
My real problem is that I want to use a vertex array and I think I can't pass a texcoord/normal for each face and have to pass it for each vertex (the tangent,binormal and normal are for each vertex of a face the same, aren't?).

jwatte
02-29-2004, 09:54 AM
If the faces are "sharp edged" then they're the same for each vertex, and you have to duplicate normal and binormal once for each vertex of the face.

If the faces are soft (like most organic shapes) then you need to average the tangent basis among all faces sharing a vertex to create the space for that vertex, and then (ortho)normalize, just like you would with normals alone. When you use interpolated spaces, you also might need to re-normalize in the shader, as you'll get de-normal basis vectors for interpolated fragment positions.