Prompt any real-world location and travel through time — explore it in the 1920s, present day, and a speculative future, all in immersive WebXR. The pipeline extracts Google Street View tiles, transforms them across time periods using Gemini Imagen, upscales with FLUX.2, and generates navigable 3D Gaussian splat worlds via World Labs.
This demo focuses on the San Francisco Ferry Building.
Built for Meta Quest 3 and Pico headsets. Also works in any WebXR-capable browser with the included headset simulator.
DEMO_TIMEMACHINE_small.mp4
| Past (1920s) | Present | Future (2150) |
|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Three Gaussian splat worlds (generated via World Labs Marble) are loaded into a WebXR scene using SparkJS and IWSDK. A spatial UI panel lets you switch between eras with animated fly-in/fly-out transitions.
| Era | Description |
|---|---|
| 1920s | Cobblestone streets, Model Ts, gas lamps, hand-painted storefronts |
| Present | San Francisco Ferry Building as it looks today |
| Future | Flying vehicles, holographic displays, vertical gardens, smart roads |
git clone git@github.com:chloepilonv/timemachine_webxr.git
cd timemachine_webxr
npm installThe Gaussian splat files are too large for git (~20-30 MB each). Download them into public/splats/ before running.
- Open each world in your browser:
- Click the download/export button on each world (SPZ format, OpenGL coordinates, Ground level)
- Rename and move:
cp "San Francisco Ferry Building Scene.spz" public/splats/present.spz
cp "San Francisco Ferry Building Scene_collider.glb" public/splats/present-collider.glb
cp "Historic City Street Clock Tower.spz" public/splats/past.spz
cp "Futuristic San Francisco Plaza.spz" public/splats/future.spzDownload wormhole.mp4 from the Google Drive assets folder and place it in public/.
npm run devOpens at https://localhost:8081/.
WebXR requires HTTPS on non-localhost origins. The dev server uses local certs via mkcert:
brew install mkcert
mkcert -install
mkcert -key-file .key.pem -cert-file .cert.pem localhost 127.0.0.1 $(ipconfig getifaddr en0) 0.0.0.0| Button | Action |
|---|---|
| A (right) | Next era |
| B (right) | Previous era |
| X (left) | Toggle talk to AI agent |
| Grip/Squeeze (either) | Push-to-talk (hold) |
| Trigger | Select / interact |
| Thumbstick | Teleport locomotion |
Location (URL / coords / place name)
|
v
[1] extract_tiles.py --> tiles_present/ (6 perspective tiles from Street View)
|
v
[2a] generate_past.py --> tiles_past/ (1920s via Gemini)
[2b] generate_future.py --> tiles_future/ (2150 via Gemini)
|
v
[3] create_world.py --> World Labs 3D world (navigable Gaussian splat)
pip install httpx python-dotenv pillowCreate a .env file:
GOOGLE_API_KEY=... # Places API + Map Tiles API + Street View
GEMINI_API_KEY=... # Gemini 3 Pro (image editing)
WORLDLABS_API_KEY=... # World Labs Marble API
python scripts/extract_tiles.py "Ferry Building, San Francisco" --tiles 6
python scripts/generate_past.py
python scripts/generate_future.py
python scripts/create_world.py image tiles_future/future_tile1_ferry_front.png- IWSDK — WebXR ECS framework
- SparkJS 2.0 — Gaussian splat renderer
- World Labs Marble — AI-generated 3D worlds from images
- Convai — Voice AI agent
- Vite — Build tooling
- sensai-webxr-worldmodels — Original template






