Something's wrong with my tangents and bitangents.

Started by
32 comments, last by Eric Lengyel 18 years, 10 months ago
Quote:Original post by Eric Lengyel
Hi Hulag --

The code at http://www.terathon.com/code/tangent.html does exactly what you need. The arrays pointed to by tan1 and tan2 contain the tangents and bitangents, respectively, after the main loop. The these are used to calculate a handedness factor, and then the bitangents are thrown out because you're expected to recalculate them in the vertex program using B = (N x T) * T.w.

Unfortunately, the example which is susceptible to division by zero has been around for a few years and copied all over the place, but it is just plain wrong. The algorithm is obviously not robust, even with that hacky epsilon test. Because you're dividing by the difference in vertex coordinates, it can't even handle an axis-aligned cube correctly.

-- Eric Lengyel

Hey Eric, I'm trying to port your code in http://www.terathon.com/code/tangent.html. I have the first loop like this:
	for (int i = 0; i < CurrentMesh->meshNodes.size(); ++i)	{		for(int j = 0; j < CurrentMesh->meshNodes->numNodeGroups; ++j)		{			for(int k = 0; k < (int)(CurrentMesh->meshNodes->nodeMaterialIndices[j]->numIndices / 3); ++k)			{				Mesh::MeshVertexInfo *v0 = &CurrentMesh->meshNodes->nodeVertices[CurrentMesh->meshNodes->nodeMaterialIndices[j]->indices[k * 3]];				Mesh::MeshVertexInfo *v1 = &CurrentMesh->meshNodes->nodeVertices[CurrentMesh->meshNodes->nodeMaterialIndices[j]->indices[k * 3 + 1]];				Mesh::MeshVertexInfo *v2 = &CurrentMesh->meshNodes->nodeVertices[CurrentMesh->meshNodes->nodeMaterialIndices[j]->indices[k * 3 + 2]];				vec3 normal, tangent, biTangent;				vec3 e0 = v1->position - v0->position;				vec3 e1 = v2->position - v0->position;				vec2 uve1 = vec2(v1->UV.x - v0->UV.x, v1->UV.y - v0->UV.y);				vec2 uve2 = vec2(v2->UV.x - v0->UV.x, v2->UV.y - v0->UV.y);				float r = 1.0f / (uve1.x * uve2.y - uve2.x * uve1.y);				vec3 sdir(	(uve2.y * e0.x - uve1.y * e1.x) * r,					(uve2.y * e0.y - uve1.y * e1.y) * r,					(uve2.y * e0.z - uve1.y * e1.z) * r );				vec3 tdir(	(uve2.x * e0.x - uve1.x * e1.x) * r,					(uve2.x * e0.y - uve1.x * e1.y) * r,					(uve2.x * e0.z - uve1.x * e1.z) * r );				v0->tangent += sdir;				v1->tangent += sdir;				v2->tangent += sdir;				v0->biTangent += tdir;				v1->biTangent += tdir;				v2->biTangent += tdir;			}		}	}

Now, I'm having problems with your second loop mostly because my math functions library isn't the same as yours. The following line confuses me
tangent[a] = (t - n * Dot(n * t)).Normalize();

What confuses me there is the Dot(n * t) part because there is no Dot() function in your math libs that takes just one parameter. So how would that whole line be decomposed competly? (with the exception of the Normalize() function). I hope you (or anybody else) can help me.
Advertisement
The Dot(n * t) is a typo -- it's been fixed. It should have said Dot(n, t). In a previous version of the code, it only said (n * t), and operator * between two vectors is overload to compute the dot product, but it wasn't as clear.

Quote:Original post by Eric Lengyel
The Dot(n * t) is a typo -- it's been fixed. It should have said Dot(n, t). In a previous version of the code, it only said (n * t), and operator * between two vectors is overload to compute the dot product, but it wasn't as clear.

Cool, now I got that part, I also have the handedness. Now I need to generate the binormal which you told me that was calculated like this:
Quote:Original post by Eric Lengyel
B = (N x T) * T.w.

Now what do you mean by "N x T"? Would that be Cross(N, T)? If not what would that operation be?

Thanks.
Yes, N x T means the cross product.

This topic is closed to new replies.

Advertisement