1
1
import type { WebGLRenderer } from 'three' ;
2
- import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js' ;
2
+ import { EffectComposer , Pass } from 'three/addons/postprocessing/EffectComposer.js' ;
3
3
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js' ;
4
4
import {
5
5
StageAdded ,
@@ -9,30 +9,28 @@ import {
9
9
type StageAddedProps ,
10
10
type StageRemovedProps ,
11
11
} from '../events.js' ;
12
+ import { hasGetRenderPass } from './IGetRenderPass.js' ;
12
13
import type { IStage } from './IStage.js' ;
13
- import { Stage2D } from './Stage2D.js' ;
14
14
import { StageRenderer } from './StageRenderer.js' ;
15
15
16
- const isRenderPassable = ( stage : IStage ) : stage is Stage2D => stage instanceof Stage2D ;
17
-
18
16
export class PostProcessingRenderer extends StageRenderer implements IStageAdded , IStageRemoved {
19
17
composer ?: EffectComposer ;
20
- renderPass : WeakMap < IStage , RenderPass > = new WeakMap ( ) ;
18
+
19
+ renderPasses : WeakMap < IStage , RenderPass > = new WeakMap ( ) ;
20
+ passes : Pass [ ] = [ ] ;
21
21
22
22
constructor ( ) {
23
23
super ( ) ;
24
24
this . on ( [ StageAdded , StageRemoved ] , this ) ;
25
25
}
26
26
27
27
override renderFrame ( renderer : WebGLRenderer , now : number , deltaTime : number , frameNo : number ) : void {
28
- if ( ! this . composer ) {
29
- this . composer = new EffectComposer ( renderer ) ;
30
- }
28
+ const composer = this . getComposer ( renderer ) ;
31
29
32
30
this . stages . forEach ( ( stage ) => {
33
31
this . resizeStage ( stage , this . width , this . height ) ;
34
32
stage . stage . renderFrame ( renderer , now , deltaTime , frameNo , ( scene , camera , autoClear ) => {
35
- const renderPass = this . renderPass . get ( stage . stage ) ;
33
+ const renderPass = this . renderPasses . get ( stage . stage ) ;
36
34
if ( renderPass ) {
37
35
renderPass . clear = autoClear ;
38
36
renderPass . scene = scene ;
@@ -41,22 +39,57 @@ export class PostProcessingRenderer extends StageRenderer implements IStageAdded
41
39
} ) ;
42
40
} ) ;
43
41
44
- this . composer . render ( ) ;
42
+ composer . render ( ) ;
43
+ }
44
+
45
+ addPass ( pass : Pass ) {
46
+ if ( this . composer ) {
47
+ this . composer . addPass ( pass ) ;
48
+ } else {
49
+ this . passes . push ( pass ) ;
50
+ }
51
+ }
52
+
53
+ removePass ( pass : Pass ) {
54
+ if ( this . composer ) {
55
+ this . composer . removePass ( pass ) ;
56
+ } else {
57
+ const index = this . passes . indexOf ( pass ) ;
58
+ if ( index !== - 1 ) {
59
+ this . passes . splice ( index , 1 ) ;
60
+ }
61
+ }
62
+ }
63
+
64
+ getComposer ( renderer : WebGLRenderer ) : EffectComposer {
65
+ if ( this . composer == null ) {
66
+ this . composer = new EffectComposer ( renderer ) ;
67
+ this . passes . forEach ( ( pass ) => this . composer . addPass ( pass ) ) ;
68
+ this . passes . length = 0 ;
69
+ }
70
+ return this . composer ;
45
71
}
46
72
47
73
stageAdded ( { stage} : StageAddedProps ) {
48
- if ( isRenderPassable ( stage ) && ! this . renderPass . has ( stage ) ) {
49
- this . renderPass . set ( stage , new RenderPass ( stage . scene , stage . camera ) ) ;
50
- console . log ( 'stageAdded as renderPass' , { stage, postEffectsRenderer : this } ) ;
74
+ if ( hasGetRenderPass ( stage ) && ! this . renderPasses . has ( stage ) ) {
75
+ const renderPass = stage . getRenderPass ( ) ;
76
+ this . renderPasses . set ( stage , renderPass ) ;
77
+ this . addPass ( renderPass ) ;
78
+
79
+ console . log ( 'stageAdded' , { stage, renderPass, postProcessingRenderer : this } ) ;
51
80
}
52
81
}
53
82
54
83
stageRemoved ( { stage} : StageRemovedProps ) {
55
- if ( this . renderPass . has ( stage ) ) {
56
- const renderPass = this . renderPass . get ( stage ) ! ;
57
- this . renderPass . delete ( stage ) ;
84
+ if ( this . renderPasses . has ( stage ) ) {
85
+ const renderPass = this . renderPasses . get ( stage ) ! ;
86
+ this . renderPasses . delete ( stage ) ;
87
+ this . removePass ( renderPass ) ;
58
88
renderPass . dispose ( ) ;
59
- console . log ( 'stageRemoved as renderPass' , { stage, postEffectsRenderer : this } ) ;
89
+
90
+ console . log ( 'stageRemoved' , { stage, renderPass, postProcessingRenderer : this } ) ;
60
91
}
61
92
}
93
+
94
+ // TODO dispose
62
95
}
0 commit comments