UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

164 lines (141 loc) 4.46 kB
import { CubeTextureLoader, LinearFilter, PMREMGenerator, sRGBEncoding, TextureLoader, UnsignedByteType } from "three"; import { EXRLoader } from "three/examples/jsm/loaders/EXRLoader.js"; import { HDRCubeTextureLoader } from "three/examples/jsm/loaders/HDRCubeTextureLoader.js"; import { noop } from "../../../../core/function/noop.js"; import { computeFileExtension } from "../../../../core/path/computeFileExtension.js"; /** * * @param {string[]|string} paths * @return {Promise<THREE.CubeTexture>} */ function load_cube_texture(paths) { // piece-wise cubemap, a collection of images for each face const cubeTextureLoader = new CubeTextureLoader(); return new Promise((resolve, reject) => { cubeTextureLoader.load( paths, texture => { texture.magFilter = LinearFilter; texture.encoding = sRGBEncoding; resolve(texture); }, noop, reject ); }); } /** * * @param {string[]|string} paths * @return {Promise<THREE.CubeTexture>} */ function load_hdr_cube_texture(paths) { // piece-wise cubemap, a collection of images for each face const cubeTextureLoader = new HDRCubeTextureLoader(); return new Promise((resolve, reject) => { cubeTextureLoader.load( paths, texture => { resolve(texture); }, noop, reject ); }); } /** * * @param {string} path * @return {Promise<THREE.Texture>} */ function load_exr_texture(path) { return new Promise((resolve, reject) => { new EXRLoader() .setDataType(UnsignedByteType) .load(path, texture => { resolve(texture); }, noop, reject); }) } /** * * @param {string} path * @return {Promise<THREE.Texture>} */ function load_standard_texture(path) { return new Promise((resolve, reject) => { new TextureLoader() .load(path, texture => { texture.encoding = sRGBEncoding; resolve(texture); }, noop, reject); }) } /** * * @param {string|string[]} path * @param {THREE.WebGLRenderer} [renderer] * @param {boolean} [original] * @param {boolean} [filtered] * @returns {{original?:THREE.CubeTexture, filtered?: THREE.CubeTexture}} */ export async function load_environment_map({ path, renderer, original = false, filtered = true }) { /** * @type {string} 'e' or 'c' */ let type; /** * @type {THREE.WebGLCubeRenderTarget} */ let cube_rt; /** * @type {THREE.Texture|THREE.CubeTexture} */ let texture; if (Array.isArray(path)) { const ext = computeFileExtension(path[0]); if (ext === 'hdr') { texture = await load_hdr_cube_texture(path); } else { texture = await load_cube_texture(path); } type = 'c'; } else if (typeof path === 'string') { // single cubemap const extension = computeFileExtension(path).toLowerCase(); if (extension === 'exr') { texture = await load_exr_texture(path); } else if (extension === 'jpg') { texture = await load_standard_texture(path); } else { // unsupported extension throw new Error(`Unsupported cube map texture extension '${extension}'`); } type = 'e'; } else { throw new Error(`Unsupported parameter format: '${path}'`); } const result = {}; if (filtered) { if (renderer === undefined) { throw new Error('renderer argument not supplied, expected a WebGLRenderer'); } const pmremGenerator = new PMREMGenerator(renderer); if (type === 'c') { cube_rt = pmremGenerator.fromCubemap(texture); } else if (type === 'e') { cube_rt = pmremGenerator.fromEquirectangular(texture); } else { throw new Error(`Unsupported cubemap type '${type}'`); } pmremGenerator.dispose(); result.filtered = cube_rt.texture; } if (original) { result.original = texture; } else { // cleanup texture.dispose(); } return result; }