From 8845729351c06cd2ff1a5c1c8d24138deea624b7 Mon Sep 17 00:00:00 2001 From: Konstantin Timoshenko Date: Mon, 7 Oct 2024 19:26:17 +0300 Subject: [PATCH 1/3] fix: stable reversed Z buffer implementation Fix: reset clip state when reset is called Fix: valid depth clear value when reversed is enabled Feat: non-persistent reversedZ state ( can be controlled via renderer.state.buffers.depth.setReversed( ))) --- src/renderers/WebGLRenderer.js | 14 ++++++--- src/renderers/webgl/WebGLCapabilities.js | 9 +----- src/renderers/webgl/WebGLState.js | 39 ++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index f464e7489a516c..82ef0412214752 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -70,6 +70,7 @@ class WebGLRenderer { preserveDrawingBuffer = false, powerPreference = 'default', failIfMajorPerformanceCaveat = false, + reverseDepthBuffer = false, } = parameters; this.isWebGLRenderer = true; @@ -288,9 +289,13 @@ class WebGLRenderer { capabilities = new WebGLCapabilities( _gl, extensions, parameters, utils ); - state = new WebGLState( _gl ); + state = new WebGLState( _gl, extensions ); - if ( capabilities.reverseDepthBuffer ) state.buffers.depth.setReversed( true ); + if ( capabilities.reverseDepthBuffer && reverseDepthBuffer ) { + + state.buffers.depth.setReversed( true ); + + } info = new WebGLInfo( _gl ); properties = new WebGLProperties(); @@ -594,7 +599,6 @@ class WebGLRenderer { if ( depth ) { bits |= _gl.DEPTH_BUFFER_BIT; - _gl.clearDepth( this.capabilities.reverseDepthBuffer ? 0 : 1 ); } @@ -1978,7 +1982,9 @@ class WebGLRenderer { // common camera uniforms - if ( capabilities.reverseDepthBuffer ) { + const reverseDepthBuffer = state.depth.getReversed (); + + if ( reverseDepthBuffer ) { _currentProjectionMatrix.copy( camera.projectionMatrix ); diff --git a/src/renderers/webgl/WebGLCapabilities.js b/src/renderers/webgl/WebGLCapabilities.js index a610a9cbbe1ea7..9fea7a1cb93c9d 100644 --- a/src/renderers/webgl/WebGLCapabilities.js +++ b/src/renderers/webgl/WebGLCapabilities.js @@ -92,14 +92,7 @@ function WebGLCapabilities( gl, extensions, parameters, utils ) { } const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; - const reverseDepthBuffer = parameters.reverseDepthBuffer === true && extensions.has( 'EXT_clip_control' ); - - if ( reverseDepthBuffer === true ) { - - const ext = extensions.get( 'EXT_clip_control' ); - ext.clipControlEXT( ext.LOWER_LEFT_EXT, ext.ZERO_TO_ONE_EXT ); - - } + const reverseDepthBuffer = extensions.has( 'EXT_clip_control' ); const maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS ); const maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); diff --git a/src/renderers/webgl/WebGLState.js b/src/renderers/webgl/WebGLState.js index 3d380b1ce69f99..cf7cb83f67bd60 100644 --- a/src/renderers/webgl/WebGLState.js +++ b/src/renderers/webgl/WebGLState.js @@ -14,7 +14,7 @@ const reversedFuncs = { [ GreaterEqualDepth ]: LessEqualDepth, }; -function WebGLState( gl ) { +function WebGLState( gl, extensions ) { function ColorBuffer() { @@ -88,10 +88,36 @@ function WebGLState( gl ) { setReversed: function ( value ) { + if ( reversed !== value ) { + + const ext = extensions.get( 'EXT_clip_control' ); + + if ( reversed ) { + + ext.clipControlEXT( ext.LOWER_LEFT_EXT, ext.ZERO_TO_ONE_EXT ); + + } else { + + ext.clipControlEXT( ext.LOWER_LEFT_EXT, ext.NEGATIVE_ONE_TO_ONE_EXT ); + + } + + const oldDepth = currentDepthClear; + currentDepthClear = null; + this.setClear( oldDepth ); + + } + reversed = value; }, + getReversed: function () { + + return reversed; + + }, + setTest: function ( depthTest ) { if ( depthTest ) { @@ -187,6 +213,12 @@ function WebGLState( gl ) { if ( currentDepthClear !== depth ) { + if ( reversed ) { + + depth = 1 - depth; + + } + gl.clearDepth( depth ); currentDepthClear = depth; @@ -201,7 +233,7 @@ function WebGLState( gl ) { currentDepthMask = null; currentDepthFunc = null; currentDepthClear = null; - + reversed = false; } }; @@ -1171,6 +1203,9 @@ function WebGLState( gl ) { gl.depthMask( true ); gl.depthFunc( gl.LESS ); + + depthBuffer.setReversed ( false ); + gl.clearDepth( 1 ); gl.stencilMask( 0xffffffff ); From f3fb71ff7182fcb4bc75477bccc16b332f47c10c Mon Sep 17 00:00:00 2001 From: Konstantin Timoshenko Date: Mon, 7 Oct 2024 19:40:17 +0300 Subject: [PATCH 2/3] fix: lint + misstakes fix: program parameters --- src/renderers/WebGLRenderer.js | 4 ++-- src/renderers/webgl/WebGLPrograms.js | 2 +- src/renderers/webgl/WebGLState.js | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 82ef0412214752..7c308ef997e148 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -291,7 +291,7 @@ class WebGLRenderer { state = new WebGLState( _gl, extensions ); - if ( capabilities.reverseDepthBuffer && reverseDepthBuffer ) { + if ( capabilities.reverseDepthBuffer && reverseDepthBuffer ) { state.buffers.depth.setReversed( true ); @@ -1982,7 +1982,7 @@ class WebGLRenderer { // common camera uniforms - const reverseDepthBuffer = state.depth.getReversed (); + const reverseDepthBuffer = state.buffers.depth.getReversed(); if ( reverseDepthBuffer ) { diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index dde9db098c9cae..a474f4030a8ffe 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -14,7 +14,6 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities const programs = []; const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; - const reverseDepthBuffer = capabilities.reverseDepthBuffer; const SUPPORTS_VERTEX_TEXTURES = capabilities.vertexTextures; let precision = capabilities.precision; @@ -109,6 +108,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities } const currentRenderTarget = renderer.getRenderTarget(); + const reverseDepthBuffer = renderer.state.buffers.depth.getReversed(); const IS_INSTANCEDMESH = object.isInstancedMesh === true; const IS_BATCHEDMESH = object.isBatchedMesh === true; diff --git a/src/renderers/webgl/WebGLState.js b/src/renderers/webgl/WebGLState.js index cf7cb83f67bd60..9992c5584c844b 100644 --- a/src/renderers/webgl/WebGLState.js +++ b/src/renderers/webgl/WebGLState.js @@ -234,6 +234,7 @@ function WebGLState( gl, extensions ) { currentDepthFunc = null; currentDepthClear = null; reversed = false; + } }; @@ -1204,7 +1205,7 @@ function WebGLState( gl, extensions ) { gl.depthMask( true ); gl.depthFunc( gl.LESS ); - depthBuffer.setReversed ( false ); + depthBuffer.setReversed( false ); gl.clearDepth( 1 ); From 4adc3994f763d9569440ac9fea13d6b6ee0b63e3 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Mon, 21 Oct 2024 18:03:12 +0200 Subject: [PATCH 3/3] Update WebGLCapabilities.js --- src/renderers/webgl/WebGLCapabilities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderers/webgl/WebGLCapabilities.js b/src/renderers/webgl/WebGLCapabilities.js index 9fea7a1cb93c9d..4f04c836c31d9a 100644 --- a/src/renderers/webgl/WebGLCapabilities.js +++ b/src/renderers/webgl/WebGLCapabilities.js @@ -92,7 +92,7 @@ function WebGLCapabilities( gl, extensions, parameters, utils ) { } const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; - const reverseDepthBuffer = extensions.has( 'EXT_clip_control' ); + const reverseDepthBuffer = parameters.reverseDepthBuffer === true && extensions.has( 'EXT_clip_control' ); const maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS ); const maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );