Buckets:
| import TempNode from '../core/TempNode.js'; | |
| import { NodeUpdateType } from '../core/constants.js'; | |
| import { nodeProxy } from '../tsl/TSLBase.js'; | |
| import { CubeTexture } from '../../textures/CubeTexture.js'; | |
| import { cubeTexture } from '../accessors/CubeTextureNode.js'; | |
| import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js'; | |
| import { CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from '../../constants.js'; | |
| const _cache = new WeakMap(); | |
| /** | |
| * This node can be used to automatically convert environment maps in the | |
| * equirectangular format into the cube map format. | |
| * | |
| * @augments TempNode | |
| */ | |
| class CubeMapNode extends TempNode { | |
| static get type() { | |
| return 'CubeMapNode'; | |
| } | |
| /** | |
| * Constructs a new cube map node. | |
| * | |
| * @param {Node} envNode - The node representing the environment map. | |
| */ | |
| constructor( envNode ) { | |
| super( 'vec3' ); | |
| /** | |
| * The node representing the environment map. | |
| * | |
| * @type {Node} | |
| */ | |
| this.envNode = envNode; | |
| /** | |
| * A reference to the internal cube texture. | |
| * | |
| * @private | |
| * @type {?CubeTexture} | |
| * @default null | |
| */ | |
| this._cubeTexture = null; | |
| /** | |
| * A reference to the internal cube texture node. | |
| * | |
| * @private | |
| * @type {CubeTextureNode} | |
| */ | |
| this._cubeTextureNode = cubeTexture( null ); | |
| const defaultTexture = new CubeTexture(); | |
| defaultTexture.isRenderTargetTexture = true; | |
| /** | |
| * A default cube texture that acts as a placeholder. | |
| * It is used when the conversion from equirectangular to cube | |
| * map has not finished yet for a given texture. | |
| * | |
| * @private | |
| * @type {CubeTexture} | |
| */ | |
| this._defaultTexture = defaultTexture; | |
| /** | |
| * The `updateBeforeType` is set to `NodeUpdateType.RENDER` since the node updates | |
| * the texture once per render in its {@link CubeMapNode#updateBefore} method. | |
| * | |
| * @type {string} | |
| * @default 'render' | |
| */ | |
| this.updateBeforeType = NodeUpdateType.RENDER; | |
| } | |
| updateBefore( frame ) { | |
| const { renderer, material } = frame; | |
| const envNode = this.envNode; | |
| if ( envNode.isTextureNode || envNode.isMaterialReferenceNode ) { | |
| const texture = ( envNode.isTextureNode ) ? envNode.value : material[ envNode.property ]; | |
| if ( texture && texture.isTexture ) { | |
| const mapping = texture.mapping; | |
| if ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ) { | |
| // check for converted cubemap map | |
| if ( _cache.has( texture ) ) { | |
| const cubeMap = _cache.get( texture ); | |
| mapTextureMapping( cubeMap, texture.mapping ); | |
| this._cubeTexture = cubeMap; | |
| } else { | |
| // create cube map from equirectangular map | |
| const image = texture.image; | |
| if ( isEquirectangularMapReady( image ) ) { | |
| const renderTarget = new CubeRenderTarget( image.height ); | |
| renderTarget.fromEquirectangularTexture( renderer, texture ); | |
| mapTextureMapping( renderTarget.texture, texture.mapping ); | |
| this._cubeTexture = renderTarget.texture; | |
| _cache.set( texture, renderTarget.texture ); | |
| texture.addEventListener( 'dispose', onTextureDispose ); | |
| } else { | |
| // default cube texture as fallback when equirectangular texture is not yet loaded | |
| this._cubeTexture = this._defaultTexture; | |
| } | |
| } | |
| // | |
| this._cubeTextureNode.value = this._cubeTexture; | |
| } else { | |
| // envNode already refers to a cube map | |
| this._cubeTextureNode = this.envNode; | |
| } | |
| } | |
| } | |
| } | |
| setup( builder ) { | |
| this.updateBefore( builder ); | |
| return this._cubeTextureNode; | |
| } | |
| } | |
| export default CubeMapNode; | |
| /** | |
| * Returns true if the given equirectangular image has been fully loaded | |
| * and is ready for further processing. | |
| * | |
| * @private | |
| * @param {Image} image - The equirectangular image to check. | |
| * @return {boolean} Whether the image is ready or not. | |
| */ | |
| function isEquirectangularMapReady( image ) { | |
| if ( image === null || image === undefined ) return false; | |
| return image.height > 0; | |
| } | |
| /** | |
| * This function is executed when `dispose()` is called on the equirectangular | |
| * texture. In this case, the generated cube map with its render target | |
| * is deleted as well. | |
| * | |
| * @private | |
| * @param {Object} event - The event object. | |
| */ | |
| function onTextureDispose( event ) { | |
| const texture = event.target; | |
| texture.removeEventListener( 'dispose', onTextureDispose ); | |
| const renderTarget = _cache.get( texture ); | |
| if ( renderTarget !== undefined ) { | |
| _cache.delete( texture ); | |
| renderTarget.dispose(); | |
| } | |
| } | |
| /** | |
| * This function makes sure the generated cube map uses the correct | |
| * texture mapping that corresponds to the equirectangular original. | |
| * | |
| * @private | |
| * @param {Texture} texture - The cube texture. | |
| * @param {number} mapping - The original texture mapping. | |
| */ | |
| function mapTextureMapping( texture, mapping ) { | |
| if ( mapping === EquirectangularReflectionMapping ) { | |
| texture.mapping = CubeReflectionMapping; | |
| } else if ( mapping === EquirectangularRefractionMapping ) { | |
| texture.mapping = CubeRefractionMapping; | |
| } | |
| } | |
| /** | |
| * TSL function for creating a cube map node. | |
| * | |
| * @tsl | |
| * @function | |
| * @param {Node} envNode - The node representing the environment map. | |
| * @returns {CubeMapNode} | |
| */ | |
| export const cubeMapNode = /*@__PURE__*/ nodeProxy( CubeMapNode ).setParameterLength( 1 ); | |
Xet Storage Details
- Size:
- 5.39 kB
- Xet hash:
- b1e472c4c7a1621ff76090d408e655b63861e2dac0e94462bda0069048470704
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.