我目前正在制作一个简单的 DirectX 引擎来温习一些图形编程知识,但目前我已经令人沮丧地陷入困境了一段时间。我试图用移动的相机渲染一个简单的三角形(目前仅翻译),但每当我移动相机时,三角形似乎都会变形。每当我移动三角形时都会发生同样的情况,但当然扭曲会发生在相反的方向。
这就是在相机不移动的情况下三角形的样子:
这就是我将相机向右移动时的样子:
这就是我向上移动相机时的样子:
我的第一个想法是 WorldViewProjection 矩阵不知何故关闭,但我真的没有看到它有任何问题。
void Renderer::CreateViewProjectionMatrix()
{
using namespace DirectX;
// Create world matrix
const XMMATRIX translation = XMMatrixTranslation(0.f, 0.f, 0.f);
const XMMATRIX rotation = XMMatrixRotationRollPitchYaw(0.f, 0.f, 0.f); // In radians
const XMMATRIX scale = XMMatrixScaling(1.f, 1.f, 1.f);
const XMMATRIX worldMatrix = scale * rotation * translation;
XMStoreFloat4x4(&m_VertexConstantBuffer.worldMatrix, worldMatrix);
// Create view matrix
const XMFLOAT3 cameraForward{ 0.f, 0.f, 1.f };
const XMFLOAT3 cameraUp{ 0.f, 1.f, 0.f };
const XMVECTOR worldPos = XMLoadFloat3(&m_CameraPos);
const XMVECTOR worldForward = XMLoadFloat3(&cameraForward);
const XMVECTOR worldUp = XMLoadFloat3(&cameraUp);
const XMMATRIX viewMatrix = XMMatrixLookToLH(worldPos, worldForward, worldUp);
// Create projection matrix
const float aspectRatioX = static_cast<float>(m_BackBufferDescription.Width) / m_BackBufferDescription.Height;
const float FOV{ 45.f };
const float nearZ{ 0.1f };
const float farZ{ 100.f };
const XMMATRIX projectionMatrix = XMMatrixPerspectiveFovLH(XMConvertToRadians(FOV), aspectRatioX, nearZ, farZ);
// Store WVP matrix
const XMMATRIX WVPMatrix = worldMatrix * viewMatrix * projectionMatrix;
XMStoreFloat4x4(&m_VertexConstantBuffer.worldViewProjection, WVPMatrix);
}
以下是创建三角形的方法,以防您需要:
HRESULT Renderer::CreateTriangle()
{
// Create triangle geometry
const BaseVertexInput triangleVertices[] =
{
{ DirectX::XMFLOAT3{ -0.5f,-0.5f, 0.0f }, DirectX::XMFLOAT3{}, DirectX::XMFLOAT2{} },
{ DirectX::XMFLOAT3{ 0.5f,-0.5f, 0.0f }, DirectX::XMFLOAT3{}, DirectX::XMFLOAT2{} },
{ DirectX::XMFLOAT3{ 0.0f, 0.3f, 0.0f }, DirectX::XMFLOAT3{}, DirectX::XMFLOAT2{} }
};
// Create vertexBuffer
const CD3D11_BUFFER_DESC vertexDescription{ sizeof(triangleVertices), D3D11_BIND_VERTEX_BUFFER};
D3D11_SUBRESOURCE_DATA vertexData;
ZeroMemory(&vertexData, sizeof(D3D11_SUBRESOURCE_DATA)); // Stops writes being compiled away if it isn't being read immeadiatly
vertexData.pSysMem = triangleVertices; // Initialization data
vertexData.SysMemPitch = 0; // Distance from beginning line of texture to the next line (only for 2D & 3D texture)
vertexData.SysMemSlicePitch = 0; // Distance from beginning of one depth level to the next (only for 3D texture)
HRESULT result = m_pDevice->CreateBuffer
(
&vertexDescription,
&vertexData,
m_pVertexBuffer.GetAddressOf()
);
if (FAILED(result))
{
Logger::Log(L"ERROR - Failed to create a vertexBuffer");
return result;
}
// Create indexBuffer
const unsigned short triangleIndices[]
{
0,2,1
};
m_IndexCount = ARRAYSIZE(triangleIndices);
const CD3D11_BUFFER_DESC indexDescription{ sizeof(triangleIndices), D3D11_BIND_INDEX_BUFFER };
D3D11_SUBRESOURCE_DATA indexData;
ZeroMemory(&indexData, sizeof(D3D11_SUBRESOURCE_DATA));
indexData.pSysMem = triangleIndices;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;
result = m_pDevice->CreateBuffer
(
&indexDescription,
&indexData,
m_pIndexBuffer.GetAddressOf()
);
if (FAILED(result))
{
Logger::Log(L"ERROR - Failed to create an indexBuffer");
return result;
}
// Creation success
m_SuccesfullCreation = true;
return result;
}
我研究了:WVP 矩阵、我的顶点着色器、顶点缓冲区的创建……
我尝试按照 Microsoft 指南执行 Transpose(RightHandMatrix(...)) 操作,但后来我根本看不到任何三角形。
除此之外,我真的不知道该去哪里寻找了。 一定要询问我是否可以/需要提供更多代码。
编辑:
这也是我完整的顶点着色器:
cbuffer CB_World : register(b0) // Register for GPU access (b. for constant buffers)
{
matrix g_WorldViewProjection; // World to projection space
matrix g_World; // World space
};
struct VS_INPUT
{
float3 position : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 position : SV_POSITION; // System value
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
VS_OUTPUT VSMain(VS_INPUT input)
{
VS_OUTPUT output;
output.position = mul(float4(input.position, 1.0), g_WorldViewProjection);
output.normal = normalize(mul(input.normal, (float3x3) g_World));
output.uv = input.uv;
return output;
}
GitHub: https://github.com/RenzoDepoortere/DistortedRender_AidProject
我已经下载并构建了项目,问题似乎是两个问题的结合:
XMMatrixLookAtLH
代替 XMMatrixLookToLH
。他们以不同的方式对待第二个论点。将 0.f、0.f、1.f 作为第二个参数传递给 XMMatrixLookToLH 意味着当移动相机位置(作为第一个参数传递)时,视图方向将保持与 z 轴平行。将 0.f、0.f、1.f 作为第二个参数传递给 XMMatrixLookAtLH 意味着当移动相机位置(再次作为第一个参数传递)时,视图方向将更改为指向 0.f、0.f、1.f (相机将旋转)。const XMMATRIX WVPMatrix = XMMatrixTranspose(worldMatrix * viewMatrix * projectionMatrix);
相机向右移动一点后XMMatrixLookToLH
的结果:相机向右移动一点后
XMMatrixLookAtLH
的结果: