@@ -16,11 +16,9 @@ import {
1616 RGFormat ,
1717 SRGBColorSpace ,
1818 Scene ,
19- ShaderMaterial ,
2019 TextureDataType ,
2120 UnsignedByteType ,
2221 UnsignedInt248Type ,
23- WebGLProgramParametersWithUniforms ,
2422 WebGLRenderTarget ,
2523 WebGLRenderer
2624} from "three" ;
@@ -32,10 +30,11 @@ import { GBuffer } from "../enums/GBuffer.js";
3230import { MSAASamples } from "../enums/MSAASamples.js" ;
3331import { GBufferConfig } from "../utils/gbuffer/GBufferConfig.js" ;
3432import { GBufferTextureConfig } from "../utils/gbuffer/GBufferTextureConfig.js" ;
35- import { extractIndices , extractOutputDefinitions } from "../utils/gbuffer/GBufferUtils.js" ;
33+ import { extractIndices } from "../utils/gbuffer/GBufferUtils.js" ;
3634import { ObservableSet } from "../utils/ObservableSet.js" ;
3735import { Selection } from "../utils/Selection.js" ;
3836import { CopyPass } from "./CopyPass.js" ;
37+ import { GBufferShaderPlugin } from "../utils/gbuffer/GBufferShaderPlugin.js" ;
3938
4039/**
4140 * GeometryPass constructor options.
@@ -110,16 +109,16 @@ export class GeometryPass extends Pass implements GeometryPassOptions, Selective
110109 readonly selection : Selection ;
111110
112111 /**
113- * A collection of materials that have been modified with `onBeforeCompile` .
112+ * A pass that copies the default input buffer to the output color buffer .
114113 */
115114
116- private static readonly registeredMaterials = new WeakSet < Material > ( ) ;
115+ private readonly copyPass : CopyPass ;
117116
118117 /**
119- * A pass that copies the default input buffer to the output color buffer .
118+ * A shader plugin that enables rendering to G-Buffer render targets .
120119 */
121120
122- private readonly copyPass : CopyPass ;
121+ private readonly gBufferShaderPlugin : GBufferShaderPlugin ;
123122
124123 /**
125124 * A resource that wraps the G-Buffer.
@@ -188,6 +187,7 @@ export class GeometryPass extends Pass implements GeometryPassOptions, Selective
188187 const gBufferComponents = new ObservableSet < GBuffer | string > ( ) ;
189188 gBufferComponents . addEventListener ( "change" , ( ) => this . updateGBuffer ( ) ) ;
190189 this . gBufferComponents = gBufferComponents ;
190+ this . gBufferShaderPlugin = new GBufferShaderPlugin ( ) ;
191191 this . gBufferResource = new RenderTargetResource ( ) ;
192192 this . output . defaultBuffer = this . gBufferResource ;
193193
@@ -325,11 +325,9 @@ export class GeometryPass extends Pass implements GeometryPassOptions, Selective
325325 }
326326
327327 /**
328- * Enables rendering to {@link GBuffer} components for the materials of a given mesh .
328+ * Enables rendering to {@link GBuffer} components for the materials of a given object .
329329 *
330- * Should be called when a material is added, removed or replaced at runtime.
331- *
332- * TODO Remove when `three` supports output layout definitions for MRT.
330+ * Should also be called when a material is added, removed or replaced at runtime.
333331 *
334332 * @param object - The object to update.
335333 */
@@ -346,61 +344,7 @@ export class GeometryPass extends Pass implements GeometryPassOptions, Selective
346344
347345 for ( const material of materials ) {
348346
349- if ( GeometryPass . registeredMaterials . has ( material ) ) {
350-
351- return ;
352-
353- }
354-
355- GeometryPass . registeredMaterials . add ( material ) ;
356-
357- /* eslint-disable @typescript-eslint/unbound-method */
358- const onBeforeCompile = material . onBeforeCompile ;
359- const customProgramCacheKey = material . customProgramCacheKey ;
360-
361- material . onBeforeCompile = ( shader : WebGLProgramParametersWithUniforms , renderer : WebGLRenderer ) => {
362-
363- // Workaround for troika-three-text, see #660.
364- if ( material . onBeforeCompile !== onBeforeCompile ) {
365-
366- onBeforeCompile . call ( material , shader , renderer ) ;
367-
368- }
369-
370- if ( this . gBuffer === null ) {
371-
372- return ;
373-
374- }
375-
376- if ( material instanceof ShaderMaterial ) {
377-
378- shader . fragmentShader = shader . fragmentShader . replace (
379- / ( ^ * v o i d \s + m a i n \( \) \s + { .* ) / m,
380- "$1\n\n#include <pp_default_output_fragment>"
381- ) ;
382-
383- }
384-
385- const outputDefinitions = extractOutputDefinitions ( this . gBuffer ) ;
386- shader . fragmentShader = outputDefinitions + "\n\n" + shader . fragmentShader ;
387-
388- } ;
389-
390- material . customProgramCacheKey = ( ) => {
391-
392- let key = this . gBuffer ?. texture ?. uuid ?? "" ;
393-
394- // Workaround for troika-three-text, see #660.
395- if ( material . customProgramCacheKey !== customProgramCacheKey ) {
396-
397- key += customProgramCacheKey . call ( material ) ;
398-
399- }
400-
401- return key ;
402-
403- } ;
347+ this . gBufferShaderPlugin . applyTo ( material ) ;
404348
405349 }
406350
@@ -614,6 +558,7 @@ export class GeometryPass extends Pass implements GeometryPassOptions, Selective
614558
615559 }
616560
561+ this . gBufferShaderPlugin . gBuffer = this . output . defaultBuffer ?. value ?? null ;
617562 this . copyPass . output . defaultBuffer = this . output . defaultBuffer ;
618563 this . updateCopyPass ( ) ;
619564
0 commit comments