• 13
• 15
• 27
• 9
• 9

# Tangent and BiTangent equation?

This topic is 4286 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi all! anyone can help me find a function other than: http://www.terathon.com/code/tangent.html < --- i just cant figure this one... that can compute Tangents and BiTangent for any given mesh with known uvs? thx

##### Share on other sites
That is pretty straightforward, simple code. Perhaps you might want to borrow Eric's book from a library, and read the text that describes the math behind the code?

##### Share on other sites
i didnt kown about the book, it would help.

maybe someone can help me figure this one out then, if it is not too much trouble...

there is 2 thing i dont understand:

first:

why does he use a vector4 to find the tangents, what is the w for?

second:

i was expecting a *vector3 for the tangents and another one for the bitangents... where are the bitangents?

##### Share on other sites
There is no hard requirement to precompute and cache the bitangent, since you can compute it using the already-stored normal and tangent vectors. Yes, would perhaps save runtime (in GPU or wherever) to cache the bitangents, but that would require more storage, and perhaps more data sent across the AGP or PCI-Express bus in a texture.... One makes a tradeoff decision! I think nVidia in their developer docs suggest just computing the bitangent in a shader.

The w is part of a homogeneous vector. It is use to enable graphics engines to treat vectors (as in direction vectors, normal vectors, etc.) and positions (location that is measured relative to some fixed coordinate origin) in a uniform manner in code. For a reasonable introduction to homogeneous coordinates, see the following:

OpenGL Red Book - Appendix F

##### Share on other sites
you were straight on the ball with this post!

thx a million!

##### Share on other sites
humm, im trying to make a version for quads also...
for (Int i = 0; i < l_mesh->GetQuadCount(); ++i)			{				Int i1 = l_quad.a;				Int i2 = l_quad.b;				Int i3 = l_quad.c;				Int i4 = l_quad.d;				const Vector3 &v1 = m_Vertex[i1];				const Vector3 &v2 = m_Vertex[i2];				const Vector3 &v3 = m_Vertex[i3];				const Vector3 &v4 = m_Vertex[i4];				const Vector2 &w1 = m_UV[0][i1];				const Vector2 &w2 = m_UV[0][i2];				const Vector2 &w3 = m_UV[0][i3];				const Vector2 &w4 = m_UV[0][i4];				Float x1 = v2.x - v1.x;				Float x2 = v3.x - v1.x;				Float x3 = v4.x - v1.x;				Float y1 = v2.y - v1.y;				Float y2 = v3.y - v1.y;				Float y3 = v4.y - v1.y;				Float z1 = v2.z - v1.z;				Float z2 = v3.z - v1.z;				Float z3 = v4.z - v1.z;				Float s1 = w2.x - w1.x;				Float s2 = w3.x - w1.x;				Float s3 = w4.x - w1.x;				Float t1 = w2.y - w1.y;				Float t2 = w3.y - w1.y;				Float t3 = w4.y - w1.y;				Float r = 1.0f / (s1 * t2 - s2 * t1);				Vector3 l_dir				(					(t2 * x1 - t1 * x2) * r,					(t2 * y1 - t1 * y2) * r,					(t2 * z1 - t1 * z2) * r				);				l_temp[i1] += l_dir;				l_temp[i2] += l_dir;				l_temp[i3] += l_dir;				l_temp[i4] += l_dir;			}

im wondering what r and l_dir will be now?... any hint would be welcome!

##### Share on other sites
In this particular case, the w-coordinate of the tangent is just being used to store a handedness value. It doesn't have anything to do with the tangent itself, but it tells you which way the bitangent is pointing with respect to the normal and tangent.

I don't think there's a straightforward way to extend the tangent calculation to quads. You can't be sure that the tangent directions are the same for each group of three vertices.

##### Share on other sites
Oh great, Eric all mighty!

I ve choose to make Tangents and BiTangents members of my primitives!

that said I use the following:

for (Int i = 0; i < m_VertexCount; ++i)
{
// Gram-Schmidt orthogonalize.
m_Tangent = (m_Tangent - m_Normal * m_Normal.DotProduct(m_Tangent)).Normalize();
m_BiTangent = (m_Normal.CrossProduct(m_Tangent)).Normalize();
}

is this correct for the BiTangents? works fine with a plane... I ll just like to be sure!

thx eric!

##### Share on other sites
Yes, your code will work if all your triangles use a right-handed mapping. You don't need to normalize the bitangent if the normal and tangent are already normalized and orthogonal. If you're using 4D tangents with the handedness in the w-coordinate, then you should multiply the bitangent by tangent.w after the cross product (to flip its direction in the left-handed case).

[Edited by - Eric Lengyel on June 14, 2006 6:36:09 PM]