summit/frontend/node_modules/three-stdlib/lights/LightProbeGenerator.cjs.map

1 line
9.9 KiB
Plaintext
Raw Normal View History

2025-12-08 16:31:30 +00:00
{"version":3,"file":"LightProbeGenerator.cjs","sources":["../../src/lights/LightProbeGenerator.js"],"sourcesContent":["import { Color, LightProbe, SphericalHarmonics3, Vector3 } from 'three'\n\nconst LightProbeGenerator = {\n // https://www.ppsloan.org/publications/StupidSH36.pdf\n fromCubeTexture(cubeTexture) {\n let totalWeight = 0\n\n const coord = new Vector3()\n\n const dir = new Vector3()\n\n const color = new Color()\n\n const shBasis = [0, 0, 0, 0, 0, 0, 0, 0, 0]\n\n const sh = new SphericalHarmonics3()\n const shCoefficients = sh.coefficients\n\n for (let faceIndex = 0; faceIndex < 6; faceIndex++) {\n const image = cubeTexture.image[faceIndex]\n\n const width = image.width\n const height = image.height\n\n const canvas = document.createElement('canvas')\n\n canvas.width = width\n canvas.height = height\n\n const context = canvas.getContext('2d')\n\n context.drawImage(image, 0, 0, width, height)\n\n const imageData = context.getImageData(0, 0, width, height)\n\n const data = imageData.data\n\n const imageWidth = imageData.width // assumed to be square\n\n const pixelSize = 2 / imageWidth\n\n for (let i = 0, il = data.length; i < il; i += 4) {\n // RGBA assumed\n\n // pixel color\n color.setRGB(data[i] / 255, data[i + 1] / 255, data[i + 2] / 255)\n\n // convert to linear color space\n if ('colorSpace' in cubeTexture) {\n if (cubeTexture.colorSpace === 'srgb') {\n color.convertSRGBToLinear()\n }\n } else if (cubeTexture.encoding === 3001) {\n // sRGBEncoding\n color.convertSRGBToLinear()\n }\n\n // pixel coordinate on unit cube\n\n const pixelIndex = i / 4\n\n const col = -1 + ((pixelIndex % imageWidth) + 0.5) * pixelSize\n\n const row = 1 - (Math.floor(pixelIndex / imageWidth) + 0.5) * pixelSize\n\n switch (faceIndex) {\n case 0:\n coord.set(-1, row, -col)\n break\n\n case 1:\n coord.set(1, row, col)\n break\n\n case 2:\n coord.set(-col, 1, -row)\n break\n\n case 3:\n coord.set(-col, -1, row)\n break\n\n case 4:\n coord.set(-col, row, 1)\n break\n\n case 5:\n coord.set(col, row, -1)\n break\n }\n\n // weight assigned to this pixel\n\n const lengthSq = coord.lengthSq()\n\n const weight = 4 / (Math.sqrt(lengthSq) * lengthSq)\n\n totalWeight += weight\n\n // direction vector to this pixel\n dir.copy(coord).normalize()\n\n // evaluate SH basis functions in direction dir\n SphericalHarmonics3.getBasisAt(dir, shBasis)\n\n // accummuulate\n for (let j = 0; j < 9; j++) {\n shCoefficients[j].x += shBasis[j] * color.r * weight\n shCoefficients[j].y += shBasis[j] * color.g * weight\n shCoefficients[j].z += shBasis[j] * color.b * weight\n }\n }\n }\n\n // normalize\n const norm = (4 * Math.PI) / totalWeight\n\n for (let j = 0; j < 9; j++) {\n shCoefficients[j].x *= norm\n shCoefficients[j].y *= norm\n shCoefficients[j].z *= norm\n }\n\n return new LightProbe(sh)\n },\n\n fromCubeRenderTarget(renderer, cubeRenderTarget) {\n // The renderTarget must be set to RGBA in order to make readRenderTargetPixels works\n let totalWeight = 0\n\n const coord = new Vector3()\n\n const dir = new Vector3()\n\n const color = new Color()\n\n const shBasis = [0, 0, 0, 0, 0, 0, 0, 0, 0]\n\n const sh = new SphericalHarmonics3()\n const shCoefficients = sh.coefficients\n\n for (let faceIndex = 0; faceIndex < 6; faceIndex++) {\n const imageWidth = cubeRenderTarget.width // assumed to be square\n const data = new Uint8Array(imageWidth * imageWidth * 4)\n renderer.readRenderTargetPixels(cubeRenderTarget, 0, 0, imageWidth, imageWidth, data, faceIndex)\n\n c