Skip to content

Commit 5aa220e

Browse files
committed
Merge pull request #110865 from brycehutchings/openxr_d3d12_near_far_fix
Fix OpenXR with D3D12 using the wrong clip space projection matrix
2 parents 6af2341 + 58ecb8a commit 5aa220e

File tree

6 files changed

+17
-32
lines changed

6 files changed

+17
-32
lines changed

modules/openxr/extensions/platform/openxr_d3d12_extension.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ bool OpenXRD3D12Extension::get_swapchain_image_data(XrSwapchain p_swapchain, int
273273

274274
bool OpenXRD3D12Extension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
275275
OpenXRUtil::XrMatrix4x4f matrix;
276-
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_D3D, p_fov, (float)p_z_near, (float)p_z_far);
276+
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, p_fov, (float)p_z_near, (float)p_z_far);
277277

278278
for (int j = 0; j < 4; j++) {
279279
for (int i = 0; i < 4; i++) {

modules/openxr/extensions/platform/openxr_metal_extension.mm

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,8 @@
298298
}
299299

300300
bool OpenXRMetalExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
301-
// Even though this is a Metal renderer we're using OpenGL coordinate systems.
302301
OpenXRUtil::XrMatrix4x4f matrix;
303-
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
302+
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, p_fov, (float)p_z_near, (float)p_z_far);
304303

305304
for (int j = 0; j < 4; j++) {
306305
for (int i = 0; i < 4; i++) {

modules/openxr/extensions/platform/openxr_opengl_extension.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
288288

289289
bool OpenXROpenGLExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
290290
OpenXRUtil::XrMatrix4x4f matrix;
291-
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
291+
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, p_fov, (float)p_z_near, (float)p_z_far);
292292

293293
for (int j = 0; j < 4; j++) {
294294
for (int i = 0; i < 4; i++) {

modules/openxr/extensions/platform/openxr_vulkan_extension.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,8 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
417417
}
418418

419419
bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
420-
// Even though this is a Vulkan renderer we're using OpenGL coordinate systems.
421420
OpenXRUtil::XrMatrix4x4f matrix;
422-
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
421+
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, p_fov, (float)p_z_near, (float)p_z_far);
423422

424423
for (int j = 0; j < 4; j++) {
425424
for (int i = 0; i < 4; i++) {

modules/openxr/openxr_util.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ String OpenXRUtil::make_xr_version_string(XrVersion p_version) {
7878
return version;
7979
}
8080

81-
// Copied from OpenXR xr_linear.h private header, so we can still link against
81+
// Based on the OpenXR xr_linear.h private header, so we can still link against
8282
// system-provided packages without relying on our `thirdparty` code.
8383

8484
// Copyright (c) 2017 The Khronos Group Inc.
@@ -87,25 +87,22 @@ String OpenXRUtil::make_xr_version_string(XrVersion p_version) {
8787
// SPDX-License-Identifier: Apache-2.0
8888

8989
// Creates a projection matrix based on the specified dimensions.
90-
// The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for the graphics API.
90+
// The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for Godot (OpenGL convention).
9191
// The far plane is placed at infinity if farZ <= nearZ.
9292
// An infinite projection matrix is preferred for rasterization because, except for
9393
// things *right* up against the near plane, it always provides better precision:
9494
// "Tightening the Precision of Perspective Rendering"
9595
// Paul Upchurch, Mathieu Desbrun
9696
// Journal of Graphics Tools, Volume 16, Issue 1, 2012
97-
void OpenXRUtil::XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const float tanAngleLeft,
98-
const float tanAngleRight, const float tanAngleUp, float const tanAngleDown,
99-
const float nearZ, const float farZ) {
97+
void OpenXRUtil::XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, const float tanAngleLeft, const float tanAngleRight,
98+
const float tanAngleUp, float const tanAngleDown, const float nearZ, const float farZ) {
10099
const float tanAngleWidth = tanAngleRight - tanAngleLeft;
101100

102-
// Set to tanAngleDown - tanAngleUp for a clip space with positive Y down (Vulkan).
103-
// Set to tanAngleUp - tanAngleDown for a clip space with positive Y up (OpenGL / D3D / Metal).
104-
const float tanAngleHeight = graphicsApi == GRAPHICS_VULKAN ? (tanAngleDown - tanAngleUp) : (tanAngleUp - tanAngleDown);
101+
// Set to tanAngleUp - tanAngleDown for a clip space with positive Y up.
102+
const float tanAngleHeight = (tanAngleUp - tanAngleDown);
105103

106-
// Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES).
107-
// Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal).
108-
const float offsetZ = (graphicsApi == GRAPHICS_OPENGL || graphicsApi == GRAPHICS_OPENGL_ES) ? nearZ : 0;
104+
// Set to nearZ for a [-1,1] Z clip space.
105+
const float offsetZ = nearZ;
109106

110107
if (farZ <= nearZ) {
111108
// place the far plane at infinity
@@ -153,13 +150,12 @@ void OpenXRUtil::XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, GraphicsAPI
153150
}
154151

155152
// Creates a projection matrix based on the specified FOV.
156-
void OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const XrFovf fov,
157-
const float nearZ, const float farZ) {
153+
void OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, const XrFovf fov, const float nearZ, const float farZ) {
158154
const float tanLeft = std::tan(fov.angleLeft);
159155
const float tanRight = std::tan(fov.angleRight);
160156

161157
const float tanDown = std::tan(fov.angleDown);
162158
const float tanUp = std::tan(fov.angleUp);
163159

164-
XrMatrix4x4f_CreateProjection(result, graphicsApi, tanLeft, tanRight, tanUp, tanDown, nearZ, farZ);
160+
XrMatrix4x4f_CreateProjection(result, tanLeft, tanRight, tanUp, tanDown, nearZ, farZ);
165161
}

modules/openxr/openxr_util.h

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,7 @@ class OpenXRUtil {
5252
float m[16];
5353
} XrMatrix4x4f;
5454

55-
typedef enum GraphicsAPI {
56-
GRAPHICS_VULKAN,
57-
GRAPHICS_OPENGL,
58-
GRAPHICS_OPENGL_ES,
59-
GRAPHICS_D3D
60-
} GraphicsAPI;
61-
62-
static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const float tanAngleLeft,
63-
const float tanAngleRight, const float tanAngleUp, float const tanAngleDown,
64-
const float nearZ, const float farZ);
65-
static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const XrFovf fov,
66-
const float nearZ, const float farZ);
55+
static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, const float tanAngleLeft, const float tanAngleRight,
56+
const float tanAngleUp, float const tanAngleDown, const float nearZ, const float farZ);
57+
static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, const XrFovf fov, const float nearZ, const float farZ);
6758
};

0 commit comments

Comments
 (0)