【问题标题】:model dont have tangent or binormal value fbxsdk directx模型没有切线或副法线值 fbxsdk directx
【发布时间】:2022-01-18 13:53:24
【问题描述】:

我正在使用翻译,所以请理解我可能缺乏经验。我目前正在尝试使用 fbxsdk 在 dx12 中创建 3d 模型。 当前示例代码中使用的建模没有问题,但是现在您在mixamo和turbo等网站上使用3d模型的那一刻, iTangentCnt 或 iBinormalCnt 值为零,因此程序不工作。 这是因为模型中没有切线和副法线吗? 即使你使用其他模型也没有价值,所以我很好奇模型没有价值。其他人是如何解决这个问题的?

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];

}

【问题讨论】:

    标签: c++ directx-11 fbx 3d-modelling directx-12


    【解决方案1】:

    如果您的运行时场景需要切线/副法线来操作,那么您需要处理它们尚未在 FBX 中定义的情况。如果iBinormalCnt 为0,那么您可以在自己的程序中使用表面法线和纹理坐标生成切线/副法线。

    伦耶尔,埃里克。 “7.5 切线空间”,游戏引擎开发基础:第 2 卷 - 渲染,Terathon Software LLC (2019) link

    米特林,马丁。 《三角网格切线空间计算》。 Shader X^4 高级渲染技术,2006 年

    参见DirectXMeshComputeTangentFrame 函数。

    有关使用 Autodesk FBX 的完整模型导出器的示例,请参阅DirectX SDK Sample Content Exporter

    注意另一个使用切线空间渲染而不导出切线/副法线的选项是在渲染时在像素着色器中计算它们。我在 DirectX Tool Kit 中使用了这种技术。

    Christian Schüler,“没有预计算切线的法线映射”,ShaderX 5,第 2.6 章,第 131 - 140 页和this blog post

    【讨论】:

      【解决方案2】:

      如果您的 fbx 文件中不存在切线和双切线(您仍然需要法线和一组纹理坐标才能使其工作),您可以使用 FbxMesh 对象的 GenerateTangentsData 来构建它们。

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

      在大多数情况下,您会希望将其覆盖为 false,并忽略切线翻转为 false。 uvSetIndex 大多数时候也会为 0(除非您的模型上有多个 uv 集)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-06
        • 2023-02-13
        • 2013-07-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多