Signatur
Beschreibung
Mit updateRenderState() legst du fest, wie eine XRSession rendert. Die wichtigste Einstellung ist baseLayer. Das ist ein XRWebGLLayer, der den WebGL-Kontext mit dem XR-Gerät verbindet. Solange kein baseLayer (bzw. keine layers) gesetzt ist, liefert die Sitzung keine Frames aus, die sich darstellen lassen. Deshalb rufst du die Methode praktisch immer direkt nach navigator.xr.requestSession() auf.
Die Änderungen gelten nicht sofort. Sie werden als „ausstehender Render-Zustand“ vorgemerkt und erst übernommen, bevor der nächste requestAnimationFrame-Callback der Sitzung ausgeführt wird. Das aktuelle session.renderState zeigt bis dahin noch die alten Werte. Rufst du die Methode mehrmals vor dem nächsten Frame auf, werden die Angaben zusammengeführt. Nicht angegebene Eigenschaften behalten ihren bisherigen Wert.
Außer dem Ziel-Layer kannst du die Clipping-Ebenen (depthNear, depthFar) und bei inline-Sitzungen das vertikale Sichtfeld (inlineVerticalFieldOfView) anpassen. Mit dem WebXR-Layers-Modul kommt die Eigenschaft layers für mehrere Kompositions-Layer hinzu.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $state | XRRenderStateInit | {} | Objekt mit den zu ändernden Eigenschaften:
|
Rückgabewert
undefined). Die Änderungen werden beim nächsten Frame übernommen.Beispiele
Immersive VR-Sitzung mit WebGL-Layer starten
const startVR = async () => {
if (!(await navigator.xr?.isSessionSupported('immersive-vr'))) {
console.log('immersive-vr wird nicht unterstützt');
return;
}
// Muss durch eine Benutzeraktion ausgelöst werden (z. B. Klick)
const session = await navigator.xr.requestSession('immersive-vr');
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2', { xrCompatible: true });
// Ohne baseLayer werden keine Frames gerendert
session.updateRenderState({
baseLayer: new XRWebGLLayer(session, gl)
});
const refSpace = await session.requestReferenceSpace('local');
const onFrame = (time, frame) => {
session.requestAnimationFrame(onFrame);
const layer = session.renderState.baseLayer;
gl.bindFramebuffer(gl.FRAMEBUFFER, layer.framebuffer);
gl.clearColor(0.1, 0.2, 0.3, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// ... Szene pro XRView zeichnen
};
session.requestAnimationFrame(onFrame);
};
document.querySelector('#enter-vr').addEventListener('click', startVR);
Clipping-Ebenen anpassen – Übernahme erst beim nächsten Frame
const setClipping = (session) => {
session.updateRenderState({ depthNear: 0.05, depthFar: 200 });
// Noch der alte Wert
console.log(session.renderState.depthFar);
session.requestAnimationFrame(() => {
// Jetzt gilt der neue Wert
console.log(session.renderState.depthFar);
});
};
Sichtfeld einer Inline-Sitzung ändern (Zoom)
const initInline = async (canvas) => {
const session = await navigator.xr.requestSession('inline');
const gl = canvas.getContext('webgl', { xrCompatible: true });
session.updateRenderState({
baseLayer: new XRWebGLLayer(session, gl),
inlineVerticalFieldOfView: Math.PI / 3 // 60°
});
// Zoom per Mausrad
canvas.addEventListener('wheel', (e) => {
const current = session.renderState.inlineVerticalFieldOfView;
const next = Math.min(Math.max(current + e.deltaY * 0.001, 0.3), 2.5);
session.updateRenderState({ inlineVerticalFieldOfView: next });
});
return session;
};
// Wichtig · Fallstricke
- Ausnahmen:
InvalidStateError, wenn die Sitzung schon beendet ist, wennbaseLayervon einer anderen Sitzung stammt oder wenninlineVerticalFieldOfViewbei einer immersiven Sitzung gesetzt wird.NotSupportedError, wennlayersohne aktivierte Layers-Funktion ('layers'als Feature) verwendet wird.TypeError, wennbaseLayerundlayersgleichzeitig angegeben werden. - Der WebGL-Kontext muss XR-kompatibel sein: Erzeuge ihn mit
{ xrCompatible: true }oder rufe vorherawait gl.makeXRCompatible()auf. Sonst wirft derXRWebGLLayer-Konstruktor einen Fehler. - Lies nach dem Aufruf nicht sofort aus
session.renderState. Die neuen Werte stehen erst im nächsten Frame-Callback bereit. depthNearunddepthFarmüssen zu deiner Projektions- bzw. Tiefenpuffer-Logik passen. Die Projektionsmatrizen inXRView.projectionMatrixwerden aus diesen Werten berechnet.- Kompatibilität: WebXR gibt es nur in sicheren Kontexten (HTTPS). Unterstützt wird es in Chromium-Browsern (Chrome, Edge, Samsung Internet) und im Meta Quest Browser. Firefox und Safari auf dem Desktop unterstützen es nicht. Mit einer Weiche wie
navigator.xr?.isSessionSupported()fängst du fehlende Unterstützung ab.