Start · Sprachen · JavaScript · Referenz · XRSession.renderState

XRSession.renderState

Eigenschaft

Liefert das aktuell gültige <code>XRRenderState</code>-Objekt einer XR-Sitzung mit Einstellungen wie Tiefenbereich, Sichtfeld und Ziel-Layer.

seit JavaScript WebXR Device API (Chrome/Edge 79+, Samsung Interne Kategorie: webapi

Signatur

XRSession.renderState

Beschreibung

Die schreibgeschützte Eigenschaft renderState eines XRSession-Objekts gibt ein XRRenderState-Objekt zurück. Es beschreibt, wie die Szene für die Sitzung gerendert wird: depthNear und depthFar (Clipping-Ebenen), inlineVerticalFieldOfView (nur bei inline-Sitzungen), baseLayer (ein XRWebGLLayer, in den gezeichnet wird) sowie – mit dem WebXR-Layers-Modul – layers.

Das Objekt selbst ist unveränderlich. Um Werte zu ändern, ruft man XRSession.updateRenderState() mit einem Wörterbuch der neuen Werte auf. Die Änderungen werden nicht sofort übernommen, sondern erst zu Beginn des nächsten Animations-Frames; erst dann gibt renderState ein neues Objekt mit den aktualisierten Werten zurück.

Typischerweise liest man renderState innerhalb des Frame-Callbacks von requestAnimationFrame(), um z. B. an den Framebuffer des baseLayer zu gelangen oder die Projektionsmatrix passend zu den Tiefenwerten zu berechnen.

Rückgabewert

Typ
XRRenderState
Beschreibung
Das aktuell gültige Render-Zustandsobjekt der Sitzung mit den Eigenschaften baseLayer, depthNear, depthFar, inlineVerticalFieldOfView und ggf. layers.

Beispiele

Sitzung starten und baseLayer setzen

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

const startXR = async () => {
  const session = await navigator.xr.requestSession('immersive-vr');
  // Neuen Render-Zustand anfordern
  session.updateRenderState({
    baseLayer: new XRWebGLLayer(session, gl),
    depthNear: 0.1,
    depthFar: 100
  });

  // Direkt danach ist der alte Zustand noch aktiv
  console.log(session.renderState.baseLayer); // null

  const refSpace = await session.requestReferenceSpace('local');
  session.requestAnimationFrame((time, frame) => {
    // Jetzt ist der neue Zustand übernommen
    console.log(session.renderState.depthNear, session.renderState.depthFar);
  });
};

document.querySelector('#enter-vr').addEventListener('click', startXR);
null 0.1 100

Framebuffer im Render-Loop verwenden

const onXRFrame = (time, frame) => {
  const session = frame.session;
  session.requestAnimationFrame(onXRFrame);

  const { baseLayer } = session.renderState;
  gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);
  gl.clearColor(0, 0, 0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

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

  for (const view of pose.views) {
    const vp = baseLayer.getViewport(view);
    gl.viewport(vp.x, vp.y, vp.width, vp.height);
    // drawScene(view.projectionMatrix, view.transform.inverse.matrix);
  }
};

Sichtfeld einer Inline-Sitzung auslesen

const session = await navigator.xr.requestSession('inline');
session.updateRenderState({
  baseLayer: new XRWebGLLayer(session, gl),
  inlineVerticalFieldOfView: Math.PI / 3
});

session.requestAnimationFrame(() => {
  const fovGrad = session.renderState.inlineVerticalFieldOfView * 180 / Math.PI;
  console.log(`Vertikales Sichtfeld: ${fovGrad.toFixed(0)}°`);
});
Vertikales Sichtfeld: 60°

// Wichtig · Fallstricke

  • Verzögerte Übernahme: Nach updateRenderState() liefert renderState bis zum nächsten Frame noch den alten Zustand. Verlass dich also nicht darauf, dass die Werte direkt danach schon übernommen sind.
  • Zu Beginn einer Sitzung ist baseLayer null. Solange kein Layer gesetzt ist, werden keine Frame-Callbacks ausgeführt.
  • Bei immersiven Sitzungen ist inlineVerticalFieldOfView null. Wenn du den Wert dort per updateRenderState() setzt, wird ein InvalidStateError ausgelöst.
  • Speichere das Objekt nicht dauerhaft zwischen. Frag session.renderState in jedem Frame neu ab, weil nach jeder Änderung ein neues Objekt entsteht.
  • Kompatibilität: WebXR funktioniert nur in sicheren Kontexten (HTTPS) und wird in Chromium-Browsern sowie auf XR-Headsets unterstützt. Firefox und Safari auf dem Desktop unterstützen WebXR nicht. Nach dem Ende der Sitzung (Ereignis end) solltest du den Zustand nicht mehr verwenden.