Signatur
Beschreibung
Die schreibgeschützte Eigenschaft mipLevels der Schnittstelle XRCompositionLayer gibt als ganze Zahl an, wie viele Mip-Levels die Texturen einer Ebene haben. Der Wert 1 bedeutet, dass nur die Basisauflösung vorhanden ist, es also keine Mipmaps gibt.
Den Wert legst du beim Erzeugen der Ebene über die Option mipLevels fest, etwa bei XRWebGLBinding.createQuadLayer(), createCylinderLayer(), createEquirectLayer() oder createCubeLayer(). Projektionsebenen (XRProjectionLayer) haben immer genau ein Mip-Level. Die Eigenschaft zeigt, wie viele Levels tatsächlich angelegt wurden. Der Browser darf weniger Levels anlegen, als du angefordert hast. Deshalb solltest du immer den Wert der Eigenschaft auswerten und dich nicht auf deine Anfrage verlassen.
Mipmaps lohnen sich vor allem bei Ebenen, die aus größerer Entfernung oder schräg betrachtet werden, z. B. bei Texttafeln, Videoflächen oder Bedienelementen im Raum. Sie verringern Flimmern und Treppeneffekte (Aliasing). Für die Inhalte der höheren Levels bist du selbst verantwortlich. Meist zeichnest du Level 0 und rufst danach gl.generateMipmap() auf, oder du befüllst jedes Level einzeln.
Rückgabewert
Beispiele
Quad-Ebene mit Mipmaps anlegen und Wert prüfen
const session = await navigator.xr.requestSession('immersive-vr', {
requiredFeatures: ['layers']
});
const gl = document.createElement('canvas').getContext('webgl2', { xrCompatible: true });
const binding = new XRWebGLBinding(session, gl);
const space = await session.requestReferenceSpace('local');
// Breite und Höhe als Zweierpotenz, damit Mipmaps möglich sind
const quadLayer = binding.createQuadLayer({
space,
viewPixelWidth: 1024,
viewPixelHeight: 512,
mipLevels: 11 // log2(1024) + 1
});
console.log(`Angefordert: 11, erhalten: ${quadLayer.mipLevels}`);
session.updateRenderState({ layers: [quadLayer] });
Mipmaps im Frame-Loop erzeugen
const onXRFrame = (time, frame) => {
session.requestAnimationFrame(onXRFrame);
if (!quadLayer.needsRedraw) return;
const subImage = binding.getSubImage(quadLayer, frame);
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, subImage.colorTexture, 0);
gl.viewport(0, 0, subImage.viewport.width, subImage.viewport.height);
drawPanelContent(gl); // eigene Zeichenfunktion für Level 0
// Höhere Levels nur erzeugen, wenn es welche gibt
if (quadLayer.mipLevels > 1) {
gl.bindTexture(gl.TEXTURE_2D, subImage.colorTexture);
gl.generateMipmap(gl.TEXTURE_2D);
}
};
session.requestAnimationFrame(onXRFrame);
Benötigte Anzahl an Levels berechnen
const fullMipChain = (width, height) =>
Math.floor(Math.log2(Math.max(width, height))) + 1;
const isPowerOfTwo = (n) => (n & (n - 1)) === 0;
const width = 512;
const height = 256;
const requested = isPowerOfTwo(width) && isPowerOfTwo(height)
? fullMipChain(width, height)
: 1;
console.log(requested);
// Wichtig · Fallstricke
- Schreibgeschützt: Wenn du der Eigenschaft einen Wert zuweist, passiert nichts. Die Anzahl lässt sich nur beim Erzeugen der Ebene festlegen.
- Weniger Levels als angefordert: Der Browser darf weniger Mip-Levels anlegen, als du angefordert hast. Prüfe deshalb immer
layer.mipLevels, bevor du einzelne Levels ansprichst. - Zweierpotenzen: Wenn du
mipLevels > 1anforderst, obwohlviewPixelWidth/viewPixelHeightkeine Zweierpotenzen sind, oder einen Wert< 1angibst, wirft der Aufruf zum Erzeugen der Ebene einenInvalidStateError. - Projektionsebenen haben immer den Wert
1. - Leistung: Wenn du
generateMipmap()in jedem Frame aufrufst, kostet das GPU-Zeit. Tu es nur, wenn sich der Inhalt geändert hat, z. B. wennneedsRedrawgesetzt ist oder dein Inhalt sich geändert hat. - Kompatibilität: Die WebXR Layers API ist experimentell. Sie steht nur in einigen Chromium-basierten XR-Browsern zur Verfügung (z. B. im Meta Quest Browser) und nur, wenn du das Feature
'layers'in der Sitzung anforderst. Sie funktioniert ausschließlich in sicheren Kontexten (HTTPS). Prüfe die Unterstützung mit'XRWebGLBinding' in windowundtypeof XRWebGLBinding.prototype.createQuadLayer === 'function'.