Skip to main content

three.js and raw WebXR: @realitycollective/threejs-interactions

The default, standalone adapter. It reads raw WebXR directly, so no other framework is needed beyond three.js itself.

What it binds

LayerDetail
InputRaw WebXR: XRSession input sources, hand joints, trigger and grip pressure through select and squeeze, gamepad analog values where present, haptic pulses
Hit-testingA three.js Raycaster over registered objects, accelerated with three-mesh-bvh when the app installs it
MovementMoves, rotates and scales three.js Object3Ds for grab, hinge, dial, slide and the pulse effect
DesktopA mouse ray cast from the camera through the cursor when no immersive session is live

Install

npm install @realitycollective/threejs-interactions three

Peer dependency: three >= 0.170.0. Optional peer: three-mesh-bvh >= 0.9.14, for accelerated raycasting against detailed meshes.

Setup

import { createThreeInteractions } from "@realitycollective/threejs-interactions";

const interactions = createThreeInteractions({
xr: renderer.xr,
camera,
domElement: renderer.domElement,
desktopGripDistance: 0.95,
});

interactions.register({ id: "button", behaviours: [{ kind: "press" }] }, buttonMesh);

What it adds over the core

It is the only adapter with no framework requirement beyond three.js itself, and the only one with a registerVisual presence API, because a standalone three.js app builds its own hand and controller models.

What it cannot do on this host, and why

It cannot show or hide a hand or controller visual until the app hands one over with registerVisual; there is nothing built in to hide. It also cannot resolve a detailed mesh's raycast quickly without three-mesh-bvh installed; without it, register a low-poly collider proxy instead of the visible mesh.

Presence and haptics

registerVisual(handedness, root) and unregisterVisual(handedness) register or remove the app's own models; capabilities.presence is false until the first one is registered. Haptics fire through the browser's actuator API on sources that report hapticsAvailable; hands have none, so a pulse aimed at a hand source no-ops.

Testing it

The adapter's suite runs against a fake XRSession and WebXRManager, so its targeting and transform-write logic is exercised without a real headset or a WebGL context.

Live demo

webxr-interactions.pages.dev, mouse-capable on desktop, with a VR button for headsets.

More information