Skip to content

feat(xr): 实现 OpenXR 运行时会话控制与双目渲染管线#4

Open
BeyondtheApex wants to merge 2 commits intoMinecraft-Radiance:mainfrom
BeyondtheApex:main
Open

feat(xr): 实现 OpenXR 运行时会话控制与双目渲染管线#4
BeyondtheApex wants to merge 2 commits intoMinecraft-Radiance:mainfrom
BeyondtheApex:main

Conversation

@BeyondtheApex
Copy link

VR 功能实现清单

1) OpenXR 生命周期与运行时会话控制(已实现)

  • 接入 OpenXR 实例/系统初始化、Vulkan 适配与会话管理。
  • 支持运行时启动/停止 XR 会话,不再只依赖启动时固定状态。
  • 会话状态变化可驱动渲染路径切换与资源重建触发。

2) 双目立体渲染主链路(已实现)

  • World Pipeline 增加 eyeCount 与 StereoMode 调度机制。
  • 多个世界模块支持按眼渲染(单实例多派发/双实例)并绑定每眼资源视图。
  • 从单眼输出扩展为数组层输出,支持每眼图像处理与合成。

3) 可见性遮罩(Visibility Mask,已实现)

  • 从 OpenXR 查询 visibility mask 网格。
  • 生成每眼遮罩纹理并在 Ray Tracing 路径中使用。
  • 非活动立体会话下可回退到全可见路径,避免错误遮挡。

4) 追踪空间与世界空间映射(已实现)

  • VRSystem 维护头显姿态、双眼参数、世界旋转/平移偏移。
  • 在 uniform 与 shader 中引入每眼 view/proj 偏移,完成 tracking space 到 game world 的映射。
  • 支持重定位(recenter)并保持世界偏移一致性。

5) 注视点相关渲染(已实现)

  • 接入眼动注视点(gazePoint/gazeValid)数据通路。
  • Ray Tracing 中接入中心/外圈参数,实现注视点相关的外圈降采样填充逻辑。

6) 控制器输入与交互(已实现)

  • OpenXR ActionSet/Action 创建与主流 profile 绑定(如 Touch/Index/Vive/simple)。
  • 同步控制器位姿、触发器/握把/摇杆/按钮状态到 VRSystem。
  • 提供 JNI 接口给上层获取头手姿态、FOV、推荐分辨率等数据。

7) 触觉反馈(已实现)

  • 支持左右手 haptic 振动触发与停止接口。

8) 性能数据(已实现)

  • 接入 CPU/GPU 帧时统计与 compositor 目标时间。
  • 输出 FPS、headroom、丢帧计数等 VR 性能指标。

9) 构建与设备选择链路(已实现)

  • CMake 增加 OpenXR 开关与依赖接入。
  • Vulkan instance/device 允许注入 OpenXR 需要的扩展。
  • 物理设备选择支持 OpenXR 指定设备优先。

10) 桌面镜像与回退行为(已实现)

  • 支持将双目结果镜像到桌面窗口(SBS 路径)。
  • OpenXR 初始化失败时可回退到非 VR 渲染路径。

11) 会话切换后的管线重建联动(已实现)

  • 会话开/关、XR 分辨率变化会触发 needRecreate。
  • 渲染链在 mono/stereo 间切换时会更新 eyeCount 与相关资源尺寸。

12) 设备/会话信息查询接口(已实现)

  • 可查询系统名、会话状态、眼分辨率、地面高度等运行时信息。
  • 提供世界位置/世界朝向设置与查询接口,支持重定位工作流。

主要影响范围

  • OpenXR 核心:
    • src/core/render/openxr_context.cpp
    • src/core/render/openxr_context.hpp
    • src/core/render/openxr_input.cpp
    • src/core/render/openxr_input.hpp
  • XR 桥接与状态:
    • src/core/middleware/com_radiance_client_proxy_vulkan_VRProxy.cpp
    • src/core/render/render_framework.cpp
    • src/core/render/render_framework.hpp
    • src/core/render/renderer.hpp
    • src/core/render/vr_system.cpp
    • src/core/render/vr_system.hpp
  • 双目渲染模块与着色器:
    • src/core/render/pipeline.cpp
    • src/core/render/pipeline.hpp
    • src/core/render/modules/world/*
    • src/shader/world/post_render/*
    • src/shader/world/ray_tracing/*
  • Vulkan/XR 引导:
    • CMakeLists.txt
    • src/core/CMakeLists.txt
    • src/core/vulkan/instance.*
    • src/core/vulkan/device.*
    • src/core/vulkan/physical_device.*
    • src/core/vulkan/image.*

测试情况

9700x 9070xt上运行正常

仅测试了nrd和fsr3路径
设备不足,无法测试dlss路径

## VR 功能实现清单

### 1) OpenXR 生命周期与运行时会话控制(已实现)
- 接入 OpenXR 实例/系统初始化、Vulkan 适配与会话管理。
- 支持运行时启动/停止 XR 会话,不再只依赖启动时固定状态。
- 会话状态变化可驱动渲染路径切换与资源重建触发。

### 2) 双目立体渲染主链路(已实现)
- World Pipeline 增加 eyeCount 与 StereoMode 调度机制。
- 多个世界模块支持按眼渲染(单实例多派发/双实例)并绑定每眼资源视图。
- 从单眼输出扩展为数组层输出,支持每眼图像处理与合成。

### 3) 可见性遮罩(Visibility Mask,已实现)
- 从 OpenXR 查询 visibility mask 网格。
- 生成每眼遮罩纹理并在 Ray Tracing 路径中使用。
- 非活动立体会话下可回退到全可见路径,避免错误遮挡。

### 4) 追踪空间与世界空间映射(已实现)
- VRSystem 维护头显姿态、双眼参数、世界旋转/平移偏移。
- 在 uniform 与 shader 中引入每眼 view/proj 偏移,完成 tracking space 到 game world 的映射。
- 支持重定位(recenter)并保持世界偏移一致性。

### 5) 注视点相关渲染(已实现)
- 接入眼动注视点(gazePoint/gazeValid)数据通路。
- Ray Tracing 中接入中心/外圈参数,实现注视点相关的外圈降采样填充逻辑。

### 6) 控制器输入与交互(已实现)
- OpenXR ActionSet/Action 创建与主流 profile 绑定(如 Touch/Index/Vive/simple)。
- 同步控制器位姿、触发器/握把/摇杆/按钮状态到 VRSystem。
- 提供 JNI 接口给上层获取头手姿态、FOV、推荐分辨率等数据。

### 7) 触觉反馈(已实现)
- 支持左右手 haptic 振动触发与停止接口。

### 8) 性能数据(已实现)
- 接入 CPU/GPU 帧时统计与 compositor 目标时间。
- 输出 FPS、headroom、丢帧计数等 VR 性能指标。

### 9) 构建与设备选择链路(已实现)
- CMake 增加 OpenXR 开关与依赖接入。
- Vulkan instance/device 允许注入 OpenXR 需要的扩展。
- 物理设备选择支持 OpenXR 指定设备优先。

### 10) 桌面镜像与回退行为(已实现)
- 支持将双目结果镜像到桌面窗口(SBS 路径)。
- OpenXR 初始化失败时可回退到非 VR 渲染路径。

### 11) 会话切换后的管线重建联动(已实现)
- 会话开/关、XR 分辨率变化会触发 needRecreate。
- 渲染链在 mono/stereo 间切换时会更新 eyeCount 与相关资源尺寸。

### 12) 设备/会话信息查询接口(已实现)
- 可查询系统名、会话状态、眼分辨率、地面高度等运行时信息。
- 提供世界位置/世界朝向设置与查询接口,支持重定位工作流。

## 主要影响范围
- OpenXR 核心:
  - src/core/render/openxr_context.cpp
  - src/core/render/openxr_context.hpp
  - src/core/render/openxr_input.cpp
  - src/core/render/openxr_input.hpp
- XR 桥接与状态:
  - src/core/middleware/com_radiance_client_proxy_vulkan_VRProxy.cpp
  - src/core/render/render_framework.cpp
  - src/core/render/render_framework.hpp
  - src/core/render/renderer.hpp
  - src/core/render/vr_system.cpp
  - src/core/render/vr_system.hpp
- 双目渲染模块与着色器:
  - src/core/render/pipeline.cpp
  - src/core/render/pipeline.hpp
  - src/core/render/modules/world/*
  - src/shader/world/post_render/*
  - src/shader/world/ray_tracing/*
- Vulkan/XR 引导:
  - CMakeLists.txt
  - src/core/CMakeLists.txt
  - src/core/vulkan/instance.*
  - src/core/vulkan/device.*
  - src/core/vulkan/physical_device.*
  - src/core/vulkan/image.*
Copilot AI review requested due to automatic review settings March 12, 2026 23:15
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 将渲染框架扩展为可在运行时启动/停止 OpenXR 会话,并把 world 渲染链路从单眼扩展为双目数组层输出,配套引入 per-eye view/proj、可见性遮罩、注视点相关的 foveated 渲染,以及与 Vulkan 设备/扩展注入的初始化桥接。

Changes:

  • 新增 OpenXRContext/OpenXRInput/VRSystem,并在 Framework 中实现会话生命周期控制与 XR swapchain 提交/镜像输出。
  • World pipeline 引入 eyeCount 与 StereoMode 调度,核心模块(ray tracing / temporal / tone mapping / post / NRD / FSR3 / DLSS)按眼渲染与按层绑定资源视图。
  • Vulkan 侧支持 OpenXR 所需 instance/device 扩展注入与物理设备覆盖选择,Image 支持 per-layer image view。

Reviewed changes

Copilot reviewed 47 out of 47 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/shader/world/ray_tracing/world.rgen 增加 visibility mask early-out、按眼 view/proj、foveated block 渲染与 block-fill。
src/shader/world/ray_tracing/end_portal.rchit 增加 push constant 并改为按眼 view/proj 投影。
src/shader/world/ray_tracing/end_gateway.rchit 同上,按眼 view/proj 投影。
src/shader/world/post_render/world_post_star.vert 增加 eyeIndex push constant,按眼 view/proj 变换。
src/shader/world/post_render/world_post.vert 增加 eyeIndex push constant,按眼 view/proj 与坐标系变换。
src/core/vulkan/physical_device.hpp 增加静态 overrideDevice 以支持 OpenXR 指定物理设备。
src/core/vulkan/physical_device.cpp 在选择物理设备时优先使用 overrideDevice。
src/core/vulkan/instance.hpp 增加静态 extraExtensions 以注入 OpenXR instance 扩展。
src/core/vulkan/instance.cpp 创建 VkInstance 时合并 extraExtensions。
src/core/vulkan/device.hpp 增加静态 extraExtensions 以注入 OpenXR device 扩展。
src/core/vulkan/device.cpp 创建 VkDevice 时合并 extraExtensions。
src/core/vulkan/image.hpp 增加 per-layer view API(createPerLayerViews/perLayerView)及 layer subresource helper。
src/core/vulkan/image.cpp 实现 per-layer image view 创建与按层取 view。
src/core/render/vr_system.hpp 新增 VRSystem/控制器/性能/眼参数等数据结构与接口。
src/core/render/vr_system.cpp 实现投影/视图 offset、simulation 更新、OpenXR 更新、recenter。
src/core/render/renderer.hpp Renderer Options 增加 VR 开关与参数,并持有 VRSystem。
src/core/render/render_framework.hpp Framework 增加 OpenXRContext 持有与会话控制接口。
src/core/render/render_framework.cpp Framework 初始化分阶段 OpenXR、运行时 begin/end frame、XR blit、GPU/CPU 计时与重建联动。
src/core/render/pipeline.hpp WorldPipelineBuildParams 增加 eyeCount;WorldPipeline/Context 增加 eyeCount 状态。
src/core/render/pipeline.cpp 按 XR 会话状态决定 eyeCount;创建 array-layer render targets;StereoMode 调度与镜像 SBS blit。
src/core/render/openxr_input.hpp 新增 OpenXR 输入/动作/触觉/注视点接口声明。
src/core/render/openxr_input.cpp 实现 actions/bindings、每帧输入同步、触觉与注视点计算。
src/core/render/openxr_context.hpp 新增 OpenXR 生命周期/会话/Swapchain/visibility mask 查询接口。
src/core/render/openxr_context.cpp 实现 pre/post Vulkan 初始化、会话控制、swapchain acquire/release、begin/end frame、visibility mask 拉取。
src/core/render/modules/world/world_module.hpp 引入 StereoMode 与按眼渲染入口(render3D/renderEye/currentEyeIndex)。
src/core/render/modules/world/tone_mapping/tone_mapping_module.hpp ToneMapping 支持 stereo(按眼 framebuffer/descriptorTable)。
src/core/render/modules/world/tone_mapping/tone_mapping_module.cpp ToneMapping 实现 3D dispatch/按眼输出与 exposure 共享策略。
src/core/render/modules/world/temporal_accumulation/temporal_accumulation_module.hpp TemporalAccumulation 标注 stereoMode 并新增 renderEye。
src/core/render/modules/world/temporal_accumulation/temporal_accumulation_module.cpp TemporalAccumulation 资源按眼索引、renderEye 路径与按层 copy/blit。
src/core/render/modules/world/ray_tracing/ray_tracing_module.hpp Ray tracing push constant 增加 eyeIndex;descriptor table 改为 [frame][eye];新增 visibility mask 资源。
src/core/render/modules/world/ray_tracing/ray_tracing_module.cpp Ray tracing 按眼 dispatch、按层绑定输出、生成/上传 visibility mask 纹理并绑定到 shader。
src/core/render/modules/world/post_render/post_render_module.hpp PostRender 增加 eyeIndex push constant 并改为 per-eye tables/framebuffers。
src/core/render/modules/world/post_render/post_render_module.cpp PostRender 按眼渲染与 push constants;按层拷贝与 per-eye depth framebuffer。
src/core/render/modules/world/nrd/nrd_module.hpp NRD 改为每眼一个 wrapper;composition 增加 eyeIndex;中间资源按眼索引。
src/core/render/modules/world/nrd/nrd_module.cpp NRD per-eye wrapper/init/denoise;为 stereo 增加 viewZ 单层拷贝与 composition 按眼 dispatch。
src/core/render/modules/world/fsr_upscaler/upscaler_module.hpp FSR3 改为 per-eye upscaler + per-eye intermediates;新增 renderEye。
src/core/render/modules/world/fsr_upscaler/upscaler_module.cpp FSR3 per-eye dispatch;array-layer 输入拷贝到单层 intermediate;输出回写到目标 array layer。
src/core/render/modules/world/dlss/dlss_wrapper.hpp setResource 增加 viewIndex 以支持 array-layer view。
src/core/render/modules/world/dlss/dlss_wrapper.cpp DLSS resource 绑定使用指定 image view / layer range。
src/core/render/modules/world/dlss/dlss_module.hpp DLSS 改为 per-eye 实例并新增 renderEye。
src/core/render/modules/world/dlss/dlss_module.cpp DLSS per-eye 实例化/资源绑定/denoise,并按层处理 firstHitDepth。
src/core/render/buffers.hpp Buffers 增加 foveated 参数 setter 与内部字段。
src/core/render/buffers.cpp WorldUBO 增加 stereo/foveated 字段填充与 gaze center 写入。
src/core/middleware/com_radiance_client_proxy_vulkan_VRProxy.cpp 新增 JNI VRProxy:会话控制、参数设置、姿态/输入/性能查询、触觉与 recenter。
src/core/CMakeLists.txt core target 增加 OpenXR 依赖、include 与编译宏。
src/common/shared.hpp WorldUBO 增加 stereo/foveated 字段(eye offsets、ipd、foveated 参数)。
CMakeLists.txt 增加 OpenXR-SDK FetchContent 与构建开关。

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +148 to +154
vec2 center = resolution * worldUBO.foveatedCenter;
float halfDiag = length(center);
uint bs = worldUBO.foveatedOuterBlockSize;
// Use block origin distance so all pixels in a block make the same decision
ivec2 blockOrigin = (pixel / ivec2(bs)) * ivec2(bs);
float originDist = length(vec2(blockOrigin) + 0.5 - center) / halfDiag;
if (originDist > worldUBO.foveatedInnerRadius) {
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Foveated rendering distance normalization uses halfDiag = length(center). When gaze moves away from screen center, this changes the denominator and can even become 0 (e.g. gaze at (0,0)), causing division-by-zero and overly aggressive block sizing. Use a constant normalization (e.g. half diagonal of the render target) or compute max distance from center to the corners, and guard against zero.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants