OpenXR 应用最佳做法

可以在 BasicXrApp 的 OpenXRProgram.cpp 文件中查看以下最佳做法的示例。 开头的 Run() 函数捕获从初始化到事件和渲染循环的典型 OpenXR 应用代码流。

提高视觉质量和稳定性的最佳做法

本部分的最佳做法介绍如何在任何 OpenXR 应用程序中获得最佳视觉质量和稳定性。

如需特定于 HoloLens 2 的更多性能建议,请参阅下面的在 HoloLens 2 上提高性能的最佳做法部分。

伽马校正渲染

必须格外小心,确保渲染管道为伽马校正。 渲染到交换链时,渲染目标视图格式应与交换链格式匹配。 例如,适用于交换链格式和渲染目标视图的 DXGI_FORMAT_B8G8R8A8_UNORM_SRGB。 如果应用的渲染管道在着色器代码中执行手动 sRGB 转换,则会出现异常。 应用应请求 sRGB 交换链格式,但使用适用于渲染目标视图的线性格式。 例如,请求 DXGI_FORMAT_B8G8R8A8_UNORM_SRGB 作为交换链格式,但使用 DXGI_FORMAT_B8G8R8A8_UNORM 作为渲染目标视图,以防止对内容进行双重伽马校正。

提交适用于投影层的深度缓冲区

将帧提交到 xrEndFrame 时,请始终使用 XR_KHR_composition_layer_depth 扩展,将深度缓冲区连同投影层一起提交。 在 HoloLens 2 上启用硬件深度重投影可提高全息影像稳定性。

选择合理的深度范围

首选较窄的深度范围来设置虚拟内容的范围,这样有助于提高 HoloLens 上的全息影像稳定性。 例如,OpenXrProgram.cpp 示例使用 0.1 米到 20 米的范围。 使用反向 Z 进行更统一的深度解析。 在 HoloLens 2 上,使用首选的 DXGI_FORMAT_D16_UNORM 深度格式将有助于实现更好的帧速率和性能,尽管 16 位深度缓冲区提供的深度分辨率低于 24 位深度缓冲区。 遵循这些最佳做法来充分利用深度分辨率变得更加重要。

为不同的环境混合模式做准备

如果应用程序还将在完全阻止这个世界的沉浸式头戴显示设备中运行,请确保使用 xrEnumerateEnvironmentBlendModes API 来枚举受支持的环境混合模式,并正确准备渲染内容。 例如,对于使用 XR_ENVIRONMENT_BLEND_MODE_ADDITIVE 的系统(例如 HoloLens),应用应使用透明色作为清色,而对于使用 XR_ENVIRONMENT_BLEND_MODE_OPAQUE 的系统,应用应在后台渲染某种不透明的颜色或某个虚拟房间。

选择无界限参考空间作为应用程序的根空间

应用程序通常会建立某个根世界坐标空间,将视图、操作和全息影像连接在一起。 当支持使用扩展来建立世界规模的坐标系统时,请使用 XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT,使应用能够避免在用户走远(例如,距离应用启动位置 5 米远)时出现意外的全息影像偏移。 如果无界限空间扩展不存在,请使用 XR_REFERENCE_SPACE_TYPE_LOCAL 作为回退。

将全息影像与空间定位点关联

使用无界限参考空间时,直接放置在该参考空间中的全息影像可能会在用户走到远处的房间然后又返回时出现偏移的情况。 对于位于世界中的某个离散位置的全息影像用户,请使用 xrCreateSpatialAnchorSpaceMSFT 扩展函数创建空间定位点,并将全息影像定位在其原点。 这将使该全息影像在一段时间内保持独立稳定的状态。

支持混合现实捕获

尽管 HoloLens 2 的主要显示器使用累加环境混合,但当用户启动混合现实捕获时,应用的渲染内容会与环境视频流进行阿尔法混合。 若要在混合现实捕获视频中获得最佳视觉质量,最好是在投影层的 layerFlags 中设置 XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT

在 HoloLens 2 上提高性能的最佳做法

作为支持硬件重投影的移动设备,HoloLens 2 对最佳性能有更严格的要求。 可以使用多种方法来提交合成数据,但这会导致需要进行后期处理并明显降低性能。

选择交换链格式

始终使用 xrEnumerateSwapchainFormats 来枚举支持的像素格式,然后从应用支持的运行时中选择第一种颜色和深度像素格式,因为这是运行时为获得最佳性能而首选的格式。 请注意,在 HoloLens 2 上,DXGI_FORMAT_B8G8R8A8_UNORM_SRGBDXGI_FORMAT_D16_UNORM 通常是提高渲染性能的第一选择。 在那些运行在台式电脑(其中的 24 位深度缓冲区对性能的影响较小)上的 VR 头戴显示设备上,此首选项可能有所不同。

性能警告:使用除主交换链颜色格式外的格式会导致运行时后期处理,造成性能显著下降。

始终使用建议的视图配置宽度/高度(XrViewConfigurationView 中的 recommendedImageRectWidthrecommendedImageRectHeight)进行渲染,并始终使用 xrLocateViews API 在渲染之前查询建议的视图、姿势、FOV 和其他渲染参数。 查询姿势和视图时,请始终使用最新 xrWaitFrame 调用中的 XrFrameEndInfo.predictedDisplayTime。 这使 HoloLens 能够调整渲染效果,为不戴 HoloLens 的人优化视觉质量。

使用单个投影层

HoloLens 2 用于渲染内容的 GPU 功能有限,会使用一个针对单个投影层进行优化的硬件合成器。 始终使用单个投影层可能有助于提高应用程序的帧速率、全息影像稳定性和视觉质量。

性能警告:提交除单个保护层外的任何内容都会导致运行时后期处理,造成性能显著下降。

使用纹理数组和 VPRT 进行渲染

使用 arraySize=2 针对颜色交换链为左眼和右眼都创建一个 xrSwapchain,并针对深度创建一个。 将左眼渲染为切片 0,将右眼渲染为切片 1。 将着色器与 VPRT 和实例化绘图调用一起用于立体渲染,以最大程度地减少 GPU 负载。 这还使运行时的优化能够在 HoloLens 2 上实现最佳性能。 与使用纹理数组相对应的替代方法(如双宽渲染或每只眼睛使用单独的交换链)会导致运行时后期处理,造成性能显著下降。

避免使用四边形层

将四边形内容直接渲染到投影交换链中,而不是使用 XrCompositionLayerQuad 将四边形层作为合成层提交。

性能警告:在单个投影层之外提供其他层(如四边形层)会导致运行时后期处理,造成性能显著下降。