Signatur
Beschreibung
Die schreibgeschützte Eigenschaft depthDataFormat einer XRSession gibt an, in welchem Format das Gerät die Tiefeninformationen tatsächlich bereitstellt. Sie ist nur in Sitzungen vom Typ immersive-ar sinnvoll, die mit dem Feature depth-sensing angefordert wurden.
Beim Aufruf von navigator.xr.requestSession() gibt die Anwendung im Wörterbuch depthSensing unter dataFormatPreference eine nach Priorität sortierte Liste gewünschter Formate an. Der Browser wählt davon ein Format aus, das er unterstützt. Welches es geworden ist, liest man anschließend über depthDataFormat ab. Mögliche Werte:
"luminance-alpha": 2 Byte pro Pixel. AlsUint16Arrayauszuwerten oder in WebGL alsLUMINANCE_ALPHA-Textur hochzuladen."float32": 4 Byte pro Pixel. AlsFloat32Arrayauszuwerten oder in WebGL 2 alsR32F-Textur hochzuladen."unsigned-short": 2 Byte pro Pixel (vorzeichenlose 16-Bit-Ganzzahl), neuerer Wert der Spezifikation.
Die Eigenschaft wird vor allem gebraucht, um die Rohdaten aus XRCPUDepthInformation.data richtig zu lesen oder um beim GPU-Pfad (XRWebGLDepthInformation.texture) im Shader die passende Dekodierung zu wählen. Rohwerte rechnet man mit rawValueToMeters in Meter um. Beim CPU-Pfad geht es auch direkt mit getDepthInMeters(x, y).
Rückgabewert
Beispiele
Sitzung mit Tiefenerkennung anfordern und Format auslesen
const startAR = async () => {
const session = await navigator.xr.requestSession('immersive-ar', {
requiredFeatures: ['depth-sensing'],
depthSensing: {
usagePreference: ['cpu-optimized', 'gpu-optimized'],
dataFormatPreference: ['luminance-alpha', 'float32']
}
});
console.log('Nutzung:', session.depthUsage);
console.log('Format:', session.depthDataFormat);
return session;
};
// Muss durch eine Benutzeraktion ausgelöst werden
document.querySelector('#ar-button').addEventListener('click', startAR);
Rohdaten der CPU-Tiefeninformation passend zum Format lesen
const createDepthReader = (session) => {
const ArrayType = session.depthDataFormat === 'float32'
? Float32Array
: Uint16Array; // luminance-alpha und unsigned-short: 2 Byte pro Pixel
return (depthInfo) => {
const raw = new ArrayType(depthInfo.data);
const cx = Math.floor(depthInfo.width / 2);
const cy = Math.floor(depthInfo.height / 2);
const value = raw[cy * depthInfo.width + cx];
return value * depthInfo.rawValueToMeters;
};
};
// Im Frame-Callback:
// const view = pose.views[0];
// const depthInfo = frame.getDepthInformation(view);
// if (depthInfo) console.log(readCenter(depthInfo).toFixed(2), 'm');
WebGL-Texturformat für den GPU-Pfad wählen
const depthTextureFormat = (session, gl) => {
switch (session.depthDataFormat) {
case 'float32':
return { internalFormat: gl.R32F, format: gl.RED, type: gl.FLOAT };
case 'unsigned-short':
return { internalFormat: gl.R16UI, format: gl.RED_INTEGER, type: gl.UNSIGNED_SHORT };
case 'luminance-alpha':
default:
return { internalFormat: gl.LUMINANCE_ALPHA, format: gl.LUMINANCE_ALPHA, type: gl.UNSIGNED_BYTE };
}
};
console.log(depthTextureFormat({ depthDataFormat: 'float32' }, WebGL2RenderingContext));
// Wichtig · Fallstricke
- Experimentell: Das Depth Sensing Module wird bisher im Wesentlichen nur von Chromium auf Android mit ARCore-fähigen Geräten unterstützt. Firefox und Safari bieten es nicht an. Vor der Nutzung sollte man mit
navigator.xr.isSessionSupported('immersive-ar')prüfen unddepth-sensingbesser alsoptionalFeaturesanfordern. - Wurde die Sitzung ohne das Feature
depth-sensingerstellt, wirft der Zugriff laut Spezifikation eineInvalidStateError-DOMException. Am besten vorhersession.enabledFeatures?.includes('depth-sensing')prüfen. - Der Browser muss die gewünschte Reihenfolge in
dataFormatPreferencenicht einhalten. Man sollte deshalb immer den tatsächlichen Wert auswerten und nicht davon ausgehen, dass das erste Format gewählt wurde. - Rohwerte immer mit
rawValueToMetersumrechnen. Bei"luminance-alpha"ergibt der Rohwert allein keine Meterangabe. - Der Wert ändert sich während der Sitzung nicht. Man kann ihn einmal nach dem Sitzungsstart zwischenspeichern.
- WebXR braucht einen sicheren Kontext (HTTPS), und die Sitzung muss durch eine Benutzeraktion gestartet werden.