| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import TempNode from '../core/TempNode.js';
- import { addNodeClass } from '../core/Node.js';
- import { NodeUpdateType } from '../core/constants.js';
- import { nodeProxy } from '../shadernode/ShaderNode.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();
- class CubeMapNode extends TempNode {
- constructor( envNode ) {
- super( 'vec3' );
- this.envNode = envNode;
- this._cubeTexture = null;
- this._cubeTextureNode = cubeTexture();
- const defaultTexture = new CubeTexture();
- defaultTexture.isRenderTargetTexture = true;
- this._defaultTexture = defaultTexture;
- 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;
- }
- }
- function isEquirectangularMapReady( image ) {
- if ( image === null || image === undefined ) return false;
- return image.height > 0;
- }
- function onTextureDispose( event ) {
- const texture = event.target;
- texture.removeEventListener( 'dispose', onTextureDispose );
- const renderTarget = _cache.get( texture );
- if ( renderTarget !== undefined ) {
- _cache.delete( texture );
- renderTarget.dispose();
- }
- }
- function mapTextureMapping( texture, mapping ) {
- if ( mapping === EquirectangularReflectionMapping ) {
- texture.mapping = CubeReflectionMapping;
- } else if ( mapping === EquirectangularRefractionMapping ) {
- texture.mapping = CubeRefractionMapping;
- }
- }
- export const cubeMapNode = nodeProxy( CubeMapNode );
- addNodeClass( 'CubeMapNode', CubeMapNode );
- export default CubeMapNode;
|