UNPKG

three

Version:

JavaScript 3D library

229 lines (123 loc) 4.74 kB
import { CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from '../../constants.js'; import { PMREMGenerator } from '../../extras/PMREMGenerator.js'; import { WebGLCubeRenderTarget } from '../WebGLCubeRenderTarget.js'; function WebGLEnvironments( renderer ) { let cubeMaps = new WeakMap(); let pmremMaps = new WeakMap(); let pmremGenerator = null; function get( texture, usePMREM = false ) { if ( texture === null || texture === undefined ) return null; if ( usePMREM ) { return getPMREM( texture ); } return getCube( texture ); } function getCube( texture ) { if ( texture && texture.isTexture ) { const mapping = texture.mapping; if ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ) { if ( cubeMaps.has( texture ) ) { const cubemap = cubeMaps.get( texture ).texture; return mapTextureMapping( cubemap, texture.mapping ); } else { const image = texture.image; if ( image && image.height > 0 ) { const renderTarget = new WebGLCubeRenderTarget( image.height ); renderTarget.fromEquirectangularTexture( renderer, texture ); cubeMaps.set( texture, renderTarget ); texture.addEventListener( 'dispose', onCubemapDispose ); return mapTextureMapping( renderTarget.texture, texture.mapping ); } else { // image not yet ready. try the conversion next frame return null; } } } } return texture; } function getPMREM( texture ) { if ( texture && texture.isTexture ) { const mapping = texture.mapping; const isEquirectMap = ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ); const isCubeMap = ( mapping === CubeReflectionMapping || mapping === CubeRefractionMapping ); // equirect/cube map to cubeUV conversion if ( isEquirectMap || isCubeMap ) { let renderTarget = pmremMaps.get( texture ); const currentPMREMVersion = renderTarget !== undefined ? renderTarget.texture.pmremVersion : 0; if ( texture.isRenderTargetTexture && texture.pmremVersion !== currentPMREMVersion ) { if ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer ); renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture, renderTarget ) : pmremGenerator.fromCubemap( texture, renderTarget ); renderTarget.texture.pmremVersion = texture.pmremVersion; pmremMaps.set( texture, renderTarget ); return renderTarget.texture; } else { if ( renderTarget !== undefined ) { return renderTarget.texture; } else { const image = texture.image; if ( ( isEquirectMap && image && image.height > 0 ) || ( isCubeMap && image && isCubeTextureComplete( image ) ) ) { if ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer ); renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture ) : pmremGenerator.fromCubemap( texture ); renderTarget.texture.pmremVersion = texture.pmremVersion; pmremMaps.set( texture, renderTarget ); texture.addEventListener( 'dispose', onPMREMDispose ); return renderTarget.texture; } else { // image not yet ready. try the conversion next frame return null; } } } } } return texture; } function mapTextureMapping( texture, mapping ) { if ( mapping === EquirectangularReflectionMapping ) { texture.mapping = CubeReflectionMapping; } else if ( mapping === EquirectangularRefractionMapping ) { texture.mapping = CubeRefractionMapping; } return texture; } function isCubeTextureComplete( image ) { let count = 0; const length = 6; for ( let i = 0; i < length; i ++ ) { if ( image[ i ] !== undefined ) count ++; } return count === length; } function onCubemapDispose( event ) { const texture = event.target; texture.removeEventListener( 'dispose', onCubemapDispose ); const cubemap = cubeMaps.get( texture ); if ( cubemap !== undefined ) { cubeMaps.delete( texture ); cubemap.dispose(); } } function onPMREMDispose( event ) { const texture = event.target; texture.removeEventListener( 'dispose', onPMREMDispose ); const pmrem = pmremMaps.get( texture ); if ( pmrem !== undefined ) { pmremMaps.delete( texture ); pmrem.dispose(); } } function dispose() { cubeMaps = new WeakMap(); pmremMaps = new WeakMap(); if ( pmremGenerator !== null ) { pmremGenerator.dispose(); pmremGenerator = null; } } return { get: get, dispose: dispose }; } export { WebGLEnvironments };