Something's wrong with my tangents and bitangents.

Started by
32 comments, last by Eric Lengyel 18 years, 10 months ago
It seems I'm doing something wrong when I calculate the tangents and bitangents of my mesh. I really need some help with this since I'm trying to do bumpmapping and specular reflections and they look all wrong. Here I have the function I use to calculate the tangents and bitangents. BTW, I did read http://www.terathon.com/code/tangent.html but it doesn't calculate bitangents, and also the code is a bit wierd to me because the structures of the geometry are different so I don't really know what I'm supposed to do. Here is my code:
void MathFuncs::calculateTangent(Mesh *CurrentMesh)
{
	for (int i = 0; i < (intCurrentMesh->meshLayers.size(); ++i)
	{
		for(int j = 0; j < CurrentMesh->meshLayers->numLayerGroups; ++j)
		{
			for(int k = 0; k < (CurrentMesh->meshLayers->layerMaterialIndices[j]->numIndices / 3); ++k)
			{
				Mesh::MeshVert *v0 = &CurrentMesh->meshLayers->layerVertices[j + (k * 3)];
				Mesh::MeshVert *v1 = &CurrentMesh->meshLayers->layerVertices[j + (k * 3 + 1)];
				Mesh::MeshVert *v2 = &CurrentMesh->meshLayers->layerVertices[j + (k * 3 + 2)];

				vec3 normal, tangent, biTangent;
				vec3 e0 = vec3(0.0f, v1->UV.x - v0->UV.x, v1->UV.y - v0->UV.y);
				vec3 e1 = vec3(0.0f, v2->UV.x - v0->UV.x, v2->UV.y - v0->UV.y);

				for(int l = 0; l < 3; l++)
				{
					e0.x = v1->position[l] - v0->position[l];
					e1.x = v2->position[l] - v0->position[l];

					vec3 v;
					v.cross(e0, e1);

					tangent[l] = -v[1] / v[0];
					biTangent[l] = -v[2] / v[0];
				}

				tangent.normalize();
				biTangent.normalize();
				normal.cross(tangent, biTangent);
				normal.normalize();

				v0->biTangent.cross(v0->normal, tangent);
				v0->biTangent.normalize();
				v0->tangent.cross(v0->biTangent, v0->normal);
				if(normal * v0->normal < 0.0f)
					v0->biTangent = -v0->biTangent;

				v1->biTangent.cross(v1->normal, tangent);
				v1->biTangent.normalize();
				v1->tangent.cross(v1->biTangent, v1->normal);
				if(normal * v1->normal < 0.0f)
					v1->biTangent = -v1->biTangent;

				v2->biTangent.cross(v2->normal, tangent);
				v2->biTangent.normalize();
				v2->tangent.cross(v2->biTangent, v2->normal);
				if(normal * v2->normal < 0.0f)
					v2->biTangent = -v2->biTangent;
			}
		}
	}
}

Just so it isn't so hard to understand the code, a Mesh is composed of several meshLayers, inside each meshLayers there are LayerGroups, each group has a number of lists, there is one list per material in the layer. The indices stored are actually indices to the vertex array in the meshLayer. So for example I have two triangles with different materials in a single layer, there would be just two layerMaterialIndices with 3 indices each, and 6 vertices in layerVertices in the layer. I hope you people can help me cause I really need to solve this. [Edited by - Hulag on June 3, 2005 12:48:23 PM]
Advertisement
Screen shot?
Try building it incrementally - (bump) no color vertex, bump w/ color vertex, bump w/color vertext & specular highlights.

Why does it look wrong?
This is C++ and directx 9?
Quote:Original post by Anonymous Poster
Screen shot?
Try building it incrementally - (bump) no color vertex, bump w/ color vertex, bump w/color vertext & specular highlights.

Why does it look wrong?

Yes, I have done that testing, in fact if I draw just the diffuse component (which is just the bumpmapping) it doesn't look that wrong, there is something wierd but it doesn't look completly wrong with many normal maps, but one simple test that should come out right if the binormal and tangents are right is when I have a normal map that's completly flat, if they were right then everything should look some kind of gray, but everything looks black.

Quote:Original post by Anonymous Poster
This is C++ and directx 9?

C++ and OpenGL.

Thanks.
I have another example of why I think the tangent and bitangents are wrong, I make a 100x100x100 box where all the faces face to the inside of the box, I put that box in such way that the coords 0.0f, 0.0f, 0.0f are the exact center of the box. Now I put a light at 0.0f, 0.0f, 0.0f and the camera at 0.0f, 0.0f, 0.0f. Now if everything is correct, all the faces should look the same but here is an screenshot:
Wrong values screenshot
Bitangent? Cotangent? I think you mean binormal.

Bitangent and cotangent mean something else:

http://mathworld.wolfram.com/Bitangent.html
http://mathworld.wolfram.com/Cotangent.html

This is probably the source of your problems :).

Quote:Original post by ganchmaster
Bitangent? Cotangent? I think you mean binormal.

Bitangent and cotangent mean something else:

http://mathworld.wolfram.com/Bitangent.html
http://mathworld.wolfram.com/Cotangent.html

This is probably the source of your problems :).

If you read http://mathworld.wolfram.com/BinormalVector.html you will see that binormal isn't right either.
Here is a quote from http://www.terathon.com/code/tangent.html
"The term binormal is commonly used as the name of the second tangent direction (that is perpendicular to the surface normal and s-aligned tangent direction). This is a misnomer. The term binormal pops up in the study of curves and completes what is known as a Frenet frame about a particular point on a curve. Curves have a single tangent direction and two orthogonal normal directions, hence the terms normal and binormal. When discussing a coordinate frame at a point on a surface, there is one normal direction and two tangent directions, which should be called the tangent and bitangent. Somewhere along the line, somebody used the wrong term and it caught on. Please help remedy the botched terminology by using the word bitangent instead of binormal in the context of bump mapping, etc."
That guy is delusional if he thinks that he is going to change the terminology used everywhere for normal mapping. All he is going to do is introduce confusion for those people unlucky enough to deal with his writing.

You can call it whatever you want, but if I were you I'd do yourself a favor and not bother with the "crusade".

Anyway, Binormal is still a better name than bitangent (or cotangent, which you also used for some reason). It means about the same thing for surfaces as it does for curves - B = T x N. So computationally it's the same thing and no-one who looks it up in Mathworld or elsewhere will be confused. Bitangent is a valid term for something else and shouldn't be hijacked just because this guy wants to split hairs about the difference between curves and surfaces. Yeah, the binormal isn't really normal to the surface...so what? Everyone knows what it means.
Quote:Original post by ganchmaster
That guy is delusional if he thinks that he is going to change the terminology used everywhere for normal mapping. All he is going to do is introduce confusion for those people unlucky enough to deal with his writing.

You can call it whatever you want, but if I were you I'd do yourself a favor and not bother with the "crusade".

Anyway, Binormal is still a better name than bitangent (or cotangent, which you also used for some reason). It means about the same thing for surfaces as it does for curves - B = T x N. So computationally it's the same thing and no-one who looks it up in Mathworld or elsewhere will be confused. Bitangent is a valid term for something else and shouldn't be hijacked just because this guy wants to split hairs about the difference between curves and surfaces. Yeah, the binormal isn't really normal to the surface...so what? Everyone knows what it means.

I'm just going to say two things. First, this thread wasn't made to discuss a bunch of terms, I just need help to solve a big problem. And second, just because all the people use a term to describe something, doesn't mean its the right term, but it is true that most people understand what it means.

PS: I confused bitangents and cotangents in my head for a second, never meant to actually write "cotangent" in my post.
Quote:Original post by ganchmaster
That guy is delusional if he thinks that he is going to change the terminology used everywhere for normal mapping. All he is going to do is introduce confusion for those people unlucky enough to deal with his writing.

You can call it whatever you want, but if I were you I'd do yourself a favor and not bother with the "crusade".

Anyway, Binormal is still a better name than bitangent (or cotangent, which you also used for some reason). It means about the same thing for surfaces as it does for curves - B = T x N. So computationally it's the same thing and no-one who looks it up in Mathworld or elsewhere will be confused. Bitangent is a valid term for something else and shouldn't be hijacked just because this guy wants to split hairs about the difference between curves and surfaces. Yeah, the binormal isn't really normal to the surface...so what? Everyone knows what it means.


that attitude might imply that it would be fair to call people niggers, chinks and wogs. but thats an unrelated matter.

This topic is closed to new replies.

Advertisement