OpenXR Development Guide
OpenXR is an open, royalty-free XR (VR/AR/MR) interface standard defined and maintained by the Khronos Group. Its core goal is to let developers "write once, run anywhere", solving the fragmentation problem of different devices each having their own set of APIs. The LCC Unity SDK now supports the OpenXR standard, so it can render 3DGS data on OpenXR-compatible devices without an SDK provided by a specific VR device vendor.
Version Requirements
The software and plugin versions used in this guide are as follows. It is recommended to develop with the same versions; other untested versions may have compatibility issues:
| Software / Plugin | Version |
|---|---|
| Unity | v6000.0.69f1 |
| LCC Unity SDK | v2.3.0 and above |
Note:
- OpenXR is a standard, and various VR device vendors may support all of its features or only part of them, so you need to check the support status of the specific device before using it.
- The OpenXR standard defines common technical specifications, but device-specific features still require vendor SDK or vendor OpenXR Extension support, such as ATW (Asynchronous Time Warp), PTW (Late Stage Reprojection) and other technologies that improve inter-frame smoothness.
- This guide mainly demonstrates OpenXR development on real VR devices; the LCC Unity SDK does not support OpenXR desktop application development (except PCVR).
Development Workflow
Step 1: Create a URP project
Select the Universal 3D (URP render pipeline) type in the project template, as shown below:

Create a Universal 3D project
Step 2: Switch the platform
After the project is created, select File → Build Profiles from the Unity menu to open the build window, and switch the platform to Android, as shown below:

Switch the platform to Android in Build Profiles
Step 3: Import Unity OpenXR
Open the UPM window via the Unity menu Window → Package Manager, select Unity Registry in the left list, enter OpenXR in the search box, select OpenXR Plugin from the search results and install it, as shown below:

Install the OpenXR Plugin from Unity Registry
Step 4: Import XR Interaction Toolkit
Select Unity Registry in the left list, enter XR in the search box, select XR Interaction Toolkit from the search results and install it, as shown below:

Install XR Interaction Toolkit from Unity Registry
Step 5: Import the LCC Unity SDK
Open the UPM window via the Unity menu Window → Package Manager, click + on the left, select Install package from disk from the drop-down menu, locate the LCC Unity SDK, and select the package.json file to import it, as shown below:

Import the LCC Unity SDK via Install package from disk
Step 6: Set up the Unity environment
Configure XR Plug-in Management (Android platform)
Select File → Project Settings from the Unity menu bar, select XR Plug-in Management on the left, check OpenXR under the Android platform tab, and check Initialize XR on Startup, as shown below:

Check OpenXR and Initialize XR on Startup on the Android platform
Configure XR Plug-in Management (Desktop platform)
Since the LCC Unity SDK does not support desktop OpenXR development, do not check OpenXR or Initialize XR on Startup under the Desktop platform, as shown below:

Do not check OpenXR or Initialize XR on Startup on the Desktop platform
Note: For desktop PCVR, refer to PCVR Streaming.
Configure the OpenXR render mode and interaction configuration
Select the OpenXR item under XR Plug-in Management, and set the Android platform Render Mode to Single Pass Instanced or Multi-View. Since OpenXR requires setting Interaction Profiles, usually select Oculus Touch Controller Profile or a profile with similar device performance characteristics, as shown below:

Set the OpenXR Render Mode and Interaction Profiles
Project Validation
Select the Project Validation item under XR Plug-in Management, and click Fix All to complete the necessary settings (you can also leave it unhandled for now and create it manually later), as shown below:

Click Fix All in Project Validation
Configure Player (Desktop platform)
Select Player on the left of Project Settings, switch to the Desktop platform, expand the Other Settings section, uncheck Auto Graphics API, set Graphics APIs to Direct3D12, Vulkan, Direct3D11, and remove the other graphics APIs; set Color Space to Gamma, as shown below:

Set the graphics APIs and the Gamma color space on the Desktop platform
Note: Some VR devices do not support the Gamma color space; in that case you can only choose the Linear color space, and LCC scenes rendered in the Linear color space will appear slightly washed out.
Configure Player (Android platform)
Select Player on the left of Project Settings, switch to the Android platform, expand the Other Settings section, uncheck Auto Graphics API, set Graphics APIs to Vulkan, and remove the other graphics APIs; set Color Space to Gamma, as shown below:

Set the graphics API to Vulkan and the Gamma color space on the Android platform
Set the Android platform scripting backend and input
Scroll down in the Other Settings tab of the Android platform, and set Minimum API Level = Android 12L (API Level 32) or above, Scripting Backend = IL2CPP, Target Architectures = ARM64, Active Input Handling = Input System Package (New) or Both, as shown below:

Set Minimum API Level, Scripting Backend, Target Architectures, and Active Input Handling
Check Graphics and Quality
Select Graphics on the left of Project Settings, and check the Render Asset corresponding to the Default Render Pipeline used by the Mobile platform, Mobile_RPAsset in this example, as shown below:

Check the Default Render Pipeline Render Asset on the Mobile platform
Select Quality on the left of Project Settings, check the Render Asset corresponding to the Default Render Pipeline used by the Mobile platform (Mobile_RPAsset in this example), set Resolution Scaling Fixed DPI Factor = 0.7, VSync Count = Don't Sync, as shown below:

Set the DPI Factor and VSync in Quality
Configure the Render Asset
Find the Render Asset corresponding to the Default Render Pipeline used by the Mobile platform (Mobile_RPAsset in this example), select the Asset, and in the property window (Inspector): uncheck Depth Texture, Opaque Texture, HDR; set Anti Aliasing (MSAA) = Disabled, Render Scale = 0.7, Upscaling Filter = Automatic, as shown below:

Turn off Depth/Opaque Texture, HDR, MSAA, and set Render Scale = 0.7 in the Render Asset
Find the matching Renderer for this Render Asset, Mobile_Renderer (Universal Renderer Data) in this example, and set its relevant properties in the property window (Inspector), as shown below:

Configure the Mobile_Renderer (Universal Renderer Data) properties
Step 7: Create the scene
Create a brand-new scene in Unity, delete Main Camera and Directional Light, right-click in an empty area of the hierarchy window (Hierarchy), and select XR → XR Origin (VR) from the popup menu to create the necessary XR objects.
Step 8: Configure the scene
Select the XR Origin (VR) GameObject in the hierarchy window (Hierarchy), and in the XR Origin component of the property window (Inspector), set Tracking Origin Mode to Floor; other relevant properties are as shown below:

Set the XR Origin Tracking Origin Mode to Floor
Select the Main Camera GameObject under XR Origin (VR) in the hierarchy window (Hierarchy), and set the Camera component properties in the property window (Inspector): Clipping Planes Near = 0.3, Far = 5000; Anti-aliasing = No Anti-aliasing; Opaque Texture = Off, Depth Texture = Off; Background Type = Solid Color, Background = black; HDR = Off, MSAA = Off; other properties are as shown below:

Set the Camera component properties of Main Camera under XR Origin (VR)
Step 9: Write code to load the scene
Right-click Create Empty in the hierarchy window (Hierarchy) to create an empty object, name it LCCManager, normalize its Transform, and attach the LCCManager script via Add Component, as shown below:

Create an LCCManager empty object and attach the LCCManager script
Right-click Create Empty in the hierarchy window (Hierarchy) to create another empty object, name it LCCRenderer, and set its Transform Rotation.x = -90, Scale.x = -1, as shown below:

Create an LCCRenderer empty object, and set Rotation.x = -90 and Scale.x = -1 to align the coordinate systems
Rotation.x = -90 and Scale.x = -1 are the alignment transformation from the LCC data coordinate system (Z-up, right-handed) to the Unity coordinate system (Y-up, left-handed); see "LCC data coordinate system" in Unity SDK Introduction.
At this point, the GameObject structure in the hierarchy window (Hierarchy) is as shown below:

The structure of the Hierarchy window
Write a C# script named LCCRenderer.cs with the following code:
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");
}
}
Attach the script to the LCCRenderer GameObject in the hierarchy window (Hierarchy), then drag the LCCManager GameObject to the script's Manager property in the property window (Inspector), and finally fill in the LCC file path.
To make it easy to debug in the Unity Editor and build directly to an Android device, the code uses compile macros to distinguish the runtime environment: in the Unity Editor, directly use the address specified by m_FilePath; on an Android device, use the on-device data source. The way to place the on-device data is:
- Run the built app on the VR device once.
- After the app is installed, enter its data directory (generally Device storage → Android → data → app BundleID → Files; refer to the Android app installation path for the specific directory), and create an
LccDatafolder under the Files subdirectory. - Copy all LCC data sources into the
LccDatafolder.
Note: In practice, it is recommended to place the app's data source on a server rather than packaging it directly into the app.
Optimization Practices
Following the steps above allows LCC data to render normally on the VR device, but there are two main issues:
2D app window display
Apps developed to the OpenXR standard without a device vendor SDK are not necessarily recognized as 3D apps on VR devices; typically the VR device system treats them as 2D apps, so a 2D app window is displayed. There are two approaches to solve this problem:
- Introduce a device vendor SDK or a device vendor OpenXR extension; the device vendor software will then handle the related issues.
- Customize
AndroidManifest.xml.
The specific steps for customizing the Manifest are: select Player on the left of Project Settings, switch to the Android platform, expand the Publishing Settings section, check Custom Main Manifest, which will generate a custom Manifest file, as shown below:

Check Custom Main Manifest to generate a custom Manifest file
Find the AndroidManifest.xml file and add the VR marker so that the VR device recognizes it as a 3D immersive app, and the launched app will be displayed as a 3D space. Example:
<?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>
Stuttering when the rendering frame rate is below 90FPS
The OpenXR standard itself does not define frame interpolation, smoothing or related content; when the frame rate cannot reach 90FPS, there will be a noticeable stuttering feel when rotating the head or moving. To provide a better experience, especially to improve smoothness under limited hardware performance, device vendors usually provide techniques such as tweening, frame interpolation, and smoothing, such as ATW (Asynchronous Time Warp), PTW (Late Stage Reprojection), etc.
If the device supports OpenXR, device vendors usually provide an OpenXR Extension or an SDK that directly supports OpenXR; in this case it is best to introduce the device vendor SDK for a smoother experience.
Related Reference
- For project settings and performance optimization, see the Project Settings Optimization Guide and Render Performance Parameters Guide chapters.
- The VR device's on-screen rendering capability for 3DGS is about 700,000 Gaussian primitives; when rendering large scenes, it is recommended to set StartLOD to
2and disable the environment data display; large scenes will be smoother with PC streaming.