Signatur
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
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);
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));
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 alsoptionalFeaturesanfordern. - Nur im aktiven Frame gültig: Beim Zugriff auf ein
XRCPUDepthInformation-Objekt außerhalb des zugehörigenrequestAnimationFrame-Callbacks wird einInvalidStateErrorausgelöst. Werte also nicht zwischenspeichern und später auslesen. - Nicht mit der Viewport-Größe verwechseln:
widthist die Auflösung der Tiefenkarte, nicht die des Canvas. Zum Abbilden von Bildschirmkoordinaten stattdessengetDepthInMeters(x, y)mit normalisierten Koordinaten odernormDepthBufferFromNormViewverwenden. - Die Auflösung kann sich je nach Gerät und im Lauf einer Sitzung ändern – Puffer und Texturen daher bei jedem Frame an
width/heightanpassen, statt feste Werte zu verwenden. - Bei
'float32'-Daten einenFloat32Array, bei'luminance-alpha'einenUint16Arraynutzen; der Index ist in beiden Fälleny * 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).