@@ -60656,7 +60656,7 @@ function WebGLBindingStates( gl, attributes ) {
6065660656
6065760657 let updateBuffers = false;
6065860658
60659- const state = getBindingState( geometry, program, material );
60659+ const state = getBindingState( object, geometry, program, material );
6066060660
6066160661 if ( currentState !== state ) {
6066260662
@@ -60709,16 +60709,28 @@ function WebGLBindingStates( gl, attributes ) {
6070960709
6071060710 }
6071160711
60712- function getBindingState( geometry, program, material ) {
60712+ function getBindingState( object, geometry, program, material ) {
6071360713
6071460714 const wireframe = ( material.wireframe === true );
6071560715
60716- let programMap = bindingStates[ geometry.id ];
60716+ let objectMap = bindingStates[ geometry.id ];
60717+
60718+ if ( objectMap === undefined ) {
60719+
60720+ objectMap = {};
60721+ bindingStates[ geometry.id ] = objectMap;
60722+
60723+ }
60724+
60725+ // Each InstancedMesh requires unique binding states because it contains instanced attributes.
60726+ const objectId = ( object.isInstancedMesh === true ) ? object.id : 0;
60727+
60728+ let programMap = objectMap[ objectId ];
6071760729
6071860730 if ( programMap === undefined ) {
6071960731
6072060732 programMap = {};
60721- bindingStates[ geometry.id ] = programMap;
60733+ objectMap[ objectId ] = programMap;
6072260734
6072360735 }
6072460736
@@ -61119,21 +61131,27 @@ function WebGLBindingStates( gl, attributes ) {
6111961131
6112061132 for ( const geometryId in bindingStates ) {
6112161133
61122- const programMap = bindingStates[ geometryId ];
61134+ const objectMap = bindingStates[ geometryId ];
6112361135
61124- for ( const programId in programMap ) {
61136+ for ( const objectId in objectMap ) {
6112561137
61126- const stateMap = programMap[ programId ];
61138+ const programMap = objectMap[ objectId ];
6112761139
61128- for ( const wireframe in stateMap ) {
61140+ for ( const programId in programMap ) {
6112961141
61130- deleteVertexArrayObject( stateMap[ wireframe ].object ) ;
61142+ const stateMap = programMap[ programId ] ;
6113161143
61132- delete stateMap[ wireframe ];
61144+ for ( const wireframe in stateMap ) {
6113361145
61134- }
61146+ deleteVertexArrayObject( stateMap[ wireframe ].object );
6113561147
61136- delete programMap[ programId ];
61148+ delete stateMap[ wireframe ];
61149+
61150+ }
61151+
61152+ delete programMap[ programId ];
61153+
61154+ }
6113761155
6113861156 }
6113961157
@@ -61147,21 +61165,27 @@ function WebGLBindingStates( gl, attributes ) {
6114761165
6114861166 if ( bindingStates[ geometry.id ] === undefined ) return;
6114961167
61150- const programMap = bindingStates[ geometry.id ];
61168+ const objectMap = bindingStates[ geometry.id ];
6115161169
61152- for ( const programId in programMap ) {
61170+ for ( const objectId in objectMap ) {
6115361171
61154- const stateMap = programMap[ programId ];
61172+ const programMap = objectMap[ objectId ];
6115561173
61156- for ( const wireframe in stateMap ) {
61174+ for ( const programId in programMap ) {
6115761175
61158- deleteVertexArrayObject( stateMap[ wireframe ].object ) ;
61176+ const stateMap = programMap[ programId ] ;
6115961177
61160- delete stateMap[ wireframe ];
61178+ for ( const wireframe in stateMap ) {
6116161179
61162- }
61180+ deleteVertexArrayObject( stateMap[ wireframe ].object );
61181+
61182+ delete stateMap[ wireframe ];
6116361183
61164- delete programMap[ programId ];
61184+ }
61185+
61186+ delete programMap[ programId ];
61187+
61188+ }
6116561189
6116661190 }
6116761191
@@ -61173,26 +61197,73 @@ function WebGLBindingStates( gl, attributes ) {
6117361197
6117461198 for ( const geometryId in bindingStates ) {
6117561199
61176- const programMap = bindingStates[ geometryId ];
61200+ const objectMap = bindingStates[ geometryId ];
61201+
61202+ for ( const objectId in objectMap ) {
61203+
61204+ const programMap = objectMap[ objectId ];
61205+
61206+ if ( programMap[ program.id ] === undefined ) continue;
6117761207
61178- if ( programMap[ program.id ] === undefined ) continue ;
61208+ const stateMap = programMap[ program.id ];
6117961209
61180- const stateMap = programMap[ program.id ];
61210+ for ( const wireframe in stateMap ) {
61211+
61212+ deleteVertexArrayObject( stateMap[ wireframe ].object );
6118161213
61182- for ( const wireframe in stateMap ) {
61214+ delete stateMap[ wireframe ];
6118361215
61184- deleteVertexArrayObject( stateMap[ wireframe ].object );
61216+ }
6118561217
61186- delete stateMap[ wireframe ];
61218+ delete programMap[ program.id ];
6118761219
6118861220 }
6118961221
61190- delete programMap[ program.id ];
61222+ }
61223+
61224+ }
61225+
61226+ function releaseStatesOfObject( object ) {
61227+
61228+ for ( const geometryId in bindingStates ) {
61229+
61230+ const objectMap = bindingStates[ geometryId ];
61231+
61232+ const objectId = ( object.isInstancedMesh === true ) ? object.id : 0;
61233+
61234+ const programMap = objectMap[ objectId ];
61235+
61236+ if ( programMap === undefined ) continue;
61237+
61238+ for ( const programId in programMap ) {
61239+
61240+ const stateMap = programMap[ programId ];
61241+
61242+ for ( const wireframe in stateMap ) {
61243+
61244+ deleteVertexArrayObject( stateMap[ wireframe ].object );
61245+
61246+ delete stateMap[ wireframe ];
61247+
61248+ }
61249+
61250+ delete programMap[ programId ];
61251+
61252+ }
61253+
61254+ delete objectMap[ objectId ];
61255+
61256+ if ( Object.keys( objectMap ).length === 0 ) {
61257+
61258+ delete bindingStates[ geometryId ];
61259+
61260+ }
6119161261
6119261262 }
6119361263
6119461264 }
6119561265
61266+
6119661267 function reset() {
6119761268
6119861269 resetDefaultState();
@@ -61222,6 +61293,7 @@ function WebGLBindingStates( gl, attributes ) {
6122261293 resetDefaultState: resetDefaultState,
6122361294 dispose: dispose,
6122461295 releaseStatesOfGeometry: releaseStatesOfGeometry,
61296+ releaseStatesOfObject: releaseStatesOfObject,
6122561297 releaseStatesOfProgram: releaseStatesOfProgram,
6122661298
6122761299 initAttributes: initAttributes,
@@ -63556,7 +63628,7 @@ function WebGLMorphtargets( gl, capabilities, textures ) {
6355663628
6355763629}
6355863630
63559- function WebGLObjects( gl, geometries, attributes, info ) {
63631+ function WebGLObjects( gl, geometries, attributes, bindingStates, info ) {
6356063632
6356163633 let updateMap = new WeakMap();
6356263634
@@ -63631,6 +63703,8 @@ function WebGLObjects( gl, geometries, attributes, info ) {
6363163703
6363263704 instancedMesh.removeEventListener( 'dispose', onInstancedMeshDispose );
6363363705
63706+ bindingStates.releaseStatesOfObject( instancedMesh );
63707+
6363463708 attributes.remove( instancedMesh.instanceMatrix );
6363563709
6363663710 if ( instancedMesh.instanceColor !== null ) attributes.remove( instancedMesh.instanceColor );
@@ -66953,6 +67027,10 @@ function painterSortStable( a, b ) {
6695367027
6695467028 return a.material.id - b.material.id;
6695567029
67030+ } else if ( a.materialVariant !== b.materialVariant ) {
67031+
67032+ return a.materialVariant - b.materialVariant;
67033+
6695667034 } else if ( a.z !== b.z ) {
6695767035
6695867036 return a.z - b.z;
@@ -67007,6 +67085,15 @@ function WebGLRenderList() {
6700767085
6700867086 }
6700967087
67088+ function materialVariant( object ) {
67089+
67090+ let variant = 0;
67091+ if ( object.isInstancedMesh ) variant += 2;
67092+ if ( object.isSkinnedMesh ) variant += 1;
67093+ return variant;
67094+
67095+ }
67096+
6701067097 function getNextRenderItem( object, geometry, material, groupOrder, z, group ) {
6701167098
6701267099 let renderItem = renderItems[ renderItemsIndex ];
@@ -67018,6 +67105,7 @@ function WebGLRenderList() {
6701867105 object: object,
6701967106 geometry: geometry,
6702067107 material: material,
67108+ materialVariant: materialVariant( object ),
6702167109 groupOrder: groupOrder,
6702267110 renderOrder: object.renderOrder,
6702367111 z: z,
@@ -67032,6 +67120,7 @@ function WebGLRenderList() {
6703267120 renderItem.object = object;
6703367121 renderItem.geometry = geometry;
6703467122 renderItem.material = material;
67123+ renderItem.materialVariant = materialVariant( object );
6703567124 renderItem.groupOrder = groupOrder;
6703667125 renderItem.renderOrder = object.renderOrder;
6703767126 renderItem.z = z;
@@ -75021,7 +75110,7 @@ class WebGLRenderer {
7502175110 attributes = new WebGLAttributes( _gl );
7502275111 bindingStates = new WebGLBindingStates( _gl, attributes );
7502375112 geometries = new WebGLGeometries( _gl, attributes, info, bindingStates );
75024- objects = new WebGLObjects( _gl, geometries, attributes, info );
75113+ objects = new WebGLObjects( _gl, geometries, attributes, bindingStates, info );
7502575114 morphtargets = new WebGLMorphtargets( _gl, capabilities, textures );
7502675115 clipping = new WebGLClipping( properties );
7502775116 programCache = new WebGLPrograms( _this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping );
@@ -77747,27 +77836,9 @@ class WebGLRenderer {
7774777836 * @param {?(Box2|Box3)} [srcRegion=null] - A bounding box which describes the source region. Can be two or three-dimensional.
7774877837 * @param {?(Vector2|Vector3)} [dstPosition=null] - A vector that represents the origin of the destination region. Can be two or three-dimensional.
7774977838 * @param {number} [srcLevel=0] - The source mipmap level to copy.
77750- * @param {?number} [dstLevel=null ] - The destination mipmap level.
77839+ * @param {?number} [dstLevel=0 ] - The destination mipmap level.
7775177840 */
77752- this.copyTextureToTexture = function ( srcTexture, dstTexture, srcRegion = null, dstPosition = null, srcLevel = 0, dstLevel = null ) {
77753-
77754- // support the previous signature with just a single dst mipmap level
77755- if ( dstLevel === null ) {
77756-
77757- if ( srcLevel !== 0 ) {
77758-
77759- // @deprecated, r171
77760- warnOnce( 'WebGLRenderer: copyTextureToTexture function signature has changed to support src and dst mipmap levels.' );
77761- dstLevel = srcLevel;
77762- srcLevel = 0;
77763-
77764- } else {
77765-
77766- dstLevel = 0;
77767-
77768- }
77769-
77770- }
77841+ this.copyTextureToTexture = function ( srcTexture, dstTexture, srcRegion = null, dstPosition = null, srcLevel = 0, dstLevel = 0 ) {
7777177842
7777277843 // gather the necessary dimensions to copy
7777377844 let width, height, depth, minX, minY, minZ;
0 commit comments