跳转到内容

OpenXR SDK — Khronos VR/AR 标准参考实现

待复核

OpenXR SDK Source 是 Khronos 维护的 OpenXR 标准配套源码仓库,里面有 loader、调试/校验层和示例程序。

日常类比:以前每个头显像不同品牌的插座,应用要自带一堆转接头;OpenXR 像统一插座标准,SDK Source 则像那套公开的插座、验电笔和样板间。

更技术一点说,OpenXR 不是某一家厂商的运行时,而是一套让 VR、AR、MR 应用和设备运行时对话的 C API。应用链接 openxr_loader,loader 再找到当前系统启用的 runtime。

最小例子是“创建一个 OpenXR 实例,再问系统有没有头显”:

XrInstance instance = XR_NULL_HANDLE;
XrInstanceCreateInfo info{XR_TYPE_INSTANCE_CREATE_INFO};
strcpy(info.applicationInfo.applicationName, "TinyXR");
info.applicationInfo.apiVersion = XR_API_VERSION_1_0;
XR_CHECK(xrCreateInstance(&info, &instance));
XrSystemId systemId = XR_NULL_SYSTEM_ID;
XrSystemGetInfo sys{XR_TYPE_SYSTEM_GET_INFO};
sys.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
XR_CHECK(xrGetSystem(instance, &sys, &systemId));

这段代码不关心你后面接的是哪家头显。真正的设备差异藏在 runtime 和扩展里。

不理解 OpenXR SDK,下面这些事都很难解释:

  • 为什么一个 XR 应用理论上能在 SteamVR、Monado、Meta、Windows Mixed Reality 等运行时之间切换
  • 为什么 VR/AR 程序不仅要写图形渲染,还要处理 XrSessionXrSpaceXrAction 这些 XR 状态
  • 为什么 repo 里既有 hello_xr 示例,也有 API Dump / Core Validation 这种“查错工具”
  • 为什么 Khronos 把 loader 放在独立仓库里:应用只链接 loader,厂商 runtime 可以各自实现

OpenXR SDK Source 可以拆成四个核心角色:

  1. Loader 是前台接待:应用只认识 openxr_loader,不直接找某家 runtime。类比:你去医院先挂号,系统再把你分到正确科室;好处是同一份应用二进制不必为每家头显重编译。

  2. Runtime 是真正干活的设备后端:SteamVR、Monado 或设备厂商 runtime 才知道如何追踪头、手柄和显示屏。类比:标准插座只规定形状,电厂和电器内部怎么实现另算。

  3. API Layers 是中间检查员:API Dump 记录调用,Core Validation 检查有效用法。类比:你发快递时加一个“全程拍照”和一个“违禁品检查”,不改变包裹本身,却让排错更可见。

  4. 示例与代码生成让标准落地hello_xr 展示实例、系统、会话、swapchain、动作输入的完整路径;部分代码从 xr.xml 生成,避免手写 API 表时和规范脱节。

真实场景:你刚拿到一台头显,想确认系统 runtime、图形 API 和 OpenXR 基础链路能不能跑通。

Terminal window
git clone https://github.com/KhronosGroup/OpenXR-SDK-Source
cd OpenXR-SDK-Source
python3 -m pip install jinja2
cmake -S . -B build/linux_debug -DCMAKE_BUILD_TYPE=Debug
cmake --build build/linux_debug
XR_RUNTIME_JSON=/path/to/active_runtime.json \
./build/linux_debug/src/tests/hello_xr/hello_xr -g Vulkan -ff Hmd -vc Stereo

逐部分解释:

  • jinja2 用来从 xr.xml 生成一部分源码,直接用预生成 SDK 时才不需要这步
  • XR_RUNTIME_JSON 临时指定 runtime manifest,适合在多个 runtime 间切换测试
  • -g Vulkan 选择图形后端;hello_xr 还支持 D3D11、D3D12、OpenGL、OpenGLES、Metal 等组合

案例 2:用 API Dump 看应用到底调用了什么

Section titled “案例 2:用 API Dump 看应用到底调用了什么”

真实场景:应用黑屏,但你不确定是没创建实例、没选对扩展,还是会话状态没进入可渲染阶段。

Terminal window
export XR_API_LAYER_PATH=$PWD/build/linux_debug/src/api_layers
export XR_ENABLE_API_LAYERS=XR_APILAYER_LUNARG_api_dump
export XR_API_DUMP_EXPORT_TYPE=text
export XR_API_DUMP_FILE_NAME=my_api_dump.txt
./build/linux_debug/src/tests/hello_xr/hello_xr -g Vulkan

逐部分解释:

  • XR_API_LAYER_PATH 告诉 loader 去哪里找刚构建出来的 layer
  • XR_ENABLE_API_LAYERS 打开 API Dump,它会记录 xrCreateInstancexrGetSystem 等调用参数
  • XR_API_DUMP_FILE_NAME 把输出写到文件,方便和正常运行时的调用顺序对比

案例 3:用 Core Validation 捕获“看起来能跑但其实违规”的调用

Section titled “案例 3:用 Core Validation 捕获“看起来能跑但其实违规”的调用”

真实场景:你写自己的 OpenXR 小程序,某个结构体 type 忘填了,runtime 只返回一个模糊错误。

Terminal window
export XR_API_LAYER_PATH=$PWD/build/linux_debug/src/api_layers
export XR_ENABLE_API_LAYERS=XR_APILAYER_LUNARG_core_validation
export XR_CORE_VALIDATION_EXPORT_TYPE=text
export XR_CORE_VALIDATION_FILE_NAME=my_validation_output.txt
./build/linux_debug/src/tests/hello_xr/hello_xr -g Vulkan -s Stage

逐部分解释:

  • Core Validation 会按 OpenXR 规范里的有效用法规则检查参数和对象状态
  • 输出里通常包含函数名、严重级别、相关对象和 VUID,能反查规范位置
  • 发布版不要启用它,因为 layer 会增加额外检查成本,主要用于开发期
  1. 把 SDK 当 runtime:SDK 只给头文件、loader、示例和工具;没有安装 runtime 时 hello_xr 也无法真正连上设备。

  2. 忘记设置活动 runtime:多 runtime 共存时,Windows 走注册表,Linux 走 XDG 路径或 XR_RUNTIME_JSON;选错会表现为创建实例失败或黑屏。

  3. 图形 API 支持不匹配:应用选择 Vulkan 不代表 runtime 和驱动都支持对应扩展,先用 hello_xr -g ... 验链路比直接查业务代码更快。

  4. 结构体 type / next 链填错:OpenXR 大量结构体靠 XrStructureType 识别,少填一个字段就可能让后续调用全部失败。

适用

  • 你要写原生 C/C++ XR 应用,想直接控制 session、swapchain、space、action
  • 你要做 XR runtime、API layer、引擎底层适配或跨设备调试
  • 你要学习标准 API 的完整生命周期,而不是只在游戏引擎里点几个选项
  • 你要验证某个 runtime 或头显是否正确实现 OpenXR 基础能力

不适用

  • 只想快速做一个 VR 小 demo,Unity、Unreal、Godot 的 OpenXR 插件更省心
  • 只做网页 XR,应该先看 WebXR,而不是直接把浏览器外的 OpenXR API 搬进去
  • 只需要 3D 渲染,不需要头显追踪、空间定位、手柄输入和合成层
  • 没有 XR 设备或模拟 runtime 时,SDK 只能编译和读代码,体验不了完整链路
  • 2017 年:Khronos 公布 OpenXR 工作组,希望降低 VR/AR 厂商 API 分裂带来的移植成本。
  • 2019 年:OpenXR 1.0 发布,核心目标是给应用和 runtime 建立稳定、向后兼容的共同接口。
  • 2020 年前后:Monado、SteamVR、Windows Mixed Reality 等 runtime 陆续让开发者能用统一入口跑程序。
  • 2024 年:OpenXR 1.1 把一批常用扩展吸收到核心规范,说明生态从“能互通”走向“减少扩展碎片”。
  • 今天:SDK Source 仍在跟随规范更新,仓库价值更像“参考实现 + 调试工具箱”,不是普通应用框架。
  1. OpenXR 的核心不是“画 3D”,而是把应用、runtime、设备、输入、空间坐标之间的契约标准化。
  2. loader/runtime 分层很关键:应用链接稳定入口,设备厂商在 runtime 层处理真实硬件差异。
  3. hello_xr 的价值不是画出漂亮场景,而是给新手一条可运行的完整 XR 生命周期路线。
  4. API Dump 和 Core Validation 是学习标准 API 的放大镜,越早用越容易定位根因。
  • vr-1988 —— 早期虚拟现实系统背景,解释为什么头显交互长期需要统一标准
  • vr-revisited-2012 —— 现代 VR 体验复兴的前史,能帮助理解 OpenXR 出现的行业动因
  • vulkan —— OpenXR 常与 Vulkan 绑定渲染,swapchain 和显存同步都绕不开图形 API
  • picogl —— 同属图形 API 学习路径,但 PicoGL 面向 WebGL2,OpenXR 面向沉浸式设备
  • godot —— 游戏引擎层会把 OpenXR 包成插件,适合对比“直接 API”和“引擎封装”
  • filament —— 实时渲染引擎关注画面质量,OpenXR 关注画面如何送进头显和空间里
  • nvidia-gpu-operator —— XR 高帧率依赖 GPU 能力,理解底层 GPU 生态有助于排性能问题

(暂无反向链接)