Start · Sprachen · JavaScript · Referenz · XRFrame.session

XRFrame.session

Eigenschaft

Die schreibgeschützte Eigenschaft <code>session</code> liefert das <code>XRSession</code>-Objekt, zu dem der aktuelle <code>XRFrame</code> gehört.

seit JavaScript WebXR Device API – Chromium-Browser (Chrome/Edge 7 Kategorie: webapi

Signatur

XRFrame.session

Beschreibung

Jeder XRFrame wird von genau einer XRSession erzeugt und an den Rückruf von XRSession.requestAnimationFrame() übergeben. Über frame.session erreicht man diese Sitzung direkt, ohne sie in einer äußeren Variablen oder einem Closure speichern zu müssen.

Gebraucht wird das vor allem in der Render-Schleife. Dort muss man den nächsten Frame mit session.requestAnimationFrame() anfordern, auf session.renderState.baseLayer (den XRWebGLLayer mit Framebuffer und Viewports) zugreifen oder Eingabequellen über session.inputSources auslesen. Ein Callback, der nur frame.session verwendet, lässt sich ohne Änderungen für mehrere Sitzungen einsetzen.

Die Eigenschaft ist schreibgeschützt und gibt für einen bestimmten Frame immer dieselbe Sitzung zurück. Man kann die Referenz auch außerhalb des Callbacks behalten, aber die meisten Frame-Methoden wie getViewerPose() oder getPose() funktionieren nur, solange der Frame aktiv ist, also während des Callbacks.

Rückgabewert

Typ
XRSession
Beschreibung
Das XRSession-Objekt, das diesen Frame erzeugt hat.

Beispiele

Render-Schleife ohne globale Sitzungsvariable

const onXRFrame = (time, frame) => {
  const session = frame.session;
  // Nächsten Frame direkt über die Sitzung des Frames anfordern
  session.requestAnimationFrame(onXRFrame);

  const pose = frame.getViewerPose(refSpace);
  if (!pose) return;

  const glLayer = session.renderState.baseLayer;
  gl.bindFramebuffer(gl.FRAMEBUFFER, glLayer.framebuffer);
  for (const view of pose.views) {
    const vp = glLayer.getViewport(view);
    gl.viewport(vp.x, vp.y, vp.width, vp.height);
    // drawScene(view) ...
  }
};

let refSpace;
const gl = document.createElement('canvas').getContext('webgl2', { xrCompatible: true });

const startXR = async () => {
  const session = await navigator.xr.requestSession('immersive-vr');
  session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });
  refSpace = await session.requestReferenceSpace('local');
  session.requestAnimationFrame(onXRFrame);
};

document.querySelector('#vr-button').addEventListener('click', startXR);

Eingabequellen im Frame auswerten

const handleInput = (frame, refSpace) => {
  for (const source of frame.session.inputSources) {
    if (!source.gripSpace) continue;
    const gripPose = frame.getPose(source.gripSpace, refSpace);
    if (gripPose) {
      const { x, y, z } = gripPose.transform.position;
      console.log(`${source.handedness}: ${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`);
    }
  }
};
left: -0.21, 1.05, -0.30 right: 0.24, 1.02, -0.28

Sitzung aus dem Frame heraus beenden

const MAX_DURATION_MS = 60_000;
let startTime = null;

const onXRFrame = (time, frame) => {
  startTime ??= time;
  if (time - startTime > MAX_DURATION_MS) {
    // Keinen weiteren Frame anfordern, Sitzung beenden
    frame.session.end().then(() => console.log('XR-Sitzung beendet'));
    return;
  }
  frame.session.requestAnimationFrame(onXRFrame);
};
XR-Sitzung beendet

// Wichtig · Fallstricke

  • Frame-Gültigkeit: frame.session bleibt auch nach dem Callback abrufbar. Methoden wie getViewerPose() oder getPose() werfen dagegen außerhalb des aktiven Callbacks einen InvalidStateError. Frames sollten deshalb nicht für spätere Nutzung gespeichert werden.
  • Beendete Sitzungen: Nach session.end() oder dem Ereignis end verweist die Eigenschaft weiterhin auf die inzwischen beendete Sitzung. Neue Frames werden dann nicht mehr ausgeliefert.
  • Kompatibilität: WebXR funktioniert nur in einem sicheren Kontext (HTTPS) und ist hauptsächlich in Chromium-Browsern und auf XR-Headsets verfügbar. Vorher mit navigator.xr?.isSessionSupported() prüfen, ob der gewünschte Sitzungsmodus unterstützt wird.
  • Die Eigenschaft ist schreibgeschützt. Eine Zuweisung wird ignoriert bzw. wirft im Strict Mode einen TypeError.