This topic is now archived and is closed to further replies.


Texture Space Axis Calculations

Recommended Posts

Hi all. I am currently trying to calculate S, and T axis in 3D space of a polygon. I need to do this for each triangle in the model. I need it for bump mapping as I need to rotate the light source into the right direction. I can do this by multiplying it by a 3x3 rotation matrix that consists of a vector pointing in the direction of the S and T axis, and then the last vector as a cross product of them. I have the XYZ position of each vertex in the model, and the ST coords at each vertex. I have an article that states I should create plane equations in the form: Ax + Bs + Ct + D = 0 Ay + Bs + Ct + D = 0 Az + Bs + Ct + D = 0 Then I have to solve them for texture gradients dsdx, dsdy, dsdz. Then a vector compromising of would be the correct S axis. I can then do the same for T. But I am not sure how to calculate this, and I am even less sure how to implement it in code. Any help would be excellent. Thanks for your time. - Weasalmongler

Share this post

Link to post
Share on other sites
Guest Anonymous Poster
OK, your S and T are known as the Binormal and Tangent of the basis (with the Normal completing it). Each triangle in your mesh will share vertices with other triangles so just like your vertex Normal you will need to sum your Binormals and Tangents for each vertex and then for each vertex calculate the average of each. The summing is done like so:

// Get the triangle vertices

cVector3 E(m_Vertices[v0].x, m_Vertices[v0].y, m_Vertices[v0].z);
cVector3 F(m_Vertices[v1].x, m_Vertices[v1].y, m_Vertices[v1].z);
cVector3 G(m_Vertices[v2].x, m_Vertices[v2].y, m_Vertices[v2].z);

// Calculate the edge vectors

cVector3 P = F - E;
cVector3 Q = G - E;

// Get the three bump-map uv coords

UV* uv_ptr[3] =

// Calculate texture deltas

float s1, s2, t1, t2;
s1 = uv_ptr[1]->u - uv_ptr[0]->u;
t1 = uv_ptr[1]->v - uv_ptr[0]->v;
s2 = uv_ptr[2]->u - uv_ptr[0]->u;
t2 = uv_ptr[2]->v - uv_ptr[0]->v;

// Calculate inverse of the texture matrix

float inverse = 1.0f / (s1 * t2 - s2 * t1);

// Solve linear system to get tangent and binormal vectors

cVector3 T = inverse * (t2 * P - t1 * Q);
cVector3 B = inverse * (s1 * Q - s2 * P);

// Sum tangent on all three vertices

m_Vertices[v0].tx += T.x;
m_Vertices[v0].ty += T.y;
m_Vertices[v0].tz += T.z;
m_Vertices[v1].tx += T.x;
m_Vertices[v1].ty += T.y;
m_Vertices[v1].tz += T.z;
m_Vertices[v2].tx += T.x;
m_Vertices[v2].ty += T.y;
m_Vertices[v2].tz += T.z;

// Sum binormals

binormals[v0] += B;
binormals[v1] += B;
binormals[v2] += B;

// Increase ref-count


The averaging (and calculation of your resultant tangent-space basis) is done like this (for each vertex):

// De-ref vertex

Vertex& vtx = m_Vertices[i];

// Get the tangent and binormal

cVector3 T(vtx.tx, vtx.ty,;
cVector3 B(binormals[i]);

// Average

T *= 1.0f / ref_count[i];
B *= 1.0f / ref_count[i];

// Normalise


// Get the vertex normal

cVector3 N(vtx.nx, vtx.ny,;

// Orthogonalise the matrix base (Gram-Schmidt)

T = T - cVector3::Dot(N, T) * N;
B = B - cVector3::Dot(N, B) * N - cVector3::Dot(T, B) * T;

// Create transform from object-space to tangent-space

cMatrix3x3 I(T, B, N);
I = cMatrix3x3::Transpose(I);

// Record the handedness of the space = I.Determinant();

// Write-back

vtx.tx = T.x;
vtx.ty = T.y; = T.z;

Note that the orthogonalisation isn''t really necessary because the space itself might not be orthogonal due to your mapping technique.

If this is for a vertex-shader driven bump mapper where you feed normals and tangents through your streams and calculate the binormal on the shader as the cross product of the two, remember to multiply the result by the .w component of the tangent (which, as seen above, records the handedness of the basis).

Share this post

Link to post
Share on other sites
Thanks man for the masses of help. I''ll have a go at getting my bump mapping working now, I think I have all the information I need for it to work as this was the last piece of the jigsaw. Thanks again.

- Weasalmongler

Share this post

Link to post
Share on other sites