我的光线投射计算遇到了很多麻烦,无法找出问题所在。我正在使用DirectX的数学库来创建向量等。
到目前为止,这是我的代码:
auto normalizedDeviceCoords = glm::vec2((float(a_frontend->GetMousePos().x) / float(a_frontend->GetWidth())) * 2.f - 1.f,
-((float(a_frontend->GetMousePos().y) / float(a_frontend->GetHeight())) * 2.f - 1.f));
auto mouseOrigin = DirectX::XMVectorSet(normalizedDeviceCoords.x, normalizedDeviceCoords.y, 0.0f, 1.0f);
auto mouseEnd = DirectX::XMVectorSet(normalizedDeviceCoords.x, normalizedDeviceCoords.y, 1.0f, 1.0f);
auto viewproj = DirectX::XMMatrixMultiply(a_frontend->GetViewMatrix(), a_frontend->GetProjMatrix());
auto determinant = DirectX::XMMatrixDeterminant(a_camera.ViewProj());
auto inverseviewproj = DirectX::XMMatrixInverse(&determinant, a_camera.ViewProj());
auto rayOrigin = DirectX::XMVector4Transform(mouseOrigin, inverseviewproj);
auto rayEnd = DirectX::XMVector4Transform(mouseEnd, inverseviewproj);
auto raySubtraction = DirectX::XMVectorSubtract(rayEnd, rayOrigin);
auto rayDirection = DirectX::XMVector3Normalize(raySubtraction);
auto planeNormal = DirectX::XMVectorSet(0.f, 1.f, 0.f, 0.f);
auto pointOnPlane = DirectX::XMVectorSet(0.f, -0.1f, 0.f, 0.f);
DirectX::XMFLOAT3 denominator;
DirectX::XMStoreFloat3(&denominator, DirectX::XMVector3Dot(planeNormal, rayDirection));
if (fabs(denominator.x) <= 0.0001f)
{
return;
}
auto pointMinusRay = DirectX::XMVectorSubtract(pointOnPlane, rayOrigin);
DirectX::XMFLOAT3 t;
auto almostT = DirectX::XMVector3Dot(pointMinusRay, planeNormal);
DirectX::XMStoreFloat3(&t, DirectX::XMVectorScale(almostT, 1.f / denominator.x));
if (t.x < 0)
{
return;
}
auto rayDirectionLength = DirectX::XMVector3Length(rayDirection);
auto rayPoint = DirectX::XMVectorAdd(rayOrigin, DirectX::XMVectorScale(rayDirection, t.x));
我已经检查过标准化的设备坐标是否正确,光线方向的长度也是1,并且光线方向看起来是正确的(很难用数字来判断)。
任何信息都会有用。我已经在堆栈溢出和其他论坛上查看了一些信息,并且还没有找到任何地方。
答案 0 :(得分:0)
我的队友能够解决这个问题。他刚开始使用DirectX Math函数Vector3Unproject。这将使用鼠标坐标并使用原点和结尾将它们转换为世界坐标(因此将鼠标坐标的z设为0然后设置为1)。然后从彼此中减去那些以获得指向世界某处的向量。然后我们能够根据相机的当前y位置除以方向矢量y的负值来取得该方向并对其进行变换。以下是我们现在拥有的所有代码:
DirectX::XMVECTOR mouseNear = DirectX::XMVectorSet((float)a_mousePos.x, (float)a_mousePos.y, 0.0f, 0.0f);
DirectX::XMVECTOR mouseFar = DirectX::XMVectorSet((float)a_mousePos.x, (float)a_mousePos.y, 1.0f, 0.0f);
DirectX::XMVECTOR unprojectedNear = DirectX::XMVector3Unproject(mouseNear, 0, 0, a_width, a_height, a_nearZ, a_farZ,
a_projection, a_view, DirectX::XMMatrixIdentity());
DirectX::XMVECTOR unprojectedFar = DirectX::XMVector3Unproject(mouseFar, 0, 0, a_width, a_height, a_nearZ, a_farZ,
a_projection, a_view, DirectX::XMMatrixIdentity());
DirectX::XMVECTOR result = DirectX::XMVector3Normalize(DirectX::XMVectorSubtract(unprojectedFar, unprojectedNear));
DirectX::XMFLOAT3 direction;
DirectX::XMStoreFloat3(&direction, result);
return direction;
//Get the distance to the ground.
DirectX::XMFLOAT3 cameraPosition = a_camera.GetPosition();
//Get the point on the ground.
cameraPosition.x += direction.x * (cameraPosition.y / -direction.y);
cameraPosition.z += direction.z * (cameraPosition.y / -direction.y);
希望这对未来的某些人有用。