Skip to content

Comments

feat: Add visibilitychange event to Object3D#32768

Open
DennisSmolek wants to merge 1 commit intomrdoob:devfrom
DennisSmolek:feature/object3d-visibility-event
Open

feat: Add visibilitychange event to Object3D#32768
DennisSmolek wants to merge 1 commit intomrdoob:devfrom
DennisSmolek:feature/object3d-visibility-event

Conversation

@DennisSmolek
Copy link

Emit event when visible property changes. Fixes #32767

Summary

Summary

Add a visibilitychange event to Object3D that fires when the visible property changes.

  • Converts visible from a plain property to a getter/setter using the existing closure-variable pattern (same as position, rotation, quaternion, scale)
  • Event only fires when the value actually changes (not on same-value assignments)
  • Event object includes the new visible state for convenience
  • Adds unit test to verify event behavior
  • Updates documentation

Fixes #32767

Changes

  • src/core/Object3D.js: Add visibilitychange event and convert visible to getter/setter
  • docs/pages/Object3D.html: Document the new event
  • test/unit/src/core/Object3D.tests.js: Add test for visibilitychange event

Usage

const mesh = new THREE.Mesh(geometry, material);

mesh.addEventListener('visibilitychange', (event) => {
    console.log('Visibility changed to:', event.visible);
});

mesh.visible = false; // fires event with event.visible = false
mesh.visible = false; // no event (same value)
mesh.visible = true;  // fires event with event.visible = true

Test Plan

  • Run npx qunit test/unit/three.source.unit.js --filter "Object3D" - all 38 tests pass
  • New visibilitychange event test verifies:
    • Event fires on visibility change
    • Event contains correct visible value
    • Event does NOT fire when setting same value

@github-actions
Copy link

github-actions bot commented Jan 16, 2026

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 355.34
84.48
355.34
84.48
+0 B
+0 B
WebGPU 621.09
172.46
621.09
172.46
+0 B
+0 B
WebGPU Nodes 619.7
172.22
619.7
172.22
+0 B
+0 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 487.57
119.37
487.73
119.44
+158 B
+71 B
WebGPU 692.03
187.85
692.18
187.91
+158 B
+54 B
WebGPU Nodes 641.83
175.02
641.99
175.1
+158 B
+79 B

@DennisSmolek DennisSmolek force-pushed the feature/object3d-visibility-event branch from 9cc753f to 61eb68a Compare January 16, 2026 04:38
Emit event when visible property changes. Fixes mrdoob#32767
@DennisSmolek DennisSmolek force-pushed the feature/object3d-visibility-event branch from 61eb68a to 1d876bc Compare January 16, 2026 04:39
* @type {boolean}
* @default true
*/
visible: {
Copy link
Collaborator

@Mugen87 Mugen87 Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

visible is usually set by applications so they already know when the property change and then can fire a custom event if required. Also given that this feature has not been requested in 16 years, I think it is premature to modify directly Object3D.

You could also set up on application level a property observer that monitors the change of any specific property so there is no need to for this change at all.

I mean what should we do if someone wants a transparentChange or castShadowChange event?

Sorry, but regarding all this I do not vote to merge this PR.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know many applications that manage visibility. We mostly rely on the three state to do this.

This includes all r3f applications.

Also from what I understand, there is no way to be a passive observer of the property without maintaining your own list of objects to track or traversing the scene graph every frame and maintaining a previous state to test against.

I was thinking about silent updates and think a second param would work for this, I will extend this PR later.

Lastly just because it wasn't asked for doesn't mean it's not worth doing. There are fully AI written PRs being merged that no one asked for, yet are interesting and potentially useful.

r3f v10 will be adding this this functionality to our visibility checks, worst case monkey-patching this in...

Copy link
Collaborator

@Mugen87 Mugen87 Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are fully AI written PRs being merged that no one asked for, yet are interesting and potentially useful.

On what PRs are you referring here?

All PRs must be reviewed and the proposed changes evaluated independently of how the code was written. If a proposed change is appropriate, it's getting merged. If there are doubts about a change or a clear refusal, it's not. This PR is a kind of change with pros and cons and just because r3f has this feature it does not mean three.js must implement it as well.

Copy link
Collaborator

@Mugen87 Mugen87 Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also from what I understand, there is no way to be a passive observer of the property without maintaining your own list of objects to track or traversing the scene graph every frame and maintaining a previous state to test against.

Proxy can do this for you: #32767 (comment)

This approach requires no scene traverse and also no state maintenance (because you see the current and new value in the setter).

Copy link
Contributor

@pailhead pailhead Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When did three start managing object visibility? Only thing I can think of is perhaps the frustum check? But that could be a different event.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When did three start managing object visibility? Only thing I can think of is perhaps the frustum check? But that could be a different event.

Not sure, Object3D.visible is a prop though used in many places. Many scroll controls or other tools will set visibility based on dom elements for example. They are within the camera frustum but need to be turned off but not removed in case you scroll back quickly.

Sometimes quad-tree systems will turn off an entire section of elements, sometimes helpers are set to visible = false when off clicked and setting visible = true is often a great trigger for other things. Like a transform control being activated etc.

In react-three-fiber we combine this with Occlusion testing now so you can see both when its visibility changes and if you want when it gets occluded it fires events.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That all sounds like it’s on the application level though. I think events are reserved for things that actually do happen inside the renderer which you dont control directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit event when visible changed

3 participants