diff --git a/src/renderers/webgl/WebGLBindingStates.js b/src/renderers/webgl/WebGLBindingStates.js index d63aeb7f35281a..06d1a07612bd43 100644 --- a/src/renderers/webgl/WebGLBindingStates.js +++ b/src/renderers/webgl/WebGLBindingStates.js @@ -4,7 +4,7 @@ function WebGLBindingStates( gl, attributes ) { const maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); - const bindingStates = {}; + const bindingStates = new Map(); const defaultState = createBindingState( null ); let currentState = defaultState; @@ -71,30 +71,30 @@ function WebGLBindingStates( gl, attributes ) { const wireframe = ( material.wireframe === true ); - let programMap = bindingStates[ geometry.id ]; + let programMap = bindingStates.get( geometry.id ); if ( programMap === undefined ) { - programMap = {}; - bindingStates[ geometry.id ] = programMap; + programMap = new Map(); + bindingStates.set( geometry.id, programMap ); } - let stateMap = programMap[ program.id ]; + let stateMap = programMap.get( program.id ); if ( stateMap === undefined ) { - stateMap = {}; - programMap[ program.id ] = stateMap; + stateMap = new Map(); + programMap.set( program.id, stateMap ); } - let state = stateMap[ wireframe ]; + let state = stateMap.get( wireframe ); if ( state === undefined ) { state = createBindingState( createVertexArrayObject() ); - stateMap[ wireframe ] = state; + stateMap.set( wireframe, state ); } @@ -475,77 +475,59 @@ function WebGLBindingStates( gl, attributes ) { reset(); - for ( const geometryId in bindingStates ) { + for ( const programMap of bindingStates.values() ) { - const programMap = bindingStates[ geometryId ]; + for ( const stateMap of programMap.values() ) { - for ( const programId in programMap ) { + for ( const state of stateMap.values() ) { - const stateMap = programMap[ programId ]; - - for ( const wireframe in stateMap ) { - - deleteVertexArrayObject( stateMap[ wireframe ].object ); - - delete stateMap[ wireframe ]; + deleteVertexArrayObject( state.object ); } - delete programMap[ programId ]; - } - delete bindingStates[ geometryId ]; - } + bindingStates.clear(); + } function releaseStatesOfGeometry( geometry ) { - if ( bindingStates[ geometry.id ] === undefined ) return; + if ( bindingStates.get( geometry.id ) === undefined ) return; - const programMap = bindingStates[ geometry.id ]; + const programMap = bindingStates.get( geometry.id ); - for ( const programId in programMap ) { + for ( const stateMap of programMap.values() ) { - const stateMap = programMap[ programId ]; + for ( const state of stateMap.values() ) { - for ( const wireframe in stateMap ) { - - deleteVertexArrayObject( stateMap[ wireframe ].object ); - - delete stateMap[ wireframe ]; + deleteVertexArrayObject( state.object ); } - delete programMap[ programId ]; - } - delete bindingStates[ geometry.id ]; + bindingStates.delete( geometry.id ); } function releaseStatesOfProgram( program ) { - for ( const geometryId in bindingStates ) { - - const programMap = bindingStates[ geometryId ]; - - if ( programMap[ program.id ] === undefined ) continue; + for ( const programMap of bindingStates.values() ) { - const stateMap = programMap[ program.id ]; + if ( programMap.get( program.id ) === undefined ) continue; - for ( const wireframe in stateMap ) { + const stateMap = programMap.get( program.id ); - deleteVertexArrayObject( stateMap[ wireframe ].object ); + for ( const state of stateMap.values() ) { - delete stateMap[ wireframe ]; + deleteVertexArrayObject( state.object ); } - delete programMap[ program.id ]; + programMap.delete( program.id ); } diff --git a/src/renderers/webgl/WebGLProperties.js b/src/renderers/webgl/WebGLProperties.js index 09a495447525f0..03516c92a27415 100644 --- a/src/renderers/webgl/WebGLProperties.js +++ b/src/renderers/webgl/WebGLProperties.js @@ -14,7 +14,24 @@ function WebGLProperties() { if ( map === undefined ) { - map = {}; + if ( object.isMaterial ) { + + map = createMaterialProperties(); + + } else if ( object.isTexture ) { + + map = createTextureProperties(); + + } else if ( object.isWebGLRenderTarget ) { + + map = createRenderTargetProperties(); + + } else { + + map = {}; + + } + properties.set( object, map ); } @@ -23,6 +40,74 @@ function WebGLProperties() { } + function createMaterialProperties() { + + return { + outputColorSpace: undefined, + batching: undefined, + batchingColor: undefined, + instancing: undefined, + instancingColor: undefined, + instancingMorph: undefined, + skinning: undefined, + morphTargets: undefined, + morphNormals: undefined, + morphColors: undefined, + morphTargetsCount: undefined, + numClippingPlanes: undefined, + numIntersection: undefined, + vertexAlphas: undefined, + vertexTangents: undefined, + toneMapping: undefined, + fog: undefined, + environment: undefined, + envMap: undefined, + envMapRotation: undefined, + programs: undefined, + currentProgram: undefined, + uniforms: undefined, + uniformsList: undefined, + needsLights: undefined, + lightsStateVersion: undefined, + receiveShadow: undefined, + light: undefined, + clippingState: undefined, + __version: undefined + }; + + } + + function createTextureProperties() { + + return { + __init: undefined, + __webglTexture: undefined, + __cacheKey: undefined, + __version: undefined, + __currentAnisotropy: undefined, + __renderTarget: undefined + }; + + } + + function createRenderTargetProperties() { + + return { + __webglFramebuffer: undefined, + __webglDepthbuffer: undefined, + __webglMultisampledFramebuffer: undefined, + __webglColorRenderbuffer: undefined, + __webglDepthRenderbuffer: undefined, + __hasExternalTextures: undefined, + __boundDepthTexture: undefined, + __depthDisposeCallback: undefined, + __autoAllocateDepthBuffer: undefined, + __useRenderToTexture: undefined, + __useDefaultFramebuffer: undefined + }; + + } + function remove( object ) { properties.delete( object ); diff --git a/src/renderers/webgl/WebGLShadowMap.js b/src/renderers/webgl/WebGLShadowMap.js index e38833a78f851b..56d70e25cca6d0 100644 --- a/src/renderers/webgl/WebGLShadowMap.js +++ b/src/renderers/webgl/WebGLShadowMap.js @@ -29,7 +29,7 @@ function WebGLShadowMap( renderer, objects, capabilities ) { _depthMaterialVSM = new MeshDepthMaterial( { depthPacking: IdentityDepthPacking } ), _distanceMaterial = new MeshDistanceMaterial(), - _materialCache = {}, + _materialCache = new Map(), _maxTextureSize = capabilities.maxTextureSize; @@ -392,21 +392,21 @@ function WebGLShadowMap( renderer, objects, capabilities ) { const keyA = result.uuid, keyB = material.uuid; - let materialsForVariant = _materialCache[ keyA ]; + let materialsForVariant = _materialCache.get( keyA ); if ( materialsForVariant === undefined ) { - materialsForVariant = {}; - _materialCache[ keyA ] = materialsForVariant; + materialsForVariant = new Map(); + _materialCache.set( keyA, materialsForVariant ); } - let cachedMaterial = materialsForVariant[ keyB ]; + let cachedMaterial = materialsForVariant.get( keyB ); if ( cachedMaterial === undefined ) { cachedMaterial = result.clone(); - materialsForVariant[ keyB ] = cachedMaterial; + materialsForVariant.set( keyB, cachedMaterial ); material.addEventListener( 'dispose', onMaterialDispose ); } @@ -528,17 +528,15 @@ function WebGLShadowMap( renderer, objects, capabilities ) { // make sure to remove the unique distance/depth materials used for shadow map rendering - for ( const id in _materialCache ) { - - const cache = _materialCache[ id ]; + for ( const cache of _materialCache.values() ) { const uuid = event.target.uuid; - if ( uuid in cache ) { + if ( cache.has( uuid ) ) { - const shadowMaterial = cache[ uuid ]; + const shadowMaterial = cache.get( uuid ); shadowMaterial.dispose(); - delete cache[ uuid ]; + cache.delete( uuid ); } diff --git a/src/renderers/webgl/WebGLTextures.js b/src/renderers/webgl/WebGLTextures.js index 8194e20243d584..e95447811ff6b2 100644 --- a/src/renderers/webgl/WebGLTextures.js +++ b/src/renderers/webgl/WebGLTextures.js @@ -1776,8 +1776,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, const disposeEvent = () => { - delete renderTargetProperties.__boundDepthTexture; - delete renderTargetProperties.__depthDisposeCallback; + renderTargetProperties.__boundDepthTexture = undefined; + renderTargetProperties.__depthDisposeCallback = undefined; depthTexture.removeEventListener( 'dispose', disposeEvent ); };