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



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

  1. D3DXMatrixLookAtLH

zaxis = 正常(在 - 眼睛)

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

-点(x轴,眼睛) -点(yaxis,眼睛) -点(zaxis,眼睛)1

  1. D3DXMatrixLookAtRH

zaxis = 正常(眼睛 - 在)

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

点(x轴,眼) 点(y轴,眼) 点(z轴,眼) 1

为什么 RH 的转换没有乘以 -1?

TL;DR:D3DXMatrixLookAtRH的Microsoft文档页面是错误的。我已经提交了 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.DXSDK.D3DX NuGet 即可避免混合使用旧版 DirectX SDK 和现代版 Visual Studio 的文档Microsoft Docs 上涵盖的所有复杂问题。新项目应移至各种替换中的任何一个。有关更多详细信息,请参阅此博客文章。

最新更新