1 line
8.3 KiB
Plaintext
1 line
8.3 KiB
Plaintext
|
|
{"version":3,"file":"XREstimatedLight.cjs","sources":["../../src/webxr/XREstimatedLight.js"],"sourcesContent":["import { DirectionalLight, Group, LightProbe, WebGLCubeRenderTarget } from 'three'\n\nclass SessionLightProbe {\n constructor(xrLight, renderer, lightProbe, environmentEstimation, estimationStartCallback) {\n this.xrLight = xrLight\n this.renderer = renderer\n this.lightProbe = lightProbe\n this.xrWebGLBinding = null\n this.estimationStartCallback = estimationStartCallback\n this.frameCallback = this.onXRFrame.bind(this)\n\n const session = renderer.xr.getSession()\n\n // If the XRWebGLBinding class is available then we can also query an\n // estimated reflection cube map.\n if (environmentEstimation && 'XRWebGLBinding' in window) {\n // This is the simplest way I know of to initialize a WebGL cubemap in Three.\n const cubeRenderTarget = new WebGLCubeRenderTarget(16)\n xrLight.environment = cubeRenderTarget.texture\n\n const gl = renderer.getContext()\n\n // Ensure that we have any extensions needed to use the preferred cube map format.\n switch (session.preferredReflectionFormat) {\n case 'srgba8':\n gl.getExtension('EXT_sRGB')\n break\n\n case 'rgba16f':\n gl.getExtension('OES_texture_half_float')\n break\n }\n\n this.xrWebGLBinding = new XRWebGLBinding(session, gl)\n\n this.lightProbe.addEventListener('reflectionchange', () => {\n this.updateReflection()\n })\n }\n\n // Start monitoring the XR animation frame loop to look for lighting\n // estimation changes.\n session.requestAnimationFrame(this.frameCallback)\n }\n\n updateReflection() {\n const textureProperties = this.renderer.properties.get(this.xrLight.environment)\n\n if (textureProperties) {\n const cubeMap = this.xrWebGLBinding.getReflectionCubeMap(this.lightProbe)\n\n if (cubeMap) {\n textureProperties.__webglTexture = cubeMap\n\n this.xrLight.environment.needsPMREMUpdate = true\n }\n }\n }\n\n onXRFrame(time, xrFrame) {\n // If either this obejct or the XREstimatedLight has been destroyed, stop\n // running the frame loop.\n if (!this.xrLight) {\n return\n }\n\n const session = xrFrame.session\n session.requestAnimationFrame(this.frameCallback)\n\n const lightEstimate = xrFrame.getLightEstimate(this.lightProbe)\n if (lightEstimate) {\n // We can copy the estimate's spherical harmonics array directly into the light probe.\n this.xrLight.lightProbe.sh.fromArray(lightEstimate.sphericalHarmonicsCoefficients)\n this.xrLight.lightProbe.intensity = 1.0\n\n // For the directional light we have to normalize the color and set the scalar as the\n // intensity, since WebXR can return color values that exceed 1.0.\n const intensityScalar = Math.max(\n 1.0,\n Math.max(\n lightEstimate.primaryLightIntensity.x,\n Math.max(lightEstimate.primaryLightIntensity.y, lightEstimate.primaryLightIntensity.z),\n ),\n )\n\n this.xrLight.directionalLight.color.setRGB(\n lightEstimate.primaryLightIntensity.x / intensityScalar,\n lightEstimate.primaryLightIntensity.y / intensityScalar,\n lightEstimate.primaryLightIntensity.z / intensityScalar,\n )\n this.xrLight.directionalLight.intensity = intensityScalar\n this.xrLight.directionalLight.position.copy(lightEstimate.primaryLightDirection)\n\n if (this.estimationStartCallback) {\n this.estimationStartCallback()\n this.estimationStartCallback = null\n }\n }\n }\n\n dispose() {\n this.xrLight = null\n this.renderer = null\n this.lightProbe = null\n this.xrWebGLBinding = null\n }\n}\n\nexport class XREstimatedLight extends Group {\n constructor(renderer, environmentEstimation = true) {\n super()\n\n this.lightProbe = new LightProbe()\n this.lightProbe.intensity = 0\n this.add(this.lightProbe)\n\n this.directionalLight = new DirectionalLight()\n
|