Version: 6000.3
语言: 中文
VR帧时序
针对 URP 中未受束缚的 XR 设备进行优化

URP 应用程序 Spacewarp

URP Application Spacewarp 是针对 OpenXR 的优化,可帮助应用程序保持高帧率。Spacewarp 每隔一帧合成一次,这可以大大降低计算能力和能耗。该技术在合成帧时使用重新投影来减少用户移动和显示更新之间的延迟。

空间扭曲可能会导致显示伪影,并且可能需要对应用程序进行更改才能获得可接受的结果。

有关如何在 Unity 项目中使用空格扭曲的信息,请参阅以下主题:

主题 描述
先决条件 列出了在 Unity 项目中使用 spacewarp 所需的技术要求,包括特定版本的 Unity、OpenXR、URP 和其他必要组件。
了解 URP 应用程序 Spacewarp 解释空间扭曲如何通过插值帧来工作,并描述相关的缓冲区、限制和可能遇到的潜在视觉瑕疵。
应用程序空间扭曲工作流程 概述如何在 Unity 项目中启用和配置空间扭曲。
在编辑器中启用OpenXR空间扭曲功能 介绍在 Unity 中启用空间扭曲的方法,可以使用适用于 Meta 设备的 Meta SDK 或手动 OpenXR 功能配置。
在运行时控制空间扭曲 详细介绍了如何在运行时控制和管理空间扭曲功能。
选择与空间扭曲兼容的着色器 列出着色器在 GPU 上运行的程序。更多信息
请参阅术语表
与 SpaceWarp 兼容。
修改自定义着色器以支持空间扭曲 如何修改自定义着色器以支持空间扭曲。
配置空间扭曲的材质 如何通过切换XR一个总称,包括虚拟现实 (VR)、增强现实 (AR) 和混合现实 (MR) 应用。支持这些形式的交互式应用程序的设备可以称为 XR 设备。更多信息
请参阅术语表
运动矢量通道(空间扭曲)
财产。

其他资源

先决条件

要使用 URP 应用程序空间扭曲,您的项目必须满足以下先决条件:

  • 统一 6.1+
  • 开放XR 1.11.0+
  • 普遍渲染管线(Render Pipeline) 获取场景内容并将其显示在屏幕上的一系列作。Unity 允许您从预构建的渲染管道中进行选择,或编写自己的渲染管道。更多信息
    请参阅术语表
    (URP) 17.0.3+
  • 渲染图(URP兼容模式下不支持空格扭曲)
  • Vulkan 图形 API
  • Android 构建目标
  • 支持 URP 应用空间扭曲的 XR 头戴式设备

注意:请参阅设备的文档和规格,以确定它是否支持 OpenXR XR_FB_space_warp扩展。(还可以查看设备上的 Android 日志,以确保在测试应用时成功启用扩展。

了解 URP 应用程序 Spacewarp

URP 应用程序 Spacewarp 使用前一帧的数据每隔一帧合成一次。除了渲染的标准眼图缓冲区场景场景包含游戏的环境和菜单。将每个唯一的场景文件视为一个独特的关卡。在每个场景中,你放置你的环境、障碍物和装饰品,基本上是将你的游戏设计和构建成碎片。更多信息
请参阅术语表
,空间扭曲需要一个运动矢量缓冲区和一个深度缓冲区保存图像中每个像素的 z 值深度的内存存储,其中 z 值是投影平面中每个呈现像素的深度。更多信息
请参阅术语表
.URP XR通道将这些渲染为低分辨率运动矢量和深度缓冲区。

要合成帧,空间扭曲移位像素计算机图像中的最小单位。像素大小取决于您的屏幕分辨率。像素光照是在每个屏幕像素下计算的。更多信息
请参阅术语表
从上一个渲染的帧到基于运动矢量和深度的新外推位置。为了减少延迟,根据最新的可用输入姿势,使用位置时间扭曲重新投影帧。

【注】位置时间扭曲是一种更有效的重新投影形式,它使用更新姿势和深度信息来平移和旋转最终帧。从技术上讲,位置时间扭曲与应用程序空间扭曲是不同的功能。当应用程序空间扭曲处于活动状态时,Meta 耳机会自动打开位置时间扭曲。其他耳机可能不会。

有关 Meta 设备上的 Application Spacewarp 的更多信息,请参阅 Application Spacewarp 开发人员指南 (Meta)

空间扭曲的局限性

  • 虽然空间扭曲可以提高应用的渲染性能,但它不会简单地将帧速率提高一倍。(Meta 估计 Quest 耳机的最佳情况下会提高 70%。但是,如果您的帧速率已经非常低(大约 18 fps 或更低),则空间扭曲根本不起作用。
  • 帧合成可能会引入视觉伪影,例如失真和卡顿。请参阅视觉工件
  • 并非所有对象都可以应用空间扭曲,这意味着它们有效地以一半的帧速率渲染。请参阅未扭曲的对象
  • Unity 不支持在 URP 兼容模式下使用空间扭曲。

视觉伪影

应用程序空间扭曲会导致视觉伪影。您应该评估空间扭曲的好处是否超过观察到的问题。

未变形的物体

如果移动对象没有运动矢量,那么它在移动时可能会显得卡顿,因为它的位置仅在渲染的帧中更新,而不是在合成帧中更新。尽管如此,在某些情况下,如果没有空间扭曲,情况可能会更好。

你可以通过更改指定材质的 XR运动矢量通道(空间扭曲)属性,将空间扭曲应用于特定对象。禁用 XR运动矢量通道(空间扭曲)的对象不会扭曲。有关更多信息,请参阅配置空间扭曲的材质

Material Inspector 显示 高级选项(Advanced Options) 部分。
Material Inspector 显示 高级选项(Advanced Options) 部分。

Unity 也不会将空间扭曲应用于:

  • 粒子系统 通过在场景中生成大量小型 2D 图像并为其设置动画来模拟流体实体(例如液体、云和火焰)的组件。更多信息
    请参阅术语表
  • 使用材质且着色器不支持空间扭曲的对象
  • 合成图层(仅扭曲默认场景图层)

透明对象

将空间扭曲应用于透明对象时可能会导致伪影,因为在运动矢量和深度缓冲区中不会捕获透明对象后面的对象移动。当靠近相机在场景中创建特定视点图像的组件。输出要么绘制到屏幕上,要么作为纹理捕获。更多信息
请参阅术语表
.

在某些情况下,您可以通过将此类内容渲染到合成图层来缓解与透明度相关的瑕疵。但是,空间扭曲不会应用于合成图层,因此图层中的动画可能会显得断断续续。

快速移动的物体

以高视速度移动的物体会产生明显的伪影。当空间扭曲移动为对象渲染的像素时,算法会扭曲背景以填充对象尾流中留下的任何空白区域。对象覆盖的区域越多,在屏幕上移动的距离越远,这种失真就越有可能明显。物体背后背景的特征也会产生影响。例如,带有直线的常规网格可能比噪点纹理更容易显示失真的影响。从一个位置“传送”到另一个位置的对象也会以同样的方式导致视觉伪影。

特别是,应评估应用中控制器或手形图形的外观。这些总是靠近用户,占据屏幕的很大一部分,并以高视速度移动,所有这些都会突出与空间扭曲相关的伪影。

应用程序空间扭曲工作流程

要在项目中启用和使用 URP 应用程序空间扭曲,请完成以下步骤:

  1. 在编辑器中启用 OpenXR 空间扭曲功能
  2. 在运行时控制空间扭曲
  3. 配置空间扭曲的材质
  4. 如有必要,修改自定义着色器以支持空间扭曲。

在编辑器中启用OpenXR空间扭曲功能

您可以通过两种方式启用 URP 应用程序空间扭曲:

  • 使用 Meta SDK(适用于 Meta 头戴式设备)。
  • 添加 OpenXR 功能描述符并手动导入所需的库函数。

如果您正在为 Meta 平台进行开发并已经使用 Meta 的 SDK 包,请使用 Meta SDK 也启用 Application Spacewarp。

如果您正在为支持空间扭曲的非 Meta 头戴显示设备进行开发,或者不想将 Meta SDK 包和资产添加到您的项目中,则应使用手动方法添加 OpenXR 功能描述符。

使用 Meta SDK 启用空间扭曲

要在使用 Meta SDK 包时启用应用程序空间扭曲:

  1. 从 Unity 获取 Meta Core SDK 包Asset StoreUnity 和社区成员创建的不断增长的免费和商业资产库。提供各种各样的资产,从纹理、模型和动画到整个项目示例、教程和编辑器扩展。更多信息
    请参阅术语表
    .
  2. 使用 Unity 包管理器在项目中安装包。
  3. 打开项目设置广泛的设置集合,允许您配置物理、音频、网络、图形、输入和项目的许多其他区域的行为方式。更多信息
    请参阅术语表
    窗。
  4. 选择 OpenXR 设置页XR的插件Unity 外部创建的一组代码,用于在 Unity 中创建功能。可以在 Unity 中使用两种插件:托管插件(使用 Visual Studio 等工具创建的托管 .NET 程序集)和本机插件(特定于平台的本机代码库)。详细信息
    请参阅术语表
    管理
    ,.
  5. 选择 Android 选项卡。
  6. OpenXR 功能组下,启用 Meta XR Spacewarp
OpenXR 设置页面显示 Meta SDK 添加的空间扭曲功能选项。
OpenXR 设置页面显示 Meta SDK 添加的空间扭曲功能选项。

注意:您还必须在运行时启用该功能,对于某些 XR 平台(包括 Meta),您必须每帧更新相机位置和旋转。

注意:过去,需要自定义的 URP 分支来支持 Spacewarp 所需的 XR 运动矢量缓冲区。从 URP 17.0.3 开始,您不再需要使用此修改后的版本。

手动启用空间扭曲

要手动启用 URP 应用程序空间扭曲功能,您必须:

  1. 扩展 OpenXRFeature 类,以使用 OpenXRFeature 属性声明空间扭曲功能。
  2. 导入MetaSetSpaceWarp,MetaSetAppSpacePositionMetaSetAppSpaceRotationUnityOpenXR dll 库中的函数。(此库是 OpenXR 包的一部分。
  3. 在 OpenXR 功能组列表中为目标 OpenXR 平台启用 XR 空间扭曲功能。有关如何查找和更改 OpenXR 设置的信息,请参阅 OpenXR:项目配置

示例脚本执行前两个步骤。在项目中包含脚本时,它会将 URP 应用程序空间扭曲选项添加到 OpenXR 设置页面。

OpenXR 设置页显示由自定义功能声明添加的空间扭曲功能选项。
OpenXR 设置页显示由自定义功能声明添加的空间扭曲功能选项。

The following script adds the feature descriptor and imports the required functions from the UnityOpenXR library:

using System.Runtime.InteropServices;
using UnityEditor;
using UnityEngine;
using UnityEngine.XR.OpenXR;
using UnityEngine.XR.OpenXR.Features;


#if UNITY_EDITOR
// OpenXR feature declaration.
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "URP Application Spacewarp",
    Desc=@"URP Application Spacewarp feature",
    Company = "Unity",
    DocumentationLink = "",
    OpenxrExtensionStrings = "XR_FB_space_warp",
    Version = "1.0.0",
    BuildTargetGroups = new []{BuildTargetGroup.Android},
    FeatureId = featureId)]
#endif
public class SpacewarpFeature : OpenXRFeature
{
    // The feature id string. This is used to give the feature a well known id for reference.
    public const string featureId = "com.unity.openxr.feature.Spacewarp";


    // Turn spacewarp on or off.
    public static bool SetSpacewarp(bool enabled)
    {
        return MetaSetSpaceWarp(enabled);
    }

    // Update spacewarp for camera movement.
    public static bool SetAppSpaceTransform(Vector3 position, Quaternion rotation)
    {
        return MetaSetAppSpacePosition(
                   position.x,
                   position.y,
                   position.z)
               &&
               MetaSetAppSpaceRotation(
                   rotation.x,
                   rotation.y,
                   rotation.z,
                   rotation.w);
    }

    // Import functions from the UnityOpenXR dll.
    [DllImport("UnityOpenXR", EntryPoint = "MetaSetSpaceWarp")]
    private static extern bool MetaSetSpaceWarp(bool enabled);

    [DllImport("UnityOpenXR", EntryPoint = "MetaSetAppSpacePosition")]
    private static extern bool MetaSetAppSpacePosition(float x, float y, float z);

    [DllImport("UnityOpenXR", EntryPoint = "MetaSetAppSpaceRotation")]
    private static extern bool MetaSetAppSpaceRotation(float x, float y, float z, float w);
}


Note: In the future, this technique of manually adding the spacewarp feature descriptor and importing the related functions from the OpenXR package libraries might be superseded in an update to the Unity OpenXR packages. You should keep your version of the SpacewarpFeature class as simple as possible to make it easy to replace when this happens.

Once you have added this script to your project, enable spacewarp by adding a script to your scene that calls SetSpacewarp(true). Depending on your headset, you might need to also update Position and Rotation via the other two functions with the main camera’s position and rotation. Refer to your headset’s specifications to see whether it’s required.

在运行时控制空间扭曲

In addition to enabling URP Application Spacewarp in your XR settings for the project, you must also turn spacewarp on at runtime.

To turn spacewarp on, call the SpacewarpFeature.SetSpacewarp function defined in the SpacewarpFeature example script. Pass true to enable spacewarp and false to turn it off.

Note: If you’re using the Meta SDK, call OVRManager.SetSpaceWarp(true) to turn on the spacewarp feature.

On Meta headsets, you must call functions to update the position and rotation of the main camera every frame. (See the documentation for your headset for other devices or if you are using the Meta SDK.)

If you are using the SpacewarpFeature example script, you can enable and control spacewarp by adding the following MonoBehaviour to your scene’s main Camera object:

using UnityEngine;

// Add to main scene camera
public class SpacewarpController : MonoBehaviour
{
    void Start()
    {
        // Enable spacewarp when scene loads
        SpacewarpFeature.SetSpacewarp(true);
    }

    void Update()
    {
        // Update spacewarp with camera position and rotation
        SpacewarpFeature.SetAppSpaceTransform(transform.position, transform.rotation);
    }
}

选择与空间扭曲兼容的着色器

URP Application Spacewarp requires shaders that record XR motion vectors, which are used to predict the position of pixels in the extrapolated frames. If you use a shader that doesn’t record XR motion vectors, rendered objects that use it won’t update in the synthesized frames. These objects might appear to stutter because they are effectively rendered at half the framerate. Refer to Understand URP Application Spacewarp for information about how spacewarp works. The following URP base shaders are spacewarp compatible:

For Shadergraph, the following Material options for the Universal Graph Target are spacewarp compatible:

  • Lit
  • Unlit

修改自定义着色器以支持空间扭曲

To enable your custom shaders to work with URP Application Spacewarp, you must add support for the XRMotionVectors render pass.

First, add the _XRMotionVectorsPass property to your shader. This property allows you to enable spacewarp on a per-material basis. (Refer to Configure Materials for spacewarp for information about how it works with the URP shaders that support spacewarp.)

[HideInInspector] _XRMotionVectorsPass("_XRMotionVectorsPass", Float) = 1.0

Next, add the following shader subpass declaration:

Pass
{
        Name "XRMotionVectors"
        Tags { "LightMode" = "XRMotionVectors" }
        ColorMask RGBA

        // Stencil write for obj motion pixels
        Stencil
        {
        WriteMask 1
                Ref 1
                Comp Always
                Pass Replace
        }

        HLSLPROGRAM
        #pragma shader_feature_local _ALPHATEST_ON
        #pragma multi_compile _ LOD_FADE_CROSSFADE
        #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY
        #define APPLICATION_SPACE_WARP_MOTION 1

        #include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl"
        #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl"
        ENDHLSL
  }

配置空间扭曲的材质

You can apply URP Application Spacewarp to specific objects by changing the XR Motion Vectors Pass (Space Warp) property of their assigned Material. You can find the XR Motion Vectors Pass (Space Warp) property in the Advanced Options section of the InspectorA Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
See in Glossary
window for a Material. Objects with XR Motion Vectors Pass (Space Warp) disabled are not warped.

Material Inspector 显示 高级选项(Advanced Options) 部分。
Material Inspector 显示 高级选项(Advanced Options) 部分。

Tip: If the XR Motion Vectors Pass (Space Warp) option is disabled or missing, make sure that your Unity project meets the Prerequisites for using URP Application Spacewarp.

VR帧时序
针对 URP 中未受束缚的 XR 设备进行优化