Start · Sprachen · JavaScript · Referenz · XRReferenceSpace

XRReferenceSpace

Schnittstelle

Beschreibt ein Koordinatensystem der WebXR Device API, in dem Posen von Betrachter, Controllern und Objekten relativ zu einem festen Ursprung angegeben werden.

seit JavaScript WebXR Device API – Chromium-Browser 79+, Meta Ques Kategorie: webapi

Signatur

interface XRReferenceSpace extends XRSpace

Beschreibung

XRReferenceSpace ist ein Interface der WebXR Device API. Es erweitert XRSpace und legt fest, wo der Ursprung liegt und wie die Achsen ausgerichtet sind, wenn der Browser Posen (Position und Ausrichtung) des Nutzers oder von Eingabegeräten berechnet. Eine Instanz bekommt man nicht über einen Konstruktor, sondern asynchron über XRSession.requestReferenceSpace(type).

Der Typ des Referenzraums bestimmt, wie sich das Koordinatensystem verhält:

  • "viewer" – Ursprung am Kopf bzw. Gerät des Nutzers, bewegt sich mit (immer verfügbar).
  • "local" – Ursprung nahe der Startposition des Betrachters, gut für sitzende Erlebnisse.
  • "local-floor" – wie local, aber mit y = 0 auf Bodenhöhe.
  • "bounded-floor" – Raum mit festen Grenzen (liefert ein XRBoundedReferenceSpace mit boundsGeometry).
  • "unbounded" – für Erlebnisse, bei denen sich der Nutzer frei über große Entfernungen bewegt (z. B. AR im Freien).

Das Interface stellt die Methode getOffsetReferenceSpace(originOffset) bereit, mit der man einen neuen, verschobenen/gedrehten Referenzraum ableitet – typisch für Teleportation oder Drehung per Controller-Stick. Außerdem feuert das Ereignis reset, wenn das System den Ursprung neu festlegt (z. B. nach Tracking-Verlust oder „Neu zentrieren“ durch den Nutzer).

In jeder Frame-Schleife übergibt man den Referenzraum an XRFrame.getViewerPose() oder XRFrame.getPose(), um die aktuellen Posen im gewählten Koordinatensystem zu erhalten.

Parameter

Name Typ Default Beschreibung
$originOffset Pflicht XRRigidTransform Parameter von getOffsetReferenceSpace(): Transformation (Position + Orientierung), um die der neue Referenzraum gegenüber dem aktuellen verschoben bzw. gedreht wird.

Beispiele

Referenzraum anfordern und in der Render-Schleife nutzen

const startXR = async () => {
  const session = await navigator.xr.requestSession('immersive-vr', {
    requiredFeatures: ['local-floor']
  });

  // Referenzraum mit Boden bei y = 0
  const refSpace = await session.requestReferenceSpace('local-floor');

  const onFrame = (time, frame) => {
    const pose = frame.getViewerPose(refSpace);
    if (pose) {
      const { x, y, z } = pose.transform.position;
      console.log(`Kopfposition: ${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`);
    }
    session.requestAnimationFrame(onFrame);
  };
  session.requestAnimationFrame(onFrame);
};

document.querySelector('#vr-button').addEventListener('click', startXR);
Kopfposition: 0.03, 1.68, -0.12

Fallback, wenn 'local-floor' nicht unterstützt wird

const getRefSpace = async (session) => {
  try {
    return await session.requestReferenceSpace('local-floor');
  } catch (err) {
    console.warn('local-floor nicht verfügbar, nutze local:', err.name);
    const local = await session.requestReferenceSpace('local');
    // Boden grob simulieren: Ursprung 1,6 m nach unten verschieben
    return local.getOffsetReferenceSpace(
      new XRRigidTransform({ x: 0, y: -1.6, z: 0 })
    );
  }
};
local-floor nicht verfügbar, nutze local: NotSupportedError

Teleportation mit getOffsetReferenceSpace()

let refSpace; // wird beim Sessionstart gesetzt

const teleportTo = (target) => {
  // Der Welt-Ursprung wird entgegengesetzt verschoben,
  // damit der Nutzer an 'target' erscheint
  const offset = new XRRigidTransform({ x: -target.x, y: 0, z: -target.z });
  refSpace = refSpace.getOffsetReferenceSpace(offset);
};

// Beispiel: 2 m nach vorne teleportieren
teleportTo({ x: 0, z: -2 });

Auf das reset-Ereignis reagieren

const handleReset = (event) => {
  console.log('Ursprung wurde zurückgesetzt');
  if (event.transform) {
    console.log('Versatz zum alten Ursprung:', event.transform.position);
  }
  // z. B. Szene neu ausrichten oder Teleport-Offset verwerfen
};

refSpace.addEventListener('reset', handleReset);
// Alternativ: refSpace.onreset = handleReset;

// Beim Beenden aufräumen
session.addEventListener('end', () => {
  refSpace.removeEventListener('reset', handleReset);
});
Ursprung wurde zurückgesetzt

// Wichtig · Fallstricke

  • Kein Konstruktor: new XRReferenceSpace() wirft einen TypeError. Instanzen gibt es nur über XRSession.requestReferenceSpace() oder getOffsetReferenceSpace().
  • Feature-Anforderung: Außer viewer und (bei immersiven Sessions) local müssen Typen wie local-floor, bounded-floor oder unbounded in requiredFeatures/optionalFeatures von requestSession() angegeben werden, sonst wird das Promise mit NotSupportedError abgelehnt.
  • Offsets sind unveränderlich: getOffsetReferenceSpace() ändert den bestehenden Raum nicht, sondern gibt einen neuen zurück – die Referenz im Code muss also ersetzt werden. Offsets addieren sich bei wiederholtem Aufruf.
  • Pose kann null sein: Bei Tracking-Verlust liefert getViewerPose() null; immer prüfen.
  • Sicherer Kontext: WebXR funktioniert nur über HTTPS (oder localhost) und erfordert eine Nutzergeste zum Start einer immersiven Session. Die Permissions-Policy xr-spatial-tracking muss in iframes erlaubt sein.
  • Kompatibilität: Unterstützt in Chromium-basierten Browsern (Chrome/Edge 79+ mit passender Hardware, Android-AR), Meta Quest Browser und Samsung Internet. Firefox und Safari auf dem Desktop unterstützen WebXR nicht; Safari auf Apple Vision Pro nur eingeschränkt. Vorher mit navigator.xr?.isSessionSupported() prüfen.