Signatur
Beschreibung
Die schreibgeschützte Eigenschaft textureWidth gehört zum Interface XRProjectionLayer aus dem WebXR Layers API. Sie liefert die Breite der Farbtexturen dieser Ebene in Pixeln, also der Texturen, die der Browser pro Frame über XRWebGLBinding.getViewSubImage() bereitstellt.
Welcher Wert herauskommt, legt der Browser fest, wenn die Ebene mit XRWebGLBinding.createProjectionLayer() erzeugt wird. Er hängt von der nativen Auflösung des Geräts, vom übergebenen scaleFactor und vom Texturtyp ab. Bei textureType: "texture" und einem nebeneinander angeordneten Stereo-Layout kann eine Textur beide Augen enthalten. Dann ist textureWidth die Breite der ganzen Textur und nicht die eines einzelnen Auges. Bei "texture-array" steht jede Ansicht in einer eigenen Array-Ebene, die Anzahl liefert textureArrayLength.
In der Praxis braucht man textureWidth zusammen mit textureHeight, um eigene Ressourcen in passender Größe anzulegen, etwa Renderbuffer, Zwischen-Framebuffer für Nachbearbeitung oder Multisample-Puffer. Welchen Bildausschnitt man für jede Ansicht rendern soll, gibt dagegen immer XRWebGLSubImage.viewport an.
Rückgabewert
unsigned long): die Breite der Farbtexturen der Ebene in Pixeln.Beispiele
Projektionsebene anlegen und Texturgröße auslesen
const startXR = async () => {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2', { xrCompatible: true });
const session = await navigator.xr.requestSession('immersive-vr', {
requiredFeatures: ['layers']
});
const binding = new XRWebGLBinding(session, gl);
const layer = binding.createProjectionLayer({
textureType: 'texture-array',
colorFormat: gl.RGBA8,
scaleFactor: 1.0
});
session.updateRenderState({ layers: [layer] });
console.log(`Farbtextur: ${layer.textureWidth} × ${layer.textureHeight} px`);
console.log(`Array-Ebenen: ${layer.textureArrayLength}`);
};
document.querySelector('#vr-button').addEventListener('click', startXR);
Wirkung des scaleFactor vergleichen
const compareScale = (binding, gl) => {
const full = binding.createProjectionLayer({ colorFormat: gl.RGBA8, scaleFactor: 1.0 });
const half = binding.createProjectionLayer({ colorFormat: gl.RGBA8, scaleFactor: 0.5 });
console.log('scaleFactor 1.0:', full.textureWidth);
console.log('scaleFactor 0.5:', half.textureWidth);
full.destroy();
return half;
};
Passenden Multisample-Renderbuffer anlegen
const createMsaaTarget = (gl, layer, samples = 4) => {
const fb = gl.createFramebuffer();
const color = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, color);
// Größe exakt an die Ebenentextur anpassen, damit blitFramebuffer 1:1 kopiert
gl.renderbufferStorageMultisample(
gl.RENDERBUFFER, samples, gl.RGBA8,
layer.textureWidth, layer.textureHeight
);
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, color);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
return { fb, color };
};
// Im Frame-Loop trotzdem den Viewport des Sub-Images verwenden:
// const sub = binding.getViewSubImage(layer, view);
// const { x, y, width, height } = sub.viewport;
// gl.viewport(x, y, width, height);
// Wichtig · Fallstricke
- Experimentelle API: Das WebXR Layers API gibt es im Wesentlichen nur in Chromium-basierten XR-Browsern, etwa dem Meta Quest Browser. Firefox und Safari unterstützen es nicht. Prüfen Sie die Unterstützung vorher, z. B. mit
typeof XRWebGLBinding !== 'undefined', und fordern Sie beim Start der Sitzung das Feature'layers'an. - Die API steht nur in sicheren Kontexten (HTTPS) zur Verfügung.
- Nicht mit dem Viewport verwechseln: Bei
textureType: "texture"kann eine Textur beide Augen enthalten. Dann isttextureWidthungefähr doppelt so groß wie eine einzelne Ansicht. Verwenden Sie fürgl.viewport()immerXRWebGLSubImage.viewport. - Der Wert steht fest, sobald die Ebene erzeugt wurde. Für eine andere Auflösung erzeugen Sie eine neue Ebene mit anderem
scaleFactor. Der Browser kann den gewünschten Wert auf gerätespezifische Grenzen abrunden oder begrenzen. - Die Eigenschaft ist schreibgeschützt. Eine Zuweisung wird still ignoriert bzw. löst im Strict Mode einen
TypeErroraus.