From ded90042d86c1b85ea2432165f253ce6500b9af1 Mon Sep 17 00:00:00 2001 From: Renaud Rohlinger Date: Tue, 3 May 2022 19:06:46 +0900 Subject: [PATCH] [WebGLMultipleRenderTarget] Support Multisampling [WebGLMultipleRenderTarget] Support Multisampling clean bufferattributes code clean bufferattributes code --- examples/files.json | 1 + examples/tags.json | 1 + ...2_multiple_rendertargets_multisampled.html | 323 ++++++++++++++++++ src/core/BufferAttribute.js | 8 - src/core/InterleavedBuffer.js | 7 - src/renderers/webgl/WebGLAttributes.js | 11 - src/renderers/webgl/WebGLTextures.js | 118 +++++-- 7 files changed, 413 insertions(+), 56 deletions(-) create mode 100644 examples/webgl2_multiple_rendertargets_multisampled.html diff --git a/examples/files.json b/examples/files.json index 56c9977a1051ac..e75deb82e9d855 100644 --- a/examples/files.json +++ b/examples/files.json @@ -300,6 +300,7 @@ "webgl2_materials_texture3d", "webgl2_materials_texture3d_partialupdate", "webgl2_multiple_rendertargets", + "webgl2_multiple_rendertargets_multisampled", "webgl2_multisampled_renderbuffers", "webgl2_rendertarget_texture2darray", "webgl2_volume_cloud", diff --git a/examples/tags.json b/examples/tags.json index e92f7794f48873..fe0c88e5489da7 100644 --- a/examples/tags.json +++ b/examples/tags.json @@ -93,6 +93,7 @@ "webgl_simple_gi": [ "global illumination" ], "webgl_tiled_forward": [ "derivatives" ], "webgl2_multiple_rendertargets": [ "mrt" ], + "webgl2_multiple_rendertargets_multisampled": [ "mrt" ], "webgl2_multisampled_renderbuffers": [ "msaa" ], "physics_ammo_cloth": [ "integration" ], "misc_controls_arcball": [ "rotation" ], diff --git a/examples/webgl2_multiple_rendertargets_multisampled.html b/examples/webgl2_multiple_rendertargets_multisampled.html new file mode 100644 index 00000000000000..2e9051270f1a7e --- /dev/null +++ b/examples/webgl2_multiple_rendertargets_multisampled.html @@ -0,0 +1,323 @@ + + + + three.js webgl - Multiple Render Targets MultiSampled + + + + + + + + + + + + + + +
+ threejs - WebGL - Multiple Render Targets Multisampled
+ Created by @onirenaud with the help of @Cody_J_Bennett. +
+
+
+ + + + + + + + + + diff --git a/src/core/BufferAttribute.js b/src/core/BufferAttribute.js index a04c88aef78030..92fb5f0611f675 100644 --- a/src/core/BufferAttribute.js +++ b/src/core/BufferAttribute.js @@ -25,8 +25,6 @@ class BufferAttribute { this.normalized = normalized === true; this.usage = StaticDrawUsage; - this.cachedUsage = StaticDrawUsage; - this.updateRange = { offset: 0, count: - 1 }; this.version = 0; @@ -43,12 +41,6 @@ class BufferAttribute { setUsage( value ) { - if ( this.usage !== value ) { - - this.version ++; - - } - this.usage = value; return this; diff --git a/src/core/InterleavedBuffer.js b/src/core/InterleavedBuffer.js index 89b286a48c2096..d252f3cd5b300b 100644 --- a/src/core/InterleavedBuffer.js +++ b/src/core/InterleavedBuffer.js @@ -10,7 +10,6 @@ class InterleavedBuffer { this.count = array !== undefined ? array.length / stride : 0; this.usage = StaticDrawUsage; - this.cachedUsage = StaticDrawUsage; this.updateRange = { offset: 0, count: - 1 }; this.version = 0; @@ -29,12 +28,6 @@ class InterleavedBuffer { setUsage( value ) { - if ( this.usage !== value ) { - - this.version ++; - - } - this.usage = value; return this; diff --git a/src/renderers/webgl/WebGLAttributes.js b/src/renderers/webgl/WebGLAttributes.js index 82685710f81fc4..177ed4bdcc8fd2 100644 --- a/src/renderers/webgl/WebGLAttributes.js +++ b/src/renderers/webgl/WebGLAttributes.js @@ -9,8 +9,6 @@ function WebGLAttributes( gl, capabilities ) { const array = attribute.array; const usage = attribute.usage; - attribute.cachedUsage = usage; - const buffer = gl.createBuffer(); gl.bindBuffer( bufferType, buffer ); @@ -90,15 +88,6 @@ function WebGLAttributes( gl, capabilities ) { gl.bindBuffer( bufferType, buffer ); - if ( attribute.cachedUsage !== attribute.usage ) { - - attribute.cachedUsage = attribute.usage; - gl.bufferData( bufferType, array, attribute.usage ); - updateRange.count = - 1; // reset range - return; - - } - if ( updateRange.count === - 1 ) { // Not using update ranges diff --git a/src/renderers/webgl/WebGLTextures.js b/src/renderers/webgl/WebGLTextures.js index 36b88ae03d818e..11dfcd02bf23e0 100644 --- a/src/renderers/webgl/WebGLTextures.js +++ b/src/renderers/webgl/WebGLTextures.js @@ -343,7 +343,20 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer ); if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); if ( renderTargetProperties.__webglMultisampledFramebuffer ) _gl.deleteFramebuffer( renderTargetProperties.__webglMultisampledFramebuffer ); - if ( renderTargetProperties.__webglColorRenderbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglColorRenderbuffer ); + + if ( renderTargetProperties.__webglMultisampledTempWrite ) _gl.deleteFramebuffer( renderTargetProperties.__webglMultisampledTempWrite ); + if ( renderTargetProperties.__webglMultisampledTempRead ) _gl.deleteFramebuffer( renderTargetProperties.__webglMultisampledTempRead ); + + if ( renderTargetProperties.__webglColorRenderbuffer ) { + + for ( let i = 0; i < renderTargetProperties.__webglColorRenderbuffer.length; i ++ ) { + + if ( renderTargetProperties.__webglColorRenderbuffer[ i ] ) _gl.deleteRenderbuffer( renderTargetProperties.__webglColorRenderbuffer[ i ] ); + + } + + } + if ( renderTargetProperties.__webglDepthRenderbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthRenderbuffer ); } @@ -1556,21 +1569,36 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - } else if ( ( isWebGL2 && renderTarget.samples > 0 ) && useMultisampledRTT( renderTarget ) === false ) { + } - renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); - renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer(); + if ( ( isWebGL2 && renderTarget.samples > 0 ) && useMultisampledRTT( renderTarget ) === false ) { - _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer ); + const textures = isMultipleRenderTargets ? texture : [ texture ]; - const glFormat = utils.convert( texture.format, texture.encoding ); - const glType = utils.convert( texture.type ); - const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding ); - const samples = getRenderTargetSamples( renderTarget ); - _gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); + renderTargetProperties.__webglMultisampledTempRead = _gl.createFramebuffer(); + renderTargetProperties.__webglMultisampledTempWrite = _gl.createFramebuffer(); + renderTargetProperties.__webglColorRenderbuffer = []; state.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer ); - _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer ); + + for ( let i = 0; i < textures.length; i ++ ) { + + const texture = textures[ i ]; + renderTargetProperties.__webglColorRenderbuffer[ i ] = _gl.createRenderbuffer(); + + _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[ i ] ); + + const glFormat = utils.convert( texture.format, texture.encoding ); + const glType = utils.convert( texture.type ); + const glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.encoding ); + const samples = getRenderTargetSamples( renderTarget ); + _gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + + _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[ i ] ); + + } + _gl.bindRenderbuffer( _gl.RENDERBUFFER, null ); if ( renderTarget.depthBuffer ) { @@ -1701,48 +1729,78 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( ( isWebGL2 && renderTarget.samples > 0 ) && useMultisampledRTT( renderTarget ) === false ) { + const textures = renderTarget.isWebGLMultipleRenderTargets ? renderTarget.texture : [ renderTarget.texture ]; const width = renderTarget.width; const height = renderTarget.height; let mask = _gl.COLOR_BUFFER_BIT; const invalidationArray = [ _gl.COLOR_ATTACHMENT0 ]; const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; + const renderTargetProperties = properties.get( renderTarget ); - if ( renderTarget.depthBuffer ) { + for ( let i = 0; i < textures.length; i ++ ) { - invalidationArray.push( depthStyle ); + if ( renderTarget.depthBuffer ) { - } + invalidationArray.push( depthStyle ); - const renderTargetProperties = properties.get( renderTarget ); - const ignoreDepthValues = ( renderTargetProperties.__ignoreDepthValues !== undefined ) ? renderTargetProperties.__ignoreDepthValues : false; + } - if ( ignoreDepthValues === false ) { + const ignoreDepthValues = ( renderTargetProperties.__ignoreDepthValues !== undefined ) ? renderTargetProperties.__ignoreDepthValues : false; - if ( renderTarget.depthBuffer ) mask |= _gl.DEPTH_BUFFER_BIT; - if ( renderTarget.stencilBuffer ) mask |= _gl.STENCIL_BUFFER_BIT; + if ( ignoreDepthValues === false ) { - } + if ( renderTarget.depthBuffer ) mask |= _gl.DEPTH_BUFFER_BIT; + if ( renderTarget.stencilBuffer ) mask |= _gl.STENCIL_BUFFER_BIT; + + } - state.bindFramebuffer( _gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer ); - state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); + state.bindFramebuffer( _gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledTempRead ); + state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledTempWrite ); - if ( ignoreDepthValues === true ) { + _gl.framebufferRenderbuffer( _gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[ i ] ); - _gl.invalidateFramebuffer( _gl.READ_FRAMEBUFFER, [ depthStyle ] ); - _gl.invalidateFramebuffer( _gl.DRAW_FRAMEBUFFER, [ depthStyle ] ); + if ( ignoreDepthValues === true ) { + + _gl.invalidateFramebuffer( _gl.READ_FRAMEBUFFER, [ depthStyle ] ); + _gl.invalidateFramebuffer( _gl.DRAW_FRAMEBUFFER, [ depthStyle ] ); + + } + + const webglTexture = properties.get( textures[ i ] ).__webglTexture; + + _gl.framebufferTexture2D( _gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, webglTexture, 0 ); + + // _gl.clearBufferfv( _gl.COLOR, 0, [0, 0, 0, 1] ); + _gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST ); + + if ( supportsInvalidateFramebuffer ) { + + _gl.invalidateFramebuffer( _gl.READ_FRAMEBUFFER, invalidationArray ); + + } + + state.bindFramebuffer( _gl.READ_FRAMEBUFFER, null ); + state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, null ); } - _gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); + + for ( let i = 0; i < textures.length; i ++ ) { - if ( supportsInvalidateFramebuffer ) { + const webglTexture = properties.get( textures[ i ] ).__webglTexture; - _gl.invalidateFramebuffer( _gl.READ_FRAMEBUFFER, invalidationArray ); + _gl.framebufferTexture2D( + _gl.DRAW_FRAMEBUFFER, + _gl.COLOR_ATTACHMENT0 + i, + _gl.TEXTURE_2D, + webglTexture, + 0, + ); } - state.bindFramebuffer( _gl.READ_FRAMEBUFFER, null ); - state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, null ); }