-
Notifications
You must be signed in to change notification settings - Fork 151
ComputeTangentFrame
DirectXMesh |
---|
Generates per-vertex tangent and bi-tangent information
HRESULT ComputeTangentFrame(
const uint16_t* indices, size_t nFaces,
const XMFLOAT3* positions, const XMFLOAT3* normals,
const XMFLOAT2* texcoords, size_t nVerts,
XMFLOAT3* tangents, XMFLOAT3* bitangents );
HRESULT ComputeTangentFrame(
const uint16_t* indices, size_t nFaces,
const XMFLOAT3* positions, const XMFLOAT3* normals,
const XMFLOAT2* texcoords, size_t nVerts,
XMFLOAT4* tangents, XMFLOAT3* bitangents );
HRESULT ComputeTangentFrame(
const uint16_t* indices, size_t nFaces,
const XMFLOAT3* positions, const XMFLOAT3* normals,
const XMFLOAT2* texcoords, size_t nVerts,
XMFLOAT4* tangents );
HRESULT ComputeTangentFrame(
const uint32_t* indices, size_t nFaces,
const XMFLOAT3* positions, const XMFLOAT3* normals,
const XMFLOAT2* texcoords, size_t nVerts,
XMFLOAT3* tangents, XMFLOAT3* bitangents );
HRESULT ComputeTangentFrame(
const uint32_t* indices, size_t nFaces,
const XMFLOAT3* positions, const XMFLOAT3* normals,
const XMFLOAT2* texcoords, size_t nVerts,
XMFLOAT4* tangents, XMFLOAT3* bitangents );
HRESULT ComputeTangentFrame(
const uint32_t* indices, size_t nFaces,
const XMFLOAT3* positions, const XMFLOAT3* normals,
const XMFLOAT2* texcoords, size_t nVerts,
XMFLOAT4* tangents );
The normals parameter can be computed from the mesh indices and vertex positions using ComputeNormals.
The tangents can be optionally returned as a 4-vector where the .w component indicates 'handedness' which allows for an easy reconstruction of the bi-tangent in the shader.
float3 normal : NORMAL0
float4 tangent : TANGENT0
...
float3 tan1 = tangent.xyz;
float3 tan2 = cross( normal, tangent.xyz ) * tangent.w;
In the overloads that take both tangents and bitangents, either but not both can be nullptr.
Note that bi-normal is another common term used for bi-tangent, although technically a bi-normal only applies in 2D and not 3D. The Direct3D HLSL semantic name for the bi-tangent is BINORMAL
.
Due to the C++ overload resolution rules, if you want to call ComputeTangentFrame
for only the binormal output and not the tangent output, you need to use an explicit cast on the nullptr parameter:
auto bitangents = std::make_unique<XMFLOAT3[]>(nVerts);
if ( FAILED( ComputeTangentFrame( mesh->indices.data(), nFaces,
pos.get(), normals.get(), texcoords.get(), nVerts,
static_cast<XMFLOAT3*>(nullptr), bitangents.get() ) ) )
// Error
auto mesh = std::make_unique<WaveFrontReader<uint16_t>>();
if ( FAILED( mesh->Load( L"test.obj" ) ) )
// Error
if ( mesh->hasNormals )
// Skip next computation
size_t nFaces = mesh->indices.size() / 3;
size_t nVerts = mesh->vertices.size();
auto pos = std::make_unique<XMFLOAT3[]>(nVerts);
for( size_t j = 0; j < nVerts; ++j )
pos[ j ] = mesh->vertices[ j ].position;
auto normals = std::make_unique<XMFLOAT3[]>(nVerts);
if ( FAILED( ComputeNormals( mesh->indices.data(), nFaces,
pos.get(), nVerts, CNORM_DEFAULT, normals.get() ) ) )
// Error
if ( !mesh->hasTexcoords )
// Skip next computation
auto texcoords = std::make_unique<XMFLOAT2[]>(nVerts);
for( size_t j = 0; j < nVerts; ++j )
texcoords[ j ] = mesh->vertices[ j ].textureCoordinate;
auto tangents = std::make_unique<XMFLOAT3[]>(nVerts);
auto bitangents = std::make_unique<XMFLOAT3[]>(nVerts);
if ( FAILED( ComputeTangentFrame( mesh->indices.data(), nFaces,
pos.get(), normals.get(), texcoords.get(), nVerts,
tangents.get(), bitangents.get() ) ) )
// Error
Lengyel, Eric. "7.5 Tangent Space", Foundations of Game Engine Development: Volume 2 - Rendering, Terathon Software LLC (2019) link
Mittring, Martin. "Triangle Mesh Tangent Space Calculation". Shader X^4 Advanced Rendering Techniques, 2006
All content and source code for this package are subject to the terms of the MIT License.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.
- Universal Windows Platform apps
- Windows desktop apps
- Windows 11
- Windows 10
- Windows 8.1
- Windows 7 Service Pack 1
- Xbox One
- Xbox Series X|S
- Windows Subsystem for Linux
- x86
- x64
- ARM64
- Visual Studio 2022
- Visual Studio 2019 (16.11)
- clang/LLVM v12 - v18
- GCC 10.5, 11.4, 12.3
- MinGW 12.2, 13.2
- CMake 3.20
DirectX Tool Kit for DirectX 11