Signatur
Beschreibung
Die schreibgeschützte Eigenschaft primaryLightIntensity eines XRLightEstimate gibt die geschätzte Intensität der stärksten Lichtquelle in der realen Umgebung an. Der Wert ist ein DOMPointReadOnly: x, y und z stehen für den Rot-, Grün- und Blauanteil, w ist immer 1. Die Werte sind lineare Farbintensitäten und können größer als 1 sein. Normiert auf 0–1 sind sie also nicht.
Zusammen mit primaryLightDirection kannst du damit in einer AR-Szene ein gerichtetes Licht (z. B. ein DirectionalLight in three.js) so einstellen, dass virtuelle Objekte ähnlich beleuchtet werden wie die echte Umgebung und passende Schatten werfen. Für das Umgebungslicht aus allen Richtungen ist dagegen sphericalHarmonicsCoefficients zuständig.
Einen XRLightEstimate bekommst du pro Frame über XRFrame.getLightEstimate(lightProbe). Die XRLightProbe dazu erzeugst du vorher mit XRSession.requestLightProbe(). Dafür muss die Sitzung mit dem Feature "light-estimation" gestartet worden sein. Findet das System keine eindeutige Hauptlichtquelle, ist die Intensität {x: 0, y: 0, z: 0, w: 1}.
Rückgabewert
x, y und z die lineare RGB-Intensität der primären Lichtquelle angeben. w ist immer 1. Gibt es keine erkennbare Hauptlichtquelle, sind alle Farbanteile 0.Beispiele
AR-Sitzung mit Lichtschätzung starten und Intensität auslesen
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 { x: r, y: g, z: b } = estimate.primaryLightIntensity;
console.log(`Primärlicht RGB: ${r.toFixed(2)}, ${g.toFixed(2)}, ${b.toFixed(2)}`);
};
session.requestAnimationFrame(onFrame);
};
document.querySelector('#ar-button').addEventListener('click', startAR);
three.js-DirectionalLight an reale Beleuchtung anpassen
import * as THREE from 'three';
const sunLight = new THREE.DirectionalLight();
scene.add(sunLight);
const applyLightEstimate = (estimate) => {
const { x: r, y: g, z: b } = estimate.primaryLightIntensity;
// Größte Komponente als Gesamtintensität, Rest als Farbe
const intensity = Math.max(r, g, b);
if (intensity > 0) {
sunLight.color.setRGB(r / intensity, g / intensity, b / intensity);
}
sunLight.intensity = intensity;
const dir = estimate.primaryLightDirection;
sunLight.position.set(dir.x, dir.y, dir.z);
};
// in der XR-Frame-Schleife:
// const estimate = frame.getLightEstimate(lightProbe);
// if (estimate) applyLightEstimate(estimate);
Fehlende Hauptlichtquelle erkennen
const hasPrimaryLight = (estimate) => {
const { x, y, z } = estimate.primaryLightIntensity;
return x + y + z > 0;
};
// in der Frame-Schleife:
// if (!hasPrimaryLight(estimate)) sunLight.visible = false;
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Eigenschaft ist experimentell und praktisch nur in Chromium-Browsern auf Android mit ARCore verfügbar. Firefox und Safari unterstützen sie nicht. Frag vorher mit
navigator.xr.isSessionSupported('immersive-ar')nach und fordere"light-estimation"besser alsoptionalFeaturesan, damit die Sitzung auch ohne das Feature startet. - Nur in einem sicheren Kontext (HTTPS) verfügbar. Die Nutzung kann per Permissions-Policy
xr-spatial-trackingeingeschränkt sein. - Die Werte sind lineare Intensitäten, keine sRGB-Farben, und können größer als 1 sein. Rechne sie also nicht direkt in CSS-Farben um. Nutze sie in einer Render-Pipeline mit linearem Farbraum.
getLightEstimate()kannnullzurückgeben, solange noch keine Schätzung vorliegt. Prüf das, bevor du auf die Eigenschaft zugreifst.- Datenschutz: Die Werte werden absichtlich ungenau gehalten und nur mit begrenzter Rate aktualisiert, damit sich daraus keine Rückschlüsse auf die Umgebung ziehen lassen (Fingerprinting). Der Wert kann deshalb über mehrere Frames gleich bleiben.