@@ -310,18 +310,18 @@ class Projector {
310310 const v2 = _vertexPool [ b ] ;
311311 const v3 = _vertexPool [ c ] ;
312312
313- // Get homogeneous clip space positions (before perspective divide)
314- _clipPos1 . copy ( v1 . positionWorld ) . applyMatrix4 ( _viewProjectionMatrix ) ;
315- _clipPos2 . copy ( v2 . positionWorld ) . applyMatrix4 ( _viewProjectionMatrix ) ;
316- _clipPos3 . copy ( v3 . positionWorld ) . applyMatrix4 ( _viewProjectionMatrix ) ;
317-
318- // Check if triangle needs clipping
319- const nearDist1 = _clipPos1 . z + _clipPos1 . w ;
320- const nearDist2 = _clipPos2 . z + _clipPos2 . w ;
321- const nearDist3 = _clipPos3 . z + _clipPos3 . w ;
322- const farDist1 = - _clipPos1 . z + _clipPos1 . w ;
323- const farDist2 = - _clipPos2 . z + _clipPos2 . w ;
324- const farDist3 = - _clipPos3 . z + _clipPos3 . w ;
313+ // Derive near/far clip distances from NDC z and stored clip-space w
314+ // (projectVertex already computed positionScreen = clipPos / w, with w preserved)
315+ const w1 = v1 . positionScreen . w ;
316+ const w2 = v2 . positionScreen . w ;
317+ const w3 = v3 . positionScreen . w ;
318+
319+ const nearDist1 = w1 * ( v1 . positionScreen . z + 1 ) ;
320+ const nearDist2 = w2 * ( v2 . positionScreen . z + 1 ) ;
321+ const nearDist3 = w3 * ( v3 . positionScreen . z + 1 ) ;
322+ const farDist1 = w1 * ( 1 - v1 . positionScreen . z ) ;
323+ const farDist2 = w2 * ( 1 - v2 . positionScreen . z ) ;
324+ const farDist3 = w3 * ( 1 - v3 . positionScreen . z ) ;
325325
326326 // Check if completely outside
327327 if ( ( nearDist1 < 0 && nearDist2 < 0 && nearDist3 < 0 ) ||
@@ -385,7 +385,10 @@ class Projector {
385385
386386 }
387387
388- // Triangle needs clipping
388+ // Triangle needs clipping - reconstruct clip-space positions from NDC + w
389+ _clipPos1 . set ( v1 . positionScreen . x * w1 , v1 . positionScreen . y * w1 , v1 . positionScreen . z * w1 , w1 ) ;
390+ _clipPos2 . set ( v2 . positionScreen . x * w2 , v2 . positionScreen . y * w2 , v2 . positionScreen . z * w2 , w2 ) ;
391+ _clipPos3 . set ( v3 . positionScreen . x * w3 , v3 . positionScreen . y * w3 , v3 . positionScreen . z * w3 , w3 ) ;
389392 _clipInputVertices [ 0 ] = _clipPos1 ;
390393 _clipInputVertices [ 1 ] = _clipPos2 ;
391394 _clipInputVertices [ 2 ] = _clipPos3 ;
@@ -577,7 +580,7 @@ class Projector {
577580
578581 if ( sortObjects === true ) {
579582
580- painterSortStable ( _renderData . objects , 0 , _renderData . objects . length ) ;
583+ _renderData . objects . sort ( painterSort ) ;
581584
582585 }
583586
@@ -843,7 +846,7 @@ class Projector {
843846
844847 if ( sortElements === true ) {
845848
846- painterSortStable ( _renderData . elements , 0 , _renderData . elements . length ) ;
849+ _renderData . elements . sort ( painterSort ) ;
847850
848851 }
849852
@@ -987,29 +990,6 @@ class Projector {
987990
988991 }
989992
990- function painterSortStable ( array , start , length ) {
991-
992- // A stable insertion sort for sorting render items
993- // This avoids the GC overhead of Array.prototype.sort()
994-
995- for ( let i = start + 1 ; i < start + length ; i ++ ) {
996-
997- const item = array [ i ] ;
998- let j = i - 1 ;
999-
1000- while ( j >= start && painterSort ( array [ j ] , item ) > 0 ) {
1001-
1002- array [ j + 1 ] = array [ j ] ;
1003- j -- ;
1004-
1005- }
1006-
1007- array [ j + 1 ] = item ;
1008-
1009- }
1010-
1011- }
1012-
1013993 // Sutherland-Hodgman triangle clipping in homogeneous clip space
1014994 // Returns count of vertices in clipped polygon (0 if completely clipped, 3+ if partially clipped)
1015995 // Result vertices are in _clipInput array
0 commit comments