Texture Space Axis Calculations
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
October 16, 2002 03:25 PM
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:
The averaging (and calculation of your resultant tangent-space basis) is done like this (for each vertex):
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).
// 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] = { m_Vertices[v0].tex_coords[2], m_Vertices[v1].tex_coords[2], m_Vertices[v2].tex_coords[2] }; // 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 ref_count[v0]++; ref_count[v1]++; ref_count[v2]++;
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, vtx.tz); cVector3 B(binormals[i]); // Average T *= 1.0f / ref_count[i]; B *= 1.0f / ref_count[i]; // Normalise T.Normalise(); B.Normalise(); // Get the vertex normal cVector3 N(vtx.nx, vtx.ny, vtx.nz); // 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 vtx.tw = I.Determinant(); // Write-back vtx.tx = T.x; vtx.ty = T.y; vtx.tz = 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).
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement