@@ -33,7 +33,7 @@ import ConvolveSpecularMapVS from "../Shaders/ConvolveSpecularMapVS.js";
3333 * @typedef {object } DynamicEnvironmentMapManager.ConstructorOptions
3434 * Options for the DynamicEnvironmentMapManager constructor
3535 * @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.
3737 * @property {number } [maximumSecondsDifference=3600] The maximum amount of elapsed seconds before a new environment map is created.
3838 * @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.
3939 * @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) {
7777 this . _sphericalHarmonicCoefficientsDirty = false ;
7878
7979 this . _shouldRegenerateShaders = false ;
80+ this . _shouldReset = false ;
8081
8182 options = defaultValue ( options , defaultValue . EMPTY_OBJECT ) ;
8283
8384 const mipmapLevels = Math . min (
84- defaultValue ( options . mipmapLevels , 10 ) ,
85+ defaultValue ( options . mipmapLevels , 7 ) ,
8586 Math . log2 ( ContextLimits . maximumCubeMapSize ) ,
8687 ) ;
8788
@@ -251,7 +252,7 @@ Object.defineProperties(DynamicEnvironmentMapManager.prototype, {
251252 }
252253
253254 this . _position = Cartesian3 . clone ( value , this . _position ) ;
254- this . reset ( ) ;
255+ this . _shouldReset = true ;
255256 } ,
256257 } ,
257258
@@ -345,7 +346,7 @@ DynamicEnvironmentMapManager._updateCommandQueue = (frameState) => {
345346 DynamicEnvironmentMapManager . _activeComputeCommandCount <
346347 DynamicEnvironmentMapManager . _maximumComputeCommandCount
347348 ) {
348- if ( command . canceled ) {
349+ if ( command . owner . isDestroyed ( ) || command . canceled ) {
349350 command = DynamicEnvironmentMapManager . _nextFrameCommandQueue . shift ( ) ;
350351 continue ;
351352 }
@@ -354,6 +355,10 @@ DynamicEnvironmentMapManager._updateCommandQueue = (frameState) => {
354355 DynamicEnvironmentMapManager . _activeComputeCommandCount ++ ;
355356 command = DynamicEnvironmentMapManager . _nextFrameCommandQueue . shift ( ) ;
356357 }
358+
359+ if ( defined ( command ) ) {
360+ DynamicEnvironmentMapManager . _nextFrameCommandQueue . push ( command ) ;
361+ }
357362 }
358363} ;
359364
@@ -398,7 +403,6 @@ DynamicEnvironmentMapManager.prototype.reset = function () {
398403 for ( let i = 0 ; i < length ; ++ i ) {
399404 if ( defined ( this . _radianceMapComputeCommands [ i ] ) ) {
400405 this . _radianceMapComputeCommands [ i ] . canceled = true ;
401- DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
402406 }
403407 this . _radianceMapComputeCommands [ i ] = undefined ;
404408 }
@@ -407,19 +411,19 @@ DynamicEnvironmentMapManager.prototype.reset = function () {
407411 for ( let i = 0 ; i < length ; ++ i ) {
408412 if ( defined ( this . _convolutionComputeCommands [ i ] ) ) {
409413 this . _convolutionComputeCommands [ i ] . canceled = true ;
410- DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
411414 }
412415 this . _convolutionComputeCommands [ i ] = undefined ;
413416 }
414417
415418 if ( defined ( this . _irradianceComputeCommand ) ) {
416419 this . _irradianceComputeCommand . canceled = true ;
417- DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
418420 this . _irradianceComputeCommand = undefined ;
419421 }
420422
421423 this . _radianceMapDirty = true ;
422424 this . _radianceCommandsDirty = true ;
425+ this . _convolutionsCommandsDirty = false ;
426+ this . _irradianceCommandDirty = false ;
423427} ;
424428
425429const scratchPackedAtmosphere = new Cartesian3 ( ) ;
@@ -539,7 +543,8 @@ function updateRadianceMap(manager, frameState) {
539543 let i = 0 ;
540544 for ( const face of CubeMap . faceNames ( ) ) {
541545 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 ( ) ) {
543548 texture . destroy ( ) ;
544549 }
545550
@@ -570,36 +575,35 @@ function updateRadianceMap(manager, frameState) {
570575 ) ;
571576 } ,
572577 } ,
573- persists : true ,
574578 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 ) {
595582 DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
583+ return ;
584+ }
596585
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+ } ;
603607
604608 manager . _radianceMapComputeCommands [ i ] = command ;
605609 DynamicEnvironmentMapManager . _queueCommand ( command , frameState ) ;
@@ -626,32 +630,48 @@ function updateSpecularMaps(manager, frameState) {
626630 const context = frameState . context ;
627631
628632 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 -- ;
634636 return ;
635637 }
638+
639+ // Copy output texture to corresponding face and mipmap level
640+ const commands = manager . _convolutionComputeCommands ;
636641 commands [ index ] = undefined ;
637642
638643 radianceCubeMap . copyFace ( frameState , texture , face , level ) ;
639644 facesCopied ++ ;
640645 DynamicEnvironmentMapManager . _activeComputeCommandCount -- ;
641646
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 ) {
644653 manager . _irradianceCommandDirty = true ;
645654 radianceCubeMap . sampler = new Sampler ( {
646655 minificationFilter : TextureMinificationFilter . LINEAR_MIPMAP_LINEAR ,
647656 } ) ;
657+
648658 manager . _shouldRegenerateShaders = true ;
659+
660+ // Cleanup shared resources
661+ manager . _va . destroy ( ) ;
662+ manager . _va = undefined ;
663+ manager . _convolveSP . destroy ( ) ;
664+ manager . _convolveSP = undefined ;
649665 }
650666 } ;
651667
652668 let index = 0 ;
653669 for ( let level = 1 ; level < mipmapLevels ; ++ level ) {
654670 for ( const face of CubeMap . faceNames ( ) ) {
671+ if ( defined ( manager . _specularMapTextures [ index ] ) ) {
672+ manager . _specularMapTextures [ index ] . destroy ( ) ;
673+ }
674+
655675 const texture = ( manager . _specularMapTextures [ index ] = new Texture ( {
656676 context : context ,
657677 width : width ,
@@ -683,6 +703,8 @@ function updateSpecularMaps(manager, frameState) {
683703 shaderProgram : shaderProgram ,
684704 vertexArray : vertexArray ,
685705 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
686708 persists : true ,
687709 owner : manager ,
688710 uniformMap : {
@@ -692,8 +714,14 @@ function updateSpecularMaps(manager, frameState) {
692714 return CubeMap . getDirection ( face , scratchCartesian ) ;
693715 } ,
694716 } ,
695- postExecute : getPostExecute ( index , texture , face , level ) ,
696717 } ) ;
718+ command . postExecute = getPostExecute (
719+ command ,
720+ index ,
721+ texture ,
722+ face ,
723+ level ,
724+ ) ;
697725 manager . _convolutionComputeCommands [ index ] = command ;
698726 DynamicEnvironmentMapManager . _queueCommand ( command , frameState ) ;
699727 ++ index ;
@@ -717,17 +745,19 @@ function updateIrradianceResources(manager, frameState) {
717745 const dimensions = irradianceTextureDimensions ;
718746
719747 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 ( ) ;
729750 }
730751
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+
731761 let fs = manager . _irradianceMapFS ;
732762 if ( ! defined ( fs ) ) {
733763 fs = new ShaderSource ( {
@@ -739,21 +769,25 @@ function updateIrradianceResources(manager, frameState) {
739769 const command = new ComputeCommand ( {
740770 fragmentShaderSource : fs ,
741771 outputTexture : texture ,
772+ owner : manager ,
742773 uniformMap : {
743774 u_radianceMap : ( ) => manager . _radianceCubeMap ?? context . defaultTexture ,
744775 } ,
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+ } ) ;
753777
778+ command . postExecute = ( ) => {
779+ if ( manager . isDestroyed ( ) || command . canceled ) {
754780 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+
757791 manager . _irradianceComputeCommand = command ;
758792 DynamicEnvironmentMapManager . _queueCommand ( command , frameState ) ;
759793 manager . _irradianceTextureDirty = true ;
@@ -768,6 +802,11 @@ function updateIrradianceResources(manager, frameState) {
768802function updateSphericalHarmonicCoefficients ( manager , frameState ) {
769803 const context = frameState . context ;
770804
805+ if ( ! defined ( manager . _irradianceMapTexture ) ) {
806+ // Operation was canceled
807+ return ;
808+ }
809+
771810 const framebuffer = new Framebuffer ( {
772811 context : context ,
773812 colorTextures : [ manager . _irradianceMapTexture ] ,
@@ -793,6 +832,8 @@ function updateSphericalHarmonicCoefficients(manager, frameState) {
793832 }
794833
795834 framebuffer . destroy ( ) ;
835+ manager . _irradianceMapTexture . destroy ( ) ;
836+ manager . _irradianceMapTexture = undefined ;
796837 manager . _shouldRegenerateShaders = true ;
797838}
798839
@@ -834,9 +875,11 @@ DynamicEnvironmentMapManager.prototype.update = function (frameState) {
834875 this . maximumSecondsDifference ,
835876 ) ) ;
836877
837- if ( regenerateEnvironmentMap ) {
878+ if ( this . _shouldReset || regenerateEnvironmentMap ) {
838879 this . reset ( ) ;
880+ this . _shouldReset = false ;
839881 this . _lastTime = JulianDate . clone ( frameState . time , this . _lastTime ) ;
882+ return ;
840883 }
841884
842885 if ( this . _radianceMapDirty ) {
@@ -910,19 +953,33 @@ DynamicEnvironmentMapManager.prototype.destroy = function () {
910953 length = this . _radianceMapTextures . length ;
911954 for ( let i = 0 ; i < length ; ++ i ) {
912955 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 ( ) ;
914959 }
915960
916961 length = this . _specularMapTextures . length ;
917962 for ( let i = 0 ; i < length ; ++ i ) {
918963 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 ( ) ;
920967 }
921968
922969 this . _radianceCubeMap =
923970 this . _radianceCubeMap && this . _radianceCubeMap . destroy ( ) ;
924971 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+ }
926983
927984 return destroyObject ( this ) ;
928985} ;
0 commit comments