The idea is to cache camera frustum checks on objects (a) to avoid recalculation and (b) to offer a simple interface.
As pointed out in https://stackoverflow.com/a/29424745, when .frustumCulled
is enabled, .inFrustum
could be populated as part of the frustum culling.
I would be happy to put up a PR if there is interest in the feature.
I'm open for such a change. However, naming the flag isVisible
(similar to Unity) sounds more user-friendly to me than inFrustum
.
One could also consider to introduce two new callbacks onBecameVisible()
and onBecameInvisible()
to provide even more flexibility.
@Mugen87 Makes sense. Considering that we are not checking for occlusions, e.g. the object might be in frustum but technically not visible, do you think isVisible
could be confusing to some people?
Well, yeah this could be a problem. Against this backdrop, inFrustum
is indeed better. Especially since we already have Object3D.frustumCulled. So I think we can expect that users at a certain level of experience are familiar with the term "frustum"^^.
I feel this is a bit complicated because if a scene / object is being rendered multiple times with multiple renderers or multiple cameras then the field would only be relevant to the previous call to render
. And in the case of a callback it could be visible by one camera but invisible to another so onBecameVisible
and onBecameInvisible
might both get called every frame if it's being rendered multiple times. To me the way you'd want to track the frustum visibility state feels like an application-specific consideration. In the long run having a more customize-able / scriptable renderer could help with this.
@Mugen87 An aside but when do you consider it correct to introduce a new member function for a callback instead of an EventDispatcher callback like dispatchEvent({ type: 'becameVisible' })
?
I don't think a feature of the library needs to cover all eventualities. The project often introduced enhancements (e.g. like Material.onBeforeCompile()
) which provide benefits for a lot of basic use cases. Like I said before, topics are often made too complicated. I see no reason why we should not start with something simple which can later be replaced with something more sophisticated.
An aside but when do you consider it correct to introduce a new member function for a callback instead of an EventDispatcher callback like dispatchEvent({ type: 'becameVisible' })?
This is a personal preference.
I have a function which takes a distance and camera as input. It then calculates the position of the four corners of that camera's frustum at the provided distance.
This is what I use to determine where the margins of my viewable area are without using an orthogonal camera.
In some ways it's more useful then simply knowing whether an object is in the frustum or not as it allows me to know where the margins of my viewable area are. I think maybe we could add a method to camera objects which provides this feature. Seemed relevant to this convo, but let me know if I should add a PR/Feature-Request for it.
As discussed in #17481, a meaningful implementation of Object3D.inFrustum
is not doable. Implementing a similar feature with callbacks will be too complicated.
@cberkay how many objects are you checking per frame to see if they're inside the camera's frustum?
@mrdoob I am working on a developer library, so in a large enough of a scene, there could be dozens depending on the consumer. Right now a more realistic number is smaller than 5.
I see. I think something like a camera.containsObject()
may be simpler then.
@mrdoob Indeed. Do you think it is still wortwhile to pursue the caching approach or would camera.containsObject()
recompute based on the camera frustum?
recompute the frustum?
Most helpful comment
Well, yeah this could be a problem. Against this backdrop,
inFrustum
is indeed better. Especially since we already have Object3D.frustumCulled. So I think we can expect that users at a certain level of experience are familiar with the term "frustum"^^.