浏览代码

BatchedMesh: fix radix sort stability (#28401)

* return z based on the the camera forward z value

* Fix sort in example

* Remove unused argument
Garrett Johnson 1 年之前
父节点
当前提交
bac3cc70d3
共有 2 个文件被更改,包括 18 次插入3 次删除
  1. 14 2
      examples/webgl_mesh_batch.html
  2. 4 1
      src/objects/BatchedMesh.js

+ 14 - 2
examples/webgl_mesh_batch.html

@@ -282,7 +282,7 @@
 
 		//
 
-		function sortFunction( list, camera ) {
+		function sortFunction( list ) {
 
 			// initialize options
 			this._options = this._options || {
@@ -293,10 +293,22 @@
 			const options = this._options;
 			options.reversed = this.material.transparent;
 
+			let minZ = Infinity;
+			let maxZ = - Infinity;
+			for ( let i = 0, l = list.length; i < l; i ++ ) {
+
+				const z = list[ i ].z;
+				if ( z > maxZ ) maxZ = z;
+				if ( z < minZ ) minZ = z;
+
+			}
+
 			// convert depth to unsigned 32 bit range
-			const factor = ( 2 ** 32 - 1 ) / camera.far; // UINT32_MAX / max_depth
+			const depthDelta = maxZ - minZ;
+			const factor = ( 2 ** 32 - 1 ) / depthDelta; // UINT32_MAX / z range
 			for ( let i = 0, l = list.length; i < l; i ++ ) {
 
+				list[ i ].z -= minZ;
 				list[ i ].z *= factor;
 
 			}

+ 4 - 1
src/objects/BatchedMesh.js

@@ -77,6 +77,8 @@ const _frustum = /*@__PURE__*/ new Frustum();
 const _box = /*@__PURE__*/ new Box3();
 const _sphere = /*@__PURE__*/ new Sphere();
 const _vector = /*@__PURE__*/ new Vector3();
+const _forward = /*@__PURE__*/ new Vector3();
+const _temp = /*@__PURE__*/ new Vector3();
 const _renderList = /*@__PURE__*/ new MultiDrawRenderList();
 const _mesh = /*@__PURE__*/ new Mesh();
 const _batchIntersects = [];
@@ -1017,6 +1019,7 @@ class BatchedMesh extends Mesh {
 			// get the camera position in the local frame
 			_invMatrixWorld.copy( this.matrixWorld ).invert();
 			_vector.setFromMatrixPosition( camera.matrixWorld ).applyMatrix4( _invMatrixWorld );
+			_forward.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld ).transformDirection( _invMatrixWorld );
 
 			for ( let i = 0, l = visibility.length; i < l; i ++ ) {
 
@@ -1037,7 +1040,7 @@ class BatchedMesh extends Mesh {
 					if ( ! culled ) {
 
 						// get the distance from camera used for sorting
-						const z = _vector.distanceTo( _sphere.center );
+						const z = _temp.subVectors( _sphere.center, _vector ).dot( _forward );
 						_renderList.push( drawRanges[ i ], z );
 
 					}