Skip to content

Commit 01777f0

Browse files
WebGLRenderer: add reverse-z via EXT_clip_control (#29445)
* WebGLRenderer: add reverse-z via EXT_clip_control * WebGLRenderer: move conversion methods to utils
1 parent 33a60fa commit 01777f0

File tree

4 files changed

+89
-4
lines changed

4 files changed

+89
-4
lines changed

src/renderers/WebGLRenderer.js

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import { WebGLUtils } from './webgl/WebGLUtils.js';
5454
import { WebXRManager } from './webxr/WebXRManager.js';
5555
import { WebGLMaterials } from './webgl/WebGLMaterials.js';
5656
import { WebGLUniformsGroups } from './webgl/WebGLUniformsGroups.js';
57-
import { createCanvasElement, probeAsync, warnOnce } from '../utils.js';
57+
import { createCanvasElement, probeAsync, toNormalizedProjectionMatrix, toReversedProjectionMatrix, warnOnce } from '../utils.js';
5858
import { ColorManagement } from '../math/ColorManagement.js';
5959

6060
class WebGLRenderer {
@@ -196,6 +196,7 @@ class WebGLRenderer {
196196

197197
// camera matrices cache
198198

199+
const _currentProjectionMatrix = new Matrix4();
199200
const _projScreenMatrix = new Matrix4();
200201

201202
const _vector3 = new Vector3();
@@ -291,6 +292,8 @@ class WebGLRenderer {
291292

292293
state = new WebGLState( _gl );
293294

295+
if ( capabilities.reverseDepthBuffer ) state.buffers.depth.setReversed( true );
296+
294297
info = new WebGLInfo( _gl );
295298
properties = new WebGLProperties();
296299
textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
@@ -590,7 +593,13 @@ class WebGLRenderer {
590593

591594
}
592595

593-
if ( depth ) bits |= _gl.DEPTH_BUFFER_BIT;
596+
if ( depth ) {
597+
598+
bits |= _gl.DEPTH_BUFFER_BIT;
599+
_gl.clearDepth( this.capabilities.reverseDepthBuffer ? 0 : 1 );
600+
601+
}
602+
594603
if ( stencil ) {
595604

596605
bits |= _gl.STENCIL_BUFFER_BIT;
@@ -1971,7 +1980,21 @@ class WebGLRenderer {
19711980

19721981
// common camera uniforms
19731982

1974-
p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
1983+
if ( capabilities.reverseDepthBuffer ) {
1984+
1985+
_currentProjectionMatrix.copy( camera.projectionMatrix );
1986+
1987+
toNormalizedProjectionMatrix( _currentProjectionMatrix );
1988+
toReversedProjectionMatrix( _currentProjectionMatrix );
1989+
1990+
p_uniforms.setValue( _gl, 'projectionMatrix', _currentProjectionMatrix );
1991+
1992+
} else {
1993+
1994+
p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
1995+
1996+
}
1997+
19751998
p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
19761999

19772000
const uCamPos = p_uniforms.map.cameraPosition;

src/renderers/webgl/WebGLCapabilities.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ function WebGLCapabilities( gl, extensions, parameters, utils ) {
9292
}
9393

9494
const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;
95+
const reverseDepthBuffer = parameters.reverseDepthBuffer === true && extensions.has( 'EXT_clip_control' );
96+
97+
if ( reverseDepthBuffer === true ) {
98+
99+
const ext = extensions.get( 'EXT_clip_control' );
100+
ext.clipControlEXT( ext.LOWER_LEFT_EXT, ext.ZERO_TO_ONE_EXT );
101+
102+
}
95103

96104
const maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
97105
const maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
@@ -119,6 +127,7 @@ function WebGLCapabilities( gl, extensions, parameters, utils ) {
119127

120128
precision: precision,
121129
logarithmicDepthBuffer: logarithmicDepthBuffer,
130+
reverseDepthBuffer: reverseDepthBuffer,
122131

123132
maxTextures: maxTextures,
124133
maxVertexTextures: maxVertexTextures,

src/renderers/webgl/WebGLState.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@ import { NotEqualDepth, GreaterDepth, GreaterEqualDepth, EqualDepth, LessEqualDe
22
import { Color } from '../../math/Color.js';
33
import { Vector4 } from '../../math/Vector4.js';
44

5+
const reversedFuncs = {
6+
[ NeverDepth ]: AlwaysDepth,
7+
[ LessDepth ]: GreaterDepth,
8+
[ EqualDepth ]: NotEqualDepth,
9+
[ LessEqualDepth ]: GreaterEqualDepth,
10+
11+
[ AlwaysDepth ]: NeverDepth,
12+
[ GreaterDepth ]: LessDepth,
13+
[ NotEqualDepth ]: EqualDepth,
14+
[ GreaterEqualDepth ]: LessEqualDepth,
15+
};
16+
517
function WebGLState( gl ) {
618

719
function ColorBuffer() {
@@ -66,13 +78,20 @@ function WebGLState( gl ) {
6678
function DepthBuffer() {
6779

6880
let locked = false;
81+
let reversed = false;
6982

7083
let currentDepthMask = null;
7184
let currentDepthFunc = null;
7285
let currentDepthClear = null;
7386

7487
return {
7588

89+
setReversed: function ( value ) {
90+
91+
reversed = value;
92+
93+
},
94+
7695
setTest: function ( depthTest ) {
7796

7897
if ( depthTest ) {
@@ -100,6 +119,8 @@ function WebGLState( gl ) {
100119

101120
setFunc: function ( depthFunc ) {
102121

122+
if ( reversed ) depthFunc = reversedFuncs[ depthFunc ];
123+
103124
if ( currentDepthFunc !== depthFunc ) {
104125

105126
switch ( depthFunc ) {

src/utils.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,36 @@ function probeAsync( gl, sync, interval ) {
117117

118118
}
119119

120-
export { arrayMin, arrayMax, arrayNeedsUint32, getTypedArray, createElementNS, createCanvasElement, warnOnce, probeAsync };
120+
function toNormalizedProjectionMatrix( projectionMatrix ) {
121+
122+
const m = projectionMatrix.elements;
123+
124+
// Convert [-1, 1] to [0, 1] projection matrix
125+
m[ 2 ] = 0.5 * m[ 2 ] + 0.5 * m[ 3 ];
126+
m[ 6 ] = 0.5 * m[ 6 ] + 0.5 * m[ 7 ];
127+
m[ 10 ] = 0.5 * m[ 10 ] + 0.5 * m[ 11 ];
128+
m[ 14 ] = 0.5 * m[ 14 ] + 0.5 * m[ 15 ];
129+
130+
}
131+
132+
function toReversedProjectionMatrix( projectionMatrix ) {
133+
134+
const m = projectionMatrix.elements;
135+
const isPerspectiveMatrix = m[ 11 ] === - 1;
136+
137+
// Reverse [0, 1] projection matrix
138+
if ( isPerspectiveMatrix ) {
139+
140+
m[ 10 ] = - m[ 10 ] - 1;
141+
m[ 14 ] = - m[ 14 ];
142+
143+
} else {
144+
145+
m[ 10 ] = - m[ 10 ];
146+
m[ 14 ] = - m[ 14 ] + 1;
147+
148+
}
149+
150+
}
151+
152+
export { arrayMin, arrayMax, arrayNeedsUint32, getTypedArray, createElementNS, createCanvasElement, warnOnce, probeAsync, toNormalizedProjectionMatrix, toReversedProjectionMatrix };

0 commit comments

Comments
 (0)