全息影像防抖动 - MRTK2

性能

为了使基础混合现实平台和设备产生最佳结果,必须实现帧速率。 目标帧速率 (例如:60 FPS 或 90 FPS) 因平台和设备而异。 但是,满足帧速率的混合现实应用程序将具有稳定的全息影像以及高效的头部跟踪、手部跟踪等。

环境跟踪

稳定的全息渲染在很大程度上依赖于平台 & 设备的头部姿势跟踪。 Unity将从基础平台估计和提供的相机姿势中呈现每个帧的场景。 如果此跟踪未正确跟踪实际头部运动,则全息影像在视觉上将显得不准确。 这对于 HoloLens 等 AR 设备尤其明显和重要,因为 HoloLens 可在其中将虚拟全息影像与现实世界相关联。 性能对于可靠的头部跟踪非常重要,但也可能存在 其他重要功能。 影响用户体验的环境元素类型取决于目标平台的具体信息。

Windows Mixed Reality

Windows Mixed Reality平台提供了一些用于稳定平台上全息影像的参考资料。 开发人员可以利用一些关键工具来改善用户的全息影像视觉体验。

深度缓冲区共享

Unity开发人员可以选择与平台共享应用程序的深度缓冲区。 这提供了当前帧存在全息影像的信息,平台可以通过硬件辅助过程(称为“Late-Stage 重新投影”)来稳定全息影像。

后期重新投影

在呈现帧结束时,Windows Mixed Reality平台采用应用程序生成的颜色 & 深度呈现目标,并转换最终屏幕输出,以考虑自上次头部姿势预测以来的任何轻微头部移动。 应用程序的游戏循环需要一段时间才能执行。 例如,在 60 FPS 时,这意味着应用程序需要大约 16.667 毫秒来呈现帧。 尽管这看起来只是一小段时间,但用户头部的位置和方向也会发生变化,从而在渲染中为相机生成新的投影矩阵。 后期重新投影会转换最终图像中的像素,以考虑此新透视。

每像素与稳定平面 LSR

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

基于每像素深度

基于每像素深度的重新投影涉及利用深度缓冲区修改每个像素的图像输出,从而稳定不同距离的全息影像。 例如,1 米外的球体可能位于 10 米外的柱子前面。 如果用户稍微倾斜头部,表示球体的像素将具有与表示柱形的远距离像素不同的转换。 每像素重新投影将考虑每个像素的此距离差异,以便更准确地重新投影。

防抖动平面

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

深度缓冲区格式

如果面向 HoloLens 进行开发,强烈建议使用 16 位深度缓冲区格式(与 24 位相比)。 尽管深度值精度较低,但这可以极大地节省性能。 为了补偿较低的精度并避免 z 格斗,建议将远剪辑平面从Unity设置的 1000 米默认值中减少。

注意

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

Unity 中的深度缓冲区共享

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

  1. “编辑>项目设置”下>,播放器>XR 设置>虚拟现实 SDK> 启用 深度缓冲区共享
    1. 如果面向 HoloLens,建议也选择 16 位深度格式
  2. 在屏幕上呈现颜色时,也呈现深度

Unity 中的不透明 GameObject 通常会自动写入深度。 但是,默认情况下,透明 & 文本对象通常不会写入深度。 如果利用 MRTK Standard着色器或文本网格 Pro,则可以轻松解决此问题。

注意

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

透明 MRTK Standard着色器

对于使用 MRTK Standard着色器的透明材料,请选择材料以在“检查器”窗口中查看它。 然后单击“ 立即修复 ”按钮,将材料转换为写入深度 (即 Z-Write on) 。

活动前

修复 MRTK Standard 着色器之前的深度缓冲区

活动后

深度缓冲区固定 MRTK Standard着色器

文本网格 Pro

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

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

自定义着色器

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

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

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

WorldAnchors (HoloLens)

除了确保满足正确的配置以确保视觉稳定性,还必须确保全息影像在其正确的物理位置保持稳定。 为了通知平台物理空间中的重要位置,开发人员可以利用 GameObjects 上的 WorldAnchors ,这些对象需要停留在一个位置。 WorldAnchor 是添加到 GameObject 的组件,该组件对对象的转换具有绝对控制权。

HoloLens 等设备不断扫描和了解环境。 因此,当 HoloLens 跟踪空间中的移动 & 位置时,其估计值将更新并调整Unity坐标系。 例如,如果 GameObject 在开始位置距相机 1 米处,则当 HoloLens 跟踪环境时,它可能会意识到 GameObject 所在的物理点实际上距离 1.1 米。 这将导致全息影像偏移。 将 WorldAnchor 应用于 GameObject 将使定位点能够控制对象的转换,以便对象将保留在正确的物理位置 (即更新到 1.1 米远,而不是 1 米处运行时) 。 若要跨应用会话保留 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 锁定工具。

另请参阅