1

I'm using a translator, so please understand that I may be inexperienced. I'm currently trying to create a 3d model in dx12 using fbxsdk. There is no problem with the modeling used in the current example code, but now the moment you use the 3d model on sites such as mixamo and turbo, iTangentCnt or iBinormalCnt value is zero, so the program is not working. Is this because there is no tangent and binormal in the model? There is no value even if you use other models, so I am curious that models have no value. How did others solve this problem?

void CFBXLoader::GetTangent(FbxMesh* _pMesh, tContainer* _pContainer, int _iIdx      , int _iVtxOrder){



int iTangentCnt = _pMesh->GetElementTangentCount();
if (1 != iTangentCnt)
    assert(NULL); 


FbxGeometryElementTangent* pTangent = _pMesh->GetElementTangent();
UINT iTangentIdx = 0;

if (pTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
{
    if (pTangent->GetReferenceMode() == FbxGeometryElement::eDirect)
        iTangentIdx = _iVtxOrder;
    else
        iTangentIdx = pTangent->GetIndexArray().GetAt(_iVtxOrder);
}
else if (pTangent->GetMappingMode() == FbxGeometryElement::eByControlPoint)
{
    if (pTangent->GetReferenceMode() == FbxGeometryElement::eDirect)
        iTangentIdx = _iIdx;
    else
        iTangentIdx = pTangent->GetIndexArray().GetAt(_iIdx);
}

FbxVector4 vTangent = pTangent->GetDirectArray().GetAt(iTangentIdx);

_pContainer->vecTangent[_iIdx].x = (float)vTangent.mData[0];
_pContainer->vecTangent[_iIdx].y = (float)vTangent.mData[2];
_pContainer->vecTangent[_iIdx].z = (float)vTangent.mData[1];}


void CFBXLoader::GetBinormal(FbxMesh* _pMesh, tContainer* _pContainer, int _iIdx, int _iVtxOrder){




int iBinormalCnt = _pMesh->GetElementBinormalCount();
if (1 != iBinormalCnt)
    assert(NULL);
FbxGeometryElementBinormal* pBinormal = _pMesh->GetElementBinormal();
UINT iBinormalIdx = 0;

if (pBinormal->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
{
    if (pBinormal->GetReferenceMode() == FbxGeometryElement::eDirect)
        iBinormalIdx = _iVtxOrder;
    else
        iBinormalIdx = pBinormal->GetIndexArray().GetAt(_iVtxOrder);
}
else if (pBinormal->GetMappingMode() == FbxGeometryElement::eByControlPoint)
{
    if (pBinormal->GetReferenceMode() == FbxGeometryElement::eDirect)
        iBinormalIdx = _iIdx;
    else
        iBinormalIdx = pBinormal->GetIndexArray().GetAt(_iIdx);
}

FbxVector4 vBinormal = pBinormal->GetDirectArray().GetAt(iBinormalIdx);

_pContainer->vecBinormal[_iIdx].x = (float)vBinormal.mData[0];
_pContainer->vecBinormal[_iIdx].y = (float)vBinormal.mData[2];
_pContainer->vecBinormal[_iIdx].z = (float)vBinormal.mData[1];

}

이동수
  • 31
  • 2

2 Answers2

1

If your run-time scenario requires tangents/binormals to operate, then you need to handle the case of them not already being defined in the FBX. If the iBinormalCnt is 0, then you can generate tangents/binormals in your own program using the surface normal and texture coordinates.

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

See DirectXMesh's ComputeTangentFrame function.

For an example of a complete model exporter using Autodesk FBX, see the DirectX SDK Sample Content Exporter.

Note another option for rendering with tangent space without exporting the tangent/binormals is to compute them in the pixel shader at render time. I use this technique in the DirectX Tool Kit.

Christian Schüler, "Normal Mapping without Precomputed Tangents", ShaderX 5, Chapter 2.6, pp. 131 – 140 and this blog post

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
0

If tangents and bitangents are not present in your fbx file (you still need normals and one set of texture coordinates to have it work), you can use the GenerateTangentsData of FbxMesh object to build them.

bool result = _pMesh->GenerateTangentsData(uvSetIndex, overwrite, ignoretangentflip);

you will want overwrite to false, and ignoretangentflip to false most of the times. uvSetIndex will be 0 most times as well (unless you have multiple uv set on your model).

mrvux
  • 8,523
  • 1
  • 27
  • 61