-
-
Notifications
You must be signed in to change notification settings - Fork 35.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Layers: add recursive property #28427
Conversation
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
@@ -3,6 +3,7 @@ class Layers { | |||
constructor() { | |||
|
|||
this.mask = 1 | 0; | |||
this.recursive = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the default should be configurable with a static property Layers.DEFAULT_RECURSIVE
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm personally not a fan of DEFAULT_
static properties since one could argue to introduce them for all normal properties to configure their default values. That makes the code more verbose and unnecessary complex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the property has to be particularly notable and value contentious to be worth reconfiguring.
Ideally, this would work in user-land for cases like #18937 (comment):
THREE.Layers.prototype.recursive = true;
console.log( new THREE.Layers().recursive ) // false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that this argumentation could be done for any other property as well. It's best if @mrdoob makes a design decision here. I'm not sure how he feels about the DEFAULT_
properties and to what extend they should be used.
The intended code should also look like so since ideally devs do not access the prototype
object:
const layers = new THREE.Layers();
layers.recursive = true;
I understand you have to set recursive
to true
for each instance but that doesn't seem like a real burden to me, tbh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not every property has a highly contentious default value, so I have to disagree here on making this a general argument against static properties. This was my compromise for #18937 since I see a lot of resistance against changing the default to true
, but if we can't allow this by configuration, then I propose making this the default instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to #19012 (comment), we want to keep false
as the default.
This is also my expected behavior of layers, tbh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to put three users on the happy path and find compromises which don't lead them into footguns undermining performance or ease-of-use, and I'm especially frustrated to fight tooth and nail to advocate for them. That entire thread is proof of disagreement around a default value, which suggests to me this should be configurable. Setting layers per object is only error-prone for their case, and this discussion alone infinitely more energy than adding a static member.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this isn't even satisfactory for @gkjohnson, then I can simply retract this PR. I'm not aware of how this is handled in user-land today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH, I never use layers recursively and if so I would probably traverse through the object hierarchy once and copy the layers to all objects that require the same mask. Granted a property that makes things configurable is easier to use but the PR also proves an increase in complexity in all components checking layers.
I'm not sure how common it is to user layers recursively in order to justify this complexity. I'm also not aware how common it is to mix recursive layer usage with non-recursive usage. If this is more a global setting then I agree a static DEFAULT_RECURSIVE
makes sense.
However, I would really like to hear @mrdoob's opinion on this change and also how he feels about the additional checks in all renderers and raycaster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this isn't even satisfactory for @gkjohnson,
I think I'm too far removed from that PR since it was over 4 year ago, now, and haven't been using layers recently. I'll have to leave this to others.
Let's revisit this when there's a clear need for it or we find a better balance with complexity. |
Thanks for continuing the work on this feature. I've been looking forward to recursive layers in Three.js for a while now, so it's sad to see progress on this halted once again. Since it seems that this PR was closed in part due to the lack of a clear use case for the feature, I thought I would share mine. Our team is developing a 3D editor application where we use the Currently, we achieve this by organizing all objects in the scene under different root nodes (e.g., Layers would be a much better fit for such a use case. But with the current implementation, there are two significant disadvantages to this approach:
Recursive layers would solve both issues and make it much easier to efficiently implement such a multi-pass rendering pipeline. Regarding the discussion on whether the default value of the proposed |
I think I simply don't have the energy to champion this. I've used these changes multiple times in production for a similar use-case, where a certain layer is rendered in post-processing. I found that collateral matrix updates were quite large and far more costly than the additional pass itself, which lead to #28534. |
Related issue: #18937
Description
Continues #19012 with handling wherever a visibility test is performed. I did not update layers tests in render-lists or transmission pass code since it was not clear to me if those lists were in any hierarchical order.
When
Layers.recursive = true
for an object and it fails the visibility test, its children are not processed.