Signatur
Beschreibung
XRCompositionLayer ist die gemeinsame Basis aller Layer, die der XR-Kompositor direkt darstellt: XRProjectionLayer, XRQuadLayer, XRCylinderLayer, XREquirectLayer und XRCubeLayer. Die Schnittstelle erbt von XRLayer und damit von EventTarget. Du kannst sie nicht selbst instanziieren. Konkrete Layer erzeugst du über Fabrikmethoden von XRWebGLBinding (z. B. createQuadLayer()) oder von XRMediaBinding (Video-Layer).
Kompositions-Layer lohnen sich, wenn Inhalte wie Text, Benutzeroberflächen oder Videos schärfer und stromsparender dargestellt werden sollen. Der Kompositor projiziert sie direkt, ohne dass sie vorher in den Projektions-Framebuffer gezeichnet und dabei erneut abgetastet werden. Das Ergebnis ist bessere Bildqualität bei geringerer GPU-Last.
Gemeinsame Mitglieder:
layout(nur lesbar): Aufbau des Layers, z. B."mono","stereo","stereo-left-right","stereo-top-bottom"oder"default".blendTextureSourceAlpha: Legt fest, ob der Alphakanal der Textur beim Überblenden berücksichtigt wird.forceMonoPresentation: Wenn gesetzt, wird ein Stereo-Layer für beide Augen mono dargestellt.opacity: Deckkraft des Layers, von0.0bis1.0.mipLevels(nur lesbar): Anzahl der tatsächlich angelegten Mip-Stufen.needsRedraw(nur lesbar):true, wenn der Layer neu gezeichnet werden muss, etwa weil der Kompositor den Inhalt verworfen hat.destroy(): Gibt die Ressourcen des Layers frei, insbesondere seine Farb- und Tiefentexturen.
Damit du Layer nutzen kannst, forderst du die Sitzung mit dem Feature "layers" an. Die Layer übergibst du anschließend über session.updateRenderState({ layers: [...] }). Die Reihenfolge im Array bestimmt die Stapelreihenfolge: Das erste Element liegt hinten.
Rückgabewert
XRQuadLayer oder XRProjectionLayer.Beispiele
Quad-Layer erzeugen und in den Render-State einhängen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2', { xrCompatible: true });
const session = await navigator.xr.requestSession('immersive-vr', {
requiredFeatures: ['layers']
});
const refSpace = await session.requestReferenceSpace('local');
const binding = new XRWebGLBinding(session, gl);
// Projektions-Layer für die 3D-Szene
const projLayer = binding.createProjectionLayer({ textureType: 'texture' });
// Quad-Layer für ein scharfes UI-Panel (XRQuadLayer erbt von XRCompositionLayer)
const uiLayer = binding.createQuadLayer({
space: refSpace,
viewPixelWidth: 1024,
viewPixelHeight: 512,
layout: 'mono',
transform: new XRRigidTransform({ x: 0, y: 1.5, z: -2 }),
width: 1.0,
height: 0.5
});
console.log(uiLayer instanceof XRCompositionLayer, uiLayer.layout);
// Das erste Element im Array liegt hinten
session.updateRenderState({ layers: [projLayer, uiLayer] });
needsRedraw im Frame-Loop auswerten
// Statischen Inhalt nur zeichnen, wenn der Kompositor es verlangt
const drawUi = (gl, binding, layer, frame) => {
const sub = binding.getSubImage(layer, frame);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, sub.colorTexture, 0);
const { x, y, width, height } = sub.viewport;
gl.viewport(x, y, width, height);
gl.clearColor(0.1, 0.1, 0.3, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(fb);
};
const onFrame = (time, frame) => {
frame.session.requestAnimationFrame(onFrame);
if (uiLayer.needsRedraw) {
drawUi(gl, binding, uiLayer, frame);
}
};
session.requestAnimationFrame(onFrame);
Deckkraft, Alpha-Blending und Aufräumen
// Panel halbtransparent einblenden
uiLayer.blendTextureSourceAlpha = true;
uiLayer.opacity = 0.8;
console.log(`Mip-Stufen: ${uiLayer.mipLevels}`);
// Panel schließen: aus dem Render-State nehmen, dann freigeben
const closePanel = () => {
session.updateRenderState({ layers: [projLayer] });
uiLayer.destroy();
};
session.addEventListener('end', () => {
projLayer.destroy();
});
// Wichtig · Fallstricke
- Kompatibilität: Die WebXR Layers API ist experimentell. Sie läuft vor allem im Meta Quest Browser und in einigen Chromium-Builds. Firefox und Safari unterstützen sie nicht. Prüfe die Verfügbarkeit mit
'XRWebGLBinding' in windowund fordere"layers"nach Möglichkeit alsoptionalFeaturesan, damit du aufXRWebGLLayerzurückfallen kannst. - Kein Konstruktor:
new XRCompositionLayer()wirft einenTypeError. Layer entstehen nur überXRWebGLBindingbzw.XRMediaBinding. - needsRedraw: Wenn der Wert
trueist, musst du den Layer im selben Frame neu zeichnen. Sonst zeigt der Kompositor womöglich leeren oder veralteten Inhalt. Das kann jederzeit passieren, z. B. nach einem Wechsel der Sichtbarkeit. - destroy(): Nach dem Aufruf sind die Texturen ungültig. Nimm den Layer vorher aus
renderState.layers. Ein zerstörter Layer im Render-State führt zu Fehlern. - Grenzen: Geräte begrenzen die Anzahl gleichzeitiger Layer. Die Größe von
mipLevelskann vom Gerät reduziert werden. Verlasse dich deshalb nicht auf den angeforderten Wert. layersundbaseLayerschließen sich im Render-State gegenseitig aus.