D3D11坐标系

Fir*_*cer 6 c++ direct3d matrix direct3d11

我的一些旧代码最终出现了一堆令人讨厌的黑客行为,以使事情“正确”工作,在移动物体和相机方面,例如必须采用“std::sin(-yaw)”而不是“std::sin(yaw)”在实现在线其他地方找到的方程时,通常会让一切变得混乱,在许多情况下都达到了追踪和错误的程度。

  1. 使用 D3D11 和 DirectXMath 的东西(所以左手坐标和行主?),预期的坐标系到底是什么,例如假设相机位于原点并沿着图像中的黄色向量看而不旋转,标签是否正确?。

    在此输入图像描述

    然后考虑到这一点,以及由(x,y,z)和俯仰(y轴鼠标/控件),偏航(x轴鼠标/控件)描述的相机,并假设我没有其他方法应该做即使...

  2. 获取视图矩阵的正确函数是什么(当前我乘以一个平移矩阵和两个旋转矩阵,乘以投影,然后乘以相关对象的任何世界矩阵,并将结果转置以用作单个着色器常量)。

  3. 获取相机所观察的向量的方程是什么(当前将 (0,0,1) 向量乘以 2 中的矩阵)。

  4. ...以及“向上”和“向右”向量(因为即使不使用观察矩阵视图函数,似乎视锥体剔除也需要知道这些)。当前再次与 2 中的矩阵相乘。
  5. 根据方向矢量计算正确的俯仰和偏航标量/分量(例如,对于具有单独的俯仰/偏航关节的炮塔)。

编辑:代码示例:

//Moving a floating object with only yaw forwards (moveX,moveY,moveZ).
//Negative yaw seems wrong?
auto c = std::cosf(-yaw);
auto s = std::sinf(-yaw);
pos.x += moveX * c - moveZ * s;
pos.y += moveY;
pos.z += moveX * s + moveZ * c;

//Gets the vector the camera is looking along
//This time yaw is positive, but pitch is negative?
float c = std::cos(-pitch);
Vector3F facing(
    c * std::sinf(yaw),
    std::sinf(-pitch),
    c * std::cosf(yaw));

//Creating the view transform matrix, everything is negative
XMMATRIX xmviewrot;
xmviewrot = XMMatrixRotationY(-yaw);
xmviewrot*= XMMatrixRotationX(-pitch);
XMMATRIX xmview;
xmview = XMMatrixTranslation(-x, -y, -z);
xmview *= xmviewrot;
XMStoreFloat4x4A(&view, xmview);

//Other vectors needed for frustum culling
XMVECTOR xmup = XMVector3Transform(XMLoadFloat4A(&UP), xmview);
XMVECTOR xmright = XMVector3Transform(XMLoadFloat4A(&RIGHT), xmview);

//Matrix for stuff that is already in world space (e.g. terrain)
XMMATRIX xmviewProj = xmview * xmproj;
//Apparently needs transposing before use on the GPU...
XMStoreFloat4x4A(&constants.transform, XMMatrixTranspose(xmviewProj));

//In the shaders
output.pos = mul(input.pos, transform);

//vertex positions for an upwards facing square with triangle strip
v0 = (x1, y, z1);
v1 = (x1, y, z2);
v2 = (x2, y, z2);
v3 = (x2, y, z1);
Run Code Online (Sandbox Code Playgroud)

所以在我看来,我在这里做了一些根本性的错误,需要在不同的地方使用 -yaw 和 +yaw、-pitch 和 +pitch ?其中一些功能我最终通过反复试验来完成,以获得正确的结果,在线样本没有使用负数。

Ros*_*dge 3

Direct3D 11 没有指定的坐标系,您可以使用任何您想要的坐标系。来自 Chuck Walbourn 关于Direct3D 11 入门的博客文章:

数学:由于 Direct3D 11 没有 Direct3D 9 的“固定功能”图形管道,因此图形数学约定(左手与右手、行主矩阵与列主矩阵等)的选择是完全由开发商决定。DirectXMath 可用于使用行主矩阵约定创建 Direct3D 样式的“左手坐标”变换以及 OpenGL 样式的“右手坐标”变换,该约定可直接与行主着色器一起使用或转置为使用列主着色器。

您的着色器决定它们期望的坐标系。最终,它们必须在同构剪辑空间中向光栅化器阶段提供顶点,Direct3D 11 将其定义为:

假设进入光栅化阶段的顶点 (x,y,z,w) 位于同质剪辑空间中。在此坐标空间中,X 轴指向右侧,Y 轴指向上方,Z 轴指向远离相机的方向。

因此,其他问题的答案取决于您为项目选择的坐标系。DirectXMath 库有许多函数可以为您计算适当的矩阵。较旧的 D3DX 库文档显示了用于计算这些矩阵的数学方法。

您的其他问题不是很清楚,但它们似乎不了解矩阵如何用于变换顶点。您可能想查看旧的 Direct3D 9 文档,其中描述了如何以及为何在固定函数管道中使用顶点,并对这些主题进行了很好的介绍。