A Unity package for generating and rendering 3D Gaussian Splatting scenes using the WorldLabs API.
WorldLabs_Unity.mp4
This package combines:
- WorldLabs API Client — Generate 3D scenes from text prompts using WorldLabs' AI
- Gaussian Splatting Renderer — Real-time rendering of 3D Gaussian Splat assets
- Runtime Browser UI — In-game VR/screen-space world browser and creator
- Editor Importer — Unity Editor window for browsing and importing worlds as project assets
The Gaussian Splatting implementation is based on UnityGaussianSplatting, extended with runtime loading, splat layer support, and WorldLabs API integration.
- Unity Version: 6000.2.10f1 (Recommended/Tested)
- Render Pipeline: Universal Render Pipeline (URP) is required
- Dependencies: Burst 1.8.8+, Collections 2.1.4+, Mathematics 1.2.6+ (installed automatically)
- Open Unity and go to Window > Package Manager
- Click the
+button and select Add package from git URL… - Enter:
https://github.com/nigelhartm/worldlabs_unity.git - Click Add
- Obtain an API key from WorldLabs
- Create a
.envfile in the project root (next to theAssets/folder):The key is read at runtime fromWORLDLABS_API_KEY=your_worldlabs_keyStreamingAssets/.env(copied by the build process) and in the Editor from the project root.
Troubleshooting: If the key does not load, open Window > WorldLabs > WorldLabsUnityIntegration > Settings and click Reload API Key.
D3D11 is NOT supported. Go to Project Settings > Player > Other Settings > Graphics APIs and use:
- Windows: D3D12 or Vulkan
- Mac: Metal
- Linux / Android (Meta Quest, Pico): Vulkan
Meta Quest Warning: Adding a Camera Rig from "Meta Building Blocks" may automatically force the project to D3D11. Switch it back to Vulkan manually and ignore the Meta Quest Project Setup Tool warning about this change.
- Locate your active URP Renderer Data asset (usually in
Assets/Settings/) - Click Add Renderer Feature and select GaussianSplatURPFeature
- Recommended mobile/XR settings:
- Depth Texture: On
- HDR: On
- MSAA: Off (Disabled)
- Go to Project Settings > Graphics
- Enable the checkbox: Compatibility Mode (Render Graph disabled)
If building for VR:
- Go to Project Settings > XR Plugin Management > OpenXR
- Change Render Mode from Single Pass Instanced to Multi-pass
These two components provide a fully in-game, API-connected world browser and loader — useful for VR builds or any runtime scene.
- In the Package Manager select WorldLabs Gaussian Splatting → Samples → Sensai Sample → Import
- The import adds:
sensai.asset— a pre-processed Gaussian Splat you can use as a default placeholderPrefabs/WorldLabs_GUI.prefab— a ready-wired prefab with both components
- Drag
WorldLabs_GUI.prefabinto your scene - Select the prefab instance, and assign
sensai.assetto World Manager → Default Asset - Enter Play Mode — the browser canvas appears and connects to your WorldLabs account
Add both components to the same GameObject:
| Component | Purpose |
|---|---|
WorldLabsWorldManager |
Downloads, processes, and renders worlds at runtime |
WorldBrowserController |
Builds a world-space Canvas UI for browsing and loading worlds |
WorldBrowserController requires WorldLabsWorldManager on the same GameObject (enforced by [RequireComponent]).
[Screenshot — WorldLabsWorldManager Inspector]
| Field | Description |
|---|---|
| Quality | GPU memory / fidelity tradeoff: VeryHigh → VeryLow |
| Preferred Resolution | SPZ resolution: FullRes, 500k (default), 100k |
| World Parent | Transform that spawned GameObjects are parented to (defaults to self) |
| Default Asset | Optional GaussianSplatAsset shown on Start and as a loading placeholder. Assign sensai.asset from the sample. |
| Default Asset Inverted | Apply −180° X rotation (required for WorldLabs worlds) |
Shaders and compute shaders are auto-assigned from the package path on reset and at runtime — no manual drag-and-drop needed.
[Screenshot — WorldBrowserController Inspector]
| Field | Description |
|---|---|
| World Manager | Auto-resolved from the same GameObject |
| Creation Model | Model for text-prompt generation: Plus (quality) or Mini (speed) |
| Canvas Pixel Size | Size of the auto-built world-space Canvas (default 420 × 600 px) |
| Columns | Card columns in the world grid (default 2) |
The full UI hierarchy (Canvas, scroll view, buttons, create panel) is auto-built at Awake when not pre-wired. Use the sample prefab and adjust there for a custom layout.
UI Features:
- Paginated grid of your WorldLabs worlds with panorama thumbnails
- Tap a card to load the world; tap again to unload it
- ➕ Create button opens a text-prompt panel to generate new worlds inline
- Progress bar and status text during download and generation
WorldLabsWorldManager and WorldBrowserController are runtime-only components that stream worlds on demand from the API. They do not create project assets.
For importing worlds into your project as Unity assets, use the Editor window:
Window → WorldLabs → WorldLabsUnityIntegration
This opens WorldLabsEditorWindow, which lets you:
- Browse and filter your WorldLabs worlds
- Generate worlds from text, image URL, image file, or video URL
- Import worlds as
GaussianSplatAssetfiles with resolution and compression quality options - Load imported assets directly into the active scene
You can drive WorldLabsWorldManager entirely from code without WorldBrowserController.
using System.Collections.Generic;
using UnityEngine;
using WorldLabs.API;
using WorldLabs.Runtime;
public class MyWorldLoader : MonoBehaviour
{
WorldLabsWorldManager _manager;
async void Start()
{
_manager = GetComponent<WorldLabsWorldManager>();
// Subscribe to events
_manager.OnWorldLoaded += (id, r) => Debug.Log($"Loaded: {id}");
_manager.OnWorldLoadFailed += (id, err) => Debug.LogError($"Failed: {err}");
_manager.OnWorldLoadProgress += (id, prog) => Debug.Log($"{id}: {prog:P0}");
// Fetch first page of your worlds
List<World> worlds = await _manager.ListWorldsAsync(pageSize: 10);
if (worlds.Count > 0)
await _manager.LoadWorldAsync(worlds[0]);
}
void Unload(string worldId) => _manager.UnloadWorld(worldId);
void RestoreDefault() => _manager.RestoreDefaultWorld();
}// List worlds (paginated)
List<World> worlds = await manager.ListWorldsAsync(
pageToken: null, // pass manager.LastNextPageToken for next page
pageSize: 20,
status: WorldStatus.SUCCEEDED,
isPublic: null);
// Load a world (download → GPU processing → spawn renderer)
GaussianSplatRenderer r = await manager.LoadWorldAsync(world);
// Unload one world
manager.UnloadWorld(worldId);
// Unload everything and restore the default asset placeholder
manager.RestoreDefaultWorld();
// Unload everything
manager.UnloadAllWorlds();
// Query state
bool loaded = manager.IsWorldLoaded(worldId);
bool loading = manager.IsWorldLoading(worldId);
IReadOnlyList<World> cached = manager.CachedWorlds;
string nextPage = manager.LastNextPageToken; // null = no more pages
// C# events
manager.OnWorldsListed += (List<World> list) => { };
manager.OnWorldLoadStarted += (string id) => { };
manager.OnWorldLoadProgress += (string id, float progress) => { };
manager.OnWorldLoaded += (string id, GaussianSplatRenderer r) => { };
manager.OnWorldLoadFailed += (string id, string error) => { };
manager.OnWorldUnloaded += (string id) => { };Import Sensai Sample via Package Manager to get:
| File | Description |
|---|---|
sensai.asset |
Pre-processed GaussianSplatAsset — assign to Default Asset in WorldLabsWorldManager |
sensai_*.bytes |
Binary splat data referenced by sensai.asset |
Prefabs/WorldLabs_GUI.prefab |
Ready-wired prefab with WorldLabsWorldManager + WorldBrowserController and a world-space Canvas |
- Open Window > WorldLabs > WorldLabsUnityIntegration
- Go to Create World, enter a text prompt (or provide an image/video URL)
- Click Generate — the operation tracks in the My Worlds list
- Once complete, click Import on the world card and choose a resolution
- Add a
GaussianSplatRenderercomponent to a GameObject and assign the imported asset
- Lighting: Gaussian Splat scenes are pre-lit — removing Unity directional lights avoids double-lighting
- Mobile/XR: Keep models at 500k points / Medium Quality for smooth framerates on standalone headsets
| Pipeline | Support |
|---|---|
| Built-in | Full |
| URP | GaussianSplatURPFeature (add to Renderer asset) |
| HDRP | GaussianSplatHDRPPass |
Created as part of the SensAI Hack — Worlds in Action, powered by SensAI Hackademy.
MIT — see LICENSE.md