Start · Sprachen · JavaScript · Referenz · XRViewport.width

XRViewport.width

Eigenschaft

Schreibgeschützte Eigenschaft: gibt die Breite des Viewports in Pixeln an, also des Bereichs der Zeichenfläche, in den eine XR-Ansicht gerendert wird.

seit JavaScript WebXR Device API – Chromium-Browser (Chrome/Edge 7 Kategorie: webapi

Signatur

XRViewport.width

Beschreibung

Die Eigenschaft width eines XRViewport-Objekts liefert die Breite des Rechtecks in Pixeln, in das eine bestimmte XRView (z. B. das linke oder rechte Auge) gerendert werden soll. Zusammen mit x, y und height beschreibt sie genau den Ausschnitt des Framebuffers, den der Browser für diese Ansicht vorsieht.

Einen Viewport erhältst du normalerweise pro Frame über XRWebGLLayer.getViewport(view) oder, mit der WebXR-Layers-API, über XRWebGLBinding.getViewSubImage(). Die Werte übergibst du direkt an gl.viewport(x, y, width, height) (und ggf. an gl.scissor()), bevor du die Szene für die jeweilige Ansicht zeichnest.

Bei stereoskopischer Darstellung teilen sich meist zwei Viewports einen Framebuffer, der nebeneinander aufgeteilt ist. width entspricht dann ungefähr der halben Framebuffer-Breite. Leg diese Aufteilung aber nicht selbst fest: Die Aufteilung bestimmt allein der Browser bzw. das XR-Gerät.

Rückgabewert

Typ
number
Beschreibung
Die Breite des Viewports in Pixeln (ganzzahlig, nicht negativ), gemessen im Koordinatensystem des WebGL-Framebuffers.

Beispiele

Viewport pro Auge im Render-Loop setzen

const onXRFrame = (time, frame) => {
  const session = frame.session;
  session.requestAnimationFrame(onXRFrame);

  const pose = frame.getViewerPose(xrRefSpace);
  if (!pose) return;

  const layer = session.renderState.baseLayer;
  gl.bindFramebuffer(gl.FRAMEBUFFER, layer.framebuffer);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  for (const view of pose.views) {
    const vp = layer.getViewport(view);
    // Zeichenbereich auf den Viewport dieser Ansicht beschränken
    gl.viewport(vp.x, vp.y, vp.width, vp.height);
    drawScene(view.projectionMatrix, view.transform.inverse.matrix);
  }
};

Seitenverhältnis für eigene Projektion berechnen

const getAspect = (layer, view) => {
  const { width, height } = layer.getViewport(view);
  return height > 0 ? width / height : 1;
};

// z. B. für ein 2D-Overlay oder einen Post-Processing-Pass
const aspect = getAspect(session.renderState.baseLayer, pose.views[0]);
console.log(`Seitenverhältnis: ${aspect.toFixed(3)}`);
Seitenverhältnis: 0.900

Viewport-Größen zur Fehlersuche protokollieren

const logViewports = (frame, refSpace) => {
  const pose = frame.getViewerPose(refSpace);
  if (!pose) return;
  const layer = frame.session.renderState.baseLayer;
  pose.views.forEach((view) => {
    const vp = layer.getViewport(view);
    console.log(`${view.eye}: ${vp.width}×${vp.height} @ (${vp.x}, ${vp.y})`);
  });
  console.log('Framebuffer:', layer.framebufferWidth, '×', layer.framebufferHeight);
};
left: 1440×1584 @ (0, 0) right: 1440×1584 @ (1440, 0) Framebuffer: 2880 × 1584

// Wichtig · Fallstricke

  • Schreibgeschützt: Eine Zuweisung an width wird ignoriert (im Strict Mode wirft sie einen TypeError). Die Auflösung beeinflusst du über framebufferScaleFactor beim Erzeugen des XRWebGLLayer oder über XRView.requestViewportScale().
  • Nicht zwischenspeichern: Hol den Viewport in jedem Frame neu. Durch dynamische Viewport-Skalierung, Änderungen an renderState oder den Wechsel des Layers kann sich die Größe ändern.
  • Nicht mit der Canvas-Größe verwechseln: width bezieht sich auf den XR-Framebuffer (layer.framebufferWidth), nicht auf canvas.width oder CSS-Pixel.
  • Nur in einem sicheren Kontext (HTTPS) verfügbar. Die Unterstützung beschränkt sich im Wesentlichen auf Chromium-Browser und XR-Headset-Browser. Prüfe vorher mit navigator.xr?.isSessionSupported(), ob die API verfügbar ist.