Start · Sprachen · JavaScript · Referenz · XRQuadLayer.space

XRQuadLayer.space

Eigenschaft

Lesbare und schreibbare Eigenschaft mit dem <code>XRSpace</code>, in dem die Position und Ausrichtung eines <code>XRQuadLayer</code> in der physischen Umgebung festgelegt sind.

seit JavaScript WebXR Layers API (experimentell) – u. a. Meta Ques Kategorie: webapi

Signatur

XRQuadLayer.space

Beschreibung

Die Eigenschaft space eines XRQuadLayer gibt das Koordinatensystem (XRSpace) an, auf das sich die Ebene bezieht. Zusammen mit XRQuadLayer.transform legt sie fest, wo die flache, rechteckige Ebene in der Szene liegt. Der Transform wird dabei relativ zu diesem Raum ausgewertet.

Normalerweise gibst du den Raum schon beim Erzeugen der Ebene über XRWebGLBinding.createQuadLayer() mit der Option space an. Weil die Eigenschaft beschreibbar ist, kannst du sie später ändern. So lässt sich eine Ebene zum Beispiel von einem weltfesten Raum ("local", "local-floor") in den "viewer"-Raum verschieben. Die Ebene hängt dann am Kopf, etwa als HUD oder Untertitel.

Welcher Raum passt, hängt vom Einsatz ab:

  • "local" / "local-floor": Die Ebene bleibt fest im Raum, z. B. ein virtueller Bildschirm oder eine Infotafel.
  • "viewer": Die Ebene bewegt sich mit dem Kopf, z. B. für Hinweise oder Menüs.
  • XRInputSource.gripSpace: Die Ebene hängt am Controller, z. B. für ein Menü am Handgelenk.

Quad-Ebenen werden direkt vom Compositor der XR-Laufzeit dargestellt. Text und Videos wirken dadurch deutlich schärfer als auf einer Textur, die in die WebGL-Szene gezeichnet wird.

Parameter

Name Typ Default Beschreibung
$value Pflicht XRSpace Nur beim Setzen: der neue Raum, auf den sich transform der Ebene künftig bezieht. Das kann ein XRReferenceSpace sein oder ein anderer XRSpace, z. B. gripSpace.

Rückgabewert

Typ
XRSpace
Beschreibung
Der aktuelle Raum der Ebene. Meist ist das ein XRReferenceSpace, er kann aber auch zu einer Eingabequelle gehören.

Beispiele

Quad-Ebene in einem weltfesten Raum erzeugen

const session = await navigator.xr.requestSession('immersive-vr', {
  requiredFeatures: ['layers']
});
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2', { xrCompatible: true });
const binding = new XRWebGLBinding(session, gl);

const refSpace = await session.requestReferenceSpace('local-floor');

const quadLayer = binding.createQuadLayer({
  space: refSpace,
  viewPixelWidth: 1024,
  viewPixelHeight: 768,
  width: 1.6,   // Breite in Metern
  height: 1.2,  // Höhe in Metern
  // 2 m vor dem Nutzer, 1,5 m über dem Boden
  transform: new XRRigidTransform({ x: 0, y: 1.5, z: -2 })
});

session.updateRenderState({ layers: [quadLayer] });
console.log(quadLayer.space === refSpace);
true

Ebene an den Kopf heften (HUD) und wieder lösen

const worldSpace = await session.requestReferenceSpace('local');
const viewerSpace = await session.requestReferenceSpace('viewer');

const setHudMode = (layer, enabled) => {
  if (enabled) {
    layer.space = viewerSpace;
    // 1 m vor den Augen, leicht nach unten versetzt
    layer.transform = new XRRigidTransform({ x: 0, y: -0.2, z: -1 });
  } else {
    layer.space = worldSpace;
    layer.transform = new XRRigidTransform({ x: 0, y: 1.4, z: -2 });
  }
};

setHudMode(quadLayer, true);

Menü am Controller befestigen

session.addEventListener('inputsourceschange', ({ added }) => {
  const left = added.find((src) => src.handedness === 'left' && src.gripSpace);
  if (!left) return;

  // Die Ebene folgt ab jetzt dem linken Controller
  menuLayer.space = left.gripSpace;
  menuLayer.transform = new XRRigidTransform(
    { x: 0, y: 0.1, z: -0.05 },
    { x: -0.383, y: 0, z: 0, w: 0.924 } // ca. 45° nach hinten gekippt
  );
});

// Wichtig · Fallstricke

  • Kompatibilität: Die WebXR Layers API ist experimentell. Gut unterstützt wird sie vor allem im Meta Quest Browser. In anderen Chromium-Browsern ist sie teilweise nur hinter einem Flag verfügbar, Firefox und Safari unterstützen sie nicht. Das Feature 'layers' muss in requestSession() angefordert werden. Prüfe außerdem vorher, ob XRWebGLBinding und createQuadLayer existieren. Es gibt dafür ein Polyfill.
  • Der transform wird immer relativ zu space ausgewertet. Wenn du den Raum wechselst, ohne den Transform anzupassen, springt die Ebene meist an eine unerwartete Stelle.
  • Ist space ein gripSpace und der Controller verliert das Tracking oder wird getrennt, kann die Ebene verschwinden oder einfrieren. Setze in diesem Fall einen Referenzraum als Ersatz.
  • Der Raum muss zur selben XRSession gehören wie die Ebene. Räume aus einer beendeten oder anderen Sitzung sind ungültig.
  • Am Kopf befestigte Ebenen ("viewer") sollten klein und nicht zu nah sein. Sonst können sie Unbehagen auslösen, und die Augen können sich schlecht darauf einstellen.