Matrix 使用DirectX中的第一人称摄影机,对象看起来很奇怪

Matrix 使用DirectX中的第一人称摄影机,对象看起来很奇怪,matrix,camera,directx,Matrix,Camera,Directx,我在DirectX 11中创建3D第一人称相机时遇到问题 我有一个在(0,0,-2)处的相机在(0,0,100)处。(0,0,0)处有一个长方体,该长方体已正确渲染。请参见下图: 当长方体(而不是摄影机)的位置更改时,将正确渲染长方体。例如,下一幅图像显示位于(1,0,0)的长方体和仍位于(0,0,-2)的摄影机: 但是,只要相机向左或向右移动,长方体就会转到相反的方向,但它看起来会扭曲。下面是一个示例,当相机位于(1,0,-2)并注视(1,0,100)时。该框仍处于(0,0,0)位置:

我在DirectX 11中创建3D第一人称相机时遇到问题

我有一个在(0,0,-2)处的相机在(0,0,100)处。(0,0,0)处有一个长方体,该长方体已正确渲染。请参见下图:

当长方体(而不是摄影机)的位置更改时,将正确渲染长方体。例如,下一幅图像显示位于(1,0,0)的长方体和仍位于(0,0,-2)的摄影机:

但是,只要相机向左或向右移动,长方体就会转到相反的方向,但它看起来会扭曲。下面是一个示例,当相机位于(1,0,-2)并注视(1,0,100)时。该框仍处于(0,0,0)位置:

下面是我如何设置相机的:

// Set the world transformation matrix.

D3DXMATRIX rotationMatrix;          // A matrix to store the rotation information
D3DXMATRIX scalingMatrix;           // A matrix to store the scaling information
D3DXMATRIX translationMatrix;       // A matrix to store the translation information

D3DXMatrixIdentity(&translationMatrix);

// Make the scene being centered on the camera position.
D3DXMatrixTranslation(&translationMatrix, -camera.GetX(), -camera.GetY(), -camera.GetZ());

m_worldTransformationMatrix = translationMatrix;

// Set the view transformation matrix.

D3DXMatrixIdentity(&m_viewTransformationMatrix);

D3DXVECTOR3 cameraPosition(camera.GetX(), camera.GetY(), camera.GetZ());

// ------------------------
// Compute the lookAt position
// ------------------------

const FLOAT lookAtDistance = 100;

FLOAT lookAtXPosition = camera.GetX() + lookAtDistance * cos((FLOAT)D3DXToRadian(camera.GetXZAngle()));
FLOAT lookAtYPosition = camera.GetY() + lookAtDistance * sin((FLOAT)D3DXToRadian(camera.GetYZAngle()));
FLOAT lookAtZPosition = camera.GetZ() + lookAtDistance * (sin((FLOAT)D3DXToRadian(camera.GetXZAngle())) * cos((FLOAT)D3DXToRadian(camera.GetYZAngle())));

D3DXVECTOR3 lookAtPosition(lookAtXPosition, lookAtYPosition, lookAtZPosition);

D3DXVECTOR3 upDirection(0, 1, 0);

D3DXMatrixLookAtLH(&m_viewTransformationMatrix,
                   &cameraPosition,
                   &lookAtPosition,
                   &upDirection);

RECT windowDimensions = GetWindowDimensions();
FLOAT width = (FLOAT)(windowDimensions.right - windowDimensions.left);
FLOAT height = (FLOAT)(windowDimensions.bottom - windowDimensions.top);

// Set the projection matrix.

D3DXMatrixIdentity(&m_projectionMatrix);
D3DXMatrixPerspectiveFovLH(&m_projectionMatrix,
                           (FLOAT)(D3DXToRadian(45)),  // Horizontal field of view
                           width / height,    // Aspect ratio
                           1.0f,              // Near view-plane
                           100.0f);           // Far view-plane
以下是最终矩阵的设置方式:

D3DXMATRIX finalMatrix = m_worldTransformationMatrix * m_viewTransformationMatrix * m_projectionMatrix;

// Set the new values for the constant buffer
mp_deviceContext->UpdateSubresource(mp_constantBuffer, 0, 0, &finalMatrix, 0, 0);
最后,这里是使用常量缓冲区的顶点着色器:

VOut VShader(float4 position : POSITION, float4 color : COLOR, float2 texcoord : TEXCOORD)
{
    VOut output;

    output.color = color;
output.texcoord = texcoord;
output.position = mul(position, finalMatrix);  // Transform the vertex from 3D to 2D

    return output;
}
你知道我做错了什么吗?如果您需要有关我的代码的更多信息,请随时提问:我真的希望这能起作用


谢谢

问题是您正在使用行主矩阵设置finalMatrix,但HLSL需要列主矩阵。解决方案是在更新常量之前使用D3DXMatrixTranspose,或在HLSL文件中声明行_major,如下所示:

cbuffer ConstantBuffer
{
    row_major float4x4 finalMatrix;
}

你在哪里设置盒子的位置?在我的主要功能中。它的位置总是在(0,0,0):它从不移动。我想您显示的代码是用于绘制长方体的。你说‘当盒子(不是相机)的位置改变时,它被正确地渲染’。那么,您如何更改此代码以确认该声明?上面显示的相同摄像头代码适用于位于(0,0,0)的摄像头和位于(1,0,0)的方框。我已经编辑了上面的问题描述,以包含摄影机位于(0,0,0)时位于(1,0,0)的长方体的图像。是否将世界变换矩阵设置为长方体位置?因为在上面的代码中,您似乎将其设置为-cameray。我们的解决方案解决了我的问题:谢谢!我想知道为什么finalMatrix是一个行主矩阵:在大多数关于相机的教程中都没有提到它。。。