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.

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.

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

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.

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?).

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.