@@ -6,6 +6,7 @@ import { GBufferConfig } from "./GBufferConfig.js";
66import { EffectShaderData } from "./EffectShaderData.js" ;
77import { EffectMaterial } from "../materials/EffectMaterial.js" ;
88import { ShaderData } from "../core/ShaderData.js" ;
9+ import { GBuffer } from "../enums/GBuffer.js" ;
910
1011/**
1112 * An effect material manager that creates, updates and caches effect shader combinations.
@@ -70,6 +71,12 @@ export class EffectMaterialManager implements Disposable {
7071
7172private _gBufferConfig :GBufferConfig | null ;
7273
74+ /**
75+ *@see {@link gBufferConfig }
76+ */
77+
78+ private _gBuffer :Set < GBuffer | string > | null ;
79+
7380/**
7481 *@see {@link dithering }
7582 */
@@ -93,6 +100,7 @@ export class EffectMaterialManager implements Disposable {
93100this . activeMaterial = null ;
94101
95102this . _gBufferConfig = null ;
103+ this . _gBuffer = null ;
96104this . _dithering = false ;
97105
98106}
@@ -130,6 +138,29 @@ export class EffectMaterialManager implements Disposable {
130138
131139}
132140
141+ /**
142+ * The current input G-Buffer components.
143+ *
144+ * Assigning a new G-Buffer will invalidate the material cache.
145+ */
146+
147+ get gBuffer ( ) :Set < GBuffer | string > | null {
148+
149+ return this . _gBuffer ;
150+
151+ }
152+
153+ set gBuffer ( value :Set < GBuffer | string > | null ) {
154+
155+ if ( this . _gBuffer !== value ) {
156+
157+ this . invalidateMaterialCache ( ) ;
158+ this . _gBuffer = value ;
159+
160+ }
161+
162+ }
163+
133164/**
134165 * Indicates whether dithering is enabled.
135166 */
@@ -178,14 +209,14 @@ export class EffectMaterialManager implements Disposable {
178209
179210private getEffectShaderData ( effects :Effect [ ] ) :EffectShaderData {
180211
181- const result = new EffectShaderData ( this . gBufferConfig ) ;
212+ const result = new EffectShaderData ( ) ;
182213const effectShaderDataCache = this . effectShaderDataCache ;
183214
184215for ( const effect of effects ) {
185216
186217if ( ! effectShaderDataCache . has ( effect ) ) {
187218
188- const data = new EffectShaderData ( this . gBufferConfig ) ;
219+ const data = new EffectShaderData ( ) ;
189220data . integrateEffect ( `e${ effect . id } ` , effect ) ;
190221effectShaderDataCache . set ( effect , data ) ;
191222
@@ -203,6 +234,31 @@ export class EffectMaterialManager implements Disposable {
203234
204235}
205236
237+ /**
238+ * Creates shader code for a `GBuffer` struct declaration.
239+ *
240+ *@param gBufferConfig - A G-Buffer config.
241+ *@return The shader code.
242+ */
243+
244+ private createGBufferStructDeclaration ( gBufferConfig :GBufferConfig ) :string {
245+
246+ if ( this . gBuffer === null ) {
247+
248+ throw new Error ( "Missing G-Buffer information" ) ;
249+
250+ }
251+
252+ return [
253+ "struct GBuffer {" ,
254+ ...Array . from ( gBufferConfig . gBufferStructDeclaration )
255+ . filter ( x => this . gBuffer ! . has ( x [ 0 ] ) )
256+ . map ( x => `\t${ x [ 1 ] } ` ) ,
257+ "};\n"
258+ ] . join ( "\n" ) ;
259+
260+ }
261+
206262/**
207263 * Creates a material based on the given effects.
208264 *
@@ -217,9 +273,15 @@ export class EffectMaterialManager implements Disposable {
217273const result = ( id === EffectMaterialManager . DEFAULT_MATERIAL_ID ) ?this . defaultMaterial :new EffectMaterial ( ) ;
218274const data = this . getEffectShaderData ( effects ) ;
219275
220- data . shaderParts . set ( Section . FRAGMENT_HEAD_GBUFFER , data . createGBufferStruct ( ) ) ;
221- data . shaderParts . set ( Section . FRAGMENT_HEAD_GDATA , data . createGDataStructDeclaration ( ) ) ;
222- data . shaderParts . set ( Section . FRAGMENT_MAIN_GDATA , data . createGDataStructInitialization ( ) ) ;
276+ const gBufferConfig = this . gBufferConfig ;
277+
278+ if ( gBufferConfig !== null ) {
279+
280+ data . shaderParts . set ( Section . FRAGMENT_HEAD_GBUFFER , this . createGBufferStructDeclaration ( gBufferConfig ) ) ;
281+ data . shaderParts . set ( Section . FRAGMENT_HEAD_GDATA , data . createGDataStructDeclaration ( gBufferConfig ) ) ;
282+ data . shaderParts . set ( Section . FRAGMENT_MAIN_GDATA , data . createGDataStructInitialization ( gBufferConfig ) ) ;
283+
284+ }
223285
224286const fragmentHead = data . shaderParts . get ( Section . FRAGMENT_HEAD_EFFECTS ) ! ;
225287data . shaderParts . set ( Section . FRAGMENT_HEAD_EFFECTS , fragmentHead + data . createBlendFunctions ( ) ) ;