Jump to content
  • Advertisement
Sign in to follow this  


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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Where I can find TBN generator? Is the big need to make similiar vectors? How work with attributes in GLSL? When I write glBindAttribLocationARB(...) before linking shaders ,after compiling there is no error in glGetError() and Attrib array is enabled but not throw the information by glVertexAttribPointerARB(...) ...

Share this post

Link to post
Share on other sites
Hi, I investigated this the other day. Here's what I do, gathered from what I read in various articles and after experimenting:

For each triangle in the mesh, I calculate the face normal and call this function for the Tangent & BiTangent:

* Function : CalculateTangentBiNormal
* Description : Calculates the tangent and binormal for the
* supplied triangle and texture coordinate
* Triangle[3] = 3 vertices of the tri
* TexCoords[3] = texture coords of above 3 verts
* Tangent = calculated tangent stored here
* BiNormal = calculated binormal stored here

void CalculateTangentBiNormal(const SVector3d Triangle[3], const STexCoord TexCoords[3], SVector3d &Tangent, SVector3d &BiNormal)
SVector3d v3dEdge1, v3dEdge2;
STexCoord uvEdge1, uvEdge2;

const SVector3d& v1 = Triangle[0];
const SVector3d& v2 = Triangle[1];
const SVector3d& v3 = Triangle[2];

STexCoord uv1 = TexCoords[0];
STexCoord uv2 = TexCoords[1];
STexCoord uv3 = TexCoords[2];

// Origin in tangent space is bottom-left of texture... if you're
// like me and treat the origin as top-left, uncomment this code to
// flip the origin for correct tangent space calculations
//uv1.v = 1.0f - uv1.v;
//uv2.v = 1.0f - uv2.v;
//uv3.v = 1.0f - uv3.v;

// v2 - v2
v3dEdge1 = Triangle[1] - Triangle[0];

// v3 - v1
v3dEdge2 = Triangle[2] - Triangle[0];

uvEdge1 = uv2 - uv1;
uvEdge2 = uv3 - uv1;

float r = 1.0F / (uvEdge1.u * uvEdge2.v - uvEdge2.u * uvEdge1.v);

SVector3d v3dTangent((uvEdge2.v * v3dEdge1.x - uvEdge1.v * v3dEdge2.x) * r, (uvEdge2.v * v3dEdge1.y - uvEdge1.v * v3dEdge2.y) * r, (uvEdge2.v * v3dEdge1.z - uvEdge1.v * v3dEdge2.z) * r);
SVector3d v3dBiNormal((uvEdge1.u * v3dEdge2.x - uvEdge2.u * v3dEdge1.x) * r, (uvEdge1.u * v3dEdge2.y - uvEdge2.u * v3dEdge1.y) * r, (uvEdge1.u * v3dEdge2.z - uvEdge2.u * v3dEdge1.z) * r);

Tangent += v3dTangent;

BiNormal += v3dBiNormal;

Then, I add the face normal and tangent to each vertex that is used in the tri. I don't add the bi-tangent as this will be calculated later on from the tweaked tangent and vertex normal.

Once the T and N have been calculated for each tri and added to each trie vert, I loop through the verts. I normalize each vert (to get the average per-vertex normals) then perform a Gram-Schmidt orthogonalization on tangent. Once I have the averaged normal and corrected tangent, I find the bitangent by taking the cross product of the normal and tangent. The handidness of the BTN is checked and corrected.

for(UInt32 ctr = 0; ctr < numVerts; ctr++)

// Gram-Schmidt orthogonalize
meshVertData[ctr].xyzTangent -= meshVertData[ctr].xyzNormal * meshVertData[ctr].xyzNormal.Dot(meshVertData[ctr].xyzTangent);

// Calculate new BiNormal from the vertex Tangent and Normal
meshVertData[ctr].xyzBiNormal.Cross(meshVertData[ctr].xyzNormal, meshVertData[ctr].xyzTangent);

// Handedness
SVector3d v3dHand;

v3dHand.Cross(meshVertData[ctr].xyzTangent, meshVertData[ctr].xyzBiNormal);

if(v3dHand.Dot(meshVertData[ctr].xyzNormal) < 0.0f)
// Make right-handed
meshVertData[ctr].xyzBiNormal *= -1;

Take a look at the following articles for an explenation of whats going on:


I'm no expert but I hope that helps (and is correct :P)

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!