@@ -33,7 +33,7 @@ import ConvolveSpecularMapVS from "../Shaders/ConvolveSpecularMapVS.js";
33
33
* @typedef {object } DynamicEnvironmentMapManager.ConstructorOptions
34
34
* Options for the DynamicEnvironmentMapManager constructor
35
35
* @property {boolean } [enabled=true] If true, the environment map and related properties will continue to update.
36
- * @property {number } [mipmapLevels=10 ] The number of mipmap levels to generate for specular maps. More mipmap levels will produce a higher resolution specular reflection.
36
+ * @property {number } [mipmapLevels=7 ] The number of mipmap levels to generate for specular maps. More mipmap levels will produce a higher resolution specular reflection.
37
37
* @property {number } [maximumSecondsDifference=3600] The maximum amount of elapsed seconds before a new environment map is created.
38
38
* @property {number } [maximumPositionEpsilon=1000] The maximum difference in position before a new environment map is created, in meters. Small differences in position will not visibly affect results.
39
39
* @property {number } [atmosphereScatteringIntensity=2.0] The intensity of the scattered light emitted from the atmosphere. This should be adjusted relative to the value of {@link Scene.light} intensity.
@@ -77,11 +77,12 @@ function DynamicEnvironmentMapManager(options) {
77
77
this . _sphericalHarmonicCoefficientsDirty = false ;
78
78
79
79
this . _shouldRegenerateShaders = false ;
80
+ this . _shouldReset = false ;
80
81
81
82
options = defaultValue ( options , defaultValue . EMPTY_OBJECT ) ;
82
83
83
84
const mipmapLevels = Math . min (
84
- defaultValue ( options . mipmapLevels , 10 ) ,
85
+ defaultValue ( options . mipmapLevels , 7 ) ,
85
86
Math . log2 ( ContextLimits . maximumCubeMapSize ) ,
86
87
) ;
87
88
@@ -251,7 +252,7 @@ Object.defineProperties(DynamicEnvironmentMapManager.prototype, {
251
252
}
252
253
253
254
this . _position = Cartesian3 . clone ( value , this . _position ) ;
254
- this . reset ( ) ;
255
+ this . _shouldReset = true ;
255
256
} ,
256
257
} ,
257
258
@@ -345,7 +346,7 @@ DynamicEnvironmentMapManager._updateCommandQueue = (frameState) => {
345
346
DynamicEnvironmentMapManager . _activeComputeCommandCount <
346
347
DynamicEnvironmentMapManager . _maximumComputeCommandCount
347
348
) {
348
- if ( command . canceled ) {
349
+ if ( command . owner . isDestroyed ( ) || command . canceled ) {
349
350
command = DynamicEnvironmentMapManager . _nextFrameCommandQueue . shift ( ) ;
350
351
continue ;
351
352
}
@@ -354,6 +355,10 @@ DynamicEnvironmentMapManager._updateCommandQueue = (frameState) => {
354
355
DynamicEnvironmentMapManager . _activeComputeCommandCount ++ ;
355
356
command = DynamicEnvironmentMapManager . _nextFrameCommandQueue . shift ( ) ;
356
357
}
358
+
359
+ if ( defined ( command ) ) {
360
+ DynamicEnvironmentMapManager . _nextFrameCommandQueue . push ( command ) ;
361
+ }
357
362
}
358
363
} ;
359
364
@@ -398,7 +403,6 @@ DynamicEnvironmentMapManager.prototype.reset = function () {
398
403
for ( let i = 0 ; i < length ; ++ i ) {
399
404
if ( defined ( this . _radianceMapComputeCommands [ i ] ) ) {
400
405
this . _radianceMapComputeCommands [ i ] . canceled = true ;
401
- DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
402
406
}
403
407
this . _radianceMapComputeCommands [ i ] = undefined ;
404
408
}
@@ -407,19 +411,19 @@ DynamicEnvironmentMapManager.prototype.reset = function () {
407
411
for ( let i = 0 ; i < length ; ++ i ) {
408
412
if ( defined ( this . _convolutionComputeCommands [ i ] ) ) {
409
413
this . _convolutionComputeCommands [ i ] . canceled = true ;
410
- DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
411
414
}
412
415
this . _convolutionComputeCommands [ i ] = undefined ;
413
416
}
414
417
415
418
if ( defined ( this . _irradianceComputeCommand ) ) {
416
419
this . _irradianceComputeCommand . canceled = true ;
417
- DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
418
420
this . _irradianceComputeCommand = undefined ;
419
421
}
420
422
421
423
this . _radianceMapDirty = true ;
422
424
this . _radianceCommandsDirty = true ;
425
+ this . _convolutionsCommandsDirty = false ;
426
+ this . _irradianceCommandDirty = false ;
423
427
} ;
424
428
425
429
const scratchPackedAtmosphere = new Cartesian3 ( ) ;
@@ -539,7 +543,8 @@ function updateRadianceMap(manager, frameState) {
539
543
let i = 0 ;
540
544
for ( const face of CubeMap . faceNames ( ) ) {
541
545
let texture = manager . _radianceMapTextures [ i ] ;
542
- if ( defined ( texture ) ) {
546
+ // Destroy any existing textures that have no yet been cleaned up
547
+ if ( defined ( texture ) && ! texture . isDestroyed ( ) ) {
543
548
texture . destroy ( ) ;
544
549
}
545
550
@@ -570,36 +575,35 @@ function updateRadianceMap(manager, frameState) {
570
575
) ;
571
576
} ,
572
577
} ,
573
- persists : true ,
574
578
owner : manager ,
575
- postExecute : ( ) => {
576
- const commands = manager . _radianceMapComputeCommands ;
577
- if ( ! defined ( commands [ index ] ) ) {
578
- // This command was cancelled
579
- return ;
580
- }
581
- commands [ index ] = undefined ;
582
-
583
- const framebuffer = new Framebuffer ( {
584
- context : context ,
585
- colorTextures : [ manager . _radianceMapTextures [ index ] ] ,
586
- destroyAttachments : false ,
587
- } ) ;
588
-
589
- // Copy the output texture into the corresponding cubemap face
590
- framebuffer . _bind ( ) ;
591
- manager . _radianceCubeMap [ face ] . copyFromFramebuffer ( ) ;
592
- framebuffer . _unBind ( ) ;
593
- framebuffer . destroy ( ) ;
594
-
579
+ } ) ;
580
+ command . postExecute = ( ) => {
581
+ if ( manager . isDestroyed ( ) || command . canceled ) {
595
582
DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
583
+ return ;
584
+ }
596
585
597
- if ( ! commands . some ( defined ) ) {
598
- manager . _convolutionsCommandsDirty = true ;
599
- manager . _shouldRegenerateShaders = true ;
600
- }
601
- } ,
602
- } ) ;
586
+ const commands = manager . _radianceMapComputeCommands ;
587
+ commands [ index ] = undefined ;
588
+
589
+ const framebuffer = new Framebuffer ( {
590
+ context : context ,
591
+ colorTextures : [ manager . _radianceMapTextures [ index ] ] ,
592
+ } ) ;
593
+
594
+ // Copy the output texture into the corresponding cubemap face
595
+ framebuffer . _bind ( ) ;
596
+ manager . _radianceCubeMap [ face ] . copyFromFramebuffer ( ) ;
597
+ framebuffer . _unBind ( ) ;
598
+ framebuffer . destroy ( ) ;
599
+
600
+ DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
601
+
602
+ if ( ! commands . some ( defined ) ) {
603
+ manager . _convolutionsCommandsDirty = true ;
604
+ manager . _shouldRegenerateShaders = true ;
605
+ }
606
+ } ;
603
607
604
608
manager . _radianceMapComputeCommands [ i ] = command ;
605
609
DynamicEnvironmentMapManager . _queueCommand ( command , frameState ) ;
@@ -626,32 +630,48 @@ function updateSpecularMaps(manager, frameState) {
626
630
const context = frameState . context ;
627
631
628
632
let facesCopied = 0 ;
629
- const getPostExecute = ( index , texture , face , level ) => ( ) => {
630
- // Copy output texture to corresponding face and mipmap level
631
- const commands = manager . _convolutionComputeCommands ;
632
- if ( ! defined ( commands [ index ] ) || commands [ index ] . canceled ) {
633
- // This command was cancelled
633
+ const getPostExecute = ( command , index , texture , face , level ) => ( ) => {
634
+ if ( manager . isDestroyed ( ) || command . canceled ) {
635
+ DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
634
636
return ;
635
637
}
638
+
639
+ // Copy output texture to corresponding face and mipmap level
640
+ const commands = manager . _convolutionComputeCommands ;
636
641
commands [ index ] = undefined ;
637
642
638
643
radianceCubeMap . copyFace ( frameState , texture , face , level ) ;
639
644
facesCopied ++ ;
640
645
DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
641
646
642
- // All faces and levels have been copied
643
- if ( facesCopied === manager . _specularMapTextures . length ) {
647
+ texture . destroy ( ) ;
648
+ manager . _specularMapTextures [ index ] = undefined ;
649
+
650
+ // All faces for each mipmap level have been copied
651
+ const length = manager . _specularMapTextures . length ;
652
+ if ( facesCopied >= length ) {
644
653
manager . _irradianceCommandDirty = true ;
645
654
radianceCubeMap . sampler = new Sampler ( {
646
655
minificationFilter : TextureMinificationFilter . LINEAR_MIPMAP_LINEAR ,
647
656
} ) ;
657
+
648
658
manager . _shouldRegenerateShaders = true ;
659
+
660
+ // Cleanup shared resources
661
+ manager . _va . destroy ( ) ;
662
+ manager . _va = undefined ;
663
+ manager . _convolveSP . destroy ( ) ;
664
+ manager . _convolveSP = undefined ;
649
665
}
650
666
} ;
651
667
652
668
let index = 0 ;
653
669
for ( let level = 1 ; level < mipmapLevels ; ++ level ) {
654
670
for ( const face of CubeMap . faceNames ( ) ) {
671
+ if ( defined ( manager . _specularMapTextures [ index ] ) ) {
672
+ manager . _specularMapTextures [ index ] . destroy ( ) ;
673
+ }
674
+
655
675
const texture = ( manager . _specularMapTextures [ index ] = new Texture ( {
656
676
context : context ,
657
677
width : width ,
@@ -683,6 +703,8 @@ function updateSpecularMaps(manager, frameState) {
683
703
shaderProgram : shaderProgram ,
684
704
vertexArray : vertexArray ,
685
705
outputTexture : texture ,
706
+ // Persist so we can use a shared shader progam and vertex array across all commands
707
+ // Shared resources are instead destroyed in postExecute
686
708
persists : true ,
687
709
owner : manager ,
688
710
uniformMap : {
@@ -692,8 +714,14 @@ function updateSpecularMaps(manager, frameState) {
692
714
return CubeMap . getDirection ( face , scratchCartesian ) ;
693
715
} ,
694
716
} ,
695
- postExecute : getPostExecute ( index , texture , face , level ) ,
696
717
} ) ;
718
+ command . postExecute = getPostExecute (
719
+ command ,
720
+ index ,
721
+ texture ,
722
+ face ,
723
+ level ,
724
+ ) ;
697
725
manager . _convolutionComputeCommands [ index ] = command ;
698
726
DynamicEnvironmentMapManager . _queueCommand ( command , frameState ) ;
699
727
++ index ;
@@ -717,17 +745,19 @@ function updateIrradianceResources(manager, frameState) {
717
745
const dimensions = irradianceTextureDimensions ;
718
746
719
747
let texture = manager . _irradianceMapTexture ;
720
- if ( ! defined ( texture ) ) {
721
- texture = new Texture ( {
722
- context : context ,
723
- width : dimensions . x ,
724
- height : dimensions . y ,
725
- pixelDatatype : PixelDatatype . FLOAT ,
726
- pixelFormat : PixelFormat . RGBA ,
727
- } ) ;
728
- manager . _irradianceMapTexture = texture ;
748
+ if ( defined ( texture ) && ! texture . isDestroyed ( ) ) {
749
+ texture . destroy ( ) ;
729
750
}
730
751
752
+ texture = new Texture ( {
753
+ context : context ,
754
+ width : dimensions . x ,
755
+ height : dimensions . y ,
756
+ pixelDatatype : PixelDatatype . FLOAT ,
757
+ pixelFormat : PixelFormat . RGBA ,
758
+ } ) ;
759
+ manager . _irradianceMapTexture = texture ;
760
+
731
761
let fs = manager . _irradianceMapFS ;
732
762
if ( ! defined ( fs ) ) {
733
763
fs = new ShaderSource ( {
@@ -739,21 +769,25 @@ function updateIrradianceResources(manager, frameState) {
739
769
const command = new ComputeCommand ( {
740
770
fragmentShaderSource : fs ,
741
771
outputTexture : texture ,
772
+ owner : manager ,
742
773
uniformMap : {
743
774
u_radianceMap : ( ) => manager . _radianceCubeMap ?? context . defaultTexture ,
744
775
} ,
745
- postExecute : ( ) => {
746
- if ( ! defined ( manager . _irradianceComputeCommand ) ) {
747
- // This command was cancelled
748
- return ;
749
- }
750
- manager . _irradianceTextureDirty = false ;
751
- manager . _irradianceComputeCommand = undefined ;
752
- manager . _sphericalHarmonicCoefficientsDirty = true ;
776
+ } ) ;
753
777
778
+ command . postExecute = ( ) => {
779
+ if ( manager . isDestroyed ( ) || command . canceled ) {
754
780
DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
755
- } ,
756
- } ) ;
781
+ return ;
782
+ }
783
+ manager . _irradianceTextureDirty = false ;
784
+ manager . _irradianceComputeCommand = undefined ;
785
+ manager . _sphericalHarmonicCoefficientsDirty = true ;
786
+ manager . _irradianceMapFS = undefined ;
787
+
788
+ DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
789
+ } ;
790
+
757
791
manager . _irradianceComputeCommand = command ;
758
792
DynamicEnvironmentMapManager . _queueCommand ( command , frameState ) ;
759
793
manager . _irradianceTextureDirty = true ;
@@ -768,6 +802,11 @@ function updateIrradianceResources(manager, frameState) {
768
802
function updateSphericalHarmonicCoefficients ( manager , frameState ) {
769
803
const context = frameState . context ;
770
804
805
+ if ( ! defined ( manager . _irradianceMapTexture ) ) {
806
+ // Operation was canceled
807
+ return ;
808
+ }
809
+
771
810
const framebuffer = new Framebuffer ( {
772
811
context : context ,
773
812
colorTextures : [ manager . _irradianceMapTexture ] ,
@@ -793,6 +832,8 @@ function updateSphericalHarmonicCoefficients(manager, frameState) {
793
832
}
794
833
795
834
framebuffer . destroy ( ) ;
835
+ manager . _irradianceMapTexture . destroy ( ) ;
836
+ manager . _irradianceMapTexture = undefined ;
796
837
manager . _shouldRegenerateShaders = true ;
797
838
}
798
839
@@ -834,9 +875,11 @@ DynamicEnvironmentMapManager.prototype.update = function (frameState) {
834
875
this . maximumSecondsDifference ,
835
876
) ) ;
836
877
837
- if ( regenerateEnvironmentMap ) {
878
+ if ( this . _shouldReset || regenerateEnvironmentMap ) {
838
879
this . reset ( ) ;
880
+ this . _shouldReset = false ;
839
881
this . _lastTime = JulianDate . clone ( frameState . time , this . _lastTime ) ;
882
+ return ;
840
883
}
841
884
842
885
if ( this . _radianceMapDirty ) {
@@ -910,19 +953,33 @@ DynamicEnvironmentMapManager.prototype.destroy = function () {
910
953
length = this . _radianceMapTextures . length ;
911
954
for ( let i = 0 ; i < length ; ++ i ) {
912
955
this . _radianceMapTextures [ i ] =
913
- this . _radianceMapTextures [ i ] && this . _radianceMapTextures [ i ] . destroy ( ) ;
956
+ this . _radianceMapTextures [ i ] &&
957
+ ! this . _radianceMapTextures [ i ] . isDestroyed ( ) &&
958
+ this . _radianceMapTextures [ i ] . destroy ( ) ;
914
959
}
915
960
916
961
length = this . _specularMapTextures . length ;
917
962
for ( let i = 0 ; i < length ; ++ i ) {
918
963
this . _specularMapTextures [ i ] =
919
- this . _specularMapTextures [ i ] && this . _specularMapTextures [ i ] . destroy ( ) ;
964
+ this . _specularMapTextures [ i ] &&
965
+ ! this . _specularMapTextures [ i ] . isDestroyed ( ) &&
966
+ this . _specularMapTextures [ i ] . destroy ( ) ;
920
967
}
921
968
922
969
this . _radianceCubeMap =
923
970
this . _radianceCubeMap && this . _radianceCubeMap . destroy ( ) ;
924
971
this . _irradianceMapTexture =
925
- this . _irradianceMapTexture && this . _irradianceMapTexture . destroy ( ) ;
972
+ this . _irradianceMapTexture &&
973
+ ! this . _irradianceMapTexture . isDestroyed ( ) &&
974
+ this . _irradianceMapTexture . destroy ( ) ;
975
+
976
+ if ( defined ( this . _va ) ) {
977
+ this . _va . destroy ( ) ;
978
+ }
979
+
980
+ if ( defined ( this . _convolveSP ) ) {
981
+ this . _convolveSP . destroy ( ) ;
982
+ }
926
983
927
984
return destroyObject ( this ) ;
928
985
} ;
0 commit comments