How do I get per-vertex tangents (and bitangents) in my export script? I'm writing a script to export models from Blender to be used in my custom OpenGL engine.  My engine wants vertices to be in a big solid "array of structs" block, with each vertex having the same amount of data, so I can easily load it into a vertex buffer object.  I started out by just exporting the positions and normals which was easy, but getting to UVs my job became more complicated, because each "vertex" could have multiple UVs.

My solution was to go over each polygon first, and for each corner of the polygon, store a whole new vertex in a list, then add an index for that vertex.  Afterwards, I scan the list of vertices, and eliminate any doubles, fixing indices as appropriate.  This works exactly as expected; when only normal and position data is considered the number of vertices is equal to the mesh's original number of vertices, and I don't have to worry about "splitting" to account for UVs and such.

This works great and all until I start looking at tangents.  All of a sudden, the number of vertices I end up with seems suspiciously close to the total number of indices, which means that (almost) no two triangles are sharing any vertices between them.  Obviously this isn't good enough.

From doing quite a lot of google searching on the issue, it appears that blender calculates tangents on a per-face basis, with no regards whatsoever to indexing, and you're expected to smooth it out yourself.  I have not been able to find any answers as to how to smooth them together.  An article I found on the subjects suggests that simply averaging them out doesn't work, and recommends using a vertex welder, then links to a 404 and google shows nothing on the subject.

I'm using calc_tangents() to create the tangent data in the first place.  I know how to access the calculated tangents of each corner of a polygon.  How do I translate this per-corner/per-face data into per-vertex?

P.S., Should I be storing bitangents in my vertex buffer from this stage, or calculate them in the fragment shader?  A lot of sources online recommend the latter, but I've read that it shows up incorrectly if the UVs are skewed.
How do I translate this per-corner/per-face data into per-vertex?


You get the appropriate vertex of the face loop this way:

import bpy

me = bpy.context.active_object.data

for face in me.polygons:
    # face loops and face vertices are in the same order
    for vert_id, loop_id in zip(face.vertices, face.loop_indices):    
        # this is the loop:
        me.loops[loop_id]
        # this is the vertex in the corner of the loop:
        me.vertices[vert_id]



  Should I be storing bitangents in my vertex buffer from this stage, or calculate them in the fragment shader?


This depends on what you want to do with your engine. You can trade some memory for faster fragment shader, but you loose a lot of functionality in the future.

If you need any mesh deformations (armature, soft-body,..) you will have to calculate normals, tangents and bitangents on the fly anyway.