|
|
@@ -1594,6 +1594,38 @@ function probeAsync( gl, sync, interval ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
+function toNormalizedProjectionMatrix( projectionMatrix ) {
|
|
|
+
|
|
|
+ const m = projectionMatrix.elements;
|
|
|
+
|
|
|
+ // Convert [-1, 1] to [0, 1] projection matrix
|
|
|
+ m[ 2 ] = 0.5 * m[ 2 ] + 0.5 * m[ 3 ];
|
|
|
+ m[ 6 ] = 0.5 * m[ 6 ] + 0.5 * m[ 7 ];
|
|
|
+ m[ 10 ] = 0.5 * m[ 10 ] + 0.5 * m[ 11 ];
|
|
|
+ m[ 14 ] = 0.5 * m[ 14 ] + 0.5 * m[ 15 ];
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+function toReversedProjectionMatrix( projectionMatrix ) {
|
|
|
+
|
|
|
+ const m = projectionMatrix.elements;
|
|
|
+ const isPerspectiveMatrix = m[ 11 ] === - 1;
|
|
|
+
|
|
|
+ // Reverse [0, 1] projection matrix
|
|
|
+ if ( isPerspectiveMatrix ) {
|
|
|
+
|
|
|
+ m[ 10 ] = - m[ 10 ] - 1;
|
|
|
+ m[ 14 ] = - m[ 14 ];
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ m[ 10 ] = - m[ 10 ];
|
|
|
+ m[ 14 ] = - m[ 14 ] + 1;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Matrices converting P3 <-> Rec. 709 primaries, without gamut mapping
|
|
|
* or clipping. Based on W3C specifications for sRGB and Display P3,
|
|
|
@@ -15895,6 +15927,14 @@ 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 maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
|
|
|
const maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
|
|
|
@@ -15922,6 +15962,7 @@ function WebGLCapabilities( gl, extensions, parameters, utils ) {
|
|
|
|
|
|
precision: precision,
|
|
|
logarithmicDepthBuffer: logarithmicDepthBuffer,
|
|
|
+ reverseDepthBuffer: reverseDepthBuffer,
|
|
|
|
|
|
maxTextures: maxTextures,
|
|
|
maxVertexTextures: maxVertexTextures,
|
|
|
@@ -22595,6 +22636,18 @@ function WebGLShadowMap( renderer, objects, capabilities ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
+const reversedFuncs = {
|
|
|
+ [ NeverDepth ]: AlwaysDepth,
|
|
|
+ [ LessDepth ]: GreaterDepth,
|
|
|
+ [ EqualDepth ]: NotEqualDepth,
|
|
|
+ [ LessEqualDepth ]: GreaterEqualDepth,
|
|
|
+
|
|
|
+ [ AlwaysDepth ]: NeverDepth,
|
|
|
+ [ GreaterDepth ]: LessDepth,
|
|
|
+ [ NotEqualDepth ]: EqualDepth,
|
|
|
+ [ GreaterEqualDepth ]: LessEqualDepth,
|
|
|
+};
|
|
|
+
|
|
|
function WebGLState( gl ) {
|
|
|
|
|
|
function ColorBuffer() {
|
|
|
@@ -22659,6 +22712,7 @@ function WebGLState( gl ) {
|
|
|
function DepthBuffer() {
|
|
|
|
|
|
let locked = false;
|
|
|
+ let reversed = false;
|
|
|
|
|
|
let currentDepthMask = null;
|
|
|
let currentDepthFunc = null;
|
|
|
@@ -22666,6 +22720,12 @@ function WebGLState( gl ) {
|
|
|
|
|
|
return {
|
|
|
|
|
|
+ setReversed: function ( value ) {
|
|
|
+
|
|
|
+ reversed = value;
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
setTest: function ( depthTest ) {
|
|
|
|
|
|
if ( depthTest ) {
|
|
|
@@ -22693,6 +22753,8 @@ function WebGLState( gl ) {
|
|
|
|
|
|
setFunc: function ( depthFunc ) {
|
|
|
|
|
|
+ if ( reversed ) depthFunc = reversedFuncs[ depthFunc ];
|
|
|
+
|
|
|
if ( currentDepthFunc !== depthFunc ) {
|
|
|
|
|
|
switch ( depthFunc ) {
|
|
|
@@ -28849,6 +28911,7 @@ class WebGLRenderer {
|
|
|
|
|
|
// camera matrices cache
|
|
|
|
|
|
+ const _currentProjectionMatrix = new Matrix4();
|
|
|
const _projScreenMatrix = new Matrix4();
|
|
|
|
|
|
const _vector3 = new Vector3();
|
|
|
@@ -28944,6 +29007,8 @@ class WebGLRenderer {
|
|
|
|
|
|
state = new WebGLState( _gl );
|
|
|
|
|
|
+ if ( capabilities.reverseDepthBuffer ) state.buffers.depth.setReversed( true );
|
|
|
+
|
|
|
info = new WebGLInfo( _gl );
|
|
|
properties = new WebGLProperties();
|
|
|
textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
|
|
|
@@ -29243,7 +29308,13 @@ class WebGLRenderer {
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( depth ) bits |= _gl.DEPTH_BUFFER_BIT;
|
|
|
+ if ( depth ) {
|
|
|
+
|
|
|
+ bits |= _gl.DEPTH_BUFFER_BIT;
|
|
|
+ _gl.clearDepth( this.capabilities.reverseDepthBuffer ? 0 : 1 );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
if ( stencil ) {
|
|
|
|
|
|
bits |= _gl.STENCIL_BUFFER_BIT;
|
|
|
@@ -30624,7 +30695,21 @@ class WebGLRenderer {
|
|
|
|
|
|
// common camera uniforms
|
|
|
|
|
|
- p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
|
|
|
+ if ( capabilities.reverseDepthBuffer ) {
|
|
|
+
|
|
|
+ _currentProjectionMatrix.copy( camera.projectionMatrix );
|
|
|
+
|
|
|
+ toNormalizedProjectionMatrix( _currentProjectionMatrix );
|
|
|
+ toReversedProjectionMatrix( _currentProjectionMatrix );
|
|
|
+
|
|
|
+ p_uniforms.setValue( _gl, 'projectionMatrix', _currentProjectionMatrix );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
|
|
|
|
|
|
const uCamPos = p_uniforms.map.cameraPosition;
|
|
|
@@ -33559,6 +33644,9 @@ class BatchedMesh extends Mesh {
|
|
|
// stores visible, active, and geometry id per object
|
|
|
this._drawInfo = [];
|
|
|
|
|
|
+ // instance ids that have been set as inactive, and are available to be overwritten
|
|
|
+ this._availableInstanceIds = [];
|
|
|
+
|
|
|
// geometry information
|
|
|
this._drawRanges = [];
|
|
|
this._reservedRanges = [];
|
|
|
@@ -33758,23 +33846,36 @@ class BatchedMesh extends Mesh {
|
|
|
|
|
|
addInstance( geometryId ) {
|
|
|
|
|
|
+ const atCapacity = this._drawInfo.length >= this.maxInstanceCount;
|
|
|
+
|
|
|
// ensure we're not over geometry
|
|
|
- if ( this._drawInfo.length >= this._maxInstanceCount ) {
|
|
|
+ if ( atCapacity && this._availableInstanceIds.length === 0 ) {
|
|
|
|
|
|
throw new Error( 'BatchedMesh: Maximum item count reached.' );
|
|
|
|
|
|
}
|
|
|
|
|
|
- this._drawInfo.push( {
|
|
|
-
|
|
|
+ const instanceDrawInfo = {
|
|
|
visible: true,
|
|
|
active: true,
|
|
|
geometryIndex: geometryId,
|
|
|
+ };
|
|
|
|
|
|
- } );
|
|
|
+ let drawId = null;
|
|
|
+
|
|
|
+ // Prioritize using previously freed instance ids
|
|
|
+ if ( this._availableInstanceIds.length > 0 ) {
|
|
|
+
|
|
|
+ drawId = this._availableInstanceIds.pop();
|
|
|
+ this._drawInfo[ drawId ] = instanceDrawInfo;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ drawId = this._drawInfo.length;
|
|
|
+ this._drawInfo.push( instanceDrawInfo );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- // initialize the matrix
|
|
|
- const drawId = this._drawInfo.length - 1;
|
|
|
const matricesTexture = this._matricesTexture;
|
|
|
const matricesArray = matricesTexture.image.data;
|
|
|
_identityMatrix.toArray( matricesArray, drawId * 16 );
|
|
|
@@ -34023,11 +34124,8 @@ class BatchedMesh extends Mesh {
|
|
|
}
|
|
|
*/
|
|
|
|
|
|
- /*
|
|
|
deleteInstance( instanceId ) {
|
|
|
|
|
|
- // Note: User needs to call optimize() afterward to pack the data.
|
|
|
-
|
|
|
const drawInfo = this._drawInfo;
|
|
|
if ( instanceId >= drawInfo.length || drawInfo[ instanceId ].active === false ) {
|
|
|
|
|
|
@@ -34036,12 +34134,12 @@ class BatchedMesh extends Mesh {
|
|
|
}
|
|
|
|
|
|
drawInfo[ instanceId ].active = false;
|
|
|
+ this._availableInstanceIds.push( instanceId );
|
|
|
this._visibilityChanged = true;
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
- */
|
|
|
|
|
|
// get bounding box and compute it if it doesn't exist
|
|
|
getBoundingBoxAt( geometryId, target ) {
|