Yanmi Yu 2025
WebXR enables immersive experiences in virtual and augmented reality within web applications. This tutorial walks through setting up a WebXR scene using Three.js, handling controllers, animating objects with GSAP, and visualizing time-series data through interactive elements. By the end of this tutorial, you will be able to create an interactive VR scene where users can switch between different years and observe animated changes in tree cover data.
Before getting started, ensure that you have the necessary dependencies installed. Three.js provides the 3D graphics framework, GSAP is used for smooth animations, and a local server is required to run WebXR applications properly.
npm install three gsap
WebXR requires a secure context (HTTPS or localhost). You can serve your project locally using:
npx http-server
To create a WebXR experience, you need a scene, camera, and renderer.
Create a scene and camera – This forms the virtual environment.
Set up the WebGL renderer – Responsible for rendering 3D objects.
Add the WebXR button – Enables VR interaction.
Example Code:
import * as THREE from "three";
import { XRButton } from "three/examples/jsm/Addons.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
let renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
document.body.appendChild(XRButton.createButton(renderer));
To interact with objects in WebXR, you need to handle controllers.
Attach controllers to the scene.
Detect button presses to trigger actions.
Example Code:
let controller1 = renderer.xr.getController(0);
let controller2 = renderer.xr.getController(1);
scene.add(controller1, controller2);
controller1.addEventListener("selectstart", () => console.log("Controller 1 activated"));
controller2.addEventListener("selectstart", () => console.log("Controller 2 activated"));
Three.js allows you to add and animate 3D objects dynamically.
Create objects – Define geometry and materials.
Apply animations – Use GSAP for smooth transitions.
Example Code:
import gsap from "gsap";
function createCube() {
let geometry = new THREE.BoxGeometry(1, 1, 1);
let material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
let cube = new THREE.Mesh(geometry, material);
scene.add(cube);
gsap.to(cube.position, { x: 2, duration: 1, yoyo: true, repeat: -1 });
}
createCube();
WebXR supports UI elements like sliders or dropdowns to modify scene parameters.
Create an HTML element (e.g., slider for year selection).
Update scene based on user input.
Example Code:
document.getElementById("yearSlider").addEventListener("input", (event) => {
let selectedYear = event.target.value;
console.log("Year selected:", selectedYear);
});
To enable VR mode, you must start the WebXR session.
Enable XR on the renderer.
Set up the animation loop to keep rendering.
Example Code:
renderer.xr.enabled = true;
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
This tutorial introduced WebXR fundamentals, including setting up a scene, adding controllers, animating objects, handling user input, and enabling VR mode. By combining these elements, you can create immersive interactive experiences in virtual reality.
WebXR development can involve complex interactions, making debugging essential. Here are some best practices:
Check for JavaScript errors using console.log(), console.warn(), and console.error().
Open the browser console (F12 or Ctrl+Shift+I in Chrome) to inspect WebXR errors.
Use navigator.xr to check if WebXR is available:
if (navigator.xr) {
console.log("WebXR is supported");
} else {
console.error("WebXR not supported on this device");
}
If controllers aren’t responding, check navigator.xr.getSession() to ensure they are properly connected.
Use console.log(controller1, controller2) to inspect their state.
Test scene rendering in a regular browser window before entering VR mode to confirm objects load correctly.
Make sure controller event listeners are being triggered correctly:
controller1.addEventListener("selectstart", () => console.log("Controller 1 activated"));
Too many objects or complex animations can slow down performance. Use requestAnimationFrame for efficient rendering.
Reduce polycount in models and textures to improve VR performance.
Chrome’s WebXR emulator extension allows testing VR interactions without needing a headset.
Use performance monitoring tools to track FPS and memory usage in VR:
console.log("FPS:", renderer.info.render.frame);