Parallax
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(...)
...
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:
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.
Take a look at the following articles for an explenation of whats going on:
http://www.terathon.com/code/tangent.html
http://jerome.jouvie.free.fr/OpenGl/Lessons/Lesson8.php
http://www.3dkingdoms.com/weekly/weekly.php?a=37
http://www.gamasutra.com/view/feature/1515/messing_with_tangent_space.php?page=1
http://www.blacksmith-studios.dk/projects/downloads/bumpmapping_using_cg.php
I'm no expert but I hope that helps (and is correct :P)
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++){ meshVertData[ctr].xyzNormal.Normalize(); // Gram-Schmidt orthogonalize meshVertData[ctr].xyzTangent -= meshVertData[ctr].xyzNormal * meshVertData[ctr].xyzNormal.Dot(meshVertData[ctr].xyzTangent); meshVertData[ctr].xyzTangent.Normalize(); // Calculate new BiNormal from the vertex Tangent and Normal meshVertData[ctr].xyzBiNormal.Cross(meshVertData[ctr].xyzNormal, meshVertData[ctr].xyzTangent); meshVertData[ctr].xyzBiNormal.Normalize(); // 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:
http://www.terathon.com/code/tangent.html
http://jerome.jouvie.free.fr/OpenGl/Lessons/Lesson8.php
http://www.3dkingdoms.com/weekly/weekly.php?a=37
http://www.gamasutra.com/view/feature/1515/messing_with_tangent_space.php?page=1
http://www.blacksmith-studios.dk/projects/downloads/bumpmapping_using_cg.php
I'm no expert but I hope that helps (and is correct :P)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement