Handle WebXR Session End Event in Three.js
When developing Virtual Reality (VR) or Augmented Reality (AR) experiences with Three.js, properly managing the lifecycle of a WebXR session is crucial for a seamless user experience. This article provides a direct, step-by-step guide on how to listen for and handle the end event of an active WebXR session in Three.js, ensuring your application gracefully transitions back to a standard 2D web interface when a user exits immersive mode.
Method 1: Using the Three.js WebXRManager (Recommended)
Three.js simplifies WebXR management through the
WebXRManager, which is accessible via your WebGL renderer
(renderer.xr). The most straightforward and idiomatic way
to detect when a session ends is to listen for the
sessionend event directly on this manager.
// Set up your listener on the WebXRManager
renderer.xr.addEventListener('sessionend', onSessionEnd);
function onSessionEnd() {
console.log('The WebXR session has ended.');
// 1. Re-enable standard screen controls (e.g., OrbitControls)
controls.enabled = true;
// 2. Show HTML UI elements hidden during VR/AR
document.getElementById('ui-overlay').style.display = 'block';
// 3. Reset camera positions if necessary
camera.position.set(0, 1.6, 3);
}This method is highly recommended because Three.js internally manages the lifecycle binding, ensuring that your callback fires reliably regardless of how the session was terminated (e.g., user exiting via headset UI, browser crash, or programmatically).
Method 2: Listening to the Native WebXR Session Event
If your application requires access to the raw WebXR session object,
you can listen to the native end event. To do this, you
first listen for the Three.js sessionstart event to
retrieve the native session, and then attach an event listener to
it.
renderer.xr.addEventListener('sessionstart', () => {
// Retrieve the active native WebXR session
const session = renderer.xr.getSession();
// Listen for the native 'end' event
session.addEventListener('end', () => {
console.log('Native WebXR session terminated.');
// Perform native WebXR cleanup here
});
});This approach is useful if you are integrating custom WebXR APIs or
external libraries alongside Three.js that require direct interaction
with the XRSession object.
Essential Cleanup Actions on Session End
When a WebXR session ends, the browser stops rendering to the headset and resumes rendering to the standard 2D canvas. To prevent visual glitches or broken controls, you should perform these actions inside your event handler:
- Re-enable 2D Controls: If you disabled camera
controllers like
OrbitControlsorPointerLockControlsduring the XR session, turn them back on. - Toggle HTML Overlays: Bring back any 2D buttons, navigation bars, or textual overlays that were hidden during the immersive experience.
- Reset Camera Transform: Immersive sessions modify the Three.js camera matrix based on headset tracking. Resetting the camera’s position and rotation ensures your 2D fallback view behaves predictably.