Skip to content

Fix clustered child light resync after parent enabled changes#18412

Merged
deltakosh merged 2 commits intoBabylonJS:masterfrom
Popov72:fix-clustered-light-parent-enabled
May 4, 2026
Merged

Fix clustered child light resync after parent enabled changes#18412
deltakosh merged 2 commits intoBabylonJS:masterfrom
Popov72:fix-clustered-light-parent-enabled

Conversation

@Popov72
Copy link
Copy Markdown
Contributor

@Popov72 Popov72 commented May 3, 2026

🤖 This PR was created by the create-pr skill.

Summary

Fixes a clustered lighting bug reported on the forum: https://forum.babylonjs.com/t/issue-when-using-lights-with-a-mesh-as-a-parent-in-clustered-lighting/63308

When a point or spot light is owned by a ClusteredLightContainer, it must not also be present in per-mesh lightSources, otherwise materials can bind it as a regular light in addition to the clustered container.

The previous cleanup handled addLight(), but a parent enabled-state change triggered Light._syncParentEnabledState() and _resyncMeshes(), which could re-add the raw child light to meshes even though it was still owned by the clustered container.

Fix

  • Mark lights internally while they are owned by a ClusteredLightContainer.
  • Skip regular mesh light-source resync for those clustered child lights.
  • Clear the marker when a light is removed from the container and added back to the scene.
  • Add a regression test for changing the enabled state of a parent mesh.

Validation

  • npx prettier --check packages/dev/core/src/Lights/Clustered/clusteredLightContainer.ts packages/dev/core/src/Lights/light.ts packages/dev/core/test/unit/Lights/Clustered/clusteredLightContainer.test.ts
  • npm test -- --run packages/dev/core/test/unit/Lights/Clustered/clusteredLightContainer.test.ts

Prevent lights owned by ClusteredLightContainer from resyncing themselves back into mesh light source lists when their parent enabled state changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 3, 2026 09:59
@Popov72 Popov72 added the bug label May 3, 2026
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a clustered-lighting edge case where child point/spot lights could be reintroduced into per-mesh lightSources (and thus bound as regular lights) after a parent enabled-state change, even while still owned by a ClusteredLightContainer.

Changes:

  • Adds an internal marker on Light to indicate when it is owned by a ClusteredLightContainer.
  • Skips mesh light-source resync for clustered child lights to prevent them from being re-added via parent enabled-state propagation.
  • Adds a unit regression test covering parent enabled-state toggling with clustered child lights.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
packages/dev/core/test/unit/Lights/Clustered/clusteredLightContainer.test.ts Adds regression coverage for parent enabled-state changes not reintroducing clustered child lights to mesh.lightSources.
packages/dev/core/src/Lights/light.ts Introduces _isClusteredLight and uses it to short-circuit _resyncMeshes() for clustered child lights.
packages/dev/core/src/Lights/Clustered/clusteredLightContainer.ts Sets/clears the clustered-ownership marker when adding/removing child lights.

Comment thread packages/dev/core/src/Lights/light.ts
Comment thread packages/dev/core/src/Lights/Clustered/clusteredLightContainer.ts
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

Snapshot stored with reference name:
refs/pull/18412/merge

Test environment:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18412/merge/index.html

To test a playground add it to the URL, for example:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18412/merge/index.html#WGZLGJ#4600

Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves):

https://playground.babylonjs.com/?snapshot=refs/pull/18412/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18412/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18412/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18412/merge

To test the snapshot in the playground with a playground ID add it after the snapshot query string:

https://playground.babylonjs.com/?snapshot=refs/pull/18412/merge#BCU1XR#0

If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

Use an owning clustered container reference instead of a boolean, skip excluded mesh resyncs while a light is clustered, and cover duplicate ownership.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

⚡ Performance Test Results

🟢 All performance tests passed — no regressions detected.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

🟢 Memory Leak Test Results

13 passed, 0 leaked out of 13 scenarios

🟢 All memory leak tests passed — no leaks detected.

Passed Scenarios (13)
Scenario Package
Core Feature Stack @babylonjs/core
Core Rendering Materials Shadows Stack @babylonjs/core
Core Textures Render Targets PostProcess Stack @babylonjs/core
GUI Fullscreen UI Controls @babylonjs/gui
GUI Mesh ADT Controls @babylonjs/gui
Loaders Boombox Import @babylonjs/loaders
Loaders OBJ Direct Load @babylonjs/loaders
Loaders STL Direct Load @babylonjs/loaders
Materials Library Stack @babylonjs/materials
Serializers glTF Export @babylonjs/serializers
Serializers GLB Export @babylonjs/serializers
PostProcesses Digital Rain Stack @babylonjs/post-processes
Procedural Textures Stack @babylonjs/procedural-textures

@deltakosh deltakosh merged commit 5adab80 into BabylonJS:master May 4, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants