@@ -10,11 +10,10 @@ import {
1010Object3D ,
1111OrthographicCamera ,
1212PerspectiveCamera ,
13- RawShaderMaterial ,
13+ SRGBColorSpace ,
1414Scene ,
1515ShaderMaterial ,
1616Texture ,
17- Uniform ,
1817Vector2 ,
1918WebGLRenderTarget ,
2019WebGLRenderer
@@ -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>
104104private readonly sceneListener :( event :SceneEvent ) => void ;
105105
106106/**
107- *Keeps track ofprevious inputdefines .
107+ *A container that keeps track of inputshader 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>
247241super ( ) ;
248242
249243this . 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
254246this . fullscreenScene = null ;
255247this . fullscreenCamera = null ;
@@ -542,18 +534,30 @@ export abstract class Pass<TMaterial extends Material | null = null>
542534
543535protected set fullscreenMaterial ( value :TMaterial ) {
544536
537+ if ( value === null ) {
538+
539+ return ;
540+
541+ }
542+
545543if ( 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 ) ;
552550this . screen . frustumCulled = false ;
553551this . fullscreenScene = new Scene ( ) ;
554552this . fullscreenCamera = new OrthographicCamera ( - 1 , 1 , 1 , - 1 , 0 , 1 ) ;
555553this . fullscreenScene . add ( this . screen ) ;
554+
555+ }
556+
557+ if ( ! this . materials . has ( value ) ) {
558+
556559this . 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 definesor uniforms available.
677+ // No definesand uniforms available.
675678return ;
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 outputdata ofthe fullscreenmaterial, if it exists .
713+ * Updates the shader outputsettings ofall 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>
11541136switch ( event . type ) {
11551137
11561138case "change" :
1157- this . updateFullscreenMaterialInput ( ) ;
1139+ this . updateFullscreenMaterialsInput ( ) ;
11581140this . onInputChange ( ) ;
11591141break ;
11601142
@@ -1180,7 +1162,7 @@ export abstract class Pass<TMaterial extends Material | null = null>
11801162
11811163case "change" :
11821164this . updateOutputBufferSize ( ) ;
1183- this . updateFullscreenMaterialOutput ( ) ;
1165+ this . updateFullscreenMaterialsOutput ( ) ;
11841166this . onOutputChange ( ) ;
11851167break ;
11861168
@@ -1222,8 +1204,7 @@ export abstract class Pass<TMaterial extends Material | null = null>
12221204
12231205this . input . dispose ( ) ;
12241206this . output . dispose ( ) ;
1225- this . previousDefines . clear ( ) ;
1226- this . previousUniforms . clear ( ) ;
1207+ this . shaderDataTracker . dispose ( ) ;
12271208
12281209for ( const material of this . materials ) {
12291210