在DirectX中反投影屏幕坐标时遇到意外结果

10
为了能够确定用户是否点击了我的3D对象中的任何一个,我正在尝试将点击的屏幕坐标转换为向量,然后使用它来检查是否有任何三角形被击中。为此,我使用DirectX提供的XMVector3Unproject方法,并在C++/CX中实现所有内容。
我面临的问题是,从未投影的屏幕坐标得到的向量与我的预期完全不同。下面的图像说明了这一点: Vector resulting from unprojection 单击发生时的光标位置(突出显示为黄色)在左侧的等轴测视图中可见。一旦我单击,从未投影的向量就会出现在模型后面,如图中表示为穿过模型的白线。因此,它并不是从等轴测视图中光标位置开始并进入屏幕,而是出现在完全不同的位置。
当我在等距视图中水平移动鼠标并单击后,再垂直移动鼠标并点击时,下方的图案会出现。两张图片中的所有线条都代表从点击中得出的向量。为了更好地展示,模型已被移除。 Vector resulting from unprojection originate in same location 如上图所示,可以看出所有向量似乎都起源于同一位置。如果我改变视角并重复这个过程,则相同的图案将出现,但向量的起点不同。

Different perspective, different origin of the vectors

这是我用来实现此功能的代码片段。首先,我使用以下代码获取光标位置,并将其与绘图区域的宽度和高度一起传递给我的“SelectObject”方法:
void Demo::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
{
  Point currentPosition = e->CurrentPoint->Position;

  if(m_model->SelectObject(currentPosition.X, currentPosition.Y, m_renderTargetWidth, m_renderTargetHeight))
  {
    m_RefreshImage = true;
  }
}

"SelectObject"方法如下:

bool Model::SelectObject(float screenX, float screenY, float screenWidth, float screenHeight)
{
  XMMATRIX projectionMatrix = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->projection);
  XMMATRIX viewMatrix       = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->view);
  XMMATRIX modelMatrix      = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->model);

  XMVECTOR v = XMVector3Unproject(XMVectorSet(screenX, screenY, 5.0f, 0.0f),
                                  0.0f,
                                  0.0f,
                                  screenWidth,
                                  screenHeight,
                                  0.0f,
                                  1.0f,
                                  projectionMatrix,
                                  viewMatrix,
                                  modelMatrix);

  XMVECTOR rayOrigin = XMVector3Unproject(XMVectorSet(screenX, screenY, 0.0f, 0.0f),
                                          0.0f,
                                          0.0f,
                                          screenWidth,
                                          screenHeight,
                                          0.0f,
                                          1.0f,
                                          projectionMatrix,
                                          viewMatrix,
                                          modelMatrix);

  // Code to retrieve v0, v1 and v2 is omitted

  if(Intersects(rayOrigin, XMVector3Normalize(v - rayOrigin), v0, v1, v2, depth))
  {
    return true;
  }
}

最终计算出的向量将被DirectX::TriangleTests命名空间下的Intersects方法使用,以检测三角形是否被击中。由于这个问题与代码无关,因此我省略了以上片段中的代码。
为了渲染这些图像,我使用正交投影矩阵和一个可以沿着其本地x和y轴旋转的摄像机来生成视图矩阵。世界矩阵始终保持不变,即它只是一个身份矩阵。
视图矩阵的计算方法如下(基于Frank Luna的书3D Game Programming中的示例):
void Camera::SetViewMatrix()
{
  XMFLOAT3 cameraPosition;
  XMFLOAT3 cameraXAxis;
  XMFLOAT3 cameraYAxis;
  XMFLOAT3 cameraZAxis;

  XMFLOAT4X4 viewMatrix;

  // Keep camera's axes orthogonal to each other and of unit length.
  m_cameraZAxis = XMVector3Normalize(m_cameraZAxis);
  m_cameraYAxis = XMVector3Normalize(XMVector3Cross(m_cameraZAxis, m_cameraXAxis));

  // m_cameraYAxis and m_cameraZAxis are already normalized, so there is no need
  // to normalize the below cross product of the two.
  m_cameraXAxis = XMVector3Cross(m_cameraYAxis, m_cameraZAxis);

  // Fill in the view matrix entries.
  float x = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraXAxis));
  float y = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraYAxis));
  float z = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraZAxis));

  XMStoreFloat3(&cameraPosition, m_cameraPosition);
  XMStoreFloat3(&cameraXAxis   , m_cameraXAxis);
  XMStoreFloat3(&cameraYAxis   , m_cameraYAxis);
  XMStoreFloat3(&cameraZAxis   , m_cameraZAxis);

  viewMatrix(0, 0) = cameraXAxis.x;
  viewMatrix(1, 0) = cameraXAxis.y;
  viewMatrix(2, 0) = cameraXAxis.z;
  viewMatrix(3, 0) = x;

  viewMatrix(0, 1) = cameraYAxis.x;
  viewMatrix(1, 1) = cameraYAxis.y;
  viewMatrix(2, 1) = cameraYAxis.z;
  viewMatrix(3, 1) = y;

  viewMatrix(0, 2) = cameraZAxis.x;
  viewMatrix(1, 2) = cameraZAxis.y;
  viewMatrix(2, 2) = cameraZAxis.z;
  viewMatrix(3, 2) = z;

  viewMatrix(0, 3) = 0.0f;
  viewMatrix(1, 3) = 0.0f;
  viewMatrix(2, 3) = 0.0f;
  viewMatrix(3, 3) = 1.0f;

  m_modelViewProjectionConstantBufferData->view = viewMatrix;
}

这受到两种方法的影响,它们分别围绕相机的x轴和y轴旋转相机:

void Camera::ChangeCameraPitch(float angle)
{
  XMMATRIX rotationMatrix = XMMatrixRotationAxis(m_cameraXAxis, angle);

  m_cameraYAxis = XMVector3TransformNormal(m_cameraYAxis, rotationMatrix);
  m_cameraZAxis = XMVector3TransformNormal(m_cameraZAxis, rotationMatrix);
}

void Camera::ChangeCameraYaw(float angle)
{
  XMMATRIX rotationMatrix = XMMatrixRotationAxis(m_cameraYAxis, angle);

  m_cameraXAxis = XMVector3TransformNormal(m_cameraXAxis, rotationMatrix);
  m_cameraZAxis = XMVector3TransformNormal(m_cameraZAxis, rotationMatrix);
}

世界/模型矩阵和投影矩阵的计算如下所示:
void Model::SetProjectionMatrix(float width, float height, float nearZ, float farZ)
{
  XMMATRIX orthographicProjectionMatrix = XMMatrixOrthographicRH(width, height, nearZ, farZ);

  XMFLOAT4X4 orientation = XMFLOAT4X4
  (
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f
  );

  XMMATRIX orientationMatrix = XMLoadFloat4x4(&orientation);

  XMStoreFloat4x4(&m_modelViewProjectionConstantBufferData->projection, XMMatrixTranspose(orthographicProjectionMatrix * orientationMatrix));
}

void Model::SetModelMatrix()
{
  XMFLOAT4X4 orientation = XMFLOAT4X4
  (
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f
  );

  XMMATRIX orientationMatrix = XMLoadFloat4x4(&orientation);

  XMStoreFloat4x4(&m_modelViewProjectionConstantBufferData->model, XMMatrixTranspose(orientationMatrix));
}

坦率地说,我还不理解我面临的问题。如果有更深入的了解的人能给我一些提示,告诉我在哪里需要进行更改,使得从未投影的向量起始于光标位置并进入屏幕,我将不胜感激。
编辑1: 我认为这可能与我的相机在世界坐标系中位于(0, 0, 0)有关。相机围绕其本地X和Y轴旋转。据我所知,由相机创建的视图矩阵构建了图像投影的平面。如果是这样,那么就可以解释为什么射线位于某种程度上“意外”的位置。
我的假设是,我需要将相机移出中心,使其位于对象之外。然而,如果我简单地修改相机的成员变量m_cameraPosition,我的模型就会完全失真。
是否有人能够提供帮助?

3
我不熟悉这个论点,但是我在 "XMVectorSet(screenX, screenY, 5.0f, 0.0f)" 中看到您使用了一个四维向量。因此,您正在使用四维空间,并且您所看到的是它的二维投影。我理解得对吗? - George Kourtis
3
或许你可以查看这个链接:http://stackoverflow.com/a/26662222/1306012 - Bruno Bieri
3
我实际上正在使用3D向量,坐标的第四个部分(0.0f)只是表示它是一个向量。将其设置为1.0f表示它是一个点。 - anon
4个回答

5

感谢您的提示,Kapil。我尝试使用XMMatrixLookAtRH方法,但无法使用该方法改变相机的俯仰/偏航角,因此我放弃了该方法并自己生成矩阵。

解决我的问题的方法是在传递给XMVector3Unproject之前使用XMMatrixTranspose转置模型、视图和投影矩阵。因此,代码不再像下面这样:

  XMMATRIX projectionMatrix = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->projection);
  XMMATRIX viewMatrix       = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->view);
  XMMATRIX modelMatrix      = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->model);

  XMVECTOR rayBegin = XMVector3Unproject(XMVectorSet(screenX, screenY, -m_boundingSphereRadius, 0.0f),
                                         0.0f,
                                         0.0f,
                                         screenWidth,
                                         screenHeight,
                                         0.0f,
                                         1.0f,
                                         projectionMatrix,
                                         viewMatrix,
                                         modelMatrix);

它需要被实现。

  XMMATRIX projectionMatrix = XMMatrixTranspose(XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->projection));
  XMMATRIX viewMatrix       = XMMatrixTranspose(XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->view));
  XMMATRIX modelMatrix      = XMMatrixTranspose(XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->model));

  XMVECTOR rayBegin = XMVector3Unproject(XMVectorSet(screenX, screenY, -m_boundingSphereRadius, 0.0f),
                                         0.0f,
                                         0.0f,
                                         screenWidth,
                                         screenHeight,
                                         0.0f,
                                         1.0f,
                                         projectionMatrix,
                                         viewMatrix,
                                         modelMatrix);

我不完全清楚为什么在传递给unproject方法之前需要转置矩阵。但我怀疑这与我移动相机时遇到的问题有关。这个问题已经在StackOverflow上被描述过,可以看这个帖子。
我还没有解决这个问题。仅仅转置视图矩阵并不能解决它。然而,我的主要问题已经解决了,我的模型终于可以点击了。
如果有人能够补充说明为什么需要转置矩阵或者为什么移动相机会扭曲模型,请随意发表评论或回答。

4

我在Model::SetViewMatrix()函数中使用了XMMatrixLookAtRH API来计算视图矩阵,并得到了不错的vrayOrigin向量值。

例如:

XMStoreFloat4x4(
        &m_modelViewProjectionConstantBufferData->view,
        XMMatrixLookAtRH(m_cameraPosition, XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f), 
        XMVectorSet(1.0f, 0.0f, 0.0f, 0.0f))
        );

虽然我无法在屏幕上观察到输出,但在控制台应用程序中计算了一些简单值后,向量值似乎是正确的。请在您的应用程序中进行检查并确认。

注意: 在使用XMMatrixLookAtRH API时,您需要提供焦点和向上方向向量参数,而不是使用当前的方法。


3

使用XMMatrixLookAtRH方法以及您的自定义视图矩阵,我能够使用以下代码获取vrayOrigin向量的相等值,而无需进行矩阵转置操作:

#include <directxmath.h>

using namespace DirectX;

XMVECTOR m_cameraXAxis;
XMVECTOR m_cameraYAxis;
XMVECTOR m_cameraZAxis;
XMVECTOR m_cameraPosition;

XMMATRIX gView;
XMMATRIX gView2;
XMMATRIX gProj;
XMMATRIX gModel;

void SetViewMatrix()
{
    XMVECTOR lTarget = XMVectorSet(2.0f, 2.0f, 2.0f, 1.0f);

    m_cameraPosition = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
    m_cameraZAxis = XMVector3Normalize(XMVectorSubtract(m_cameraPosition, lTarget));
    m_cameraXAxis = XMVector3Normalize(XMVector3Cross(XMVectorSet(1.0f, -1.0f, -1.0f, 0.0f), m_cameraZAxis));

    XMFLOAT3 cameraPosition;
    XMFLOAT3 cameraXAxis;
    XMFLOAT3 cameraYAxis;
    XMFLOAT3 cameraZAxis;

    XMFLOAT4X4 viewMatrix;

    // Keep camera's axes orthogonal to each other and of unit length.
    m_cameraZAxis = XMVector3Normalize(m_cameraZAxis);
    m_cameraYAxis = XMVector3Normalize(XMVector3Cross(m_cameraZAxis, m_cameraXAxis));

    // m_cameraYAxis and m_cameraZAxis are already normalized, so there is no need
    // to normalize the below cross product of the two.
    m_cameraXAxis = XMVector3Cross(m_cameraYAxis, m_cameraZAxis);

    // Fill in the view matrix entries.
    float x = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraXAxis));
    float y = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraYAxis));
    float z = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraZAxis));

    XMStoreFloat3(&cameraPosition, m_cameraPosition);
    XMStoreFloat3(&cameraXAxis, m_cameraXAxis);
    XMStoreFloat3(&cameraYAxis, m_cameraYAxis);
    XMStoreFloat3(&cameraZAxis, m_cameraZAxis);

    viewMatrix(0, 0) = cameraXAxis.x;
    viewMatrix(1, 0) = cameraXAxis.y;
    viewMatrix(2, 0) = cameraXAxis.z;
    viewMatrix(3, 0) = x;

    viewMatrix(0, 1) = cameraYAxis.x;
    viewMatrix(1, 1) = cameraYAxis.y;
    viewMatrix(2, 1) = cameraYAxis.z;
    viewMatrix(3, 1) = y;

    viewMatrix(0, 2) = cameraZAxis.x;
    viewMatrix(1, 2) = cameraZAxis.y;
    viewMatrix(2, 2) = cameraZAxis.z;
    viewMatrix(3, 2) = z;

    viewMatrix(0, 3) = 0.0f;
    viewMatrix(1, 3) = 0.0f;
    viewMatrix(2, 3) = 0.0f;
    viewMatrix(3, 3) = 1.0f;

    gView = XMLoadFloat4x4(&viewMatrix);

    gView2 = XMMatrixLookAtRH(m_cameraPosition, XMVectorSet(2.0f, 2.0f, 2.0f, 1.0f),
            XMVectorSet(1.0f, -1.0f, -1.0f, 0.0f));

    //m_modelViewProjectionConstantBufferData->view = viewMatrix;
    printf("yo");
}

void SetProjectionMatrix(float width, float height, float nearZ, float farZ)
{
    XMMATRIX orthographicProjectionMatrix = XMMatrixOrthographicRH(width, height, nearZ, farZ);

    XMFLOAT4X4 orientation = XMFLOAT4X4
        (
            1.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 1.0f
            );

    XMMATRIX orientationMatrix = XMLoadFloat4x4(&orientation);

    gProj = XMMatrixTranspose( XMMatrixMultiply(orthographicProjectionMatrix, orientationMatrix));
}

void SetModelMatrix()
{
    XMFLOAT4X4 orientation = XMFLOAT4X4
        (
            1.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 1.0f
            );

    XMMATRIX orientationMatrix = XMMatrixTranspose( XMLoadFloat4x4(&orientation));

    gModel = orientationMatrix;
}

bool SelectObject(float screenX, float screenY, float screenWidth, float screenHeight)
{
    XMMATRIX projectionMatrix = gProj;
    XMMATRIX viewMatrix = gView;
    XMMATRIX modelMatrix = gModel;
    XMMATRIX viewMatrix2 = gView2;

    XMVECTOR v = XMVector3Unproject(XMVectorSet(screenX, screenY, 5.0f, 0.0f),
        0.0f,
        0.0f,
        screenWidth,
        screenHeight,
        0.0f,
        1.0f,
        projectionMatrix,
        viewMatrix,
        modelMatrix);

    XMVECTOR rayOrigin = XMVector3Unproject(XMVectorSet(screenX, screenY, 0.0f, 0.0f),
        0.0f,
        0.0f,
        screenWidth,
        screenHeight,
        0.0f,
        1.0f,
        projectionMatrix,
        viewMatrix,
        modelMatrix);

    // Code to retrieve v0, v1 and v2 is omitted
    auto diff = v - rayOrigin;
    auto diffNorm = XMVector3Normalize(diff);

    XMVECTOR v2 = XMVector3Unproject(XMVectorSet(screenX, screenY, 5.0f, 0.0f),
        0.0f,
        0.0f,
        screenWidth,
        screenHeight,
        0.0f,
        1.0f,
        projectionMatrix,
        viewMatrix2,
        modelMatrix);

    XMVECTOR rayOrigin2 = XMVector3Unproject(XMVectorSet(screenX, screenY, 0.0f, 0.0f),
        0.0f,
        0.0f,
        screenWidth,
        screenHeight,
        0.0f,
        1.0f,
        projectionMatrix,
        viewMatrix2,
        modelMatrix);

    auto diff2 = v2 - rayOrigin2;
    auto diffNorm2 = XMVector3Normalize(diff2);

    printf("hi");
    return true;
}

int main()
{
    SetViewMatrix();
    SetProjectionMatrix(1000, 1000, 0.0f, 1.0f);
    SetModelMatrix();

    SelectObject(500, 500, 1000, 1000);

    return 0;
}

请检查您的应用程序代码并确认。您会发现代码与您之前的代码相同,唯一的区别是在SetViewMatrix()中使用XMMatrixLookAtRH方法计算第二个视图矩阵的初始值,并使用两个视图矩阵计算向量在SelectObject()中。 无需转置 我没有必要对任何矩阵进行转置。投影和模型矩阵都是对角矩阵,不需要转置,因为它们的转置将给出相同的矩阵。我认为也不需要转置视图矩阵。 XMMatrixLookAtRH的公式在这里解释,提供了与您的视图矩阵完全相同的视图矩阵。此外,此处提供的示例项目在检查交集时不会转置其矩阵。您可以下载并检查示例项目。 可能存在问题的原因 1)初始化:我无法看到的唯一代码是您对m_cameraZAxism_cameraXAxisnearZfarZ参数等的初始化。此外,我没有使用您的相机旋转函数。正如您所看到的,我通过使用位置、目标和方向向量进行计算来初始化相机。请检查您对m_cameraZAxis的初始计算是否符合我的示例代码。
2)左/右手视图:确保您的代码中没有意外混淆左手右手视图。
3)检查您的旋转代码(ChangeCameraPitchChangeCameraYaw)是否意外地创建了不正交的相机轴。您正在使用相机的Y轴作为ChangeCameraYaw的输入和ChangeCameraPitch的输出。但是,在SetViewMatrix中,Y轴被交叉乘积或X和Z轴重置。因此,Y轴的早期值可能会丢失。
祝您的应用程序好运!如果您找到问题的适当解决方法和根本原因,请告诉我们。

2
@ackh,请注意在发布的代码中,我还将相机位置设置为1,1,1,1,即在原点外。即使如此,我仍然可以获得正确的屏幕向量值。唯一的问题是我仍然无法可视化输出,除了在Visual Studio调试器中检查向量值之外。我在纸上绘制了这些值的向量,它们似乎是正确的。请在您的GUI应用程序中检查。 - Kapil Dhaimade
1
非常感谢您在这里的努力。我会尝试您建议的方法并再次报告。不幸的是,这是一个副业项目,需要一些时间才能回到它。 - anon

0

如前所述,尽管现在点击功能可用,但移动相机时模型变形的问题仍未完全解决。我怀疑这与模型变形问题有关。我所说的“模型变形”是在以下插图中可见的:

enter image description here

左侧图像显示了当摄像机位于世界中心(0,0,0)时模型的外观,而右侧图像显示了当我将摄像机向负y轴方向移动时会发生什么。可以看到,模型在底部变宽,在顶部变小,这与我已经提供的link中描述的行为相同。
最终我所做的解决两个问题的方法是:
  1. 在传递给XMVector3Unproject之前转置矩阵(如上所述)
  2. 通过更改SetViewMatrix方法的代码来转置我的视图矩阵(请参见下面的代码)
现在,SetViewMatrix方法的代码如下:
void Camera::SetViewMatrix()
{
  XMFLOAT3 cameraPosition;
  XMFLOAT3 cameraXAxis;
  XMFLOAT3 cameraYAxis;
  XMFLOAT3 cameraZAxis;

  XMFLOAT4X4 viewMatrix;

  // Keep camera's axes orthogonal to each other and of unit length.
  m_cameraZAxis = XMVector3Normalize(m_cameraZAxis);
  m_cameraYAxis = XMVector3Normalize(XMVector3Cross(m_cameraZAxis, m_cameraXAxis));

  // m_cameraYAxis and m_cameraZAxis are already normalized, so there is no need
  // to normalize the below cross product of the two.
  m_cameraXAxis = XMVector3Cross(m_cameraYAxis, m_cameraZAxis);

  // Fill in the view matrix entries.
  float x = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraXAxis));
  float y = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraYAxis));
  float z = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraZAxis));

  //XMStoreFloat3(&cameraPosition, m_cameraPosition);
  XMStoreFloat3(&cameraXAxis, m_cameraXAxis);
  XMStoreFloat3(&cameraYAxis, m_cameraYAxis);
  XMStoreFloat3(&cameraZAxis, m_cameraZAxis);

  viewMatrix(0, 0) = cameraXAxis.x;
  viewMatrix(0, 1) = cameraXAxis.y;
  viewMatrix(0, 2) = cameraXAxis.z;
  viewMatrix(0, 3) = x;

  viewMatrix(1, 0) = cameraYAxis.x;
  viewMatrix(1, 1) = cameraYAxis.y;
  viewMatrix(1, 2) = cameraYAxis.z;
  viewMatrix(1, 3) = y;

  viewMatrix(2, 0) = cameraZAxis.x;
  viewMatrix(2, 1) = cameraZAxis.y;
  viewMatrix(2, 2) = cameraZAxis.z;
  viewMatrix(2, 3) = z;

  viewMatrix(3, 0) = 0.0f;
  viewMatrix(3, 1) = 0.0f;
  viewMatrix(3, 2) = 0.0f;
  viewMatrix(3, 3) = 1.0f;

  m_modelViewProjectionConstantBufferData->view = viewMatrix;
}

所以我只是交换了行和列的坐标。请注意,我必须确保在调用ChangeCameraPitch方法之前调用我的ChangeCameraYaw方法。这是必要的,因为否则模型的方向不符合我的要求。
还有另一种方法可以使用。而不是通过交换行和列坐标并在传递给XMVector3Unproject之前对其进行转置来转置视图矩阵,我可以在顶点着色器中使用row_major关键字和视图矩阵一起使用。
cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
  matrix model;
  row_major matrix view;
  matrix projection;
};

我在this博客文章中发现了这个想法。关键字row_major影响着着色器编译器如何解释矩阵在内存中的位置。同样的结果也可以通过在顶点着色器中改变向量*矩阵乘积的顺序来实现,即使用pos = mul(view, pos);而不是pos = mul(pos, view); 就是这样。这两个问题确实相互关联,但是使用我在这个问题中发布的内容,我能够解决这两个问题,因此我接受自己的回复作为对这个问题的答案。希望它能帮助未来的某个人。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接