Signatur
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
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 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;
};
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));
// 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
xoderyaußerhalb von[0, 1], wird einRangeErrorgeworfen. - 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. SpeichereXRCPUDepthInformationalso nicht über mehrere Frames hinweg. getDepthInformation()gibtnullzurü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.