@@ -10,11 +10,10 @@ import {
1010 Object3D ,
1111 OrthographicCamera ,
1212 PerspectiveCamera ,
13- RawShaderMaterial ,
13+ SRGBColorSpace ,
1414 Scene ,
1515 ShaderMaterial ,
1616 Texture ,
17- Uniform ,
1817 Vector2 ,
1918 WebGLRenderTarget ,
2019 WebGLRenderer
@@ -25,6 +24,7 @@ import { IdManager } from "../utils/IdManager.js";
2524import { ImmutableTimer } from "../utils/ImmutableTimer.js" ;
2625import { Resolution } from "../utils/Resolution.js" ;
2726import { SceneEvent , SceneEventTarget } from "../utils/SceneEventTarget.js" ;
27+ import { ShaderDataTracker } from "../utils/ShaderDataTracker.js" ;
2828import { Scissor } from "../utils/Scissor.js" ;
2929import { Viewport } from "../utils/Viewport.js" ;
3030import { BaseEventMap } from "./BaseEventMap.js" ;
@@ -104,16 +104,10 @@ export abstract class Pass<TMaterial extends Material | null = null>
104104 private readonly sceneListener : ( event : SceneEvent ) => void ;
105105
106106 /**
107- * Keeps track of previous input defines .
107+ * A container that keeps track of input shader data .
108108 */
109109
110- private readonly previousDefines : Map < string , string | number | boolean > ;
111-
112- /**
113- * Keeps track of previous input uniforms.
114- */
115-
116- private readonly previousUniforms : Map < string , Uniform > ;
110+ private readonly shaderDataTracker : ShaderDataTracker ;
117111
118112 /**
119113 * A scene that contains the fullscreen mesh.
@@ -247,9 +241,7 @@ export abstract class Pass<TMaterial extends Material | null = null>
247241 super ( ) ;
248242
249243 this . sceneListener = ( event ) => this . handleSceneEvent ( event ) ;
250-
251- this . previousDefines = new Map < string , string | number | boolean > ( ) ;
252- this . previousUniforms = new Map < string , Uniform > ( ) ;
244+ this . shaderDataTracker = new ShaderDataTracker ( ) ;
253245
254246 this . fullscreenScene = null ;
255247 this . fullscreenCamera = null ;
@@ -542,18 +534,30 @@ export abstract class Pass<TMaterial extends Material | null = null>
542534
543535 protected set fullscreenMaterial ( value : TMaterial ) {
544536
537+ if ( value === null ) {
538+
539+ return ;
540+
541+ }
542+
545543 if ( this . screen !== null ) {
546544
547- this . screen . material = value ! ;
545+ this . screen . material = value ;
548546
549547 } else {
550548
551- this . screen = new Mesh ( Pass . fullscreenGeometry , value ! ) ;
549+ this . screen = new Mesh ( Pass . fullscreenGeometry , value ) ;
552550 this . screen . frustumCulled = false ;
553551 this . fullscreenScene = new Scene ( ) ;
554552 this . fullscreenCamera = new OrthographicCamera ( - 1 , 1 , 1 , - 1 , 0 , 1 ) ;
555553 this . fullscreenScene . add ( this . screen ) ;
554+
555+ }
556+
557+ if ( ! this . materials . has ( value ) ) {
558+
556559 this . materials . add ( value ) ;
560+ this . updateFullscreenMaterialInput ( value ) ;
557561
558562 }
559563
@@ -661,86 +665,64 @@ export abstract class Pass<TMaterial extends Material | null = null>
661665 }
662666
663667 /**
664- * Updates the shader input data of the fullscreen material, if it exists.
668+ * Updates the shader input data of the given fullscreen material.
669+ *
670+ * @param material - The material to update.
665671 */
666672
667- private updateFullscreenMaterialInput ( ) : void {
668-
669- const fullscreenMaterial = this . fullscreenMaterial ;
673+ private updateFullscreenMaterialInput ( material : Material | null ) : void {
670674
671- if ( ! ( fullscreenMaterial instanceof RawShaderMaterial ||
672- fullscreenMaterial instanceof ShaderMaterial ) ) {
675+ if ( ! ( material instanceof ShaderMaterial ) ) {
673676
674- // No defines or uniforms available.
677+ // No defines and uniforms available.
675678 return ;
676679
677680 }
678681
679- if ( fullscreenMaterial instanceof FullscreenMaterial ) {
680-
681- fullscreenMaterial . inputBuffer = this . input . defaultBuffer ?. value ?? null ;
682-
683- } else {
684-
685- if ( this . input . frameBufferPrecisionHigh ) {
686-
687- fullscreenMaterial . defines . FRAME_BUFFER_PRECISION_HIGH = true ;
688-
689- } else {
690-
691- delete fullscreenMaterial . defines . FRAME_BUFFER_PRECISION_HIGH ;
692-
693- }
694-
695- }
696-
697- // Remove previous input defines and uniforms.
698-
699- for ( const key of this . previousDefines . keys ( ) ) {
700-
701- delete fullscreenMaterial . defines [ key ] ;
702-
703- }
704-
705- for ( const key of this . previousUniforms . keys ( ) ) {
682+ if ( material instanceof FullscreenMaterial ) {
706683
707- delete fullscreenMaterial . uniforms [ key ] ;
684+ material . inputBuffer = this . input . defaultBuffer ?. value ?? null ;
708685
709686 }
710687
711- this . previousDefines . clear ( ) ;
712- this . previousUniforms . clear ( ) ;
713-
714- // Add the new input defines and uniforms.
688+ this . shaderDataTracker
689+ . applyDefines ( material , this . input . defines )
690+ . applyUniforms ( material , this . input . uniforms ) ;
715691
716- for ( const entry of this . input . defines ) {
692+ }
717693
718- this . previousDefines . set ( entry [ 0 ] , entry [ 1 ] ) ;
719- fullscreenMaterial . defines [ entry [ 0 ] ] = entry [ 1 ] ;
694+ /**
695+ * Updates the shader input data of all fullscreen {@link materials}.
696+ */
720697
721- }
698+ private updateFullscreenMaterialsInput ( ) : void {
722699
723- for ( const entry of this . input . uniforms ) {
700+ for ( const material of this . materials ) {
724701
725- this . previousUniforms . set ( entry [ 0 ] , entry [ 1 ] ) ;
726- fullscreenMaterial . uniforms [ entry [ 0 ] ] = entry [ 1 ] ;
702+ this . updateFullscreenMaterialInput ( material ) ;
727703
728704 }
729705
730- fullscreenMaterial . needsUpdate = true ;
706+ this . shaderDataTracker
707+ . trackDefines ( this . input . defines )
708+ . trackUniforms ( this . input . uniforms ) ;
731709
732710 }
733711
734712 /**
735- * Updates the shader output data of the fullscreen material, if it exists .
713+ * Updates the shader output settings of all fullscreen { @link materials} .
736714 */
737715
738- private updateFullscreenMaterialOutput ( ) : void {
716+ private updateFullscreenMaterialsOutput ( ) : void {
717+
718+ for ( const material of this . materials ) {
739719
740- if ( this . fullscreenMaterial instanceof FullscreenMaterial ) {
720+ if ( material instanceof FullscreenMaterial ) {
741721
742- // High precision buffers use HalfFloatType (mediump).
743- this . fullscreenMaterial . outputPrecision = this . output . frameBufferPrecisionHigh ? "mediump" : "lowp" ;
722+ // High precision buffers use HalfFloatType (mediump).
723+ material . outputPrecision = this . output . frameBufferPrecisionHigh ? "mediump" : "lowp" ;
724+
725+ }
744726
745727 }
746728
@@ -1154,7 +1136,7 @@ export abstract class Pass<TMaterial extends Material | null = null>
11541136 switch ( event . type ) {
11551137
11561138 case "change" :
1157- this . updateFullscreenMaterialInput ( ) ;
1139+ this . updateFullscreenMaterialsInput ( ) ;
11581140 this . onInputChange ( ) ;
11591141 break ;
11601142
@@ -1180,7 +1162,7 @@ export abstract class Pass<TMaterial extends Material | null = null>
11801162
11811163 case "change" :
11821164 this . updateOutputBufferSize ( ) ;
1183- this . updateFullscreenMaterialOutput ( ) ;
1165+ this . updateFullscreenMaterialsOutput ( ) ;
11841166 this . onOutputChange ( ) ;
11851167 break ;
11861168
@@ -1222,8 +1204,7 @@ export abstract class Pass<TMaterial extends Material | null = null>
12221204
12231205 this . input . dispose ( ) ;
12241206 this . output . dispose ( ) ;
1225- this . previousDefines . clear ( ) ;
1226- this . previousUniforms . clear ( ) ;
1207+ this . shaderDataTracker . dispose ( ) ;
12271208
12281209 for ( const material of this . materials ) {
12291210
0 commit comments