Tangent and BiTangent equation?

Started by
13 comments, last by hplus0603 17 years, 10 months ago
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
Advertisement
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?
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
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?
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
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
you were straight on the ball with this post!

thx a million!
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!
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.
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!
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]
omg... tangents and bitangents nailed down!

thank you so much!

This topic is closed to new replies.

Advertisement