Signatur
Beschreibung
createQuadLayer() gehört zur XRMediaBinding-Schnittstelle der WebXR Layers API. Die Methode verknüpft ein <video>-Element direkt mit einer Kompositionsschicht vom Typ XRQuadLayer. Der Browser holt die Videobilder selbst und setzt sie in die Szene ein. Du musst die Frames also nicht in jedem Durchlauf per WebGL in eine Textur hochladen.
Sinnvoll ist das für virtuelle Kinoleinwände, Videotafeln, Tutorials oder UI-Panels mit Video in immersiven Sitzungen. Weil der Compositor die Schicht direkt zeichnet, wird das Bild schärfer und es gibt weniger Artefakte durch doppeltes Resampling. Das gilt vor allem für Text und fein aufgelöste Inhalte. Außerdem spart es Rechenzeit auf der GPU.
Die erzeugte Schicht erscheint erst, wenn du sie in das Array layers von XRSession.updateRenderState() einträgst. Position und Ausrichtung ergeben sich aus space und transform. Die Größe in Metern legst du mit width und height fest. Stereoskopische Videos (Seite an Seite oder übereinander) lassen sich über layout richtig auf beide Augen verteilen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $video Pflicht | HTMLVideoElement | Das Videoelement, dessen Bilder in der Schicht gezeigt werden. | |
| $options Pflicht | Object | Konfigurationsobjekt mit den folgenden Eigenschaften. | |
| $options.space Pflicht | XRSpace | Referenzraum, in dem die Schicht liegt, z. B. aus session.requestReferenceSpace('local'). |
|
| $options.transform | XRRigidTransform | Identität | Position und Ausrichtung der Schicht relativ zu space. |
| $options.width | number | abhängig vom Seitenverhältnis | Breite der Fläche in Metern. Fehlen width und height, wird die Größe aus dem Seitenverhältnis des Videos berechnet. |
| $options.height | number | abhängig vom Seitenverhältnis | Höhe der Fläche in Metern. |
| $options.layout | "mono" | "stereo" | "stereo-left-right" | "stereo-top-bottom" | "mono" | Gibt an, wie das Video auf die Augen verteilt wird. Für Stereo-Videos nimmst du "stereo-left-right" (Bilder nebeneinander) oder "stereo-top-bottom" (Bilder übereinander). |
| $options.invertStereo | boolean | false | Vertauscht die Bilder für das linke und das rechte Auge, falls die Quelle sie andersherum ablegt. |
Rückgabewert
XRQuadLayer, die an das Video gebunden ist. Du fügst sie über updateRenderState({ layers }) der Sitzung hinzu.Beispiele
Virtuelle Leinwand vor dem Nutzer
const startCinema = async () => {
const session = await navigator.xr.requestSession('immersive-vr', {
requiredFeatures: ['layers']
});
const refSpace = await session.requestReferenceSpace('local');
const video = document.createElement('video');
video.src = 'trailer.mp4';
video.crossOrigin = 'anonymous';
await video.play();
const binding = new XRMediaBinding(session);
const screen = binding.createQuadLayer(video, {
space: refSpace,
width: 3.2,
height: 1.8,
// 3 m vor dem Nutzer, auf Augenhöhe
transform: new XRRigidTransform({ x: 0, y: 1.6, z: -3 })
});
session.updateRenderState({ layers: [screen] });
console.log(screen.width, screen.height);
};
document.querySelector('#vr-btn').addEventListener('click', startCinema);
Stereo-3D-Video (Seite an Seite) mit WebGL-Szene kombinieren
const setupLayers = async (session, gl, refSpace, video) => {
const glBinding = new XRWebGLBinding(session, gl);
const projection = glBinding.createProjectionLayer({ textureType: 'texture' });
const mediaBinding = new XRMediaBinding(session);
const quad = mediaBinding.createQuadLayer(video, {
space: refSpace,
layout: 'stereo-left-right',
width: 2,
height: 1.125,
transform: new XRRigidTransform({ x: 0, y: 1.5, z: -2.5 })
});
// Reihenfolge = Zeichenreihenfolge: die Szene zuerst, das Video darüber
session.updateRenderState({ layers: [projection, quad] });
return quad;
};
Unterstützung prüfen, bevor du die Schicht erzeugst
const supportsMediaLayers = () =>
'XRMediaBinding' in window &&
typeof XRMediaBinding.prototype.createQuadLayer === 'function';
console.log(supportsMediaLayers() ? 'Media-Layer verfügbar' : 'Fallback: Video als WebGL-Textur');
// Wichtig · Fallstricke
- Eingeschränkte Unterstützung: Die Methode ist experimentell und praktisch nur in Chromium-basierten XR-Browsern verfügbar, etwa im Meta Quest Browser. Firefox und Safari unterstützen sie nicht. Baue immer eine Merkmalserkennung und einen Fallback über eine WebGL-Textur ein.
- Die Sitzung muss immersiv sein und mit dem Feature
'layers'angefordert werden. Sonst oder nach dem Ende der Sitzung wird einInvalidStateErrorgeworfen. - Videos von anderen Ursprüngen brauchen korrekte CORS-Header und
crossOrigin. Andernfalls können die Frames nicht verwendet werden. - Die Schicht startet die Wiedergabe nicht selbst. Autoplay-Regeln gelten weiterhin, also rufe
video.play()nach einer Nutzeraktion auf. - Eine erzeugte Schicht ist unsichtbar, solange sie nicht in
updateRenderState({ layers })steht. Die Reihenfolge im Array bestimmt, welche Schicht über welcher liegt.