Tangent Space Vector for my Terrain mesh

@knackered: Well, there is no need for hacks when there is a proper, documented method. This method gives you non-orthagonal tangent space vectors, which, among other things is just plain wrong. There is a better method and its the cheapest means of calculating the tangent space. I don’t understand why one would opt a wrong method when the proper method is the cheapest method especially after the construction of a LUT which gets rid of the cross product.
The example was wild, because well-behaved meshes usually do not have totally vertical surfaces, but steep slopes are frequent, which can still give a lot of problems.

Ok, I am still lost… What I have is an array that holds my terrain data for normals,vertex,tex coord,tangent. So with
this code

for(z = 0; z < mapData.map_Z - 1; z++)
	{
		for(x = 0; x < mapData.map_X - 1; x++)
		{
//terrain[z * mapData.map_Z + x].nx //normals nx,ny,nz
//terrain[z * mapData.map_Z + x].vx //vertex vx,vy,vz
//terrain[z * mapData.map_Z + x].s // tex coord
//terrain[z * mapData.map_Z + x].t // tex coord
//terrain[z * mapData.map_Z + x].tx //tangent tx,ty,tz

//what should I be doing here...
}
}

Ok, what I understand so far is vertex data means nothing normals and tex coords are whats needed…

Originally posted by Zulfiqar Malik:
@knackered: Well, there is no need for hacks when there is a proper, documented method.
Oh, I forgot you didn’t read the whole thread.
Well, my method doesn’t require knowledge of the neighbouring vertices, and so fits a vertex shader implementation.

BTW,

your method of assuming (1, 0, 0) to be the bitangent is wrong and will definitely fail most of the time.
I assume you meant to say “will definitely fail in extreme circumstances”.

Well, i don’t know what exactly are you trying to do. But here is my code that calculates the normal LUT

	for (int x = -g_halfHeight/2; x <= g_halfHeight/2; x++)
	{
		float		fHeightX	= (float)x;
		vec3f		vTangent		= vec3f(fDist, 0, fHeightX);
		vTangent.Normalize();
		for (int y = -g_halfHeight/2; y <= g_halfHeight/2; y++)
		{
			float	fHeightY	= (float)y;
			vec3f	vBitangent	= vec3f(0, fDist, fHeightY);
			vBitangent.Normalize();
			vec3f	vNormal	= vTangent.Cross(vBitangent);
			vNormal.Normalize();
			m_arrNormalLUT[x + g_maxHeight][y + g_maxHeight]	= vNormal;
		}
	}

where g_maxHeight is the maximum height that can be reached, 256 in my case. As far as your problem goes, g_halfHeight is the same i.e. 256. fDist is the distance along x-axis between adjacent vertices for tangent and along y-axis for bitangent. Its the same in my case.
Then you can easily do a lookup at runtime using:

		int		x		= (heightPosX - heightNegX) + g_maxHeight;
		int		y		= (heightPosY - heightNegY) + g_maxHeight;
		return m_arrNormalLUT[x][y];

Where heightPosX is the heightmap value on the right of current vertex and heightNegX is the value on the left. heightPosY is the value above and heightNegY is the value below the height map index of the current vertex.

Thanks for the post Zulfiqar Malik. So the LUT is all the tangents for each vertex then or the normals, as you have sent the normal vector to the array to be updated… I have normals already calculated in my code. Thanks

Its the normals in my case but vTangent is the tangent and vBitangent is the bitangent. You can keep them in an array similar to the normals array at the exact same index as the normals. The lookup indices can then be used for those arrays as well (or you can make one small struct and keep all three in one array).