OpenXR 开发指南
OpenXR 是一个由 Khronos Group 制定并维护的开放、免版税的 XR(VR/AR/MR)接口标准,核心目标是让开发者「一次编写,随处运行」,解决过去不同设备各搞一套 API 的碎片化问题。LCC Unity SDK 现已支持 OpenXR 标准,无需特定 VR 设备厂商提供的 SDK,即可在支持 OpenXR 的设备上渲染 3DGS 数据。
版本要求
本指南使用的软件及插件版本如下,建议使用相同版本开发,其他未经测试的版本可能存在兼容问题:
| 软件 / 插件 | 版本 |
|---|---|
| Unity | v6000.0.69f1 |
| LCC Unity SDK | v2.3.0 及以上 |
注意:
- OpenXR 是一个标准,各 VR 设备厂商可能支持其全部特性,也可能只支持一部分,因此使用前需要先查阅特定设备的支持情况。
- OpenXR 标准定义了通用的技术规范,但各厂商设备的特定特性仍需厂商 SDK 或厂商 OpenXR Extension 扩展支持,例如 ATW(Asynchronous Time Warp,异步时间扭曲)、PTW(Late Stage Reprojection,晚期阶段重投影)等提高帧间平滑度的技术。
- 本指南主要演示 VR 设备真机的 OpenXR 开发,LCC Unity SDK 不支持 OpenXR 桌面端应用开发(除PCVR)。
开发流程
步骤 1:创建 URP 工程
在工程模板中选择 Universal 3D(URP 渲染管线)类型,如下图所示:

创建 Universal 3D 工程
步骤 2:切换平台
工程创建完成后,在 Unity 菜单中选择 File → Build Profiles 打开应用构建窗口,将平台切换为 Android,如下图所示:

在 Build Profiles 中将平台切换为 Android
步骤 3:导入 Unity OpenXR
通过 Unity 菜单 Window → Package Manager 打开 UPM 窗口,在左侧列表中选择 Unity Registry,在搜索框中输入 OpenXR,从检索列表中选择 OpenXR Plugin 并安装,如下图所示:

从 Unity Registry 安装 OpenXR Plugin
步骤 4:导入 XR Interaction Toolkit
在左侧列表中选择 Unity Registry,在搜索框中输入 XR,从检索列表中选择 XR Interaction Toolkit 并安装,如下图所示:

从 Unity Registry 安装 XR Interaction Toolkit
步骤 5:导入 LCC Unity SDK
通过 Unity 菜单 Window → Package Manager 打开 UPM 窗口,单击左侧 +,在下拉菜单中选择 Install package from disk,定位到 LCC Unity SDK,选择 package.json 文件导入,如下图所示:

通过 Install package from disk 导入 LCC Unity SDK
步骤 6:设置 Unity 环境
配置 XR Plug-in Management(Android 平台)
在 Unity 菜单栏中选择 File → Project Settings,在左侧选择 XR Plug-in Management,在 Android 平台选项卡下勾选 OpenXR,并勾选 Initialize XR on Startup,如下图所示:

在 Android 平台勾选 OpenXR 与 Initialize XR on Startup
配置 XR Plug-in Management(Desktop 平台)
由于 LCC Unity SDK 不支持桌面端 OpenXR 开发,在 Desktop 平台下不勾选 OpenXR,也不勾选 Initialize XR on Startup,如下图所示:

在 Desktop 平台不勾选 OpenXR 与 Initialize XR on Startup
注意:桌面端PCVR请参考 PCVR串流。
配置 OpenXR 渲染模式与交互配置
选择 XR Plug-in Management 下的 OpenXR 项,将 Android 平台的 Render Mode 设为 Single Pass Instanced 或 Multi-View。由于 OpenXR 必须设置 Interaction Profiles,通常选择 Oculus Touch Controller Profile 或与设备性能特性相近的 Profile,如下图所示:

设置 OpenXR 的 Render Mode 与 Interaction Profiles
Project Validation
选择 XR Plug-in Management 下的 Project Validation 项,点击 Fix All 完成必要设置(也可以先不处理,后续手动创建),如下图所示:

在 Project Validation 中点击 Fix All
设置 Player(Desktop 平台)
在 Project Settings 左侧选中 Player,切换到 Desktop 平台,展开 Other Settings 卷展栏,取消勾选 Auto Graphics API,将 Graphics APIs 设为 Direct3D12、Vulkan、Direct3D11,并移除其它图形 API;将 Color Space 设为 Gamma,如下图所示:

Desktop 平台设置图形 API 与 Gamma 颜色空间
注意:有的 VR 设备不支持 Gamma 颜色空间,此时只能选择 Linear 线性颜色空间,LCC 场景在 Linear 颜色空间下渲染颜色会略微发白。
设置 Player(Android 平台)
在 Project Settings 左侧选中 Player,切换到 Android 平台,展开 Other Settings 卷展栏,取消勾选 Auto Graphics API,将 Graphics APIs 设为 Vulkan,并移除其它图形 API;将 Color Space 设为 Gamma,如下图所示:

Android 平台设置图形 API 为 Vulkan 与 Gamma 颜色空间
设置 Android 平台脚本后端与输入
在 Android 平台的 Other Settings 选项卡中向下滑动,设置 Minimum API Level = Android 12L (API Level 32) 及以上、Scripting Backend = IL2CPP、Target Architectures = ARM64、Active Input Handling = Input System Package (New) 或 Both,如下图所示:

设置 Minimum API Level、Scripting Backend、Target Architectures 与 Active Input Handling
检查 Graphics 与 Quality
在 Project Settings 左侧选中 Graphics 项,查看 Mobile 平台所使用的 Default Render Pipeline 对应的 Render Asset,本示例中为 Mobile_RPAsset,如下图所示:

查看 Mobile 平台的 Default Render Pipeline Render Asset
在 Project Settings 左侧选中 Quality 项,查看 Mobile 平台所使用的 Default Render Pipeline 对应的 Render Asset(本示例中为 Mobile_RPAsset),设置 Resolution Scaling Fixed DPI Factor = 0.7、VSync Count = Don't Sync,如下图所示:

在 Quality 中设置 DPI Factor 与垂直同步
配置 Render Asset
找到 Mobile 平台所使用的 Default Render Pipeline 对应的 Render Asset(本示例中为 Mobile_RPAsset),选中该 Asset,在属性窗口(Inspector)中:取消勾选 Depth Texture、Opaque Texture、HDR,设置 Anti Aliasing (MSAA) = Disabled、Render Scale = 0.7、Upscaling Filter = Automatic,如下图所示:

在 Render Asset 中关闭 Depth/Opaque Texture、HDR、MSAA 并设置 Render Scale = 0.7
找到该 Render Asset 的配套 Renderer,本示例中为 Mobile_Renderer(Universal Renderer Data),在属性窗口(Inspector)中设置其相关属性,如下图所示:

配置 Mobile_Renderer(Universal Renderer Data)属性
步骤 7:创建场景
在 Unity 中创建一个全新的场景,删除 Main Camera 和 Directional Light,在层级窗口(Hierarchy)空白处单击鼠标右键,在弹出菜单中选择 XR → XR Origin (VR),创建必要的 XR 对象。
步骤 8:配置场景
在层级窗口(Hierarchy)中选中 XR Origin (VR) 游戏对象,在属性窗口(Inspector)的 XR Origin 组件中,将 Tracking Origin Mode 设为 Floor,其他相关属性如下图所示:

将 XR Origin 的 Tracking Origin Mode 设为 Floor
在层级窗口(Hierarchy)中选中 XR Origin (VR) 下的 Main Camera 游戏对象,在属性窗口(Inspector)中设置 Camera 组件相关属性:Clipping Planes Near = 0.3、Far = 5000;Anti-aliasing = No Anti-aliasing;Opaque Texture = Off、Depth Texture = Off;Background Type = Solid Color、Background = 黑色;HDR = Off、MSAA = Off,其他属性如下图所示:

设置 XR Origin (VR) 下 Main Camera 的 Camera 组件属性
步骤 9:编写代码,加载场景
在层级窗口(Hierarchy)中右键 Create Empty 创建一个空对象,命名为 LCCManager,将其 Transform 归一,并通过 Add Component 为其挂载 LCCManager 脚本,如下图所示:

创建 LCCManager 空对象并挂载 LCCManager 脚本
在层级窗口(Hierarchy)中右键 Create Empty 创建另一个空对象,命名为 LCCRenderer,将其 Transform 设置 Rotation.x = -90、Scale.x = -1,如下图所示:

创建 LCCRenderer 空对象,设置 Rotation.x = -90、Scale.x = -1 以对齐坐标系
Rotation.x = -90、Scale.x = -1 是 LCC 数据坐标系(Z-up 右手)到 Unity 坐标系(Y-up 左手)的对齐变换,详见 Unity SDK 简介 中的「LCC 数据坐标系」。
此时层级窗口(Hierarchy)中的游戏对象结构如下图所示:

Hierarchy 窗口的结构
编写一个 C# 脚本,命名为 LCCRenderer.cs,代码如下:
using LCCCore;
using UnityEngine;
using UnityEngine.XR;
public class LCCRenderer : MonoBehaviour
{
public LCCManager m_manager;
public string m_FilePath;
private LCCCore.Renderer m_renderer;
void Start()
{
#if UNITY_EDITOR
m_manager.SetPlatformType(PlatformType.PC);
m_renderer = m_manager.GetRender(this.gameObject.transform);
m_renderer.Load(m_FilePath, onProgress, onLoaded);
#else
m_manager.SetPlatformType(PlatformType.OpenXR);
m_renderer = m_manager.GetRender(this.gameObject.transform);
m_renderer.Load($"{Application.persistentDataPath}/LccData/meta.lcc2", onProgress, onLoaded);
#endif
}
private void onProgress(float v)
{
Debug.Log("progress:" + v);
}
private void onLoaded()
{
m_manager.SetStartLod(2);
m_renderer.SetEnvironment(false);
Debug.Log("Data loaded");
}
}
将该脚本挂载到层级窗口(Hierarchy)中的 LCCRenderer 游戏对象上,然后在属性窗口(Inspector)中将 LCCManager 游戏对象拖到脚本的 Manager 属性上,最后填写 LCC 文件的路径地址。
为方便在 Unity Editor 中调试并直接打包到 Android 真机设备,代码使用编译宏区分运行环境:在 Unity Editor 中直接使用 m_FilePath 指定的地址;在 Android 设备上则使用设备本地的数据源。设备端数据的放置方式为:
- 先将打包好的应用在 VR 设备上运行一次。
- 应用安装后,进入其数据目录(一般为 设备存储盘 → Android → data → 应用 BundleID → Files,具体目录可查阅 Android 应用安装路径),在 Files 子目录下创建
LccData文件夹。 - 将 LCC 数据源全部拷贝到
LccData文件夹下。
注意:实际使用中,建议将应用的数据源放在服务器上,而不是直接打包进应用。
优化实践
按上述步骤可以在 VR 设备上正常渲染 LCC 数据,但会存在以下两个主要问题:
2D 应用窗口显示
按 OpenXR 标准开发且未引入设备厂商 SDK 的应用,在 VR 设备上不一定会被识别为 3D 应用,通常 VR 设备系统会将其看作 2D 应用,因此会显示 2D 应用窗口。解决这个问题有两个思路:
- 引入设备厂商的 SDK 或设备厂商 OpenXR 扩展,此时设备厂商软件会处理相关问题。
- 自定义
AndroidManifest.xml。
自定义 Manifest 的具体操作为:在 Project Settings 左侧选中 Player,切换到 Android 平台,展开 Publishing Settings 卷展栏,勾选 Custom Main Manifest,此时会生成自定义 Manifest 文件,如下图所示:

勾选 Custom Main Manifest 生成自定义 Manifest 文件
找到 AndroidManifest.xml 文件,添加 VR 标识,让 VR 设备识别这是一个 3D 沉浸式应用,启动的应用将以 3D 空间的形式展示,示例如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<!--Used when Application Entry is set to GameActivity, otherwise remove this activity block-->
<activity android:name="com.unity3d.player.UnityPlayerGameActivity"
android:theme="@style/BaseUnityGameActivityTheme"
android:resizeableActivity="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="org.khronos.openxr.intent.category.IMMERSIVE_HMD" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="android.app.lib_name" android:value="game" />
</activity>
</application>
</manifest>
渲染帧率不足 90FPS 的卡顿
OpenXR 标准本身并没有定义插帧、平滑等相关内容,当帧率达不到 90FPS 时,旋转头部或移动时会有明显的卡顿感。各设备厂商为了更好的体验,特别是在有限的硬件性能条件下提高流畅度,通常会提供补间、插帧、平滑等技术,如 ATW(Asynchronous Time Warp,异步时间扭曲)、PTW(Late Stage Reprojection,晚期阶段重投影)等。
如果设备支持 OpenXR,设备厂商通常都会提供 OpenXR Extension 扩展或直接支持 OpenXR 的 SDK,此时最好引入设备厂商 SDK,以获得更流畅的体验。
相关参考
- 工程项目与性能优化,请参见工程设置优化指南、渲染性能参数设置指南 章节。
- VR 设备端 3DGS 同屏渲染能力约为 70 万高斯基元,渲染大场景时建议将 StartLOD 设为
2并关闭环境数据显示;大场景使用 PC 串流会更流畅。