Signatur
Beschreibung
Die schreibgeschützte Eigenschaft sphericalHarmonicsCoefficients von XRLightEstimate gehört zur WebXR Lighting Estimation API. Sie liefert ein Float32Array, das die vom Gerät geschätzte Beleuchtung der realen Umgebung als Kugelflächenfunktionen (Spherical Harmonics) zweiter Ordnung (L2) beschreibt. Es sind 9 Koeffizienten mit je einem Rot-, Grün- und Blauwert, das Array hat also 27 Elemente in der Reihenfolge [r0, g0, b0, r1, g1, b1, …].
Mit diesen Koeffizienten lässt sich diffuses Umgebungslicht in einem Shader sehr effizient nachbilden. Virtuelle Objekte in einer AR-Sitzung (immersive-ar) wirken dadurch so, als würden sie vom echten Raumlicht beleuchtet. Viele Engines können die Werte direkt übernehmen, zum Beispiel THREE.LightProbe in three.js oder die Umgebungsbeleuchtung in Babylon.js.
Ein XRLightEstimate bekommt man pro Frame über XRFrame.getLightEstimate(lightProbe). Die dafür nötige XRLightProbe erzeugt man vorher mit XRSession.requestLightProbe(). Die Sitzung muss mit dem Feature "light-estimation" angefordert worden sein. Die Koeffizienten beziehen sich auf das Koordinatensystem von XRLightProbe.probeSpace.
Rückgabewert
Float32Array mit 27 Werten: 9 L2-Koeffizienten zu je 3 Farbkanälen (RGB), verschachtelt angeordnet.Beispiele
AR-Sitzung mit Lichtschätzung starten und Koeffizienten lesen
const startAR = async () => {
const session = await navigator.xr.requestSession('immersive-ar', {
requiredFeatures: ['light-estimation']
});
const refSpace = await session.requestReferenceSpace('local');
const lightProbe = await session.requestLightProbe();
const onFrame = (time, frame) => {
session.requestAnimationFrame(onFrame);
const estimate = frame.getLightEstimate(lightProbe);
if (!estimate) return; // noch keine Schätzung vorhanden
const sh = estimate.sphericalHarmonicsCoefficients;
console.log('Anzahl Werte:', sh.length);
};
session.requestAnimationFrame(onFrame);
};
// Muss durch eine Benutzeraktion ausgelöst werden
document.querySelector('#ar-button').addEventListener('click', startAR);
Koeffizienten an eine three.js-LightProbe übergeben
import * as THREE from 'three';
const scene = new THREE.Scene();
const probe = new THREE.LightProbe();
scene.add(probe);
// im XR-Frame-Callback aufrufen
const applyLightEstimate = (frame, xrLightProbe) => {
const estimate = frame.getLightEstimate(xrLightProbe);
if (!estimate) return;
// SphericalHarmonics3.fromArray erwartet genau 27 Werte
probe.sh.fromArray(estimate.sphericalHarmonicsCoefficients);
probe.intensity = 1;
};
Mittlere Umgebungsfarbe aus dem L0-Koeffizienten ableiten
// Y00-Basiskonstante: 1 / (2 * sqrt(pi))
const Y00 = 0.282095;
const ambientColor = (estimate) => {
const sh = estimate.sphericalHarmonicsCoefficients;
const [r, g, b] = [sh[0], sh[1], sh[2]].map((c) => Math.max(0, c * Y00));
return { r, g, b };
};
// Verwendung im Frame-Callback:
// const { r, g, b } = ambientColor(frame.getLightEstimate(lightProbe));
// ambientLight.color.setRGB(r, g, b);
// Wichtig · Fallstricke
- Das Array hat 27 Werte, nicht 9: Jeder der 9 Koeffizienten besteht aus einem RGB-Tripel. Wer nur 9 Werte ausliest, bekommt falsche Farben.
XRFrame.getLightEstimate()kannnullzurückgeben, solange das Gerät noch keine Schätzung hat. Das vor dem Zugriff immer prüfen.- Die Werte sind im Koordinatensystem von
probeSpaceangegeben. Weicht dieses vom Referenzraum der Szene ab, muss man die Koeffizienten passend drehen. - Die Werte sind lineare Strahlungswerte (keine sRGB-Werte). Je nach Renderer braucht man noch eine Farbraum-Umwandlung oder Tonemapping.
- Kompatibilität: Die API ist experimentell und wird derzeit nur von Chromium auf Android mit ARCore unterstützt. Sie braucht einen sicheren Kontext (HTTPS) und eine aktive
immersive-ar-Sitzung mit dem Feature"light-estimation". Vorher mitnavigator.xr?.isSessionSupported('immersive-ar')prüfen. - Datenschutz: Aus Lichtdaten lassen sich Rückschlüsse auf die Umgebung ziehen. Browser können die Werte deshalb ungenauer machen oder die Funktion nur nach Zustimmung des Nutzers freigeben.