Start · Sprachen · JavaScript · Referenz · XRWebGLSubImage.imageIndex

XRWebGLSubImage.imageIndex

Eigenschaft

Schreibgeschützter Index der Ebene im Texturarray, in die für das aktuelle Auge gerendert wird, wenn der Layer mit <code>textureType: "texture-array"</code> angelegt wurde. Sonst <code>null</code>.

seit JavaScript WebXR Layers API – experimentell (Chromium-basiert Kategorie: webapi

Signatur

XRWebGLSubImage.imageIndex

Beschreibung

Die Eigenschaft imageIndex eines XRWebGLSubImage gibt an, in welche Ebene (Layer) eines WebGL-2-Texturarrays (TEXTURE_2D_ARRAY) gerendert werden soll. Sie ist nur gesetzt, wenn der zugehörige Layer über XRWebGLBinding mit der Option textureType: "texture-array" erzeugt wurde. Dann teilen sich beide Augen eine einzige Array-Textur, und jedes Auge bekommt eine eigene Array-Ebene (typischerweise 0 für links und 1 für rechts).

Gebraucht wird der Wert jedes Frame. Nach dem Abruf des Sub-Images mit XRWebGLBinding.getViewSubImage() oder getSubImage() hängt man die Farbtextur mit gl.framebufferTextureLayer() an den Framebuffer an und übergibt imageIndex als Ebenen-Parameter. Wurde der Layer dagegen mit "texture" angelegt (Standard), ist imageIndex null. In dem Fall nutzt man gl.framebufferTexture2D() und viewport.

Texturarrays lassen sich gut mit der Multiview-Erweiterung OVR_multiview2 kombinieren. Damit rendert man beide Augen in einem einzigen Draw-Durchlauf, was auf mobilen VR-Headsets spürbar Leistung spart.

Rückgabewert

Typ
number | null
Beschreibung
Eine Ganzzahl ≥ 0 als Ebenen-Index im Texturarray. null, wenn der Layer nicht mit textureType: "texture-array" erzeugt wurde.

Beispiele

Projektions-Layer mit Texturarray anlegen und imageIndex nutzen

const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2', { xrCompatible: true });

const session = await navigator.xr.requestSession('immersive-vr', {
  requiredFeatures: ['layers']
});
const refSpace = await session.requestReferenceSpace('local');
const binding = new XRWebGLBinding(session, gl);

// Beide Augen teilen sich eine Array-Textur
const layer = binding.createProjectionLayer({ textureType: 'texture-array' });
session.updateRenderState({ layers: [layer] });

const fb = gl.createFramebuffer();

const onFrame = (time, frame) => {
  session.requestAnimationFrame(onFrame);
  const pose = frame.getViewerPose(refSpace);
  if (!pose) return;

  gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
  for (const view of pose.views) {
    const sub = binding.getViewSubImage(layer, view);
    // imageIndex wählt die Ebene im Array
    gl.framebufferTextureLayer(
      gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
      sub.colorTexture, 0, sub.imageIndex
    );
    const { x, y, width, height } = sub.viewport;
    gl.viewport(x, y, width, height);
    gl.clearColor(0.1, 0.2, 0.3, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);
    // ... Szene für dieses Auge zeichnen
  }
};
session.requestAnimationFrame(onFrame);

Beide Textur-Typen robust behandeln

const attachSubImage = (gl, sub) => {
  if (sub.imageIndex !== null) {
    // Layer wurde mit 'texture-array' angelegt
    gl.framebufferTextureLayer(
      gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
      sub.colorTexture, 0, sub.imageIndex
    );
  } else {
    // Normale 2D-Textur
    gl.framebufferTexture2D(
      gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
      gl.TEXTURE_2D, sub.colorTexture, 0
    );
  }
};

Wert pro Auge protokollieren

const logIndices = (binding, layer, pose) => {
  for (const view of pose.views) {
    const sub = binding.getViewSubImage(layer, view);
    console.log(view.eye, sub.imageIndex);
  }
};
left 0 right 1

// Wichtig · Fallstricke

  • Kompatibilität: Die WebXR Layers API ist experimentell. Unterstützt wird sie vor allem im Meta Quest Browser und in Chromium mit aktiviertem Feature-Flag. Firefox und Safari unterstützen sie nicht. Das Feature 'layers' muss in requestSession() angefordert werden. Mit typeof XRWebGLBinding !== 'undefined' lässt sich vorab prüfen, ob die Schnittstelle überhaupt existiert.
  • Nur WebGL 2: Für "texture-array" braucht es einen WebGL2RenderingContext. In einem WebGL-1-Kontext wirft createProjectionLayer() einen Fehler.
  • Auf null prüfen: Bei null darf man den Wert nicht an framebufferTextureLayer() übergeben. Sonst wird null zu 0 umgewandelt, und die Textur ist falsch gebunden.
  • Nicht davon ausgehen, dass das linke Auge immer 0 hat. Den Wert jedes Frame neu aus dem Sub-Image lesen.
  • Das Sub-Image und seine Texturen gelten nur innerhalb des aktuellen XRFrame-Callbacks.