0

I have this code I sorta put together from a few different sites. It works perfect at creating the bitangent... but for what ever reason. the tangent is thrashed.. In other words and to make this more clear, the code is generating BAD tangents!! The tangent is usually pointing down, kinda opposite the normal. I'm expecting it to be aligned with the V axis of the texture coordinate.. The strange thing is, I use the cross of the normal and tangent to get the bitangent, which is fine.

I have tried flipping the coordinates, the UVs.. just about everything.. Im not great in math so.. can some one take a look at my code and see if it looks "legit"? Thank you!

Private Sub ComputeTangentBasis(ByRef p0 As vertex_data, ByRef p1 As vertex_data, ByRef p2 As vertex_data)
    Dim tangent, bitangent As Vector3D
    Dim n As Vector3D

    n.X = p0.nx
    n.Y = p0.ny
    n.Z = p0.nz

    'convert to vector3d type... they are WAY easier to do complex math with!!
    Dim v0 = convert_vector3d(p0)
    Dim v1 = convert_vector3d(p1)
    Dim v2 = convert_vector3d(p2)

    Dim edge1 = v1 - v2
    Dim edge2 = v2 - v0
    Dim deltaU1 = (p1.u - p0.u) * -0.1
    Dim deltaU2 = (p2.u - p0.u) * -0.1
    Dim deltaV1 = (p1.v - p0.v) * -0.1
    Dim deltaV2 = (p2.v - p0.v) * -0.1
    Dim dividend = (deltaU1 * deltaV2) - (deltaU2 - deltaV1)
    Dim f As Double
    If dividend = 0.0 Then
        f = 1.0
    End If
    tangent.X = f * ((deltaV2 * edge1.X) - (deltaV1 * edge2.X))
    tangent.Y = f * ((deltaV2 * edge1.Y) - (deltaV1 * edge2.Y))
    tangent.Z = f * ((deltaV2 * edge1.Z) - (deltaV1 * edge2.Z))
    bitangent = Vector3D.CrossProduct(tangent, n)

    '
    p0.t.x = tangent.X
    p0.t.y = tangent.Y
    p0.t.z = tangent.Z
    p0.bt.x = bitangent.X
    p0.bt.y = bitangent.Y
    p0.bt.z = bitangent.Z
    '
    p1.t.x = tangent.X
    p1.t.y = tangent.Y
    p1.t.z = tangent.Z
    p1.bt.x = bitangent.X
    p1.bt.y = bitangent.Y
    p1.bt.z = bitangent.Z
    '
    p2.t.x = tangent.X
    p2.t.y = tangent.Y
    p2.t.z = tangent.Z
    p2.bt.x = bitangent.X
    p2.bt.y = bitangent.Y
    p2.bt.z = bitangent.Z


End Sub 

Here's a pic of the problem.. Norms are red.. Tangents Green... BiTangents.. blueish. Bad Tangents

Mike O
  • 149
  • 10
  • I don't think your description is clear enough. It would be nice if you could clarify, what exactly happens wrong now and what you expect. – SergGr Mar 22 '17 at 02:26
  • Seems clear enough.. the code is not generating the correct Tangents. I'll change the question though.. – Mike O Mar 22 '17 at 16:58

3 Answers3

1

You will likely need to recalculate the tangent from cross-product of the normal and bitangent. This ensures that the normal, tangent and bitangent are orthagonal to one another.

In most implementations I've seen, the first calculation for a perpendicular axis to the normal is a placeholder as there are an infinite number of possible axes to choose from, and as such requires it to be recalculated to be orthagonal.

NotVeryMoe
  • 544
  • 5
  • 9
  • I tried t = cross(b,n).. Oddly it works in the shader but not in the code I posted.. I wonder if its a thing with the Vector3D class? – Mike O Mar 22 '17 at 17:05
  • Hm. That's certainly strange. It's unlikely to be an issue with Vector3D as that's a fairly common class. I would suggest looking a couple things: Are you making sure to normalize the vectors at some point? And are you sure that you're passing in the tangent information correctly (perhaps check by swapping the tangent and normal to see if the normal becomes wonky)? – NotVeryMoe Mar 23 '17 at 02:52
  • Yeah... It was a couple of dumb things on my part.. A typo and wanting to work and not learn :( – Mike O Mar 23 '17 at 03:04
1

In your code you don't take dividend into the calculus, except for the case is 0.

Any two points in a triangle form a tangent or a bitangent. There are infinite possibilities. If you want to align T and B with some texture coordinates you need more maths.

With little effort you would have found this: How to calculate Tangent and Binormal?

Community
  • 1
  • 1
Ripi2
  • 7,031
  • 1
  • 17
  • 33
  • I have seen this formula all over the place only with different variable names... I assumed it would work.. Maybe its a simple typo some where. – Mike O Mar 23 '17 at 00:56
1

Ok... I found 2 problems..

  1. Dim edge1 = v1 - v2 should be Dim edge1 = v1 - v0

  2. I looked in to what Ripi2 commented about.. I watched the video I got this from over again.. I messed a part where he changed the code.. He removed dividend and the if statement and replaced it with this line:

    Dim f As Single = 1.0! / ((deltaU1 * deltaV2) - (deltaU2 * deltaV1))
    

Now it creates prefect Tangents and BiTangents. I added normalization using these 2 lines.

tangent /= tangent.Length
bitangent /= bitangent.Length

I hope this helps anyone out there.

Mike O
  • 149
  • 10