Skip to content

Fix NodeMaterial SSS with clustered lights#18413

Open
Popov72 wants to merge 5 commits intoBabylonJS:masterfrom
Popov72:fix/nodematerial-sss-clustered-lights-clean
Open

Fix NodeMaterial SSS with clustered lights#18413
Popov72 wants to merge 5 commits intoBabylonJS:masterfrom
Popov72:fix/nodematerial-sss-clustered-lights-clean

Conversation

@Popov72
Copy link
Copy Markdown
Contributor

@Popov72 Popov72 commented May 3, 2026

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

Summary

  • Fix NodeMaterial PBR shader generation so subsurface-scattering declarations are emitted before clustered/direct-light helper functions that depend on them.
  • Prepare clustered-light tile-mask resources according to shader language so WebGPU WGSL effects use tileMaskBuffer.
  • Keep WebGPU clustered-light runtime binding on the storage-buffer path; the WebGPU NodeMaterial repro should load the snippet as WGSL instead of relying on a GLSL texture fallback.
  • Bind a default empty texture for WebGPU TextureBlock and ImageSourceBlock resources that have no texture assigned, preventing bind group creation failures.
  • Propagate material shader language through materials-library clustered-light preparation.

Motivation

The forum repro at https://forum.babylonjs.com/t/nodematerial-compile-error-when-using-sub-surface-scattering-with-clustered-lights/63299 failed with NodeMaterial subsurface scattering and clustered lights.

For the WebGPU playground repro (#CSCJO2#97), the NodeMaterial snippet must be loaded as WGSL, for example by passing { shaderLanguage: BABYLON.ShaderLanguage.WGSL } to NodeMaterial.ParseFromSnippetAsync. This preserves the WebGPU clustered-light fast path (tileMaskBuffer, batch size 32) instead of adding a slower GLSL texture fallback.

Validation

  • Added unit coverage for NodeMaterial SSS clustered-light shader ordering.
  • Added unit coverage for clustered-light tile-mask sampler/buffer selection.
  • Added unit coverage for WebGPU default texture binding for missing TextureBlock and ImageSourceBlock resources.
  • Verified the WebGPU playground repro locally with the snippet loaded as WGSL, clustered lights using tileMaskBuffer, and WebGPU batch size remaining 32.

Popov72 and others added 3 commits May 3, 2026 12:48
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Handle GLSL NodeMaterial clustered light tile mask bindings on WebGPU, propagate shader language into clustered sampler preparation, and bind a default texture for missing WebGPU TextureBlock resources.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@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.

@Popov72 Popov72 changed the title Fix NodeMaterial SSS with clustered lights on WebGPU Fix NodeMaterial SSS with clustered lights May 3, 2026
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

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

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

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

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18413/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/18413/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18413/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18413/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18413/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/18413/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

🟢 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

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

⚡ Performance Test Results

❌ Failed Tests (1)

Test Error
SSAO2 [#XT1HAS#1] (webgpu) Error: page.evaluate: Execution context was destroyed, most likely because of a navigation.

@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

🟢 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

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

Pass material shader language through materials-library clustered light preparation and correct the WebGPU storage-buffer comment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Popov72 Popov72 force-pushed the fix/nodematerial-sss-clustered-lights-clean branch from 95bc1d1 to b07b755 Compare May 3, 2026 13:23
@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.

@Popov72 Popov72 marked this pull request as ready for review May 3, 2026 13:28
Copilot AI review requested due to automatic review settings May 3, 2026 13:28
@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

This PR aims to make clustered-light handling shader-language-aware across core and materials-library materials, while also addressing NodeMaterial/WebGPU binding issues around subsurface scattering and missing texture resources. It fits into Babylon.js's rendering pipeline by aligning effect resource binding with whether a material is compiled as GLSL or WGSL.

Changes:

  • Propagate shaderLanguage into light uniform/sampler preparation for core and materials-library materials.
  • Adjust clustered-light resource selection and NodeMaterial shader generation around SSS + clustered-light interactions.
  • Add unit tests for clustered-light sampler selection, NodeMaterial shader ordering, and WebGPU default texture binding.

Reviewed changes

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

Show a summary per file
File Description
packages/dev/materials/src/water/waterMaterial.ts Passes material shader language into light sampler preparation.
packages/dev/materials/src/triPlanar/triPlanarMaterial.ts Same shader-language propagation for triplanar material.
packages/dev/materials/src/terrain/terrainMaterial.ts Same shader-language propagation for terrain material.
packages/dev/materials/src/simple/simpleMaterial.ts Same shader-language propagation for simple material.
packages/dev/materials/src/shadowOnly/shadowOnlyMaterial.ts Same shader-language propagation for shadow-only material.
packages/dev/materials/src/normal/normalMaterial.ts Same shader-language propagation for normal material.
packages/dev/materials/src/mix/mixMaterial.ts Same shader-language propagation for mix material.
packages/dev/materials/src/lava/lavaMaterial.ts Same shader-language propagation for lava material.
packages/dev/materials/src/gradient/gradientMaterial.ts Same shader-language propagation for gradient material.
packages/dev/materials/src/fur/furMaterial.ts Same shader-language propagation for fur material.
packages/dev/materials/src/cell/cellMaterial.ts Same shader-language propagation for cell material.
packages/dev/core/test/unit/Materials/materialHelper.functions.test.ts Adds tests for clustered-light sampler selection.
packages/dev/core/test/unit/Materials/Node/Blocks/textureBlock.test.ts Adds tests for WebGPU fallback texture binding.
packages/dev/core/test/unit/Materials/Node/Blocks/pbrMetallicRoughnessBlock.test.ts Adds a shader-ordering test for NodeMaterial PBR subsurface handling.
packages/dev/core/test/unit/Lights/Clustered/clusteredLightContainer.test.ts Adds tests for clustered-light texture vs storage-buffer binding.
packages/dev/core/src/Materials/standardMaterial.ts Passes shader language to uniform/sampler preparation.
packages/dev/core/src/Materials/materialHelper.functions.ts Makes clustered-light sampler generation depend on shader language.
packages/dev/core/src/Materials/PBR/pbrBaseMaterial.ts Passes shader language to light sampler preparation.
packages/dev/core/src/Materials/PBR/openpbrMaterial.ts Passes shader language to light sampler preparation.
packages/dev/core/src/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.ts Changes clustered-light helper emission/order and WGSL sampler selection.
packages/dev/core/src/Materials/Node/Blocks/Dual/textureBlock.ts Binds a default texture on WebGPU when no texture is assigned.
packages/dev/core/src/Materials/Node/Blocks/Dual/lightBlock.ts Makes NodeMaterial light sampler generation depend on shader language.
packages/dev/core/src/Materials/Background/backgroundMaterial.ts Passes shader language to uniform/sampler preparation.
packages/dev/core/src/Lights/Clustered/clusteredLightContainer.ts Switches tile-mask binding between texture and storage buffer by effect shader language.

Comment thread packages/dev/core/src/Lights/Clustered/clusteredLightContainer.ts Outdated
Comment thread packages/dev/core/src/Materials/Node/Blocks/Dual/textureBlock.ts
@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

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

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

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

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18413/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/18413/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18413/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18413/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18413/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/18413/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

Move WGSL direct-lighting helper emission after subsurface declarations, keep WebGPU clustered masks on the storage-buffer path, and bind a WebGPU fallback texture for missing ImageSourceBlock resources.

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

@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

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented May 3, 2026

⚡ Performance Test Results

Baseline: Latest · Candidate: Dev

Metric Value
🟢 Average 1.1%25 faster
Median 1.1%25 faster
Tests 1 conclusive, 0 inconclusive
🔘 Not Significant — p ≥ 0.05 (1)
Test Baseline Candidate Diff p-value GPU/frame (B/C)
SSAO2 [#XT1HAS#1] (webgpu) 27.9ms 27.6ms 1.1%25 faster 0.8277 16.92 / 16.92

❌ Failed Tests (1)

Test Error
Node material PBR 1 [#D8AK3Z#121] (webgl2) �[31mTest timeout of 300000ms exceeded.�[39m

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.

4 participants