Start · Sprachen · JavaScript · Referenz · XRProjectionLayer.textureHeight

XRProjectionLayer.textureHeight

Eigenschaft

Schreibgeschützte Eigenschaft, die die Höhe der Farbtexturen einer <code>XRProjectionLayer</code> in Pixeln als Ganzzahl liefert.

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

Signatur

XRProjectionLayer.textureHeight

Beschreibung

Die Eigenschaft textureHeight einer XRProjectionLayer gibt an, wie hoch (in Pixeln) die Farbtexturen sind, die der Browser für diese Projektionsebene bereitstellt. Die Größe legst du nicht direkt fest. Der Browser (User Agent) bestimmt sie beim Erzeugen der Ebene über XRWebGLBinding.createProjectionLayer(). Dabei richtet er sich nach der nativen Auflösung des Geräts und nach der Option scaleFactor.

Du brauchst den Wert vor allem, wenn eigene GPU-Ressourcen genau zur Ebene passen müssen. Beispiele sind ein eigener Tiefenpuffer (wenn beim Erzeugen depthFormat: 0 angegeben wurde), Offscreen-Renderziele für Nachbearbeitung oder Multisampling-Renderbuffer. Zusammen mit textureWidth und textureArrayLength beschreibt der Wert die vollständige Geometrie der Texturen.

Wichtig: textureHeight ist die Höhe der gesamten Textur und nicht die Höhe eines einzelnen Augen-Bildbereichs. Welcher Ausschnitt für eine bestimmte Ansicht gilt, erfährst du in jedem Frame über XRWebGLBinding.getViewSubImage() bzw. über dessen Eigenschaft viewport.

Rückgabewert

Typ
number
Beschreibung
Eine positive Ganzzahl (unsigned long): die Höhe der Farbtexturen der Ebene in Pixeln. Der Wert ist schreibgeschützt.

Beispiele

Texturgröße nach dem Erzeugen der Ebene ausgeben

const startXR = async (canvas) => {
  const session = await navigator.xr.requestSession('immersive-vr', {
    requiredFeatures: ['layers']
  });
  const gl = canvas.getContext('webgl2', { xrCompatible: true });
  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(`Textur: ${layer.textureWidth} x ${layer.textureHeight}, Layer: ${layer.textureArrayLength}`);
  return { session, gl, binding, layer };
};

document.querySelector('#enter-vr').addEventListener('click', () => {
  startXR(document.querySelector('canvas'));
});
Textur: 1832 x 1920, Layer: 2 (gerätabhängig)

Eigenen Tiefenpuffer passend zur Ebene anlegen

// Ebene ohne vom Browser verwalteten Tiefenpuffer erzeugen
const layer = binding.createProjectionLayer({
  textureType: 'texture',
  colorFormat: gl.RGBA8,
  depthFormat: 0
});

// Eigenen Tiefen-Renderbuffer exakt in Texturgröße anlegen
const depthBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
gl.renderbufferStorage(
  gl.RENDERBUFFER,
  gl.DEPTH_COMPONENT24,
  layer.textureWidth,
  layer.textureHeight
);

const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);

Gesamthöhe mit dem Viewport pro Auge vergleichen

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

  for (const view of pose.views) {
    const subImage = binding.getViewSubImage(layer, view);
    const { x, y, width, height } = subImage.viewport;
    // height ist höchstens so groß wie layer.textureHeight
    console.log(view.eye, height, '/', layer.textureHeight);
    gl.viewport(x, y, width, height);
  }
};
session.requestAnimationFrame(onXRFrame);
left 1920 / 1920 right 1920 / 1920

// Wichtig · Fallstricke

  • Kompatibilität: Die WebXR Layers API ist experimentell und steht nur in Chromium-basierten Browsern zur Verfügung, vor allem im Meta Quest Browser und in Chrome mit WebXR. Firefox und Safari unterstützen sie derzeit nicht. Die API funktioniert nur in einem sicheren Kontext (HTTPS), und die Sitzung muss mit dem Feature 'layers' angefordert worden sein.
  • Nicht mit der Viewport-Größe verwechseln: Bei textureType: 'texture' liegen beide Augen oft in einer Textur. Deren Höhe entspricht dann zwar meist der Höhe eines Auges, die Breite aber nicht. Für das Rendern gilt immer getViewSubImage(...).viewport.
  • Nicht ableitbar: Die tatsächliche Größe hängt vom Gerät und vom scaleFactor ab. Der Browser kann sie außerdem nach oben begrenzen (siehe XRWebGLBinding.nativeProjectionScaleFactor). Rechne sie also nicht selbst aus, sondern lies sie immer aus.
  • Der Wert bleibt über die Lebensdauer der Ebene gleich. Für eine andere Auflösung musst du eine neue Ebene erzeugen und per updateRenderState() setzen.