Start · Sprachen · JavaScript · Referenz · XRCPUDepthInformation.getDepthInMeters()

XRCPUDepthInformation.getDepthInMeters()

Methode

Gibt die Entfernung in Metern am Punkt (<code>x</code>, <code>y</code>) in normalisierten Ansichtskoordinaten zurück. Der Ursprung liegt oben links.

seit JavaScript WebXR Depth Sensing Module (experimentell) – Chrom Kategorie: webapi

Signatur

XRCPUDepthInformation.prototype.getDepthInMeters(x, y)

Beschreibung

Mit getDepthInMeters() liest du aus einem XRCPUDepthInformation-Objekt die Entfernung zwischen der Kamera bzw. dem Betrachter und der realen Umgebung an einem bestimmten Bildpunkt aus. Die Koordinaten sind normalisiert: 0.0 steht für den linken bzw. oberen Rand der Ansicht, 1.0 für den rechten bzw. unteren Rand. Die Methode rechnet diese Werte intern über normDepthBufferFromNormView in Koordinaten des Tiefenpuffers um und wendet rawValueToMeters an.

Typische Einsatzfälle in AR-Anwendungen sind Hit-Tests ohne Ebenenerkennung, das Messen von Entfernungen, eine Verdeckung (Occlusion) in Software und die Prüfung, ob ein virtuelles Objekt hinter einem realen Gegenstand liegt. Weil die Werte auf der CPU liegen, eignet sich die Methode gut für einzelne Abfragen. Brauchst du jedes Pixel des Tiefenpuffers, ist der Weg über die GPU (XRWebGLDepthInformation) meist schneller.

Du bekommst das Objekt pro Frame über XRFrame.getDepthInformation(view). Voraussetzung ist eine Session mit dem Feature "depth-sensing" und usagePreference: ["cpu-optimized"]. Das Objekt gilt nur innerhalb des aktuellen requestAnimationFrame-Callbacks.

Parameter

Name Typ Default Beschreibung
$x Pflicht number Horizontale Koordinate in normalisierten Ansichtskoordinaten (0.0 = links, 1.0 = rechts).
$y Pflicht number Vertikale Koordinate in normalisierten Ansichtskoordinaten (0.0 = oben, 1.0 = unten).

Rückgabewert

Typ
number
Beschreibung
Die Entfernung in Metern (Gleitkommazahl). Der Wert 0 bedeutet in der Regel, dass für diesen Punkt keine gültige Tiefe vorliegt.

Beispiele

Session mit CPU-Tiefenerkennung starten und Bildmitte abfragen

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

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 depthInfo = frame.getDepthInformation(view);
    if (!depthInfo) continue;
    // Bildmitte abfragen
    const meters = depthInfo.getDepthInMeters(0.5, 0.5);
    console.log(`Entfernung Bildmitte: ${meters.toFixed(2)} m`);
  }
};

session.requestAnimationFrame(onFrame);
Entfernung Bildmitte: 1.37 m

Entfernung an einer Touch-Position messen

let tapPoint = null;

// Touch-Position in normalisierte Koordinaten umrechnen
canvas.addEventListener('pointerdown', (e) => {
  const rect = canvas.getBoundingClientRect();
  tapPoint = {
    x: (e.clientX - rect.left) / rect.width,
    y: (e.clientY - rect.top) / rect.height
  };
});

const measureAtTap = (frame, view) => {
  if (!tapPoint) return;
  const depthInfo = frame.getDepthInformation(view);
  if (!depthInfo) return;

  const d = depthInfo.getDepthInMeters(tapPoint.x, tapPoint.y);
  hud.textContent = d > 0 ? `${(d * 100).toFixed(0)} cm` : 'Keine Tiefe verfügbar';
  tapPoint = null;
};
HUD zeigt z. B. "84 cm"

Einfache Verdeckungsprüfung für ein virtuelles Objekt

// Liegt das virtuelle Objekt hinter einer realen Oberfläche?
const isOccluded = (depthInfo, normX, normY, objectDistance) => {
  const realDepth = depthInfo.getDepthInMeters(normX, normY);
  if (realDepth === 0) return false; // ungültiger Messwert
  return realDepth < objectDistance;
};

// Aufruf innerhalb des Frame-Callbacks
console.log(isOccluded(depthInfo, 0.3, 0.6, 2.0));
true

// Wichtig · Fallstricke

  • Experimentelle API: Das Depth-Sensing-Modul funktioniert derzeit praktisch nur in Chromium-Browsern unter Android mit ARCore-fähigen Geräten. Firefox und Safari unterstützen es nicht. Frage die Unterstützung vorab mit navigator.xr.isSessionSupported('immersive-ar') ab und fange Fehler beim Anfordern der Session ab.
  • Liegt x oder y außerhalb von [0, 1], wird ein RangeError geworfen.
  • Wird die Methode außerhalb des Frame-Callbacks aufgerufen, in dem das Objekt entstanden ist, oder ist der Frame nicht aktiv, wird ein InvalidStateError (DOMException) geworfen. Speichere XRCPUDepthInformation also nicht über mehrere Frames hinweg.
  • getDepthInformation() gibt null zurück, wenn gerade keine Tiefendaten vorliegen. Prüfe das immer vorher.
  • Die Auflösung des Tiefenpuffers (width/height) ist deutlich geringer als die Kameraauflösung, und die Werte schwanken. Für stabile Ergebnisse glättest du über mehrere Frames oder mittelst benachbarte Punkte.
  • Viele Aufrufe pro Frame, etwa für jedes Pixel, kosten viel Rechenzeit. Für die Verdeckung ganzer Szenen ist die GPU-Variante (gpu-optimized) die bessere Wahl.
  • Die API ist nur in sicheren Kontexten (HTTPS) verfügbar.