WebXR Demos and Examples
Basic scene
This is a step-by-step guide on how to add XR features to a basic scene
Basic Scene with XR Support
Here we just add an environment, a sphere, and XR support
const xrHelper = await scene.createDefaultXRExperienceAsync();
Adding teleportation
To get teleportation enabled, we want to provide the experience helper with an array of floor meshes:
const xrHelper = await scene.createDefaultXRExperienceAsync({// define floor meshesfloorMeshes: [environment.ground]});
Adding a color picker to the basic scene
Add a color picker (from our GUI library) and use it to change the sphere's color.
Notice that no changes were made in the XR code, and that the scene works perfectly well outside VR as well.
// GUIvar plane = BABYLON.Mesh.CreatePlane("plane", 1);plane.position = new BABYLON.Vector3(1.4, 1.5, 0.4)var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh(plane);var panel = new BABYLON.GUI.StackPanel();advancedTexture.addControl(panel);var header = new BABYLON.GUI.TextBlock();header.text = "Color GUI";header.height = "100px";header.color = "white";header.textHorizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;header.fontSize = "120"panel.addControl(header);var picker = new BABYLON.GUI.ColorPicker();picker.value = sphere.material.diffuseColor;picker.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;picker.height = "350px";picker.width = "350px";picker.onValueChangedObservable.add(function(value) {sphere.material.diffuseColor.copyFrom(value);});panel.addControl(picker);
Other demos
Goalkeeper TrainingPhysics PlaygroundBabylon.js scenes with XR support
MansionHill ValleyEspilitWebXR with Vite
Step-by-step project setup using Vite and Babylon.js ES6 modules for WebXR development.
Install Vite
## Setup vitenpm create vite@latest##> Project name: babylon-webxr-test##> Select a framework: vanilla##> Select a variant: vanilla-ts
Install @babylonjs ES6 packages
npm install @babylonjs/core@^5.0.0-beta.8npm install @babylonjs/loaders@^5.0.0-beta.8
Enable HTTPS dev server
HTTPS is required by most VR devices. Create or modify vite.config.ts
:
import { defineConfig } from 'vite'// https://vitejs.dev/config/export default defineConfig({server: {port: 3443,https: true,// Uncomment to allow access from network// (or use `npm run dev -- -- host=0.0.0.0`)//host: '0.0.0.0',},})
Setup a basic WebXR scene
Modify main.ts
:
import './style.css'import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera.js'import { Color3 } from '@babylonjs/core/Maths/math.color.js'import { Engine } from '@babylonjs/core/Engines/engine.js'import { EnvironmentHelper } from '@babylonjs/core/Helpers/environmentHelper.js'import { HemisphericLight } from '@babylonjs/core/Lights/hemisphericLight.js'import { Mesh } from '@babylonjs/core/Meshes/mesh'import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder.js'import { Scene } from '@babylonjs/core/scene.js'import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial.js'import { Vector3 } from '@babylonjs/core/Maths/math.vector.js'import { WebXRDefaultExperience } from '@babylonjs/core/XR/webXRDefaultExperience.js'// Required for EnvironmentHelperimport '@babylonjs/core/Materials/Textures/Loaders'// Enable GLTF/GLB loader for loading controller models from WebXR Input registryimport '@babylonjs/loaders/glTF'// Without this next import, an error message like this occurs loading controller models:// Build of NodeMaterial failed" error when loading controller model// Uncaught (in promise) Build of NodeMaterial failed: input rgba from block// FragmentOutput[FragmentOutputBlock] is not connected and is not optional.import '@babylonjs/core/Materials/Node/Blocks'// Create a canvas element for renderingconst app = document.querySelector<HTMLDivElement>('#app')const canvas = document.createElement('canvas')app?.appendChild(canvas)// Create engine and a sceneconst babylonEngine = new Engine(canvas, true)const scene = new Scene(babylonEngine)// Add a basic lightnew HemisphericLight('light1', new Vector3(0, 2, 0), scene)// Create a default environment (skybox, ground mesh, etc)const envHelper = new EnvironmentHelper({skyboxSize: 30,groundColor: new Color3(0.5, 0.5, 0.5),}, scene)// Add a camera for the non-VR view in browserconst camera = new ArcRotateCamera("Camera", -(Math.PI / 4) * 3, Math.PI / 4, 10, new Vector3(0, 0, 0), scene);camera.attachControl(true)// Add a sphere to have something to look atconst sphereD = 1.0const sphere = MeshBuilder.CreateSphere('xSphere', { segments: 16, diameter: sphereD }, scene)sphere.position.x = 0sphere.position.y = sphereD * 2sphere.position.z = 0const rMat = new StandardMaterial("matR", scene)rMat.diffuseColor = new Color3(1.0, 0, 0)sphere.material = rMat// Setup default WebXR experience// Use the enviroment floor to enable teleportationWebXRDefaultExperience.CreateAsync(scene, {floorMeshes: [envHelper?.ground as Mesh],optionalFeatures: true,})// Run render loopbabylonEngine.runRenderLoop(() => {scene.render()})
Corresponding git repo: kaliatech/babylon-docs-vite-webxr
Run server and verify
Start vite dev server and make it accessible from the network:
npm run dev -- --host 0.0.0.0
Browsing to https://<your-server-ip>:3443
on a desktop machine should show the basic scene. If
the WebXR API Emulator is enabled, you
should also see Babylon.js's default VR headset mode icon
If viewing from within a headset, the controller models should correspond to what is available in the global registry for your device.
To check TypeScript types and build:
npm run build
Using the setup above, vite reports a vendor.js size of ~2.4MB (520k gzipped) as of babylon-5.0.0-beta.8.