DX9 中的 LookAt 矩阵计算需要澄清

时间:2021-05-20 04:38:10

标签: c++ directx directx-9

我将通过这两种方法来计算观察矩阵

  1. D3DXMatrixLookAtLH

zaxis = normal(At - Eye)

xaxis = normal(cross(Up, zaxis))

yaxis = cross(zaxis, xaxis)

xaxis.x yaxis.x zaxis.x 0

xaxis.y yaxis.y zaxis.y 0

xaxis.z yaxis.z zaxis.z 0

-dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1

  1. D3DXMatrixLookAtRH

zaxis = normal(Eye - At)

xaxis = normal(cross(Up, zaxis))

yaxis = cross(zaxis, xaxis)

xaxis.x yaxis.x zaxis.x 0

xaxis.y yaxis.y zaxis.y 0

xaxis.z yaxis.z zaxis.z 0

dot(xaxis, eye) dot(yaxis, eye) dot(zaxis, eye) 1

为什么 RH 的翻译不乘以 -1?

1 个答案:

答案 0 :(得分:1)

TL;DR: D3DXMatrixLookAtRH 的 Microsoft Doc 页面有误。我已提交 PR 来修复它。

在 D3DXMath 的实际实现中,很明显,在这两种情况下,LH 和 RH 的翻译都应该是 -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye)

唯一的区别在于zaxis计算。

D3DXMATRIX* WINAPI D3DXMatrixLookAtRH
    ( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
      const D3DXVECTOR3 *pUp )
{
    D3DXVECTOR3 XAxis, YAxis, ZAxis;

    // Compute direction of gaze. (-Z)
    D3DXVec3Subtract(&ZAxis, pEye, pAt);
    D3DXVec3Normalize(&ZAxis, &ZAxis);

    // Compute orthogonal axes from cross product of gaze and pUp vector.
    D3DXVec3Cross(&XAxis, pUp, &ZAxis);
    D3DXVec3Normalize(&XAxis, &XAxis);
    D3DXVec3Cross(&YAxis, &ZAxis, &XAxis);

    // Set rotation and translate by pEye
    pOut->_11 = XAxis.x;
    pOut->_21 = XAxis.y;
    pOut->_31 = XAxis.z;
    pOut->_41 = -D3DXVec3Dot(&XAxis, pEye);

    pOut->_12 = YAxis.x;
    pOut->_22 = YAxis.y;
    pOut->_32 = YAxis.z;
    pOut->_42 = -D3DXVec3Dot(&YAxis, pEye);

    pOut->_13 = ZAxis.x;
    pOut->_23 = ZAxis.y;
    pOut->_33 = ZAxis.z;
    pOut->_43 = -D3DXVec3Dot(&ZAxis, pEye);

    pOut->_14 = 0.0f;
    pOut->_24 = 0.0f;
    pOut->_34 = 0.0f;
    pOut->_44 = 1.0f;


    return pOut;
}

D3DXMATRIX* WINAPI D3DXMatrixLookAtLH
    ( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
      const D3DXVECTOR3 *pUp )
{
    D3DXVECTOR3 XAxis, YAxis, ZAxis;

    // Compute direction of gaze. (+Z)
    D3DXVec3Subtract(&ZAxis, pAt, pEye);
    D3DXVec3Normalize(&ZAxis, &ZAxis);

    // Compute orthogonal axes from cross product of gaze and pUp vector.
    D3DXVec3Cross(&XAxis, pUp, &ZAxis);
    D3DXVec3Normalize(&XAxis, &XAxis);
    D3DXVec3Cross(&YAxis, &ZAxis, &XAxis);

    // Set rotation and translate by pEye
    pOut->_11 = XAxis.x;
    pOut->_21 = XAxis.y;
    pOut->_31 = XAxis.z;
    pOut->_41 = -D3DXVec3Dot(&XAxis, pEye);

    pOut->_12 = YAxis.x;
    pOut->_22 = YAxis.y;
    pOut->_32 = YAxis.z;
    pOut->_42 = -D3DXVec3Dot(&YAxis, pEye);

    pOut->_13 = ZAxis.x;
    pOut->_23 = ZAxis.y;
    pOut->_33 = ZAxis.z;
    pOut->_43 = -D3DXVec3Dot(&ZAxis, pEye);

    pOut->_14 = 0.0f;
    pOut->_24 = 0.0f;
    pOut->_34 = 0.0f;
    pOut->_44 = 1.0f;

    return pOut;
}
<块引用>

D3DXMatrixLookAtRHD3DXMatrixLookAtLH 都是“D3DXMath”的一部分,D3DXMath 是 D3DX9 和 D3DX10 中包含的数学库。这些帮助程序库与 DirectX SDK 本身一样已被弃用。建议改用 DirectXMath

<块引用>

如果您出于某种原因必须使用 D3DX9,请注意,您可以通过使用 Microsoft Docs NuGet 来避免 Microsoft.DXSDK.D3DX 混合旧版 DirectX SDK 和现代版本的 Visual Studio 中涵盖的所有复杂问题。新项目应移至任何 various replacements。有关详情,请参阅 this blog post

相关问题