0

用 XMVector3Project 投影点 (-1, 0, 0) 和 (1, 0, 0) 给我结果:

P: (589.75,512,0.999683) <-> (1458.25,512,0.999683)

使用 XMVector3Unproject 取消投影这些点给出:

U:-0.000416635,0,-23.99 <-> 0.000416635,0,-23.99

现在,被后者适当地困惑了,我在这里犯了什么错误?我的期望是 unprojecting 会给我大约 x = -5 和 x = 5。我在下面包含了一个 repo(控制台应用程序,需要 Windows SDK):

#include <iostream>
#include <D3D11.h>
#include <DirectXMath.h>

#pragma comment(lib, "d3d11.lib")

int main()
{
    // Viewport.

    float viewport_width = 2048;
    float viewport_height = 1024;
    float viewport_near = 0.01f;
    float viewport_far = 100.0f;

    // Camera sits on -z looking towards the origin.

    DirectX::XMVECTOR eye = DirectX::XMVectorSet(0.0f, 0.0f, -24.0f, 0.0f);
    DirectX::XMVECTOR at = DirectX::XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
    DirectX::XMVECTOR up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);

    // Camera matrices.

    DirectX::XMMATRIX view = DirectX::XMMatrixLookAtLH(eye, at, up);
    DirectX::XMMATRIX projection = DirectX::XMMatrixPerspectiveFovLH(DirectX::XM_PIDIV4 / 8, 2.0f, viewport_near, viewport_far);
    DirectX::XMMATRIX world = DirectX::XMMatrixIdentity();

    // Project the points (-5, 0) and (5, 0) onto the display

    DirectX::XMVECTOR vector_left;
    DirectX::XMVECTOR vector_right;
    DirectX::XMFLOAT4 projected_left;
    DirectX::XMFLOAT4 projected_right;
    DirectX::XMFLOAT4 unprojected_left;
    DirectX::XMFLOAT4 unprojected_right;

    vector_left = DirectX::XMVector3Project(DirectX::XMVectorSet(-1.0f, 0.0f, 0.0f, 1.0f),
                                            0,
                                            0,
                                            viewport_width,
                                            viewport_height,
                                            0.0f,
                                            1.0f,
                                            projection,
                                            view,
                                            world);

    DirectX::XMStoreFloat4(&projected_left, vector_left);

    vector_right = DirectX::XMVector3Project(DirectX::XMVectorSet(1.0f, 0.0f, 0.0f, 1.0f),
                                             0,
                                             0,
                                             viewport_width,
                                             viewport_height,
                                             0.0f,
                                             1.0f,
                                             projection,
                                             view,
                                             world);

    DirectX::XMStoreFloat4(&projected_right, vector_right);

    std::cout << "P: "
              << projected_left.x << ","
              << projected_left.y << ","
              << projected_left.z << " <-> "        
              << projected_right.x << ","
              << projected_right.y << ","
              << projected_right.z << std::endl;

    // Unproject both resulting points.

    vector_left = DirectX::XMVector3Unproject(DirectX::XMVectorSet(projected_left.x, projected_left.y, 0.0f, 1.0f),
                                              0,
                                              0,
                                              viewport_width,
                                              viewport_height,
                                              0.0f,
                                              1.0f,
                                              projection,
                                              view,
                                              world);

    DirectX::XMStoreFloat4(&unprojected_left, vector_left);

    vector_right = DirectX::XMVector3Unproject(DirectX::XMVectorSet(projected_right.x, projected_right.y, 0.0f, 1.0f),
                                               0,
                                               0,
                                               viewport_width,
                                               viewport_height,
                                               0.0f,
                                               1.0f,
                                               projection,
                                               view,
                                               world);

    DirectX::XMStoreFloat4(&unprojected_right, vector_right);

    std::cout << "U: "
              << unprojected_left.x  << ","
              << unprojected_left.y  << ","
              << unprojected_left.z  << " <-> "
              << unprojected_right.x << ","
              << unprojected_right.y << ","
              << unprojected_right.z << std::endl;
}
4

0 回答 0