用 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;
}