Signatur
Beschreibung
Die schreibgeschützte Eigenschaft XRView.index gibt eine ganze Zahl zurück. Sie gibt an, an welcher Stelle die aktuelle Ansicht im Array XRViewerPose.views steht. Eine XRViewerPose erhältst du pro Frame mit XRFrame.getViewerPose(). Sie enthält für jede Ansicht, die gerendert werden muss, ein eigenes XRView-Objekt. Bei einem VR-Headset sind das meist zwei (linkes und rechtes Auge), bei einem Smartphone im AR-Modus meist nur eine.
Nützlich ist index, wenn du nur ein einzelnes XRView-Objekt hast, aber Daten pro Ansicht brauchst, die du selbst in Arrays verwaltest. Beispiele sind eigene Framebuffer, Uniform-Puffer, Schatten-Kameras oder die Ebene eines Textur-Arrays bei Multiview-Rendering. Du musst dann keinen eigenen Zähler mitführen und nicht auf views.indexOf(view) zurückgreifen.
Wichtig: Der Index sagt nichts darüber aus, welches Auge gemeint ist. Dafür gibt es die Eigenschaft XRView.eye ("left", "right" oder "none"). Außerdem kann sich die Anzahl der Ansichten zwischen Frames ändern, zum Beispiel wenn zusätzliche Ansichten ein- oder ausgeschaltet werden. Speicherst du Daten nach Index, prüfe deshalb in jedem Frame views.length.
Rückgabewert
0: die Position dieser XRView im Array XRViewerPose.views des aktuellen Frames.Beispiele
Index und Auge jeder Ansicht ausgeben
const startXR = async () => {
const session = await navigator.xr.requestSession('immersive-vr');
const refSpace = await session.requestReferenceSpace('local');
const onFrame = (time, frame) => {
const pose = frame.getViewerPose(refSpace);
if (pose) {
for (const view of pose.views) {
console.log(`Ansicht ${view.index}: Auge = ${view.eye}`);
}
}
session.requestAnimationFrame(onFrame);
};
session.requestAnimationFrame(onFrame);
};
document.querySelector('#vr-button').addEventListener('click', startXR);
Eigene Daten pro Ansicht über den Index verwalten
// Eigene Daten pro Ansicht, z. B. eine Kamera-Matrix für jede Ansicht
const perViewData = [];
const getViewData = (view) => {
// Eintrag bei Bedarf anlegen
perViewData[view.index] ??= {
viewProjection: new Float32Array(16),
frameCount: 0
};
return perViewData[view.index];
};
const renderView = (view) => {
const data = getViewData(view);
data.frameCount++;
// Projektions- und Ansichtsmatrix übernehmen (vereinfacht, ohne Multiplikation)
data.viewProjection.set(view.projectionMatrix);
console.log(`Ansicht ${view.index} gerendert, Frames: ${data.frameCount}`);
};
const onFrame = (time, frame) => {
const session = frame.session;
const pose = frame.getViewerPose(window.xrRefSpace);
if (pose) {
// Nicht mehr benötigte Einträge entfernen, falls es weniger Ansichten gibt
perViewData.length = Math.min(perViewData.length, pose.views.length);
pose.views.forEach(renderView);
}
session.requestAnimationFrame(onFrame);
};
Ebene eines Textur-Arrays wählen (WebGL2)
// gl: WebGL2RenderingContext, arrayTexture: TEXTURE_2D_ARRAY mit einer Ebene je Ansicht
const renderToLayer = (gl, framebuffer, arrayTexture, view, viewport) => {
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
// Die Ebene der Textur entspricht dem Index der Ansicht
gl.framebufferTextureLayer(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
arrayTexture,
0,
view.index
);
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// ... Szene mit view.projectionMatrix und view.transform zeichnen
};
// Wichtig · Fallstricke
- Experimentell:
XRView.indexgehört nicht zum Kern der WebXR-Spezifikation und wird bislang nur von einigen Chromium-basierten Browsern unterstützt. Prüfe die Unterstützung vorher, z. B. mit'index' in view, und nimm sonst den Index aus der Schleife (pose.views.forEach((view, i) => …)). - Index ist nicht gleich Auge: Schließe vom Index nicht auf das linke oder rechte Auge. Nutze dafür
XRView.eye. - Nur für den aktuellen Frame gültig:
XRView-Objekte gehören zum jeweiligen Frame. Speichere sie nicht über mehrere Frames hinweg. Speichere höchstens den Index und passe deine Daten an, wenn sichviews.lengthändert. - WebXR steht nur in sicheren Kontexten (HTTPS) zur Verfügung und braucht eine aktive
XRSession.