Start · Sprachen · JavaScript · Referenz · XRLightEstimate.primaryLightDirection

XRLightEstimate.primaryLightDirection

Eigenschaft

Schreibgeschützter <code>DOMPointReadOnly</code> mit der normierten Richtung vom <code>probeSpace</code> einer <code>XRLightProbe</code> zur hellsten Lichtquelle der realen Umgebung.

seit JavaScript WebXR Lighting Estimation Module – experimentell, Kategorie: webapi

Signatur

XRLightEstimate.primaryLightDirection

Beschreibung

Die schreibgeschützte Eigenschaft primaryLightDirection eines XRLightEstimate-Objekts gibt an, aus welcher Richtung das stärkste Licht der realen Umgebung kommt. Der Wert ist ein DOMPointReadOnly. Er beschreibt einen Richtungsvektor im Koordinatensystem des probeSpace der zugehörigen XRLightProbe, also vom Probe-Ursprung hin zur Lichtquelle.

Den Wert brauchst du vor allem in AR-Anwendungen (immersive-ar), in denen virtuelle Objekte glaubwürdig beleuchtet werden und Schatten werfen sollen. Normalerweise nimmst du den Vektor als Richtung für ein gerichtetes Licht deiner 3D-Engine, etwa DirectionalLight in three.js. Die passende Farbe und Stärke liefert primaryLightIntensity.

Bei einem Richtungsvektor ist die w-Komponente immer 0. Die Komponenten x, y und z ergeben einen normierten Vektor der Länge 1. Findet der Browser keine eindeutige Hauptlichtquelle, liefert er als Ersatzwert in der Regel {x: 0, y: 1, z: 0, w: 0}, also Licht von direkt oben.

Rückgabewert

Typ
DOMPointReadOnly
Beschreibung
Ein normierter Richtungsvektor (w = 0) im probeSpace der XRLightProbe. Er zeigt zur primären Lichtquelle.

Beispiele

Lichtrichtung pro Frame auslesen

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 verfügbar

  const { x, y, z, w } = estimate.primaryLightDirection;
  console.log(`Licht aus Richtung (${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}), w=${w}`);
};
session.requestAnimationFrame(onFrame);
Licht aus Richtung (0.31, 0.89, -0.33), w=0

three.js-DirectionalLight an der realen Sonne ausrichten

import * as THREE from 'three';

const sun = new THREE.DirectionalLight(0xffffff, 1);
sun.castShadow = true;
scene.add(sun, sun.target);

const applyLightEstimate = (frame, lightProbe, refSpace) => {
  const estimate = frame.getLightEstimate(lightProbe);
  if (!estimate) return;

  // Richtung ist relativ zum probeSpace -> in den Referenzraum umrechnen
  const probePose = frame.getPose(lightProbe.probeSpace, refSpace);
  const dir = new THREE.Vector3(
    estimate.primaryLightDirection.x,
    estimate.primaryLightDirection.y,
    estimate.primaryLightDirection.z
  );
  if (probePose) {
    const o = probePose.transform.orientation;
    dir.applyQuaternion(new THREE.Quaternion(o.x, o.y, o.z, o.w));
  }

  // Licht in Richtung der Quelle versetzen und auf den Ursprung zielen
  sun.position.copy(dir.multiplyScalar(10));
  sun.target.position.set(0, 0, 0);

  const { x: r, y: g, z: b } = estimate.primaryLightIntensity;
  const max = Math.max(r, g, b, 1e-4);
  sun.color.setRGB(r / max, g / max, b / max);
  sun.intensity = max;
};

Auf Änderungen der Lichtverhältnisse reagieren

const lightProbe = await session.requestLightProbe();
let latestDirection = null;

// 'reflectionchange' zeigt eine neue Umgebungs-Cubemap an – guter Anlass zum Aktualisieren
lightProbe.addEventListener('reflectionchange', () => {
  console.log('Umgebungslicht hat sich geändert');
});

session.requestAnimationFrame(function loop(t, frame) {
  session.requestAnimationFrame(loop);
  const est = frame.getLightEstimate(lightProbe);
  if (est) latestDirection = est.primaryLightDirection;
});
Umgebungslicht hat sich geändert

// Wichtig · Fallstricke

  • Experimentelle API: Das Lighting Estimation Module wird bisher im Wesentlichen nur von Chrome für Android (mit ARCore) unterstützt. Firefox und Safari bieten es nicht an. Prüfe die Unterstützung vorher mit navigator.xr.isSessionSupported('immersive-ar'). Das Feature 'light-estimation' musst du beim Start der Sitzung anfordern.
  • Nur im sicheren Kontext: Die API steht nur über HTTPS zur Verfügung. Außerdem muss die Seite eine immersive Sitzung starten dürfen, was eine Nutzeraktion voraussetzt.
  • Koordinatensystem beachten: Die Richtung bezieht sich auf den probeSpace der Probe, nicht auf deinen Referenzraum. Rechne sie über frame.getPose(lightProbe.probeSpace, refSpace) um, bevor du sie in der Szene verwendest.
  • Richtung zur Quelle: Der Vektor zeigt zur Lichtquelle hin, nicht in die Richtung, in die das Licht fällt. Engines, die eine Ausbreitungsrichtung erwarten, brauchen den umgekehrten Vektor.
  • frame.getLightEstimate() kann null zurückgeben, besonders in den ersten Frames. Prüfe den Wert deshalb immer vor dem Zugriff.
  • Datenschutz: Lichtdaten können Hinweise auf die Umgebung der Nutzerin oder des Nutzers geben. Browser können die Werte deshalb mit Absicht ungenau machen oder nur selten aktualisieren.