Signatur
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
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);
});
});
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));
// 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 Parametertransposedeshalbfalsesein. - WebVR erfordert einen sicheren Kontext (HTTPS) und eine Nutzerinteraktion, bevor
requestPresent()aufgerufen werden darf.