Start · Sprachen · JavaScript · Referenz · XRLightEstimate.primaryLightIntensity

XRLightEstimate.primaryLightIntensity

Eigenschaft

Liefert ein schreibgeschütztes <code>DOMPointReadOnly</code> mit der RGB-Intensität der primären (hellsten) Lichtquelle, die im <code>probeSpace</code> einer <code>XRLightProbe</code> geschätzt wurde.

seit JavaScript WebXR Lighting Estimation Module; Chromium-Browser Kategorie: webapi

Signatur

XRLightEstimate.primaryLightIntensity

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

Typ
DOMPointReadOnly
Beschreibung
Ein Punkt, dessen 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);
Primärlicht RGB: 1.84, 1.72, 1.55

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 als optionalFeatures an, damit die Sitzung auch ohne das Feature startet.
  • Nur in einem sicheren Kontext (HTTPS) verfügbar. Die Nutzung kann per Permissions-Policy xr-spatial-tracking eingeschrä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() kann null zurü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.