three-stdlib
Version:
stand-alone library of threejs examples
128 lines (127 loc) • 4.56 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
class SessionLightProbe {
constructor(xrLight, renderer, lightProbe, environmentEstimation, estimationStartCallback) {
this.xrLight = xrLight;
this.renderer = renderer;
this.lightProbe = lightProbe;
this.xrWebGLBinding = null;
this.estimationStartCallback = estimationStartCallback;
this.frameCallback = this.onXRFrame.bind(this);
const session = renderer.xr.getSession();
if (environmentEstimation && "XRWebGLBinding" in window) {
const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(16);
xrLight.environment = cubeRenderTarget.texture;
const gl = renderer.getContext();
switch (session.preferredReflectionFormat) {
case "srgba8":
gl.getExtension("EXT_sRGB");
break;
case "rgba16f":
gl.getExtension("OES_texture_half_float");
break;
}
this.xrWebGLBinding = new XRWebGLBinding(session, gl);
this.lightProbe.addEventListener("reflectionchange", () => {
this.updateReflection();
});
}
session.requestAnimationFrame(this.frameCallback);
}
updateReflection() {
const textureProperties = this.renderer.properties.get(this.xrLight.environment);
if (textureProperties) {
const cubeMap = this.xrWebGLBinding.getReflectionCubeMap(this.lightProbe);
if (cubeMap) {
textureProperties.__webglTexture = cubeMap;
this.xrLight.environment.needsPMREMUpdate = true;
}
}
}
onXRFrame(time, xrFrame) {
if (!this.xrLight) {
return;
}
const session = xrFrame.session;
session.requestAnimationFrame(this.frameCallback);
const lightEstimate = xrFrame.getLightEstimate(this.lightProbe);
if (lightEstimate) {
this.xrLight.lightProbe.sh.fromArray(lightEstimate.sphericalHarmonicsCoefficients);
this.xrLight.lightProbe.intensity = 1;
const intensityScalar = Math.max(
1,
Math.max(
lightEstimate.primaryLightIntensity.x,
Math.max(lightEstimate.primaryLightIntensity.y, lightEstimate.primaryLightIntensity.z)
)
);
this.xrLight.directionalLight.color.setRGB(
lightEstimate.primaryLightIntensity.x / intensityScalar,
lightEstimate.primaryLightIntensity.y / intensityScalar,
lightEstimate.primaryLightIntensity.z / intensityScalar
);
this.xrLight.directionalLight.intensity = intensityScalar;
this.xrLight.directionalLight.position.copy(lightEstimate.primaryLightDirection);
if (this.estimationStartCallback) {
this.estimationStartCallback();
this.estimationStartCallback = null;
}
}
}
dispose() {
this.xrLight = null;
this.renderer = null;
this.lightProbe = null;
this.xrWebGLBinding = null;
}
}
class XREstimatedLight extends THREE.Group {
constructor(renderer, environmentEstimation = true) {
super();
this.lightProbe = new THREE.LightProbe();
this.lightProbe.intensity = 0;
this.add(this.lightProbe);
this.directionalLight = new THREE.DirectionalLight();
this.directionalLight.intensity = 0;
this.add(this.directionalLight);
this.environment = null;
let sessionLightProbe = null;
let estimationStarted = false;
renderer.xr.addEventListener("sessionstart", () => {
const session = renderer.xr.getSession();
if ("requestLightProbe" in session) {
session.requestLightProbe({
reflectionFormat: session.preferredReflectionFormat
}).then((probe) => {
sessionLightProbe = new SessionLightProbe(this, renderer, probe, environmentEstimation, () => {
estimationStarted = true;
this.dispatchEvent({ type: "estimationstart" });
});
});
}
});
renderer.xr.addEventListener("sessionend", () => {
if (sessionLightProbe) {
sessionLightProbe.dispose();
sessionLightProbe = null;
}
if (estimationStarted) {
this.dispatchEvent({ type: "estimationend" });
}
});
this.dispose = () => {
if (sessionLightProbe) {
sessionLightProbe.dispose();
sessionLightProbe = null;
}
this.remove(this.lightProbe);
this.lightProbe = null;
this.remove(this.directionalLight);
this.directionalLight = null;
this.environment = null;
};
}
}
exports.XREstimatedLight = XREstimatedLight;
//# sourceMappingURL=XREstimatedLight.cjs.map