Start · Sprachen · JavaScript · Referenz · XRViewport.y

XRViewport.y

Eigenschaft

Schreibgeschützte Ganzzahl: der Abstand in Pixeln von der unteren Kante der Zieloberfläche (meist ein <code>XRWebGLLayer</code>) bis zur unteren Kante des Viewports.

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

Signatur

XRViewport.y

Beschreibung

Die Eigenschaft y eines XRViewport-Objekts gibt an, wie weit der Viewport einer XR-Ansicht (XRView) von der unteren Kante der Zeichenoberfläche entfernt ist. Der Wert wird in Pixeln angegeben. Zusammen mit x, width und height beschreibt er das Rechteck, in das die Szene für ein bestimmtes Auge oder eine bestimmte Ansicht gezeichnet wird.

Die Koordinaten folgen der Konvention von WebGL: Der Ursprung liegt unten links, und die y-Achse zeigt nach oben. Deshalb lassen sich die vier Werte direkt an gl.viewport() und gl.scissor() übergeben, ohne sie umzurechnen.

Einen XRViewport erhältst du pro Frame über XRWebGLLayer.getViewport(view) für jede Ansicht in XRViewerPose.views. Bei stereoskopischen Headsets liegen die Viewports für linkes und rechtes Auge oft nebeneinander im selben Framebuffer. Dann ist y für beide meist 0, und nur x ist verschieden. Bei anderen Anordnungen (zum Beispiel übereinander) kann y aber auch andere Werte haben. Verlass dich deshalb nie auf feste Werte.

Rückgabewert

Typ
number
Beschreibung
Ganzzahliger Versatz in Pixeln von der unteren Kante der Zieloberfläche bis zur unteren Kante des Viewports. Die Eigenschaft ist schreibgeschützt.

Beispiele

Viewport pro Ansicht im Render-Loop setzen

// Voraussetzung: gl ist ein XR-kompatibler WebGL-Kontext, xrRefSpace ist ein XRReferenceSpace
const onXRFrame = (time, frame) => {
  const session = frame.session;
  session.requestAnimationFrame(onXRFrame);

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

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

  for (const view of pose.views) {
    const vp = glLayer.getViewport(view);
    // y wird direkt übernommen – Ursprung unten links wie in WebGL
    gl.viewport(vp.x, vp.y, vp.width, vp.height);
    drawScene(view.projectionMatrix, view.transform.inverse.matrix);
  }
};

Viewport-Daten zur Fehlersuche ausgeben

const logViewports = (frame, refSpace) => {
  const pose = frame.getViewerPose(refSpace);
  if (!pose) return;
  const layer = frame.session.renderState.baseLayer;

  pose.views.forEach((view) => {
    const { x, y, width, height } = layer.getViewport(view);
    console.log(`${view.eye}: x=${x}, y=${y}, ${width}x${height}`);
  });
};
left: x=0, y=0, 1440x1600 right: x=1440, y=0, 1440x1600

Scissor-Test auf den Viewport begrenzen

// Nur den Bereich des aktuellen Auges löschen, z. B. mit Hintergrundfarbe pro Auge
const clearView = (gl, vp, color) => {
  gl.enable(gl.SCISSOR_TEST);
  gl.scissor(vp.x, vp.y, vp.width, vp.height);
  gl.clearColor(...color);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.disable(gl.SCISSOR_TEST);
};

// Aufruf im Frame-Loop:
// clearView(gl, glLayer.getViewport(view), [0.1, 0.1, 0.2, 1]);

// Wichtig · Fallstricke

  • Ursprung unten links: y wird von der unteren Kante aus gemessen und nicht von oben wie bei DOM- oder Canvas-2D-Koordinaten. Willst du die Werte mit CSS-Koordinaten oder readPixels-Auswertungen im Bildschirmformat vergleichen, musst du umrechnen: top = framebufferHeight - (y + height).
  • Nicht zwischenspeichern: Die Viewports können sich zwischen Frames ändern, zum Beispiel nach einer Änderung von framebufferScaleFactor oder bei dynamischer Auflösung. Frag getViewport() deshalb in jedem Frame neu ab.
  • Keine festen Annahmen: Dass y gleich 0 ist, ist üblich, aber nicht garantiert. Nutze immer den gelieferten Wert.
  • Kompatibilität: WebXR läuft nur in sicheren Kontexten (HTTPS). Unterstützt wird es vor allem von Chromium-Browsern und dem Meta Quest Browser. Firefox und Safari auf dem Desktop unterstützen es nicht. Prüf die Verfügbarkeit mit navigator.xr?.isSessionSupported().