Initial project import
This commit is contained in:
146
node_modules/three-stdlib/lights/LightProbeGenerator.js
generated
vendored
Normal file
146
node_modules/three-stdlib/lights/LightProbeGenerator.js
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
import { Vector3, Color, SphericalHarmonics3, LightProbe } from "three";
|
||||
const LightProbeGenerator = {
|
||||
// https://www.ppsloan.org/publications/StupidSH36.pdf
|
||||
fromCubeTexture(cubeTexture) {
|
||||
let totalWeight = 0;
|
||||
const coord = new Vector3();
|
||||
const dir = new Vector3();
|
||||
const color = new Color();
|
||||
const shBasis = [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
const sh = new SphericalHarmonics3();
|
||||
const shCoefficients = sh.coefficients;
|
||||
for (let faceIndex = 0; faceIndex < 6; faceIndex++) {
|
||||
const image = cubeTexture.image[faceIndex];
|
||||
const width = image.width;
|
||||
const height = image.height;
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const context = canvas.getContext("2d");
|
||||
context.drawImage(image, 0, 0, width, height);
|
||||
const imageData = context.getImageData(0, 0, width, height);
|
||||
const data = imageData.data;
|
||||
const imageWidth = imageData.width;
|
||||
const pixelSize = 2 / imageWidth;
|
||||
for (let i = 0, il = data.length; i < il; i += 4) {
|
||||
color.setRGB(data[i] / 255, data[i + 1] / 255, data[i + 2] / 255);
|
||||
if ("colorSpace" in cubeTexture) {
|
||||
if (cubeTexture.colorSpace === "srgb") {
|
||||
color.convertSRGBToLinear();
|
||||
}
|
||||
} else if (cubeTexture.encoding === 3001) {
|
||||
color.convertSRGBToLinear();
|
||||
}
|
||||
const pixelIndex = i / 4;
|
||||
const col = -1 + (pixelIndex % imageWidth + 0.5) * pixelSize;
|
||||
const row = 1 - (Math.floor(pixelIndex / imageWidth) + 0.5) * pixelSize;
|
||||
switch (faceIndex) {
|
||||
case 0:
|
||||
coord.set(-1, row, -col);
|
||||
break;
|
||||
case 1:
|
||||
coord.set(1, row, col);
|
||||
break;
|
||||
case 2:
|
||||
coord.set(-col, 1, -row);
|
||||
break;
|
||||
case 3:
|
||||
coord.set(-col, -1, row);
|
||||
break;
|
||||
case 4:
|
||||
coord.set(-col, row, 1);
|
||||
break;
|
||||
case 5:
|
||||
coord.set(col, row, -1);
|
||||
break;
|
||||
}
|
||||
const lengthSq = coord.lengthSq();
|
||||
const weight = 4 / (Math.sqrt(lengthSq) * lengthSq);
|
||||
totalWeight += weight;
|
||||
dir.copy(coord).normalize();
|
||||
SphericalHarmonics3.getBasisAt(dir, shBasis);
|
||||
for (let j = 0; j < 9; j++) {
|
||||
shCoefficients[j].x += shBasis[j] * color.r * weight;
|
||||
shCoefficients[j].y += shBasis[j] * color.g * weight;
|
||||
shCoefficients[j].z += shBasis[j] * color.b * weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
const norm = 4 * Math.PI / totalWeight;
|
||||
for (let j = 0; j < 9; j++) {
|
||||
shCoefficients[j].x *= norm;
|
||||
shCoefficients[j].y *= norm;
|
||||
shCoefficients[j].z *= norm;
|
||||
}
|
||||
return new LightProbe(sh);
|
||||
},
|
||||
fromCubeRenderTarget(renderer, cubeRenderTarget) {
|
||||
let totalWeight = 0;
|
||||
const coord = new Vector3();
|
||||
const dir = new Vector3();
|
||||
const color = new Color();
|
||||
const shBasis = [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
const sh = new SphericalHarmonics3();
|
||||
const shCoefficients = sh.coefficients;
|
||||
for (let faceIndex = 0; faceIndex < 6; faceIndex++) {
|
||||
const imageWidth = cubeRenderTarget.width;
|
||||
const data = new Uint8Array(imageWidth * imageWidth * 4);
|
||||
renderer.readRenderTargetPixels(cubeRenderTarget, 0, 0, imageWidth, imageWidth, data, faceIndex);
|
||||
const pixelSize = 2 / imageWidth;
|
||||
for (let i = 0, il = data.length; i < il; i += 4) {
|
||||
color.setRGB(data[i] / 255, data[i + 1] / 255, data[i + 2] / 255);
|
||||
if ("colorSpace" in cubeRenderTarget.texture) {
|
||||
if (cubeRenderTarget.texture.colorSpace === "srgb") {
|
||||
color.convertSRGBToLinear();
|
||||
}
|
||||
} else if (cubeRenderTarget.texture.encoding === 3001) {
|
||||
color.convertSRGBToLinear();
|
||||
}
|
||||
const pixelIndex = i / 4;
|
||||
const col = -1 + (pixelIndex % imageWidth + 0.5) * pixelSize;
|
||||
const row = 1 - (Math.floor(pixelIndex / imageWidth) + 0.5) * pixelSize;
|
||||
switch (faceIndex) {
|
||||
case 0:
|
||||
coord.set(1, row, -col);
|
||||
break;
|
||||
case 1:
|
||||
coord.set(-1, row, col);
|
||||
break;
|
||||
case 2:
|
||||
coord.set(col, 1, -row);
|
||||
break;
|
||||
case 3:
|
||||
coord.set(col, -1, row);
|
||||
break;
|
||||
case 4:
|
||||
coord.set(col, row, 1);
|
||||
break;
|
||||
case 5:
|
||||
coord.set(-col, row, -1);
|
||||
break;
|
||||
}
|
||||
const lengthSq = coord.lengthSq();
|
||||
const weight = 4 / (Math.sqrt(lengthSq) * lengthSq);
|
||||
totalWeight += weight;
|
||||
dir.copy(coord).normalize();
|
||||
SphericalHarmonics3.getBasisAt(dir, shBasis);
|
||||
for (let j = 0; j < 9; j++) {
|
||||
shCoefficients[j].x += shBasis[j] * color.r * weight;
|
||||
shCoefficients[j].y += shBasis[j] * color.g * weight;
|
||||
shCoefficients[j].z += shBasis[j] * color.b * weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
const norm = 4 * Math.PI / totalWeight;
|
||||
for (let j = 0; j < 9; j++) {
|
||||
shCoefficients[j].x *= norm;
|
||||
shCoefficients[j].y *= norm;
|
||||
shCoefficients[j].z *= norm;
|
||||
}
|
||||
return new LightProbe(sh);
|
||||
}
|
||||
};
|
||||
export {
|
||||
LightProbeGenerator
|
||||
};
|
||||
//# sourceMappingURL=LightProbeGenerator.js.map
|
||||
Reference in New Issue
Block a user