Advertisement

Texture Space Axis Calculations

Started by October 16, 2002 12:02 PM
1 comment, last by weasalmongler 22 years, 4 months ago
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
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] =	{		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).
Advertisement
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

This topic is closed to new replies.

Advertisement