# Least-Squares Estimation of Tangent Space for a Triangular Mesh
## 2 Background  
### Linear Methods for Tangent Space Computation  
A simple and popular method to compute the tangent space from texture coordinates consists of three steps [2; 5; 6]. Initially, the tangent vector, \(\mathbf{t}\), the bitangent vector, \(\mathbf{b}\), and the normal vector, \(\mathbf{n}\), of each triangle are estimated. Subsequently, for each vertex these vectors of its neighboring triangles are averaged. Finally, as an optional step, the averaged \(\mathbf{t}\), \(\mathbf{b}\), and \(\mathbf{n}\) vectors of the tangent space at each vertex are orthonormalized.  
Consider a triangle in world space with three vertex positions, \(\mathbf{p}_{0}\), \(\mathbf{p}_{1}\), and \(\mathbf{p}_{2}\), and their corresponding texture coordinates, \((u_{0},v_{0})\), \((u_{1},v_{1})\), and \((u_{2},v_{2})\), respectively. The normal vector, \(\mathbf{n}\), for this triangle can be computed by \(\mathbf{n}=(\mathbf{p}_{1}-\mathbf{p}_{0})\times(\mathbf{p}_{2}-\mathbf{p}_{0 })/\|(\mathbf{p}_{1}-\mathbf{p}_{0})\times(\mathbf{p}_{2}-\mathbf{p}_{0})\|\). Assuming a linear mapping of the triangle from texture space to world space, we can estimate the tangent vector, \(\mathbf{t}\), and the bitangent vector, \(\mathbf{b}\), which correspond to the \(u\)- and \(v\)-axes of texture space, by establishing the relationship between the triangle edges in texture space and world space:  
\[\mathbf{p}_{1}-\mathbf{p}_{0} =(u_{1}-u_{0})\mathbf{t}+(v_{1}-v_{0})\mathbf{b}, \tag{1}\] \[\mathbf{p}_{2}-\mathbf{p}_{0} =(u_{2}-u_{0})\mathbf{t}+(v_{2}-v_{0})\mathbf{b}. \tag{2}\]  
Rearranging these equations for \(\mathbf{t}\) and \(\mathbf{b}\) gives  
\[\Big{[}(\mathbf{p}_{1}-\mathbf{p}_{0})\big{|}(\mathbf{p}_{2}-\mathbf{p}_{0}) \Big{]}=\Big{[}\mathbf{t}|\mathbf{b}\Big{]}\begin{bmatrix}(u_{1}-u_{0})&(u_{2} -u_{0})\\ (v_{1}-v_{0})&(v_{2}-v_{0})\end{bmatrix}. \tag{3}\]  
Thus, \(\mathbf{t}\) and \(\mathbf{b}\) of the triangle can be obtained by  
\[\Big{[}\mathbf{t}|\mathbf{b}\Big{]}=\Big{[}\mathbf{p}_{1}-\mathbf{p}_{0}\big{|} \mathbf{p}_{2}-\mathbf{p}_{0}\Big{]}\begin{bmatrix}(u_{1}-u_{0})&(u_{2}-u_{0}) \\ (v_{1}-v_{0})&(v_{2}-v_{0})\end{bmatrix}^{-1}. \tag{4}\]  
For smooth shading across triangles, it is necessary to average the tangent, bitangent, and normal vectors of the triangles adjacent to a vertex. Note that the averaged vectors are not unit vectors, and they are not necessarily mutually orthogonal. To establish a valid tangent space, they should be orthonormalized. In [2; 5; 6], the Gram-Schmidt process is employed for orthonormalization, which alters the tangent vector and then the bitangent vector. Changing the order can produce different results. Consequently, this approach involves two somewhat intricate operations: averaging and the Gram-Schmidt orthonormalization process.  
[PERSON] addressed various issues in normal map generation and application [3]. In particular, a slightly different orthonormalization was introduced. The tangent and bitangent vectors of the triangles sharing a vertex are projected onto the plane perpendicular to the normal vector of the vertex and then normalized before the final averaging and normalization. The computation for the per-vertex bitangent vectors can be omitted, and the bitangent vector at a surface point can be computed directly by the cross product of the normal vector and tangent vector during per-pixel shading. Despite being published in 2008, [PERSON]'s work has evolved into the industry standard over the past decade. This framework has been widely adopted in commercial software tools and game engines, including Autodesk Maya 2024, Autodesk 3 ds Max 2021, Adobe Substance 3D 13, Epic Games Unreal Engine 4, Unity Technologies Unity 5.3, Marmoset Toolbox 3, SideFX Houdini 17.5, and Foundry Modo 10.0v1, as well as in free/open-source platforms such as Blender 2.57, xNormal 3.17.5, and Godot Engine 3.4.