PDA

View Full Version : Something's wrong with my tangents and binormals



Baggio
06-03-2005, 11:02 AM
It seems I'm doing something wrong when I calculate the tangents and binormals 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 binormals. BTW, I did read http://www.terathon.com/code/tangent.html but it doesn't calculate binormals, 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[i]->numLayerGroups; ++j)
{
for(int k = 0; k < (CurrentMesh->meshLayers[i]->layerMaterialIndices[j]->numIndices / 3); ++k)
{
Mesh::MeshVert *v0 = &amp;CurrentMesh->meshLayers[i]->layerVertices[j + (k * 3)];
Mesh::MeshVert *v1 = &amp;CurrentMesh->meshLayers[i]->layerVertices[j + (k * 3 + 1)];
Mesh::MeshVert *v2 = &amp;CurrentMesh->meshLayers[i]->layerVertices[j + (k * 3 + 2)];

vec3 normal, tangent, binormal;
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];
binormal[l] = -v[2] / v[0];
}

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

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

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

v2->binormal.cross(v2->normal, tangent);
v2->binormal.normalize();
v2->tangent.cross(v2->binormal, v2->normal);
if(normal * v2->normal < 0.0f)
v2->binormal = -v2->binormal;
}
}
}
}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.

Now, I have an example of why I think the tangent and binormals 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:
http://img107.echo.cx/img107/8149/wrongbump2rq.th.jpg (http://img107.echo.cx/my.php?image=wrongbump2rq.jpg)

I hope you people can help me cause I really need to solve this. Thanks.

dorbie
06-03-2005, 09:22 PM
You need to make sure that your tangent space basis matches the vectors in the bumpmap and that corresponds correctly with the vertex program position & vector transformations to tangent space. The application of your texture coordinates is also important remember because these form the tangent space basis, if you flip the derivative of s or t coordinates the tangent space tangent and binormal vectors will be wrong.

So consider your system as a whole, including the derivatives of the box, and remember you're *inside* the box, this matters.