Start · Sprachen · JavaScript · Referenz · XRDepthInformation.width

XRDepthInformation.width

Eigenschaft

Schreibgeschützte Eigenschaft, die die Breite des Tiefenpuffers einer WebXR-Tiefenmessung in Pixeln (Anzahl der Spalten) als <code>unsigned long</code> liefert.

seit JavaScript Experimentell: Chrome/Edge 90+ (Android, ARCore), Kategorie: webapi

Signatur

XRDepthInformation.width

Beschreibung

Die schreibgeschützte Eigenschaft width der Schnittstelle XRDepthInformation gibt an, wie viele Spalten der Tiefenpuffer hat, den die WebXR Depth Sensing API für einen Frame bereitstellt. Zusammen mit height beschreibt sie die Auflösung der Tiefenkarte.

Die Tiefenkarte hat in der Regel eine deutlich geringere Auflösung als der Kamera- oder Darstellungspuffer (z. B. 160×90 oder 256×192). Daher braucht man width immer dann, wenn man den Puffer selbst durchläuft, eine WebGL-Textur anlegt oder Pixelkoordinaten in normalisierte Koordinaten umrechnet.

Die Eigenschaft steht sowohl bei XRCPUDepthInformation (Zugriff über XRFrame.getDepthInformation(), Daten in data als ArrayBuffer) als auch bei XRWebGLDepthInformation (Zugriff über XRWebGLBinding.getDepthInformation(), Daten als WebGLTexture) zur Verfügung, da beide von XRDepthInformation erben.

Rückgabewert

Typ
number
Beschreibung
Eine positive Ganzzahl (unsigned long) mit der Anzahl der Spalten des Tiefenpuffers.

Beispiele

Auflösung der Tiefenkarte im Render-Loop auslesen

const session = await navigator.xr.requestSession('immersive-ar', {
  requiredFeatures: ['depth-sensing'],
  depthSensing: {
    usagePreference: ['cpu-optimized'],
    dataFormatPreference: ['luminance-alpha']
  }
});
const refSpace = await session.requestReferenceSpace('local');

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

  for (const view of pose.views) {
    const depth = frame.getDepthInformation(view);
    if (depth) {
      console.log(`Tiefenkarte: ${depth.width} x ${depth.height}`);
    }
  }
};
session.requestAnimationFrame(onFrame);
Tiefenkarte: 160 x 90

Pixel des CPU-Tiefenpuffers manuell durchlaufen

// depth ist ein XRCPUDepthInformation im Format 'luminance-alpha' (Uint16)
const findNearestPoint = (depth) => {
  const values = new Uint16Array(depth.data);
  let min = Infinity;
  let minX = 0, minY = 0;

  for (let y = 0; y < depth.height; y++) {
    for (let x = 0; x < depth.width; x++) {
      const raw = values[y * depth.width + x]; // Zeilenindex * Breite + Spalte
      if (raw === 0) continue; // 0 = kein gültiger Messwert
      const meters = raw * depth.rawValueToMeters;
      if (meters < min) { min = meters; minX = x; minY = y; }
    }
  }
  return { x: minX / depth.width, y: minY / depth.height, meters: min };
};

console.log(findNearestPoint(depth));
{ x: 0.49375, y: 0.6, meters: 0.42 }

Pixelbreite für Shader-Uniform berechnen (GPU-Pfad)

const glBinding = new XRWebGLBinding(session, gl);

const updateDepthUniforms = (view, program) => {
  const depth = glBinding.getDepthInformation(view);
  if (!depth) return;
  // Größe eines Texels, z. B. für Weichzeichnung/Nachbarabfragen im Shader
  const loc = gl.getUniformLocation(program, 'uDepthTexelSize');
  gl.uniform2f(loc, 1 / depth.width, 1 / depth.height);
};

// Wichtig · Fallstricke

  • Experimentelle API: Depth Sensing ist derzeit nur in Chromium-Browsern auf Android mit ARCore-fähigen Geräten verfügbar; Firefox und Safari unterstützen sie nicht. Vorher mit navigator.xr.isSessionSupported('immersive-ar') prüfen und 'depth-sensing' möglichst als optionalFeatures anfordern.
  • Nur im aktiven Frame gültig: Beim Zugriff auf ein XRCPUDepthInformation-Objekt außerhalb des zugehörigen requestAnimationFrame-Callbacks wird ein InvalidStateError ausgelöst. Werte also nicht zwischenspeichern und später auslesen.
  • Nicht mit der Viewport-Größe verwechseln: width ist die Auflösung der Tiefenkarte, nicht die des Canvas. Zum Abbilden von Bildschirmkoordinaten stattdessen getDepthInMeters(x, y) mit normalisierten Koordinaten oder normDepthBufferFromNormView verwenden.
  • Die Auflösung kann sich je nach Gerät und im Lauf einer Sitzung ändern – Puffer und Texturen daher bei jedem Frame an width/height anpassen, statt feste Werte zu verwenden.
  • Bei 'float32'-Daten einen Float32Array, bei 'luminance-alpha' einen Uint16Array nutzen; der Index ist in beiden Fällen y * width + x.
  • Die Tiefenmessung erlaubt Rückschlüsse auf die Umgebung des Nutzers; Browser verlangen daher eine ausdrückliche Zustimmung und einen sicheren Kontext (HTTPS).