DirectX 扭曲/拉伸三角形渲染

问题描述 投票:0回答:1

我目前正在制作一个简单的 DirectX 引擎来温习一些图形编程知识,但目前我已经令人沮丧地陷入困境了一段时间。我试图用移动的相机渲染一个简单的三角形(目前仅翻译),但每当我移动相机时,三角形似乎都会变形。每当我移动三角形时都会发生同样的情况,但当然扭曲会发生在相反的方向。

这就是在相机不移动的情况下三角形的样子: CameraNeutral

这就是我将相机向右移动时的样子: CameraRight

这就是我向上移动相机时的样子: CameraUp

我的第一个想法是 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

c++ graphics rendering directx
1个回答
0
投票

我已经下载并构建了项目,问题似乎是两个问题的结合:

  1. 使用
    XMMatrixLookAtLH
    代替
    XMMatrixLookToLH
    。他们以不同的方式对待第二个论点。将 0.f、0.f、1.f 作为第二个参数传递给 XMMatrixLookToLH 意味着当移动相机位置(作为第一个参数传递)时,视图方向将保持与 z 轴平行。将 0.f、0.f、1.f 作为第二个参数传递给 XMMatrixLookAtLH 意味着当移动相机位置(再次作为第一个参数传递)时,视图方向将更改为指向 0.f、0.f、1.f (相机将旋转)。
  2. 缺乏转置
const XMMATRIX WVPMatrix = XMMatrixTranspose(worldMatrix * viewMatrix * projectionMatrix);
相机向右移动一点后

XMMatrixLookToLH

的结果:
enter image description here 相机向右移动一点后

XMMatrixLookAtLH

的结果:

enter image description here
    
	

© www.soinside.com 2019 - 2024. All rights reserved.