全息影像稳定化

性能

为了使底层混合现实平台和设备产生最佳结果,实现帧速率非常重要。 目标帧速率 (例如: 60 FPS 或 90 FPS) 在不同的平台和设备之间有所不同。 不过,以帧速率为的混合现实应用程序将具有稳定的全息影像,并具有有效的头跟踪、手动跟踪等。

环境跟踪

稳定的全息呈现很大程度上取决于平台 & 设备的头姿势跟踪。 Unity 将从相机中呈现每个帧,这是由基础平台估计和提供的。 如果此跟踪没有正确地遵循实际头运动,则全息影像将显示不准确。 这对于 AR 设备(如 HoloLens,用户可在其中将虚拟全息关联到现实世界)尤其明显且非常重要。 性能对于可靠的头跟踪非常重要,但也有 其他重要功能。 影响用户体验的环境元素类型将取决于目标平台细节。

Windows Mixed Reality

该 Windows Mixed Reality 平台提供了一些用于平台上的稳定全息影像的参考材料。 虽然开发人员可以利用这些重要工具来改进用户的全息图视觉体验。

深度缓冲区共享

Unity 开发人员可以选择使用平台共享应用程序的深度缓冲区。 这提供了一些信息,其中,对于当前帧,该平台可通过硬件辅助过程(称为 Late-Stage Reprojection)将其用于稳定的全息影像。

后期阶段 reprojection

在呈现帧的末尾,Windows Mixed Reality 平台将使用应用程序生成的颜色 & 深度呈现目标,并转换最终屏幕输出,以考虑自上一次头姿势预测后发生的任何轻微移动。 应用程序的游戏循环需要执行时间。 例如,在 60 FPS,这意味着应用程序将占用 ~ 16.667 ms 来呈现帧。 尽管这可能看起来像是远少于的时间,但用户的位置和方向会变化,导致照相机呈现时的新投影矩阵。 后期阶段 reprojection 转换最终图像中的像素,以考虑此新透视。

每像素与稳定平面 LSR

根据 Windows Mixed Reality 设备上运行的设备终结点和操作系统版本,Late-Stage Reprojection 算法将按像素或通过稳定平面执行。

基于像素的深度

基于像素深度的 reprojection 涉及到使用深度缓冲区来修改每个像素的图像输出,进而以不同的距离来修改稳定的全息影像。 例如,球1m 可能位于10m 的支柱的前面。 如果用户稍微倾斜其球,表示球的像素将具有不同的变换(表示支柱)。 以像素为单位的 reprojection 将在每个像素上考虑此距离差异,以获得更精确的 reprojection。

稳定平面

如果无法创建与平台共享的准确的深度缓冲区,则另一种形式的 LSR 将使用稳定平面。 场景中的所有全息影像都将接收到一些稳定性,但所需平面的全息影像将接收到最大硬件稳定性。 可以通过 Unity 提供SetFocusPointForFrame API 将平面的点和法线提供给平台。

深度缓冲区格式

如果面向开发 HoloLens,强烈建议使用16位深度缓冲区格式,而不是24位。 这可以节省极大的性能,但深度值的精度较低。 若要弥补降低精度并避免进行 z 向,建议从1000m 默认值(由 Unity 设置)中减少 far 剪裁平面

备注

如果使用的是 16 位深度格式,模具缓冲区所需的效果将不起作用,因为 Unity 不会在此设置中 创建模具缓冲区 。 相反,选择 24 位深度格式 通常会创建 8 位模具缓冲区(如果适用于终结点图形平台)。

Unity 中的深度缓冲区共享

为了利用基于深度的 LSR,开发人员需要执行两个重要的步骤。

  1. 编辑 > Project 设置 > Player > XR 设置 > 虚拟现实 sdk > 启用 深度缓冲区共享
    1. 如果以 HoloLens 为目标,则建议同时选择 16 位深度格式
  2. 在屏幕上呈现颜色时,还呈现深度

Unity 中的不透明 gameobject通常会自动写入深度。 但是,默认情况下,透明 & 文本对象通常不会写入深度。 如果利用 MRTK 标准着色器或文本网格 Pro,可以轻松地进行修正。

备注

若要快速确定场景中哪些对象不会直观写入深度缓冲区,可以使用 MRTK 配置文件中 编辑器设置 的 " 呈现深度缓冲区" 实用工具

透明 MRTK 标准着色器

对于使用 MRTK 标准着色器的透明材料,请在 " 检查器 " 窗口中选择要查看的材料。 然后单击 " 立即修复 " 按钮,将材料转换为深度 (例如 Z-写入) 。

以前

修复 MRTK 标准着色器前的深度缓冲区

调整后的文本

深度缓冲区固定 MRTK 标准着色器

文本网格 Pro

对于 Pro 对象的文本网格,请选择 TMP GameObject 以在检查器中查看它。 在材料组件下,切换所分配材料的着色器以使用 MRTK TextMeshPro 着色器。

文本网格 Pro 深度缓冲区修复

自定义着色器

如果编写自定义着色器,请将 ZWrite 标志 添加到 传递 块定义的顶部,以将着色器配置为写入深度缓冲区。

Shader "Custom/MyShader"
{
    SubShader
    {
        Pass
        {
            ...
            ZWrite On
            ...
        }
    }
}
不透明 backings

如果上面的方法不适用于给定方案 (即 使用 Unity UI) ,可以将另一个对象写入深度缓冲区。 常见的示例是在场景中的浮动面板上使用 Unity UI 文本。 通过使面板不透明或至少写入深度,该面板 & 的文本都将被平台稳定,因为其 z 值彼此接近。

WorldAnchors (HoloLens)

除了确保满足正确的配置以确保视觉稳定性,还必须确保全息影像在正确的物理位置上保持稳定。 若要将平台通知到物理空间中的重要位置,开发人员可以利用 Gameobject 上的 WorldAnchorsWorldAnchor是一个添加到 GameObject 的组件,可对该对象的转换进行绝对控制。

设备(如 HoloLens)不断地扫描和了解环境。 因此,随着 HoloLens 在空间中跟踪移动 & 位置,将更新其估计值并调整 Unity 坐标系统。 例如,如果 GameObject 是从照相机开始,当 HoloLens 跟踪环境时,它可能会认识到 GameObject 所在的物理点实际上是 1.1 m。 这将导致全息图偏移。 将 WorldAnchor 应用于 GameObject 会使定位点控制对象的转换,以便对象将保留在正确的物理位置 (即 在运行时) 更新为 1.1 m,而不是1m。 若要跨应用会话保持 WorldAnchors ,开发人员可以使用 WorldAnchorStore保存和加载 WorldAnchors

备注

将 WorldAnchor 组件添加到 GameObject 后,不能修改该 GameObject 的转换 (例如 transform: position = x) 。 开发人员必须删除 WorldAnchor 才能编辑转换。

WorldAnchor m_anchor;

public void AddAnchor()
{
    this.m_anchor = this.gameObject.AddComponent<WorldAnchor>();
}

public void RemoveAnchor()
{
    DestroyImmediate(m_anchor);
}

如果你想要使用其他方法手动处理锚点,请查看 Microsoft World 锁定工具。

另请参阅