Skip to content

Commit f3a46e6

Browse files
wrangelvidCody Bennett
andcommitted
Layers: Add recursive property
Co-Authored-By: Cody Bennett <cody.j.bennett@icloud.com>
1 parent 90d2cdd commit f3a46e6

8 files changed

Lines changed: 60 additions & 3 deletions

File tree

examples/jsm/renderers/CSS2DRenderer.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,22 @@ class CSS2DRenderer {
221221

222222
}
223223

224+
const layerVisible = object.layers.test( camera.layers );
225+
226+
if ( layerVisible === false && object.layers.recursive === true ) {
227+
228+
hideObject( object );
229+
230+
return;
231+
232+
}
233+
224234
if ( object.isCSS2DObject ) {
225235

226236
_vector.setFromMatrixPosition( object.matrixWorld );
227237
_vector.applyMatrix4( _viewProjectionMatrix );
228238

229-
const visible = ( _vector.z >= - 1 && _vector.z <= 1 ) && ( object.layers.test( camera.layers ) === true );
239+
const visible = ( _vector.z >= - 1 && _vector.z <= 1 ) && layerVisible;
230240

231241
const element = object.element;
232242
element.style.display = visible === true ? '' : 'none';

examples/jsm/renderers/CSS3DRenderer.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,19 @@ class CSS3DRenderer {
369369

370370
}
371371

372+
const layerVisible = object.layers.test( camera.layers );
373+
374+
if ( layerVisible === false && object.layers.recursive === true ) {
375+
376+
hideObject( object );
377+
378+
return;
379+
380+
}
381+
372382
if ( object.isCSS3DObject ) {
373383

374-
const visible = ( object.layers.test( camera.layers ) === true );
384+
const visible = layerVisible;
375385

376386
const element = object.element;
377387
element.style.display = visible === true ? '' : 'none';

src/core/Layers.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ class Layers {
2626
*/
2727
this.mask = 1 | 0;
2828

29+
/**
30+
* When set to `true`, if the layer test fails during rendering traversal,
31+
* the entire subtree of children will be skipped. This improves performance
32+
* by culling entire hierarchies that don't match the camera's layers.
33+
*
34+
* @type {boolean}
35+
* @default false
36+
*/
37+
this.recursive = false;
38+
2939
}
3040

3141
/**

src/core/Raycaster.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,13 @@ function ascSort( a, b ) {
235235

236236
function intersect( object, raycaster, intersects, recursive ) {
237237

238+
const visible = object.layers.test( raycaster.layers );
239+
240+
if ( visible === false && object.layers.recursive === true ) return;
241+
238242
let propagate = true;
239243

240-
if ( object.layers.test( raycaster.layers ) ) {
244+
if ( visible ) {
241245

242246
const result = object.raycast( raycaster, intersects );
243247

src/renderers/WebGLRenderer.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,6 +1803,8 @@ class WebGLRenderer {
18031803

18041804
const visible = object.layers.test( camera.layers );
18051805

1806+
if ( visible === false && object.layers.recursive === true ) return;
1807+
18061808
if ( visible ) {
18071809

18081810
if ( object.isGroup ) {

src/renderers/common/Renderer.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2809,6 +2809,8 @@ class Renderer {
28092809

28102810
const visible = object.layers.test( camera.layers );
28112811

2812+
if ( visible === false && object.layers.recursive === true ) return;
2813+
28122814
if ( visible ) {
28132815

28142816
if ( object.isGroup ) {

src/renderers/webgl/WebGLShadowMap.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,8 @@ function WebGLShadowMap( renderer, objects, capabilities ) {
509509

510510
const visible = object.layers.test( camera.layers );
511511

512+
if ( visible === false && object.layers.recursive === true ) return;
513+
512514
if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {
513515

514516
if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) {

test/unit/src/core/Layers.tests.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,23 @@ export default QUnit.module( 'Core', () => {
123123

124124
} );
125125

126+
QUnit.test( 'recursive', ( assert ) => {
127+
128+
const a = new Layers();
129+
130+
// Default value should be false
131+
assert.strictEqual( a.recursive, false, 'Default recursive is false' );
132+
133+
// Can be set to true
134+
a.recursive = true;
135+
assert.strictEqual( a.recursive, true, 'Can set recursive to true' );
136+
137+
// Can be set back to false
138+
a.recursive = false;
139+
assert.strictEqual( a.recursive, false, 'Can set recursive to false' );
140+
141+
} );
142+
126143
} );
127144

128145
} );

0 commit comments

Comments
 (0)