I’m having problems calculating tangents from plane information generated from position and texture coordinate information.
Here’s the code I have for generating tangent information from 3 given positions, and 3 texture coordinates.
/**
* Calculates a per-triangle tangent from given triangle texture UV and position data (normalized)
* @param v0 The triangle's 1st vertex
* @param v1 The triangle's 2nd vertex
* @param v2 The triangle's 3rd vertex
* @param st0 The triangle's 1st texture UV
* @param st1 The triangle's 2st texture UV
* @param st2 The triangle's 3st texture UV
* @return A per-triangle tangent from given triangle texture UV and position data
*/
public static Vector3f getTangent(Vector4f v0, Vector4f v1, Vector4f v2,
Vector2f st0, Vector2f st1, Vector2f st2){
float x1 = v1.x - v0.x;
float x2 = v2.x - v0.x;
float y1 = v1.y - v0.y;
float y2 = v2.y - v0.y;
float z1 = v1.z - v0.z;
float z2 = v2.z - v0.z;
float s1 = st1.x - st0.x;
float s2 = st2.x - st0.x;
float t1 = st1.y - st0.y;
float t2 = st2.y - st0.y;
float r = 1.0f / (s1 * t2 - s2 * t1); // POSSIBLE CAUSE 1
Vector3f out = new Vector3f(( t2 * x1 - t1 * x2 ) * r, ( t2 * y1 - t1 * y2 ) * r, ( t2 * z1 - t1 * z2 ) * r);
out.normalize(); // POSSIBLE CAUSE 2
return out;
}
Printing face information gave me this:
Face information for a not-working triangle.
positions p1: (-0.688189, -0.525736, 0.499997, 1.0) p2: (-0.894426, -0.447216, 0.0, 1.0) p3: (-0.52573, -0.850652, 0.0, 1.0)
texcoords t1: (0.573431, 0.856142) t2: (0.713285, 0.856142) t3: (0.856142, 0.856142)
normal: (0.4089, 0.6617, -0.6284)
tangent: (NaN, NaN, NaN)
And the face information for a triangle that’s working…
positions p1: (-0.52573, -0.850652, 0.0, 1.0) p2: (-0.688189, -0.525736, 0.499997, 1.0) p3: (-0.894426, -0.447216, 0.0, 1.0)
texcoords t1: (0.713285, 0.716288) t2: (0.573431, 0.856142) t3: (0.713285, 0.856142)
normal: (0.4911, 0.7947, -0.3568)
tangent: (-0.37735644, 0.14366975, -0.9148557)
[quote]“NaN” stands for “not a number”. “Nan” is produced if a floating point operation has some input parameters that cause the operation to produce some undefined result. For example, 0.0 divided by 0.0 is arithmetically undefined. Taking the square root of a negative number is also undefined.
[/quote]
The only division being done there is the [icode]1.0f / (s1 * t2 - s2 * t1);[/icode] and the normalization. So either the vector was (0.0, 0.0, 0.0) and divided by the length of itself for normalization would equal (NaN, NaN, NaN), or the [icode]r[/icode] value is being calculated incorrectly or encountered (1.0 / 0.0).
So many headaches… Thanks in advance.
EDIT:
So with the tangent-normal-binormal matrix being this: [icode][T, B, N][/icode], and multiplying it by a vector remapped from a texture (common normal mapping practice) I got this:
The texture of the sphere is pure black, the black triangles are because the normal * TBN for that face is (0.0, 0.0, 0.0, 0.0)
The texture of the box is showing through, because the normal * TBN for that face is (0.0, 0.0, 0.0, 0.0)
As you can see, when the normals become (0, 0, 0, 0) (RED GREEN BLUE ALPHA) they show the ambient texture that’s drawn before it. So on certain parts of the mesh, the tangent row of the matrix is (0, 0, 0, 0), which multiplied by any vector returns (0, 0, 0, 0). But the normals themselfs are perfectly fine, and I’ve tested them before. So is the bitangent. So the code block at the top is to blame…