diff --git a/examples/files.json b/examples/files.json index e67c9ac04f3979..e704fd87b33b47 100644 --- a/examples/files.json +++ b/examples/files.json @@ -317,6 +317,7 @@ "webgpu_centroid_sampling", "webgpu_clearcoat", "webgpu_clipping", + "webgpu_clipping_stencil", "webgpu_compile_async", "webgpu_compute_audio", "webgpu_compute_birds", diff --git a/examples/screenshots/webgpu_clipping_stencil.jpg b/examples/screenshots/webgpu_clipping_stencil.jpg new file mode 100644 index 00000000000000..dbe8c4d6bab321 Binary files /dev/null and b/examples/screenshots/webgpu_clipping_stencil.jpg differ diff --git a/examples/webgpu_clipping_stencil.html b/examples/webgpu_clipping_stencil.html new file mode 100644 index 00000000000000..a3ff121284a010 --- /dev/null +++ b/examples/webgpu_clipping_stencil.html @@ -0,0 +1,321 @@ + + + + three.js webgpu - clipping stencil + + + + + + + + + +
+ + +
+ three.jsClipping Stencil +
+ + Solid geometry with clip planes and stencil materials. +
+ + + + + + + diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index a86234d1f0bd53..cf2b0cc6b10162 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -3256,6 +3256,7 @@ class WebGLRenderer { _gl.bufferData( _gl.PIXEL_PACK_BUFFER, buffer.byteLength, _gl.STREAM_READ ); _gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), 0 ); + _gl.bindBuffer( _gl.PIXEL_PACK_BUFFER, null ); // reset the frame buffer to the currently set buffer before waiting const currFramebuffer = _currentRenderTarget !== null ? properties.get( _currentRenderTarget ).__webglFramebuffer : null; @@ -3271,6 +3272,7 @@ class WebGLRenderer { // read the data and delete the buffer _gl.bindBuffer( _gl.PIXEL_PACK_BUFFER, glBuffer ); _gl.getBufferSubData( _gl.PIXEL_PACK_BUFFER, 0, buffer ); + _gl.bindBuffer( _gl.PIXEL_PACK_BUFFER, null ); _gl.deleteBuffer( glBuffer ); _gl.deleteSync( sync ); diff --git a/src/renderers/common/ClippingContext.js b/src/renderers/common/ClippingContext.js index 1ed98b973eeb54..d441736f01bfa2 100644 --- a/src/renderers/common/ClippingContext.js +++ b/src/renderers/common/ClippingContext.js @@ -5,6 +5,8 @@ import { Vector4 } from '../../math/Vector4.js'; const _plane = /*@__PURE__*/ new Plane(); +let _clippingContextId = 0; + /** * Represents the state that is used to perform clipping via clipping planes. * There is a default clipping context for each render context. When the @@ -22,6 +24,14 @@ class ClippingContext { */ constructor( parentContext = null ) { + /** + * The id of the clipping context. + * + * @type {number} + * @readonly + */ + this.id = _clippingContextId ++; + /** * The clipping context's version. * @@ -222,7 +232,7 @@ class ClippingContext { if ( update ) { this.version ++; - this.cacheKey = `${ this.intersectionPlanes.length }:${ this.unionPlanes.length }`; + this.cacheKey = `${ this.id }:${ this.intersectionPlanes.length }:${ this.unionPlanes.length }`; } diff --git a/src/renderers/webgl-fallback/WebGLBackend.js b/src/renderers/webgl-fallback/WebGLBackend.js index ff4bb212b9407d..00649a36bbe28a 100644 --- a/src/renderers/webgl-fallback/WebGLBackend.js +++ b/src/renderers/webgl-fallback/WebGLBackend.js @@ -821,6 +821,7 @@ class WebGLBackend extends Backend { const clearStencil = renderer.getClearStencil(); if ( depth ) this.state.setDepthMask( true ); + if ( stencil ) this.state.setStencilMask( 0xffffffff ); if ( descriptor.textures === null ) { diff --git a/src/renderers/webgl-fallback/utils/WebGLState.js b/src/renderers/webgl-fallback/utils/WebGLState.js index 1fb2f4fa6ea106..897be18b97d081 100644 --- a/src/renderers/webgl-fallback/utils/WebGLState.js +++ b/src/renderers/webgl-fallback/utils/WebGLState.js @@ -959,28 +959,27 @@ class WebGLState { ? this.enable( gl.SAMPLE_ALPHA_TO_COVERAGE ) : this.disable( gl.SAMPLE_ALPHA_TO_COVERAGE ); - if ( hardwareClippingPlanes > 0 ) { - if ( this.currentClippingPlanes !== hardwareClippingPlanes ) { + if ( this.currentClippingPlanes !== hardwareClippingPlanes ) { - const CLIP_DISTANCE0_WEBGL = 0x3000; + const CLIP_DISTANCE0_WEBGL = 0x3000; - for ( let i = 0; i < 8; i ++ ) { + for ( let i = 0; i < 8; i ++ ) { - if ( i < hardwareClippingPlanes ) { + if ( i < hardwareClippingPlanes ) { - this.enable( CLIP_DISTANCE0_WEBGL + i ); + this.enable( CLIP_DISTANCE0_WEBGL + i ); - } else { - - this.disable( CLIP_DISTANCE0_WEBGL + i ); + } else { - } + this.disable( CLIP_DISTANCE0_WEBGL + i ); } } + this.currentClippingPlanes = hardwareClippingPlanes; + } } diff --git a/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js b/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js index 4387a3f2486550..b9b4f131c69f0d 100644 --- a/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +++ b/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js @@ -1281,6 +1281,7 @@ class WebGLTextureUtils { backend.state.bindFramebuffer( gl.READ_FRAMEBUFFER, null ); + gl.deleteBuffer( buffer ); gl.deleteFramebuffer( fb ); return dstBuffer;