UNPKG

@babylonjs/loaders

Version:

For usage documentation please visit https://doc.babylonjs.com/features/featuresDeepDive/importers/loadingFileTypes/.

116 lines 5.77 kB
import { SphericalHarmonics, SphericalPolynomial } from "@babylonjs/core/Maths/sphericalPolynomial.js"; import { Quaternion, Matrix } from "@babylonjs/core/Maths/math.vector.js"; import { RawCubeTexture } from "@babylonjs/core/Materials/Textures/rawCubeTexture.js"; import { GLTFLoader, ArrayItem } from "../glTFLoader.js"; import { registerGLTFExtension, unregisterGLTFExtension } from "../glTFLoaderExtensionRegistry.js"; const NAME = "EXT_lights_image_based"; /** * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_lights_image_based/README.md) */ // eslint-disable-next-line @typescript-eslint/naming-convention export class EXT_lights_image_based { /** * @internal */ constructor(loader) { /** * The name of this extension. */ this.name = NAME; this._loader = loader; this.enabled = this._loader.isExtensionUsed(NAME); } /** @internal */ dispose() { this._loader = null; delete this._lights; } /** @internal */ onLoading() { const extensions = this._loader.gltf.extensions; if (extensions && extensions[this.name]) { const extension = extensions[this.name]; this._lights = extension.lights; } } /** * @internal */ // eslint-disable-next-line no-restricted-syntax loadSceneAsync(context, scene) { return GLTFLoader.LoadExtensionAsync(context, scene, this.name, async (extensionContext, extension) => { this._loader._allMaterialsDirtyRequired = true; const promises = new Array(); promises.push(this._loader.loadSceneAsync(context, scene)); this._loader.logOpen(`${extensionContext}`); const light = ArrayItem.Get(`${extensionContext}/light`, this._lights, extension.light); promises.push( // eslint-disable-next-line github/no-then this._loadLightAsync(`/extensions/${this.name}/lights/${extension.light}`, light).then((texture) => { this._loader.babylonScene.environmentTexture = texture; })); this._loader.logClose(); // eslint-disable-next-line github/no-then return await Promise.all(promises).then(() => { }); }); } // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax _loadLightAsync(context, light) { if (!light._loaded) { const promises = new Array(); this._loader.logOpen(`${context}`); const imageData = new Array(light.specularImages.length); for (let mipmap = 0; mipmap < light.specularImages.length; mipmap++) { const faces = light.specularImages[mipmap]; imageData[mipmap] = new Array(faces.length); for (let face = 0; face < faces.length; face++) { const specularImageContext = `${context}/specularImages/${mipmap}/${face}`; this._loader.logOpen(`${specularImageContext}`); const index = faces[face]; const image = ArrayItem.Get(specularImageContext, this._loader.gltf.images, index); promises.push( // eslint-disable-next-line github/no-then this._loader.loadImageAsync(`/images/${index}`, image).then((data) => { imageData[mipmap][face] = data; })); this._loader.logClose(); } } this._loader.logClose(); // eslint-disable-next-line github/no-then light._loaded = Promise.all(promises).then(async () => { const babylonTexture = new RawCubeTexture(this._loader.babylonScene, null, light.specularImageSize); babylonTexture.name = light.name || "environment"; light._babylonTexture = babylonTexture; if (light.intensity != undefined) { babylonTexture.level = light.intensity; } if (light.rotation) { let rotation = Quaternion.FromArray(light.rotation); // Invert the rotation so that positive rotation is counter-clockwise. if (!this._loader.babylonScene.useRightHandedSystem) { rotation = Quaternion.Inverse(rotation); } Matrix.FromQuaternionToRef(rotation, babylonTexture.getReflectionTextureMatrix()); } if (!light.irradianceCoefficients) { throw new Error(`${context}: Irradiance coefficients are missing`); } const sphericalHarmonics = SphericalHarmonics.FromArray(light.irradianceCoefficients); sphericalHarmonics.scaleInPlace(light.intensity); sphericalHarmonics.convertIrradianceToLambertianRadiance(); const sphericalPolynomial = SphericalPolynomial.FromHarmonics(sphericalHarmonics); // Compute the lod generation scale to fit exactly to the number of levels available. const lodGenerationScale = (imageData.length - 1) / Math.log2(light.specularImageSize); return await babylonTexture.updateRGBDAsync(imageData, sphericalPolynomial, lodGenerationScale); }); } // eslint-disable-next-line github/no-then return light._loaded.then(() => { return light._babylonTexture; }); } } unregisterGLTFExtension(NAME); registerGLTFExtension(NAME, true, (loader) => new EXT_lights_image_based(loader)); //# sourceMappingURL=EXT_lights_image_based.js.map