Start · Sprachen · JavaScript · Referenz · XRMediaBinding.createEquirectLayer()

XRMediaBinding.createEquirectLayer()

Methode

Erzeugt ein <code>XREquirectLayer</code>, das ein equirectangulares Video (z. B. 360°-Video) auf die Innenseite einer Kugel um den Betrachter abbildet.

seit JavaScript WebXR Layers API (experimentell, u. a. Meta Quest Kategorie: webapi

Signatur

XRMediaBinding.prototype.createEquirectLayer(video, options)

Beschreibung

createEquirectLayer() gehört zur XRMediaBinding-Schnittstelle der WebXR Layers API. Die Methode verbindet ein HTMLVideoElement direkt mit einer Kompositionsebene, die das Video als equirectangulare Projektion auf die Innenseite einer Kugel legt. So lassen sich 360°- und 180°-Videos in einer immersiven XR-Sitzung abspielen, ohne dass jeder Videoframe selbst per WebGL in eine Textur kopiert und gerendert werden muss.

Weil der XR-Compositor die Ebene direkt darstellt, sind Bildqualität und Schärfe meist besser als beim Rendern über eine Projektionsebene: Das Video wird nur einmal abgetastet, und Bildrate und Stromverbrauch profitieren davon. Das ist vor allem auf Standalone-Headsets spürbar.

Über das options-Objekt legst du den Referenzraum, die Stereo-Aufteilung des Videos (mono, stereo-left-right, stereo-top-bottom), den Kugelradius und die abgedeckten Winkelbereiche fest. Mit diesen Winkeln kannst du auch Teilkugeln abbilden, etwa bei 180°-VR-Videos. Damit die erzeugte Ebene sichtbar wird, muss sie über XRSession.updateRenderState({ layers: [...] }) in die Ebenenliste der Sitzung aufgenommen werden.

Voraussetzung ist eine immersive Sitzung, die mit dem Feature "layers" angefordert wurde (requiredFeatures oder optionalFeatures).

Parameter

Name Typ Default Beschreibung
$video Pflicht HTMLVideoElement Das Videoelement, dessen Frames in der Ebene angezeigt werden. Die Wiedergabe steuerst du weiter über video.play()/pause().
$options object {} Konfigurationsobjekt (XRMediaEquirectLayerInit) mit den folgenden Eigenschaften.
$options.space Pflicht XRSpace Raum, in dem die Kugel verankert ist, typischerweise ein Referenzraum wie "local". Ohne Angabe wirft die Methode einen Fehler.
$options.layout "mono" | "stereo" | "stereo-left-right" | "stereo-top-bottom" "mono" Anordnung der Bilder für linkes und rechtes Auge innerhalb des Videos.
$options.invertStereo boolean false Vertauscht die Bilder für linkes und rechtes Auge, z. B. bei falsch gemasterten Videos.
$options.transform XRRigidTransform Identität Position und Ausrichtung des Kugelmittelpunkts relativ zu space.
$options.radius number 0 Kugelradius in Metern. 0 bedeutet unendlich groß, die Kugel wirkt also wie eine Umgebung ohne Parallaxe.
$options.centralHorizontalAngle number 6.28318 (2π) Horizontal abgedeckter Winkel in Radiant. Math.PI ergibt z. B. eine 180°-Halbkugel.
$options.upperVerticalAngle number π/2 Oberer vertikaler Grenzwinkel in Radiant.
$options.lowerVerticalAngle number -π/2 Unterer vertikaler Grenzwinkel in Radiant.

Rückgabewert

Typ
XREquirectLayer
Beschreibung
Eine neue XREquirectLayer-Ebene. Ihre Eigenschaften (z. B. radius, transform, centralHorizontalAngle) kannst du auch nach dem Erzeugen noch ändern.

Beispiele

360°-Video in einer immersiven Sitzung abspielen

const video = document.createElement('video');
video.src = '/media/strand-360.mp4';
video.crossOrigin = 'anonymous';
video.loop = true;

const startXR = async () => {
  const session = await navigator.xr.requestSession('immersive-vr', {
    requiredFeatures: ['layers']
  });
  const refSpace = await session.requestReferenceSpace('local');

  const mediaBinding = new XRMediaBinding(session);
  const equirect = mediaBinding.createEquirectLayer(video, {
    space: refSpace,
    layout: 'mono'
  });

  session.updateRenderState({ layers: [equirect] });
  await video.play();
  console.log('Radius:', equirect.radius);
};

document.querySelector('#vr-start').addEventListener('click', startXR);
Radius: 0

180°-Stereo-Video (Side-by-Side) als Halbkugel

const createVR180Layer = (session, refSpace, video) => {
  const binding = new XRMediaBinding(session);
  return binding.createEquirectLayer(video, {
    space: refSpace,
    layout: 'stereo-left-right',
    centralHorizontalAngle: Math.PI,   // 180° horizontal
    upperVerticalAngle: Math.PI / 2,
    lowerVerticalAngle: -Math.PI / 2,
    radius: 20
  });
};

const layer = createVR180Layer(session, refSpace, video);
session.updateRenderState({ layers: [layer] });

Equirect-Ebene mit WebGL-Projektionsebene kombinieren

const gl = canvas.getContext('webgl2', { xrCompatible: true });
const glBinding = new XRWebGLBinding(session, gl);
const projLayer = glBinding.createProjectionLayer();

const equirect = new XRMediaBinding(session).createEquirectLayer(video, {
  space: refSpace,
  transform: new XRRigidTransform({ x: 0, y: 1.6, z: 0 })
});

// Reihenfolge = Zeichenreihenfolge: Video hinten, 3D-UI davor
session.updateRenderState({ layers: [equirect, projLayer] });

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die WebXR Layers API ist experimentell und wird derzeit im Wesentlichen vom Meta Quest Browser unterstützt. Prüfe die Unterstützung vorher mit 'XRMediaBinding' in window und fordere "layers" am besten als optionalFeatures an, damit du eine Ausweichlösung anbieten kannst.
  • Ist die Sitzung bereits beendet oder das Feature "layers" nicht aktiviert, wirft die Methode einen InvalidStateError. Ein ungültiges layout wie "default" führt zu einem Fehler.
  • Die Ebene wird erst angezeigt, wenn sie in updateRenderState({ layers }) eingetragen ist. Die Reihenfolge im Array bestimmt, welche Ebene über welcher liegt.
  • Videos von fremden Ursprüngen brauchen korrekte CORS-Header und crossOrigin. Wegen der Autoplay-Richtlinien der Browser muss video.play() meist durch eine Nutzeraktion ausgelöst werden.
  • Die Winkel werden in Radiant angegeben, nicht in Grad. Ein radius von 0 bedeutet eine unendlich große Kugel.
  • Stimmt layout nicht mit dem tatsächlichen Videoformat überein, sieht man doppelte oder verzerrte Bilder. Prüfe daher, wie das Video gemastert ist.