@@ -14,7 +14,7 @@ function WebGLBindingStates( gl, attributes ) {
1414
1515 let updateBuffers = false ;
1616
17- const state = getBindingState ( geometry , program , material ) ;
17+ const state = getBindingState ( object , geometry , program , material ) ;
1818
1919 if ( currentState !== state ) {
2020
@@ -67,16 +67,28 @@ function WebGLBindingStates( gl, attributes ) {
6767
6868 }
6969
70- function getBindingState ( geometry , program , material ) {
70+ function getBindingState ( object , geometry , program , material ) {
7171
7272 const wireframe = ( material . wireframe === true ) ;
7373
74- let programMap = bindingStates [ geometry . id ] ;
74+ let objectMap = bindingStates [ geometry . id ] ;
75+
76+ if ( objectMap === undefined ) {
77+
78+ objectMap = { } ;
79+ bindingStates [ geometry . id ] = objectMap ;
80+
81+ }
82+
83+ // Each InstancedMesh requires unique binding states because it contains instanced attributes.
84+ const objectId = ( object . isInstancedMesh === true ) ? object . id : 0 ;
85+
86+ let programMap = objectMap [ objectId ] ;
7587
7688 if ( programMap === undefined ) {
7789
7890 programMap = { } ;
79- bindingStates [ geometry . id ] = programMap ;
91+ objectMap [ objectId ] = programMap ;
8092
8193 }
8294
@@ -477,21 +489,27 @@ function WebGLBindingStates( gl, attributes ) {
477489
478490 for ( const geometryId in bindingStates ) {
479491
480- const programMap = bindingStates [ geometryId ] ;
492+ const objectMap = bindingStates [ geometryId ] ;
481493
482- for ( const programId in programMap ) {
494+ for ( const objectId in objectMap ) {
483495
484- const stateMap = programMap [ programId ] ;
496+ const programMap = objectMap [ objectId ] ;
485497
486- for ( const wireframe in stateMap ) {
498+ for ( const programId in programMap ) {
487499
488- deleteVertexArrayObject ( stateMap [ wireframe ] . object ) ;
500+ const stateMap = programMap [ programId ] ;
489501
490- delete stateMap [ wireframe ] ;
502+ for ( const wireframe in stateMap ) {
491503
492- }
504+ deleteVertexArrayObject ( stateMap [ wireframe ] . object ) ;
493505
494- delete programMap [ programId ] ;
506+ delete stateMap [ wireframe ] ;
507+
508+ }
509+
510+ delete programMap [ programId ] ;
511+
512+ }
495513
496514 }
497515
@@ -505,21 +523,27 @@ function WebGLBindingStates( gl, attributes ) {
505523
506524 if ( bindingStates [ geometry . id ] === undefined ) return ;
507525
508- const programMap = bindingStates [ geometry . id ] ;
526+ const objectMap = bindingStates [ geometry . id ] ;
509527
510- for ( const programId in programMap ) {
528+ for ( const objectId in objectMap ) {
511529
512- const stateMap = programMap [ programId ] ;
530+ const programMap = objectMap [ objectId ] ;
513531
514- for ( const wireframe in stateMap ) {
532+ for ( const programId in programMap ) {
515533
516- deleteVertexArrayObject ( stateMap [ wireframe ] . object ) ;
534+ const stateMap = programMap [ programId ] ;
517535
518- delete stateMap [ wireframe ] ;
536+ for ( const wireframe in stateMap ) {
519537
520- }
538+ deleteVertexArrayObject ( stateMap [ wireframe ] . object ) ;
521539
522- delete programMap [ programId ] ;
540+ delete stateMap [ wireframe ] ;
541+
542+ }
543+
544+ delete programMap [ programId ] ;
545+
546+ }
523547
524548 }
525549
@@ -531,26 +555,73 @@ function WebGLBindingStates( gl, attributes ) {
531555
532556 for ( const geometryId in bindingStates ) {
533557
534- const programMap = bindingStates [ geometryId ] ;
558+ const objectMap = bindingStates [ geometryId ] ;
559+
560+ for ( const objectId in objectMap ) {
561+
562+ const programMap = objectMap [ objectId ] ;
563+
564+ if ( programMap [ program . id ] === undefined ) continue ;
565+
566+ const stateMap = programMap [ program . id ] ;
567+
568+ for ( const wireframe in stateMap ) {
569+
570+ deleteVertexArrayObject ( stateMap [ wireframe ] . object ) ;
571+
572+ delete stateMap [ wireframe ] ;
573+
574+ }
575+
576+ delete programMap [ program . id ] ;
577+
578+ }
579+
580+ }
581+
582+ }
583+
584+ function releaseStatesOfObject ( object ) {
585+
586+ for ( const geometryId in bindingStates ) {
587+
588+ const objectMap = bindingStates [ geometryId ] ;
535589
536- if ( programMap [ program . id ] === undefined ) continue ;
590+ const objectId = ( object . isInstancedMesh === true ) ? object . id : 0 ;
537591
538- const stateMap = programMap [ program . id ] ;
592+ const programMap = objectMap [ objectId ] ;
539593
540- for ( const wireframe in stateMap ) {
594+ if ( programMap === undefined ) continue ;
541595
542- deleteVertexArrayObject ( stateMap [ wireframe ] . object ) ;
596+ for ( const programId in programMap ) {
543597
544- delete stateMap [ wireframe ] ;
598+ const stateMap = programMap [ programId ] ;
599+
600+ for ( const wireframe in stateMap ) {
601+
602+ deleteVertexArrayObject ( stateMap [ wireframe ] . object ) ;
603+
604+ delete stateMap [ wireframe ] ;
605+
606+ }
607+
608+ delete programMap [ programId ] ;
545609
546610 }
547611
548- delete programMap [ program . id ] ;
612+ delete objectMap [ objectId ] ;
613+
614+ if ( Object . keys ( objectMap ) . length === 0 ) {
615+
616+ delete bindingStates [ geometryId ] ;
617+
618+ }
549619
550620 }
551621
552622 }
553623
624+
554625 function reset ( ) {
555626
556627 resetDefaultState ( ) ;
@@ -580,6 +651,7 @@ function WebGLBindingStates( gl, attributes ) {
580651 resetDefaultState : resetDefaultState ,
581652 dispose : dispose ,
582653 releaseStatesOfGeometry : releaseStatesOfGeometry ,
654+ releaseStatesOfObject : releaseStatesOfObject ,
583655 releaseStatesOfProgram : releaseStatesOfProgram ,
584656
585657 initAttributes : initAttributes ,
0 commit comments