Signatur
Beschreibung
Die Eigenschaft textureArrayLength des Interfaces XRProjectionLayer liefert die Anzahl der Schichten der Farb- bzw. Tiefentextur, die der Browser für eine Projektionsebene bereitstellt. Sie ist nur dann wirklich aussagekräftig, wenn die Ebene über XRWebGLBinding.createProjectionLayer() mit der Option textureType: "texture-array" erzeugt wurde. In diesem Fall liegt jede Ansicht (z. B. linkes und rechtes Auge) in einer eigenen Schicht einer TEXTURE_2D_ARRAY.
Praktisch nutzt man den Wert vor allem für Multiview-Rendering (WebGL-Erweiterung OVR_multiview2): Die Anzahl der Views, die in einem Draw-Call gleichzeitig gerendert werden, muss zur Schichtanzahl der Array-Textur passen. Bei einer typischen Stereo-Sitzung ist der Wert 2. Wird dagegen textureType: "texture" (Standard) verwendet, gibt es keine Array-Textur, und der Wert ist 1.
Für das Rendern einer einzelnen Ansicht ohne Multiview liefert XRWebGLBinding.getViewSubImage() ein XRWebGLSubImage, dessen imageIndex die passende Schicht (0 bis textureArrayLength - 1) angibt – diese reicht man an gl.framebufferTextureLayer() weiter.
Rückgabewert
2 bei Stereo mit "texture-array"); 1, wenn keine Array-Textur verwendet wird. Schreibgeschützt.Beispiele
Projektionsebene mit Array-Textur anlegen und Schichtanzahl lesen
const startXR = async () => {
const session = await navigator.xr.requestSession('immersive-vr', {
requiredFeatures: ['layers']
});
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2', { xrCompatible: true });
const binding = new XRWebGLBinding(session, gl);
const layer = binding.createProjectionLayer({
textureType: 'texture-array',
colorFormat: gl.RGBA8
});
session.updateRenderState({ layers: [layer] });
console.log('Schichten:', layer.textureArrayLength);
};
document.querySelector('#vr-button').addEventListener('click', startXR);
Jede Ansicht in ihre eigene Schicht rendern
// Annahme: session, gl, binding, layer, refSpace wie oben angelegt
const framebuffer = gl.createFramebuffer();
const onFrame = (time, frame) => {
session.requestAnimationFrame(onFrame);
const pose = frame.getViewerPose(refSpace);
if (!pose) return;
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
for (const view of pose.views) {
const sub = binding.getViewSubImage(layer, view);
// imageIndex liegt immer im Bereich 0 … textureArrayLength - 1
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.1, 0.2, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// drawScene(view) …
}
};
session.requestAnimationFrame(onFrame);
Multiview-Framebuffer passend zur Schichtanzahl einrichten
const ext = gl.getExtension('OVR_multiview2');
const setupMultiview = (subImage) => {
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb);
// numViews muss der Schichtanzahl der Array-Textur entsprechen
ext.framebufferTextureMultiviewOVR(
gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
subImage.colorTexture, 0,
0, layer.textureArrayLength
);
return fb;
};
if (!ext) {
console.warn('OVR_multiview2 nicht verfügbar – Fallback auf Einzel-Rendering');
}
// Wichtig · Fallstricke
- Kompatibilität: Die WebXR Layers API ist experimentell und praktisch nur im Meta Quest Browser und teils in Chromium-Browsern (hinter Flags) verfügbar. Vorher mit
'XRWebGLBinding' in windowund dem Session-Feature'layers'prüfen. textureType: "texture-array"braucht einen WebGL2-Kontext. Bei WebGL1 wirftcreateProjectionLayer()einen Fehler.- Der Wert ist schreibgeschützt. Zuweisungen werden stillschweigend ignoriert (im Strict Mode gibt es einen
TypeError). - Bei
textureType: "texture"ist der Wert1. Wer Code für beide Varianten schreibt, sollte trotzdem immerimageIndexausgetViewSubImage()verwenden, statt Schichtindizes fest einzutragen. - Die Texturen gehören dem Browser und sind nur innerhalb des aktuellen XR-Frames gültig. Nicht über Frames hinweg zwischenspeichern.