How to Check if User is in VR with Three.js

This article explains how to determine if a user is actively viewing a Three.js scene inside a VR headset using the WebXR API. You will learn how to access the isPresenting boolean on the Three.js WebXR manager and listen to session changes to dynamically adjust your experience.

In Three.js, WebXR capabilities are managed through the WebXRManager, which is attached directly to the WebGLRenderer instance. To check if a user is currently presenting in virtual reality (or augmented reality), you query the isPresenting boolean property.

Querying the isPresenting Boolean

To check the current state at any given moment—such as inside your animation loop—access the property via the renderer:

const isUserInVR = renderer.xr.isPresenting;

if (isUserInVR) {
    // The user is actively wearing a VR headset and viewing the scene
    console.log("User is in VR mode");
} else {
    // The user is viewing the scene on a flat screen (desktop/mobile)
    console.log("User is in normal desktop/mobile mode");
}

Listening to Session Events

While you can query renderer.xr.isPresenting at any time, it is highly recommended to listen for session events. This allows you to execute code immediately when a user enters or exits VR, rather than checking the boolean on every frame.

Three.js fires sessionstart and sessionend events on the WebXRManager object:

// Triggered when the user enters VR
renderer.xr.addEventListener('sessionstart', () => {
    console.log("VR Session started. isPresenting:", renderer.xr.isPresenting); // Outputs: true
    // Put your VR-specific setup code here (e.g., hiding 2D UI)
});

// Triggered when the user exits VR
renderer.xr.addEventListener('sessionend', () => {
    console.log("VR Session ended. isPresenting:", renderer.xr.isPresenting); // Outputs: false
    // Put your desktop fallback code here (e.g., restoring 2D UI)
});

Use Cases for isPresenting

Checking this boolean is crucial for: * UI Adaptation: Hiding traditional HTML overlays (which do not render in VR) and enabling 3D user interfaces. * Performance Optimization: Lowering graphical settings or reducing physics calculations to maintain a consistent 90Hz/120Hz refresh rate inside the headset. * Input Handling: Enabling VR controller scripts and disabling desktop mouse/keyboard controls when the headset is active.