Signatur
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
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);
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 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.prototypeprüfen. - Erfordert einen sicheren Kontext (HTTPS) und das Feature
"light-estimation"beim Sitzungsaufbau – sonst schlägtrequestLightProbe()fehl. - Gehört die Licht-Sonde zu einer anderen Sitzung als die Bindung, wird eine
InvalidStateError-DOMExceptionausgelöst. - Der Rückgabewert kann
nullsein, 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 mitdeleteTexture()freigeben. - Beim Format
"rgba16f"muss unter WebGL 1 die ErweiterungOES_texture_half_floataktiviert sein. - Datenschutz: Reflexions-Maps können Details der realen Umgebung enthalten; Browser liefern daher oft nur grobe, niedrig aufgelöste Daten.