Start · Sprachen · JavaScript · Referenz · VRFrameData.leftViewMatrix

VRFrameData.leftViewMatrix

Eigenschaft

Schreibgeschütztes <code>Float32Array</code> mit einer 4×4-View-Matrix, die die Kameratransformation für das Rendern des linken Auges beschreibt.

seit JavaScript WebVR 1.1 (veraltet, nicht standardisiert – ersetz deprecated seit ja Kategorie: webapi

Signatur

VRFrameData.leftViewMatrix

Beschreibung

Die Eigenschaft leftViewMatrix der Schnittstelle VRFrameData aus der veralteten WebVR-API liefert ein Float32Array mit 16 Werten. Diese Werte bilden eine 4×4-Matrix in Spaltenreihenfolge (column-major), wie WebGL sie erwartet. Die Matrix beschreibt die View-Transformation für das linke Auge. Sie berücksichtigt also die Kopfposition und -ausrichtung des Headsets (Pose) und zusätzlich den Augenversatz (VREyeParameters.offset).

Gefüllt wird die Matrix, sobald man VRDisplay.getFrameData(frameData) aufruft. Das passiert typischerweise in jedem Frame innerhalb des Rückrufs von VRDisplay.requestAnimationFrame(). Danach übergibt man die Matrix zusammen mit leftProjectionMatrix per gl.uniformMatrix4fv() an den Shader und zeichnet die Szene in die linke Hälfte des Canvas.

Für das rechte Auge gibt es das Gegenstück rightViewMatrix. Beim stereoskopischen Rendern zeichnet man die Szene zweimal, einmal pro Auge, jeweils mit eigenem Viewport.

Rückgabewert

Typ
Float32Array
Beschreibung
Ein Float32Array mit 16 Elementen: die View-Matrix des linken Auges in Spaltenreihenfolge. Sie wird bei jedem Aufruf von getFrameData() aktualisiert.

Beispiele

View-Matrix des linken Auges auslesen

const frameData = new VRFrameData();

navigator.getVRDisplays().then((displays) => {
  if (displays.length === 0) return;
  const vrDisplay = displays[0];

  vrDisplay.requestAnimationFrame(() => {
    vrDisplay.getFrameData(frameData);
    const view = frameData.leftViewMatrix;
    console.log(view.length);    // 16
    console.log(view instanceof Float32Array);
  });
});
16 true

Stereo-Rendering mit WebGL (linke Hälfte)

// Annahmen: gl, program, vrDisplay und canvas sind bereits eingerichtet
const frameData = new VRFrameData();
const projLoc = gl.getUniformLocation(program, 'uProjection');
const viewLoc = gl.getUniformLocation(program, 'uView');

const drawScene = () => { /* gl.drawArrays(...) */ };

const onFrame = () => {
  vrDisplay.requestAnimationFrame(onFrame);
  vrDisplay.getFrameData(frameData);

  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  // Linkes Auge
  gl.viewport(0, 0, canvas.width / 2, canvas.height);
  gl.uniformMatrix4fv(projLoc, false, frameData.leftProjectionMatrix);
  gl.uniformMatrix4fv(viewLoc, false, frameData.leftViewMatrix);
  drawScene();

  // Rechtes Auge
  gl.viewport(canvas.width / 2, 0, canvas.width / 2, canvas.height);
  gl.uniformMatrix4fv(projLoc, false, frameData.rightProjectionMatrix);
  gl.uniformMatrix4fv(viewLoc, false, frameData.rightViewMatrix);
  drawScene();

  vrDisplay.submitFrame();
};

vrDisplay.requestAnimationFrame(onFrame);

Kameraposition aus der View-Matrix ableiten (mit gl-matrix)

import { mat4, vec3 } from 'gl-matrix';

const getLeftEyePosition = (frameData) => {
  const inv = mat4.create();
  mat4.invert(inv, frameData.leftViewMatrix); // View-Matrix -> Welt-Matrix
  const pos = vec3.create();
  mat4.getTranslation(pos, inv);
  return pos;
};

console.log(getLeftEyePosition(frameData));
Float32Array(3) [x, y, z]

// Wichtig · Fallstricke

Veraltet: WebVR und damit VRFrameData wurden nie standardisiert und sind in aktuellen Browsern entfernt. Unterstützt wurden sie nur zeitweise, etwa in Firefox bis Version 97 (unter Windows/macOS), im Samsung Internet Browser und in älteren Chrome-Versionen hinter einer Flag. Für neue Projekte sollte man die WebXR Device API verwenden. Dort entspricht XRView.transform.inverse.matrix der View-Matrix eines Auges.

  • Die Matrix ist erst gültig, nachdem getFrameData() aufgerufen wurde. Vorher enthält sie keine sinnvollen Werte.
  • Das Array wird bei jedem Frame überschrieben. Wer Werte aufheben möchte, muss sie kopieren, z. B. mit new Float32Array(frameData.leftViewMatrix).
  • Die Werte liegen in Spaltenreihenfolge vor. Bei gl.uniformMatrix4fv() muss der Parameter transpose deshalb false sein.
  • WebVR erfordert einen sicheren Kontext (HTTPS) und eine Nutzerinteraktion, bevor requestPresent() aufgerufen werden darf.