Complete step-by-step guide for configuring the project in Unity Editor.
- Open Unity Hub
- Click Add → Add project from disk
- Navigate to
/Users/zd/CascadeProjects/xr-vr/GaussianSplatViewer - Select the folder and click Open
- If prompted about Unity version:
- Select Unity 6 (6000.0.x LTS) - download if needed
- Click Open with Unity 6
- Wait for initial import (packages will download automatically)
After opening, you may see console errors. Fix them:
- Go to Window → Package Manager
- Wait for packages to load
- If any packages show errors, click on them and press Update or Repair
- Required packages should include:
- Universal RP (17.0.3+)
- XR Interaction Toolkit (3.0.7+)
- OpenXR Plugin (1.14.0+)
- Meta OpenXR (2.1.0+)
- Burst (1.8.18+)
- Input System (1.11.2+)
- In Package Manager, click + → Add package by name
- Enter:
com.unity.xr.meta-openxr - Click Add
- Go to File → Build Settings
- Select Android in the platform list
- Click Switch Platform (wait for recompile)
- Configure settings:
- Texture Compression: ASTC
- ETC2 fallback: 32-bit
- Click Player Settings (bottom left)
In Edit → Project Settings → Player:
-
Rendering:
- Color Space: Linear
- Auto Graphics API: Unchecked
- Graphics APIs: Remove OpenGLES, keep only Vulkan
-
Identification:
- Package Name:
com.gaussiansplatviewer.quest - Minimum API Level: Android 10.0 (API level 29)
- Target API Level: Automatic (highest installed)
- Package Name:
-
Configuration:
- Scripting Backend: IL2CPP
- API Compatibility Level: .NET Standard 2.1
- Target Architectures: ARM64 only (uncheck ARMv7)
- Allow unsafe Code: Checked
-
Optimization:
- Managed Stripping Level: Low
- Go to Edit → Project Settings → XR Plug-in Management
- Click Install XR Plug-in Management if not installed
- Select Android tab (robot icon)
- Check OpenXR
- A warning will appear - click Fix All if shown
- Under XR Plug-in Management, click OpenXR
- Under Android tab:
- Render Mode: Single Pass Instanced
- Depth Submission Mode: Depth 16 Bit
- Under Interaction Profiles, click + and add:
- Oculus Touch Controller Profile
- Meta Quest Touch Pro Controller Profile
- Under OpenXR Feature Groups, enable:
- Meta Quest Support
- Click the gear icon next to it:
- Target Devices: Quest 3, Quest 2, Quest Pro
- Hand Tracking: Enabled
- System Splash Screen: Enabled
- Still in OpenXR settings, look for red/yellow warnings
- Click Fix All to resolve common issues
- Common fixes:
- "Interaction profile not configured" → Add profiles above
- "Render mode not optimal" → Set to Single Pass Instanced
- Go to Assets → Settings folder
- Right-click → Create → Rendering → URP Asset (with Universal Renderer)
- Name it
URPAsset - A Renderer will be created alongside it
-
Select the URPAsset in Assets/Settings
-
In Inspector, configure:
Rendering:
- Render Scale: 1.0
- Upscaling Filter: Auto
Quality:
- HDR: Unchecked (saves performance on Quest)
- Anti Aliasing (MSAA): 2x or 4x
Lighting:
- Main Light: Per Pixel
- Additional Lights: Disabled (saves performance)
- Cast Shadows: Unchecked
Shadows:
- Max Distance: 0 (disable shadows for performance)
- Go to Edit → Project Settings → Graphics
- Under Scriptable Render Pipeline Settings:
- Drag your
URPAssetinto the slot
- Drag your
- Go to Edit → Project Settings → Quality
- For each quality level, assign the same
URPAsset
- Select the URPAsset_Renderer (the Renderer Data asset)
- In Inspector, scroll to Renderer Features
- Click Add Renderer Feature → Gaussian Splat Renderer Feature
- Configure the feature:
- Render Pass Event: After Rendering Transparents
- Preprocess Shader: Drag
GaussianSplatCompute.compute - Sort Shader: Drag
RadixSort.compute - Splat Material: (create in next step)
- Right-click in Assets → Create → Material
- Name it
GaussianSplatMaterial - In Inspector:
- Change shader to GaussianSplatViewer/GaussianSplat
- Alpha Cutoff: 0.004
- Drag this material into the Renderer Feature's Splat Material slot
- Right-click in Assets → Create → Input Actions
- Name it
VRInputActions - Double-click to open Input Actions editor
Click + next to Action Maps, create XR:
Movement Actions:
| Action Name | Action Type | Control Type | Binding |
|---|---|---|---|
| Move | Value | Vector2 | <XRController>{LeftHand}/thumbstick |
| Turn | Value | Vector2 | <XRController>{RightHand}/thumbstick |
UI Actions:
| Action Name | Action Type | Control Type | Binding |
|---|---|---|---|
| Menu | Button | Button | <XRController>{LeftHand}/menuButton |
| Reset | Button | Button | <XRController>{RightHand}/primaryButton (A button) |
| Select | Button | Button | <XRController>/triggerPressed |
- Click Save Asset
- In the Inspector for VRInputActions, check Generate C# Class
- Click Apply
- File → New Scene → Basic (Built-in)
- File → Save As → Save to
Assets/GaussianSplatViewer/Scenes/MainScene.unity - Delete the default Main Camera and Directional Light
- Go to Tools → Gaussian Splat Viewer → Setup Main Scene
- This creates the basic hierarchy
- Select XR Origin in Hierarchy
- Add Component: XR Origin (XR Rig)
- Camera Floor Offset Object: Drag Camera Offset here
- Camera: Drag Main Camera here
- Origin Base GameObject: Leave as XR Origin itself
- Tracking Origin Mode: Floor
- Select Main Camera under Camera Offset
- Add Component: Tracked Pose Driver
- Tracking Type: Rotation And Position
- Position Input: Center Eye Position
- Rotation Input: Center Eye Rotation
- Ensure Camera has:
- Clear Flags: Solid Color
- Background: Dark gray (0.1, 0.1, 0.15)
- Near Clip: 0.01
- Far Clip: 1000
Left Hand Controller:
- Select Left Hand Controller
- Add Component: XR Controller (Action-based)
- Configure tracking:
- Position Action: Use Reference → Add binding →
<XRController>{LeftHand}/devicePosition - Rotation Action: Use Reference → Add binding →
<XRController>{LeftHand}/deviceRotation
- Position Action: Use Reference → Add binding →
- Add Component: XR Ray Interactor
- Add Component: XR Interactor Line Visual
- Add Component: Line Renderer (for ray visualization)
Right Hand Controller:
- Repeat the same steps with
{RightHand}bindings
- Select XR Origin
- Add Component: Teleportation Provider
- Add Component: XR Interaction Manager (if not present)
- Right-click in Hierarchy → UI → Canvas
- Rename to File Browser Canvas
- Configure Canvas:
- Render Mode: World Space
- Event Camera: Drag Main Camera
- Width: 800, Height: 600
- Set Transform:
- Position: (0, 1.5, 2)
- Scale: (0.002, 0.002, 0.002)
- Select File Browser Canvas
- Add Component: Tracked Device Graphic Raycaster
- Remove the default Graphic Raycaster if present
Background Panel:
- Right-click Canvas → UI → Panel
- Rename to Background
- Set color to dark (0.15, 0.15, 0.2, 0.95)
Header:
- Right-click Background → UI → Text - TextMeshPro
- If prompted, click Import TMP Essentials
- Rename to PathText
- Anchor: Top, Stretch horizontal
- Text: "/sdcard/Download"
- Font Size: 24
- Position: Top of panel
File List (ScrollView):
- Right-click Background → UI → Scroll View
- Rename to FileScrollView
- Anchor: Stretch all
- Set padding from edges (20px top for header)
- Under Scroll View → Viewport → Content:
- Add Component: Vertical Layout Group
- Child Force Expand: Width checked, Height unchecked
- Spacing: 5
File Entry Prefab:
- Right-click Content → UI → Button - TextMeshPro
- Rename to FileEntryPrefab
- Configure:
- Height: 50
- Text: "📁 FolderName"
- Font Size: 20
- Alignment: Left
- Drag to Assets to create prefab
- Delete from scene (it's now a prefab)
Back Button:
- Right-click Background → UI → Button - TextMeshPro
- Rename to BackButton
- Position: Top-left corner
- Text: "← Back"
Close Button:
- Right-click Background → UI → Button - TextMeshPro
- Rename to CloseButton
- Position: Top-right corner
- Text: "✕"
Loading Panel:
- Right-click Background → UI → Panel
- Rename to LoadingPanel
- Add Slider child for progress
- Add Text child for status
- Set panel inactive by default
Status Text:
- Right-click Background → UI → Text - TextMeshPro
- Rename to StatusText
- Position: Bottom of panel
- Text: "Ready"
- Select the File Browser Canvas (or a child object)
- Add Component: VR File Browser
- Assign references:
- Canvas: File Browser Canvas
- Splat Renderer: Gaussian Splat Renderer
- File List Container: Content (under ScrollView)
- File Entry Prefab: Your FileEntryPrefab
- Current Path Text: PathText
- Status Text: StatusText
- Back Button: BackButton
- Close Button: CloseButton
- Loading Slider: The Slider in LoadingPanel
- Loading Panel: LoadingPanel
- Select GaussianSplatViewerApp in Hierarchy
- In Inspector, assign:
- Splat Renderer: Gaussian Splat Renderer object
- VR Rig: XR Origin's VRRigController
- Locomotion: XR Origin's VRLocomotion
- File Browser: The VRFileBrowser component
- Menu Action: Create reference to your Menu input action
- Reset Action: Create reference to your Reset input action
- Select Gaussian Splat Renderer in Hierarchy
- Add Component: Gaussian Splat Renderer (if not present)
- Assign:
- Preprocess Shader: GaussianSplatCompute.compute
- Sort Shader: RadixSort.compute
- Splat Material: GaussianSplatMaterial
- Configure settings:
- Splat Scale: 1.0
- Alpha Cutoff: 0.004
- Max Visible Splats: 400000
- Right-click Hierarchy → Light → Directional Light
- Configure:
- Rotation: (50, -30, 0)
- Intensity: 1.0
- Shadow Type: No Shadows (performance)
- Right-click Hierarchy → UI → Event System
- Remove Standalone Input Module if present
- Add Component: XR UI Input Module
- Create 3D Object → Plane for floor
- Add Component: Teleportation Area
- Configure teleport settings
- Ctrl+S / Cmd+S to save
- Go to File → Build Settings
- Click Add Open Scenes
- Ensure MainScene is in the list with index 0
- Connect Quest 3 via USB cable
- Put on headset and Allow USB debugging when prompted
- In Unity, go to File → Build Settings
- Under Run Device, select your Quest 3
- Click Build (or Build and Run)
- Choose output location (e.g.,
Builds/GaussianSplatViewer.apk) - Wait for build to complete
adb install -r Builds/GaussianSplatViewer.apk- On Quest 3, go to App Library → Unknown Sources
- Find and launch Gaussian Splat Viewer
- Grant storage permissions when prompted
- Copy a PLY file to Quest:
adb push /path/to/your/file.ply /sdcard/Download/
- In app, navigate to Downloads folder
- Select the PLY file
- Wait for loading
- Left Thumbstick: Move
- Right Thumbstick: Turn (snap or smooth)
- Left Menu Button: Toggle file browser
- A Button: Reset view
- Trigger: Select in UI
- Check OpenXR is enabled for Android
- Verify Meta Quest Support feature is enabled
- Check Vulkan is the only Graphics API
- Verify Renderer Feature is added to URP Renderer
- Check compute shaders are assigned
- Verify material uses correct shader
- Check Canvas is World Space
- Verify Tracked Device Graphic Raycaster is added
- Check XR UI Input Module exists
- Reduce Max Visible Splats to 200000
- Disable MSAA
- Lower render scale to 0.8
- Manually grant in Quest Settings → Apps → Gaussian Splat Viewer → Permissions