mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Merge pull request #110865 from brycehutchings/openxr_d3d12_near_far_fix
Fix OpenXR with D3D12 using the wrong clip space projection matrix
This commit is contained in:
commit
5aa220efee
6 changed files with 17 additions and 32 deletions
|
@ -273,7 +273,7 @@ bool OpenXRD3D12Extension::get_swapchain_image_data(XrSwapchain p_swapchain, int
|
||||||
|
|
||||||
bool OpenXRD3D12Extension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
bool OpenXRD3D12Extension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
||||||
OpenXRUtil::XrMatrix4x4f matrix;
|
OpenXRUtil::XrMatrix4x4f matrix;
|
||||||
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_D3D, p_fov, (float)p_z_near, (float)p_z_far);
|
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, p_fov, (float)p_z_near, (float)p_z_far);
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
|
|
|
@ -298,9 +298,8 @@ void OpenXRMetalExtension::cleanup_swapchain_graphics_data(void **p_swapchain_gr
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenXRMetalExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
bool OpenXRMetalExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
||||||
// Even though this is a Metal renderer we're using OpenGL coordinate systems.
|
|
||||||
OpenXRUtil::XrMatrix4x4f matrix;
|
OpenXRUtil::XrMatrix4x4f matrix;
|
||||||
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
|
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, p_fov, (float)p_z_near, (float)p_z_far);
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
|
|
|
@ -288,7 +288,7 @@ bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
|
||||||
|
|
||||||
bool OpenXROpenGLExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
bool OpenXROpenGLExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
||||||
OpenXRUtil::XrMatrix4x4f matrix;
|
OpenXRUtil::XrMatrix4x4f matrix;
|
||||||
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
|
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, p_fov, (float)p_z_near, (float)p_z_far);
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
|
|
|
@ -417,9 +417,8 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
||||||
// Even though this is a Vulkan renderer we're using OpenGL coordinate systems.
|
|
||||||
OpenXRUtil::XrMatrix4x4f matrix;
|
OpenXRUtil::XrMatrix4x4f matrix;
|
||||||
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
|
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, p_fov, (float)p_z_near, (float)p_z_far);
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
|
|
|
@ -78,7 +78,7 @@ String OpenXRUtil::make_xr_version_string(XrVersion p_version) {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copied from OpenXR xr_linear.h private header, so we can still link against
|
// Based on the OpenXR xr_linear.h private header, so we can still link against
|
||||||
// system-provided packages without relying on our `thirdparty` code.
|
// system-provided packages without relying on our `thirdparty` code.
|
||||||
|
|
||||||
// Copyright (c) 2017 The Khronos Group Inc.
|
// Copyright (c) 2017 The Khronos Group Inc.
|
||||||
|
@ -87,25 +87,22 @@ String OpenXRUtil::make_xr_version_string(XrVersion p_version) {
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// Creates a projection matrix based on the specified dimensions.
|
// Creates a projection matrix based on the specified dimensions.
|
||||||
// The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for the graphics API.
|
// The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for Godot (OpenGL convention).
|
||||||
// The far plane is placed at infinity if farZ <= nearZ.
|
// The far plane is placed at infinity if farZ <= nearZ.
|
||||||
// An infinite projection matrix is preferred for rasterization because, except for
|
// An infinite projection matrix is preferred for rasterization because, except for
|
||||||
// things *right* up against the near plane, it always provides better precision:
|
// things *right* up against the near plane, it always provides better precision:
|
||||||
// "Tightening the Precision of Perspective Rendering"
|
// "Tightening the Precision of Perspective Rendering"
|
||||||
// Paul Upchurch, Mathieu Desbrun
|
// Paul Upchurch, Mathieu Desbrun
|
||||||
// Journal of Graphics Tools, Volume 16, Issue 1, 2012
|
// Journal of Graphics Tools, Volume 16, Issue 1, 2012
|
||||||
void OpenXRUtil::XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const float tanAngleLeft,
|
void OpenXRUtil::XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, const float tanAngleLeft, const float tanAngleRight,
|
||||||
const float tanAngleRight, const float tanAngleUp, float const tanAngleDown,
|
const float tanAngleUp, float const tanAngleDown, const float nearZ, const float farZ) {
|
||||||
const float nearZ, const float farZ) {
|
|
||||||
const float tanAngleWidth = tanAngleRight - tanAngleLeft;
|
const float tanAngleWidth = tanAngleRight - tanAngleLeft;
|
||||||
|
|
||||||
// Set to tanAngleDown - tanAngleUp for a clip space with positive Y down (Vulkan).
|
// Set to tanAngleUp - tanAngleDown for a clip space with positive Y up.
|
||||||
// Set to tanAngleUp - tanAngleDown for a clip space with positive Y up (OpenGL / D3D / Metal).
|
const float tanAngleHeight = (tanAngleUp - tanAngleDown);
|
||||||
const float tanAngleHeight = graphicsApi == GRAPHICS_VULKAN ? (tanAngleDown - tanAngleUp) : (tanAngleUp - tanAngleDown);
|
|
||||||
|
|
||||||
// Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES).
|
// Set to nearZ for a [-1,1] Z clip space.
|
||||||
// Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal).
|
const float offsetZ = nearZ;
|
||||||
const float offsetZ = (graphicsApi == GRAPHICS_OPENGL || graphicsApi == GRAPHICS_OPENGL_ES) ? nearZ : 0;
|
|
||||||
|
|
||||||
if (farZ <= nearZ) {
|
if (farZ <= nearZ) {
|
||||||
// place the far plane at infinity
|
// place the far plane at infinity
|
||||||
|
@ -153,13 +150,12 @@ void OpenXRUtil::XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, GraphicsAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a projection matrix based on the specified FOV.
|
// Creates a projection matrix based on the specified FOV.
|
||||||
void OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const XrFovf fov,
|
void OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, const XrFovf fov, const float nearZ, const float farZ) {
|
||||||
const float nearZ, const float farZ) {
|
|
||||||
const float tanLeft = std::tan(fov.angleLeft);
|
const float tanLeft = std::tan(fov.angleLeft);
|
||||||
const float tanRight = std::tan(fov.angleRight);
|
const float tanRight = std::tan(fov.angleRight);
|
||||||
|
|
||||||
const float tanDown = std::tan(fov.angleDown);
|
const float tanDown = std::tan(fov.angleDown);
|
||||||
const float tanUp = std::tan(fov.angleUp);
|
const float tanUp = std::tan(fov.angleUp);
|
||||||
|
|
||||||
XrMatrix4x4f_CreateProjection(result, graphicsApi, tanLeft, tanRight, tanUp, tanDown, nearZ, farZ);
|
XrMatrix4x4f_CreateProjection(result, tanLeft, tanRight, tanUp, tanDown, nearZ, farZ);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,16 +52,7 @@ public:
|
||||||
float m[16];
|
float m[16];
|
||||||
} XrMatrix4x4f;
|
} XrMatrix4x4f;
|
||||||
|
|
||||||
typedef enum GraphicsAPI {
|
static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, const float tanAngleLeft, const float tanAngleRight,
|
||||||
GRAPHICS_VULKAN,
|
const float tanAngleUp, float const tanAngleDown, const float nearZ, const float farZ);
|
||||||
GRAPHICS_OPENGL,
|
static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, const XrFovf fov, const float nearZ, const float farZ);
|
||||||
GRAPHICS_OPENGL_ES,
|
|
||||||
GRAPHICS_D3D
|
|
||||||
} GraphicsAPI;
|
|
||||||
|
|
||||||
static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const float tanAngleLeft,
|
|
||||||
const float tanAngleRight, const float tanAngleUp, float const tanAngleDown,
|
|
||||||
const float nearZ, const float farZ);
|
|
||||||
static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const XrFovf fov,
|
|
||||||
const float nearZ, const float farZ);
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue