Signatur
Beschreibung
framebufferWidth gibt die Breite (in Pixeln) des Framebuffers an, den eine XRWebGLLayer für das Rendern einer immersiven oder Inline-Sitzung bereitstellt. Der Framebuffer selbst ist über XRWebGLLayer.framebuffer zugänglich. Bei stereoskopischen Geräten enthält er meist alle Ansichten nebeneinander, also z. B. linkes und rechtes Auge. Die Breite umfasst dann beide Augenbereiche zusammen.
Der Wert hängt von der nativen Auflösung des Geräts und vom Parameter framebufferScaleFactor ab, der beim Erzeugen der Ebene angegeben wird. Nach dem Erzeugen der Ebene bleibt der Wert gleich. Soll sich die Auflösung ändern, musst du eine neue Ebene anlegen und per session.updateRenderState() setzen.
In der Praxis brauchst du framebufferWidth (zusammen mit framebufferHeight) vor allem, um passende Offscreen-Ressourcen anzulegen, etwa Render-Targets für Post-Processing, Tiefen-Texturen oder Multisample-Renderbuffer. Außerdem hilft der Wert beim Debuggen und Protokollieren der tatsächlichen Render-Auflösung. Für das Setzen des Viewports pro Auge verwendest du dagegen XRWebGLLayer.getViewport(view). Die Viewport-Werte beziehen sich auf genau diesen Framebuffer.
Rückgabewert
XRWebGLLayer einer Inline-Sitzung entspricht sie in der Regel der Breite des zugehörigen Canvas (drawingBufferWidth).Beispiele
Framebuffer-Größe nach dem Start einer immersiven Sitzung ausgeben
const startXR = async () => {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2', { xrCompatible: true });
const session = await navigator.xr.requestSession('immersive-vr');
const layer = new XRWebGLLayer(session, gl);
await session.updateRenderState({ baseLayer: layer });
console.log(`Framebuffer: ${layer.framebufferWidth} x ${layer.framebufferHeight} px`);
};
document.querySelector('#vr-button').addEventListener('click', startXR);
Auswirkung von framebufferScaleFactor vergleichen
const compareScales = async (session, gl) => {
const nativeScale = XRWebGLLayer.getNativeFramebufferScaleFactor(session);
const standard = new XRWebGLLayer(session, gl);
const reduced = new XRWebGLLayer(session, gl, { framebufferScaleFactor: 0.5 });
console.log('Native Skalierung:', nativeScale);
console.log('Standard-Breite:', standard.framebufferWidth);
console.log('Halbe Skalierung:', reduced.framebufferWidth);
// Die leistungsschonende Ebene verwenden
await session.updateRenderState({ baseLayer: reduced });
};
Passendes Offscreen-Render-Target für Post-Processing anlegen
const createPostProcessTarget = (gl, layer) => {
const width = layer.framebufferWidth;
const height = layer.framebufferHeight;
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0,
gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
const depth = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depth);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT24, width, height);
const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depth);
console.log(`Render-Target ${width}x${height} erstellt`);
return { fbo, texture };
};
// Wichtig · Fallstricke
- Schreibgeschützt: Eine Zuweisung wie
layer.framebufferWidth = 1024wird ignoriert, im Strict Mode wirft sie einenTypeError. Die Auflösung änderst du nur über eine neue Ebene mit einem anderenframebufferScaleFactor. - Nicht die Breite eines Auges: Bei Stereo-Sitzungen umfasst der Wert meist alle Ansichten. Für den Viewport pro Auge verwendest du immer
layer.getViewport(view). Die Breite halbieren und dabei eine bestimmte Anordnung annehmen ist fehleranfällig. - Keine feste Größe: Der Wert unterscheidet sich je nach Gerät, Browser und Skalierungsfaktor. Der Browser kann den gewünschten Faktor außerdem auf einen erlaubten Bereich begrenzen.
- Leistung: Große Framebuffer kosten viel Füllrate. Auf mobilen Headsets kann ein
framebufferScaleFactorunter 1 die Bildrate spürbar verbessern. - Kompatibilität: WebXR funktioniert nur in sicheren Kontexten (HTTPS). Unterstützt wird es in Chromium-Browsern und im Meta Quest Browser, nicht aber in Firefox und Safari auf dem Desktop. Prüfe die Unterstützung vorher mit
'xr' in navigator. Den WebGL-Kontext erzeugst du mitxrCompatible: trueoder bereitest ihn pergl.makeXRCompatible()vor.