Start · Sprachen · JavaScript · Referenz · XRWebGLBinding.getReflectionCubeMap()

XRWebGLBinding.getReflectionCubeMap()

Methode

Gibt eine <code>WebGLTexture</code> mit der aktuellen Reflexions-Cube-Map einer <code>XRLightProbe</code> zurück, um realistische Spiegelungen in AR zu rendern.

seit JavaScript Experimentell: Chrome/Edge 90+ (Android mit ARCore Kategorie: webapi

Signatur

XRWebGLBinding.prototype.getReflectionCubeMap(lightProbe)

Beschreibung

Die Methode getReflectionCubeMap() gehört zur WebXR Lighting Estimation API. Sie liefert zu einer XRLightProbe eine Cube-Map-Textur (TEXTURE_CUBE_MAP), die das Gerät aus der realen Umgebung schätzt. Diese Textur kannst du als Umgebungs-Map (Environment Map) für physikalisch basiertes Rendering (PBR) verwenden, damit virtuelle Objekte glänzende Oberflächen mit plausiblen Spiegelungen der echten Umgebung zeigen.

Voraussetzung ist eine immersive-ar-Sitzung mit dem Feature "light-estimation". Die Licht-Sonde erhältst du über XRSession.requestLightProbe(). Da das Erfassen der Umgebung Zeit braucht und sich die Umgebung verändert, solltest du auf das Ereignis reflectionchange der Sonde hören und die Cube-Map erst dann (neu) abrufen – nicht in jedem Frame.

Das Format der Textur hängt vom beim Anfordern der Sonde gewählten reflectionFormat ab: "srgba8" (Standard, 8 Bit sRGB) oder "rgba16f" (Half-Float, HDR). Welches Format das Gerät bevorzugt, verrät XRSession.preferredReflectionFormat.

Parameter

Name Typ Default Beschreibung
$lightProbe Pflicht XRLightProbe Die über XRSession.requestLightProbe() erzeugte Licht-Sonde, deren Reflexions-Map abgefragt werden soll. Sie muss zur selben XRSession gehören wie die Bindung.

Rückgabewert

Typ
WebGLTexture | null
Beschreibung
Eine WebGLTexture vom Typ Cube-Map mit der geschätzten Umgebungsreflexion, oder null, wenn (noch) keine Reflexionsdaten verfügbar sind.

Beispiele

AR-Sitzung mit Lichtschätzung und Cube-Map abrufen

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl2', { xrCompatible: true });

const startAR = async () => {
  const session = await navigator.xr.requestSession('immersive-ar', {
    requiredFeatures: ['light-estimation']
  });
  await session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });

  const glBinding = new XRWebGLBinding(session, gl);
  const lightProbe = await session.requestLightProbe();

  let envMap = null;
  lightProbe.addEventListener('reflectionchange', () => {
    // Nur bei Änderung neu abrufen – nicht in jedem Frame
    envMap = glBinding.getReflectionCubeMap(lightProbe);
    console.log('Neue Reflexions-Map:', envMap);
  });

  return { session, glBinding, lightProbe, getEnvMap: () => envMap };
};

document.querySelector('#ar-button').addEventListener('click', startAR);
Neue Reflexions-Map: WebGLTexture {}

Bevorzugtes HDR-Format nutzen

const setupProbe = async (session, gl) => {
  const format = session.preferredReflectionFormat; // 'srgba8' oder 'rgba16f'

  // Für rgba16f unter WebGL 1 wird die Half-Float-Erweiterung benötigt
  if (format === 'rgba16f' && !(gl instanceof WebGL2RenderingContext)) {
    gl.getExtension('OES_texture_half_float');
  }

  const lightProbe = await session.requestLightProbe({ reflectionFormat: format });
  const glBinding = new XRWebGLBinding(session, gl);

  lightProbe.addEventListener('reflectionchange', () => {
    const cubeMap = glBinding.getReflectionCubeMap(lightProbe);
    console.log(`Cube-Map im Format ${format}:`, cubeMap !== null);
  });

  return lightProbe;
};
Cube-Map im Format rgba16f: true

Cube-Map im Render-Loop als Umgebungs-Map binden

// Annahme: program, envMap (aus reflectionchange) und uEnvMap-Uniform existieren
const drawObject = (gl, program, envMap) => {
  gl.useProgram(program);
  if (envMap) {
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_CUBE_MAP, envMap);
    gl.uniform1i(gl.getUniformLocation(program, 'uEnvMap'), 0);
  }
  // ... Geometrie zeichnen
};

// Mit three.js wäre das Pendant z. B. XREstimatedLight aus den Addons

// Wichtig · Fallstricke

  • Experimentell: Nur in Chromium-Browsern auf Android mit ARCore verfügbar; Firefox und Safari unterstützen die Lighting Estimation API nicht. Vorher per navigator.xr.isSessionSupported('immersive-ar') und 'getReflectionCubeMap' in XRWebGLBinding.prototype prüfen.
  • Erfordert einen sicheren Kontext (HTTPS) und das Feature "light-estimation" beim Sitzungsaufbau – sonst schlägt requestLightProbe() fehl.
  • Gehört die Licht-Sonde zu einer anderen Sitzung als die Bindung, wird eine InvalidStateError-DOMException ausgelöst.
  • Der Rückgabewert kann null sein, solange noch keine Umgebungsdaten vorliegen – immer prüfen, bevor die Textur gebunden wird.
  • Performance: Nicht in jedem Frame aufrufen, sondern nur nach dem reflectionchange-Ereignis. Die zurückgegebene Textur wird vom Browser verwaltet; nicht selbst mit deleteTexture() freigeben.
  • Beim Format "rgba16f" muss unter WebGL 1 die Erweiterung OES_texture_half_float aktiviert sein.
  • Datenschutz: Reflexions-Maps können Details der realen Umgebung enthalten; Browser liefern daher oft nur grobe, niedrig aufgelöste Daten.