Axmol v3: VR 引入 OpenXR 运行时渲染路径
2026/7/21 8:33:30 网站建设 项目流程


这次更新为 Axmol 带来了真正基于 OpenXR 的 VR 渲染路径。过去的 generic VR renderer 更适合本地预览和调试双眼渲染效果,但它并不连接真实头显运行时。现在,Axmol 可以创建 OpenXR session,渲染到运行时提供的 swapchain,提交双眼 projection layer,并把手柄输入接回引擎事件系统。

从 Renderer 到 Compositor

这次重构把场景渲染扩展点从SceneRenderer调整为SceneCompositor。Compositor 负责和一帧画面绑定的场景呈现策略:它可以在逻辑更新前轮询运行时事件,也可以按普通方式渲染场景,或者把同一个场景按多视图、多目标、多运行时 swapchain 的方式组合输出。

默认SceneCompositor保持普通渲染行为。VR 现在拆成两条路径:

  • VRPreviewSceneCompositor:不依赖 XR runtime,用于本地双眼预览、畸变网格和调试。
  • VRSceneCompositor:基于 OpenXR 的真实 HMD 渲染路径。

这样预览路径仍然轻量,产品级 VR 路径则可以按运行时要求处理 frame timing、swapchain 和控制器输入。

OpenXR 路径做了什么

新增的OpenXRDriver驱动 OpenXR 帧管线:

  • OpenXR instance、system、session 和 local space。
  • 双眼 view configuration 和 swapchain。
  • 每帧xrWaitFramexrBeginFramexrEndFrame流程。
  • 把 OpenXR swapchain image 包装成当前 RHI 可渲染纹理。
  • 手柄 action set、binding、pose、button、thumbstick 和 interaction profile。

VRSceneCompositor则把这些运行时状态接入 Axmol 的帧循环:在 scheduler update 前同步 XR 事件和输入,根据 runtime 给出的 eye pose 和非对称投影矩阵渲染每只眼睛,绘制手柄射线,提交 GPU 命令,释放 swapchain image,最后提交 projection layer。

手柄射线接入 PointerEvent

OpenXR 手柄输入现在会进入两个层级。

如果需要 XR 原生语义,可以使用XRInputEventListener监听 button、axis、aim pose 和 grip pose。

如果要复用现有 UI 和场景交互,手柄 aim ray 也会桥接为PointerEvent。现在PointerEvent可以携带:

  • PointerType::Controller
  • 当前和上一帧 3D ray
  • 世界坐标中的PointerHitResult

这意味着已有的 pointer listener 可以参与 VR 交互;自定义节点也可以覆写Node::onPointerHitTest()来支持射线拾取。Widget、ScrollView、Menu、Terrain 以及相关测试已经适配了这条路径。

RHI 层的支撑

OpenXR swapchain image 由运行时拥有,而不是由 Axmol 创建。为了渲染到这些图像,RHI 新增了ExternalTextureDesc,用于包装外部 native texture。Renderer 也新增了只提交当前 GPU 命令、不 present 默认窗口 surface 的接口,方便 OpenXR compositor 在释放 swapchain image 前确保渲染工作已经提交。

对于 Vulkan,OpenXRVulkanInterop实现了VulkanInterop抽象接口,通过Application::registerVulkanInterop()在引擎初始化阶段注入。GraphicsCore(原DriverContext)在创建 Vulkan 设备时通过该接口向 OpenXR runtime 查询所需的 extension 和 runtime 选择的 physical device,核心 RHI 层不再依赖 OpenXR 头文件。

如何启用

CMake 开启:

-DAX_ENABLE_VR=ON -DAX_ENABLE_OPENXR=ON

如果 OpenXR 使用 Vulkan,请在applicationWillLaunch()中调用:

voidAppDelegate::applicationWillLaunch(){#ifdefAX_ENABLE_OPENXRregisterVulkanInterop();#endif}

然后安装对应 compositor:

#ifdefAX_ENABLE_OPENXRrenderView->setSceneCompositor(std::make_unique<ax::VRSceneCompositor>());#elserenderView->setSceneCompositor(std::make_unique<ax::VRPreviewSceneCompositor>());#endif

这是 Axmol VR 栈接入 OpenXR 的关键一步:真实运行时 frame timing、头显 swapchain、双眼 pose/projection,以及手柄输入都进入了引擎主路径。

平台说明:本 PR 仅在 Win32 desktop 上验证通过,Android 未经测试,不承诺兼容。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询