OpenXR Projection view to DX11 Left Handed Projection matrix

Hi, I am trying to integrate Varjo XR3 headset into my DX11 Custom Engine which works on left handed orientation. I had a sample of OPENXR which shows about views and projection matrix.

Sample code for View Matrix:

XrCompositionLayerProjectionView view = projectionLayerViews[viewIndex];
XMMATRIX mat_view = XMMatrixTranspose(XMMatrixInverse(nullptr, XMMatrixAffineTransformation(
DirectX::g_XMOne, DirectX::g_XMZero,
XMLoadFloat4((XMFLOAT4*)&view.pose.orientation),
XMLoadFloat3((XMFLOAT3*)&view.pose.position))));

Sample code for Projection Matrix
struct Matrix4x4f {
float m[16];
};

void Open_XR::Varjo::FI3D3D11OpenXR::createProjection(Matrix4x4f* result, float tanAngleLeft, float tanAngleRight, float tanAngleUp, float const tanAngleDown, const float nearZ, const float farZ)
{
const float tanAngleWidth = tanAngleRight - tanAngleLeft;
const float tanAngleHeight = tanAngleUp - tanAngleDown;

const float offsetZ = 0;

result->m[0] = 2 / tanAngleWidth;
result->m[4] = 0;
result->m[8] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
result->m[12] = 0;

result->m[1] = 0;
result->m[5] = 2 / tanAngleHeight;
result->m[9] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
result->m[13] = 0;

result->m[2] = 0;
result->m[6] = 0;
result->m[10] = -(farZ + offsetZ) / (farZ - nearZ);
result->m[14] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ);

result->m[3] = 0;
result->m[7] = 0;
result->m[11] = -1;
result->m[15] = 0;

}

void Open_XR::Varjo::FI3D3D11OpenXR::createProjectionFov(Matrix4x4f* result, XrFovf fov, float nearZ, float farZ)
{
const float tanLeft = tanf(fov.angleLeft);
const float tanRight = tanf(fov.angleRight);

const float tanDown = tanf(fov.angleDown);
const float tanUp = tanf(fov.angleUp);

createProjection(result, tanLeft, tanRight, tanUp, tanDown, nearZ, farZ);

}

Matrix4x4f projectionMatrix{};
createProjectionFov(&projectionMatrix, view.fov, m_nearZ, m_farZ);
const DirectX::XMMATRIX projection = DirectX::XMMatrixTranspose(LoadXrMatrix(projectionMatrix));

when i am using these values in my engine, my scene is completely different in both the eyes with no overlapping.
My question is how to create left handed offcentre projection matrix and view matrix for my DX11 engine from OPENXR values.

I can’t speak for the sample code you’ve shared, but I recommend you look into the XrMath utilities from the Microsoft OpenXR samples:

In particular, there is an xr::math::LoadInvertedXrPose() and an xr::math::ComposeProjectionMatrix() that can take structs directly from your xrLocateViews() results. These helpers have never failed me to date :slight_smile:

You can see an example here of usage that should hopefully be transposable directly into your code:

@mbucchia1
Thanks for the reply. I tried to extract yaw pitch roll from spaceToView matrix which you mentioned but I had to negate all the values to work. My engine has a main camera and its yaw pitch roll and position had to be set manually rather then directly sending view matrix to shader. Moreover this function ComposeProjectionMatrix uses XMMatrixPerspectiveOffCenterRH to construct projection but my engine uses left hand system so XMMatrixPerspectiveOffCenterLH should be used. so using both of these, nothing changed in the headset view.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.