Содержание
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 );
Parameters
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.
Remark
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
Example
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
Further Reading
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
For Use
- 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
For Development
- 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
Related Projects
DirectX Tool Kit for DirectX 11
DirectX Tool Kit for DirectX 12
Tools
See also
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 opencode@microsoft.com with any additional questions or comments.