@@ -49,6 +49,9 @@ THREE.EffectComposer2 = function ( renderer, colorRenderTarget ) {
4949
5050 this . _previousFrameTime = Date . now ( ) ;
5151
52+ this . maskActive = false ;
53+ this . renderer . autoClearStencil = false ; // Only mask passes should clear the stencil.
54+
5255} ;
5356
5457Object . assign ( THREE . EffectComposer2 . prototype , {
@@ -127,11 +130,12 @@ Object.assign( THREE.EffectComposer2.prototype, {
127130 if ( bufferConfig . isOutput ) {
128131
129132 var buffer = this . getColorOutputBuffer ( bufferConfig , writeToFinalColorTarget , finalColorRenderTarget ) ;
130- if ( buffer == finalColorRenderTarget && bufferConfig . isInput && ! bufferConfig . clear )
133+ var passClearsWholeBuffer = bufferConfig . clear && ! this . maskActive ;
134+ if ( buffer == finalColorRenderTarget && bufferConfig . isInput && ! passClearsWholeBuffer )
131135 {
132- // The output buffer is also used as a color input in the pass.
136+ // The output buffer is also used as a color input in the pass and the pass does not clear it .
133137 // Copy the color buffer from the previous pass to the final target before executing the pass.
134- this . copyPass . render ( this . renderer , [ buffer , this . colorReadBuffer ] , 0 ) ;
138+ this . copyPass . render ( this . renderer , [ buffer , this . colorReadBuffer ] , 0 , this . maskActive ) ;
135139 }
136140 if ( buffer == this . colorWriteBuffer ) {
137141 writesToColorWriteBuffer = true ;
@@ -171,6 +175,31 @@ Object.assign( THREE.EffectComposer2.prototype, {
171175
172176 } ,
173177
178+ handleMaskPass : function ( pass ) {
179+
180+ if ( THREE . MaskPass2 !== undefined ) {
181+
182+ if ( pass instanceof THREE . MaskPass2 ) {
183+
184+ this . maskActive = true ;
185+
186+ pass . render ( this . renderer , [ this . colorWriteBuffer , this . colorReadBuffer ] ) ;
187+ return true ;
188+
189+ } else if ( pass instanceof THREE . ClearMaskPass2 ) {
190+
191+ this . maskActive = false ;
192+ pass . render ( this . renderer ) ;
193+ return true ;
194+
195+ }
196+
197+ }
198+
199+ return false ;
200+
201+ } ,
202+
174203 render : function ( finalColorRenderTarget , deltaTime ) {
175204
176205 if ( finalColorRenderTarget == undefined ) {
@@ -191,6 +220,8 @@ Object.assign( THREE.EffectComposer2.prototype, {
191220
192221 var pass , i , il = this . passes . length ;
193222
223+ this . maskActive = false ;
224+
194225 for ( i = 0 ; i < il ; i ++ ) {
195226
196227 pass = this . passes [ i ] ;
@@ -199,18 +230,20 @@ Object.assign( THREE.EffectComposer2.prototype, {
199230
200231 var writeToFinalColorTarget = this . isLastEnabledPass ( i ) ;
201232
233+ if ( this . handleMaskPass ( pass ) ) continue ;
234+
202235 var buffers = [ ] ;
203236 var writesToColorWriteBuffer = this . gatherBuffersForPass ( pass , writeToFinalColorTarget , finalColorRenderTarget , buffers ) ;
204237
205- pass . render ( this . renderer , buffers , deltaTime ) ;
238+ pass . render ( this . renderer , buffers , deltaTime , this . maskActive ) ;
206239
207240 // Check if we need to copy the final output from a texture to the default framebuffer.
208241 if ( writeToFinalColorTarget && ! finalColorRenderTarget ) {
209242
210243 var wroteToBuffer = this . passWroteToBuffer ( pass , writeToFinalColorTarget , finalColorRenderTarget ) ;
211244 if ( wroteToBuffer ) {
212245 // In case the pass is only able to use a texture as its write buffer, copy the result to screen here.
213- this . copyPass . render ( this . renderer , [ null , wroteToBuffer ] , 0 ) ;
246+ this . copyPass . render ( this . renderer , [ null , wroteToBuffer ] , 0 , this . maskActive ) ;
214247 }
215248
216249 } else if ( writesToColorWriteBuffer ) {
@@ -283,8 +316,8 @@ THREE.IntermediateBufferConfig = function() {
283316 this . mustBeTexture = false ;
284317
285318 // Set to true if the pass clears this buffer before reading from or writing to it. Should only be set if isOutput
286- // is also true. If this is set then isInput is essentially ignored and the contents of the buffer are undefined
287- // when it is given to the pass.
319+ // is also true. If this is set and a mask is not active then isInput is essentially ignored and the contents of the
320+ // buffer are undefined when it is given to the pass.
288321 this . clear = false ;
289322
290323} ;
@@ -333,6 +366,8 @@ THREE.Pass2.renderWithClear = function( renderer, scene, camera, writeBuffer, cl
333366 var oldAutoClear = renderer . autoClear ;
334367 renderer . autoClear = false ;
335368
369+ // TODO: Maybe this function should specifically clear only color and depth and make sure that clearing stencil is
370+ // disabled?
336371 renderer . render ( scene , camera , writeBuffer , clear ) ;
337372
338373 renderer . autoClear = oldAutoClear ;
0 commit comments