[WebGPU] Add WGSL shader paths for GUI3D and GPU particles#18460
[WebGPU] Add WGSL shader paths for GUI3D and GPU particles#18460matthargett wants to merge 11 commits into
Conversation
Effect shader preparation can reject asynchronously before a pipeline context is available. Previously that rejection could be left as a floating promise, which made Native/WebGPU readiness failures show up as a timeout or a swallowed console error instead of a useful JS exception.\n\nRoute the async rejection through the normal compilation-error path, preserve the original stack as the cause, and keep getCompilationError actionable for field diagnostics.
The GUI3D fluent button and backplate paths need real WGSL shader sources when the host engine is WebGPU. Add WGSL sources for FluentButtonMaterial, load them through extraInitializationsAsync, and replace the placeholder FluentBackplate WGSL with the full shader port.\n\nThis removes the need for Native validation to force GUI3D effects onto ad hoc WGSL shims and lets browser WebGPU and NativeWebGPU exercise the same BabylonJS material path.
MeshDebugPluginMaterial advertised WGSL compatibility, but several WGSL snippets still used GLSL syntax or interpolation semantics: float declarations, ternary expressions, unqualified uniforms, single-line discard, and missing flat varyings.\n\nPort those snippets to valid WGSL and restore flat interpolation for per-primitive debug data so the WebGPU screenshot renders the intended triangle/vertex overlay instead of timing out or producing a mostly black mesh.
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
|
Snapshot stored with reference name: Test environment: To test a playground add it to the URL, for example: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18460/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/18460/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/18460/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. |
🟢 Memory Leak Test Results13 passed, 0 leaked out of 13 scenarios 🟢 All memory leak tests passed — no leaks detected. Passed Scenarios (13)
|
|
WebGL2 visualization test reporter: |
⚡ Performance Test Results🟢 All performance tests passed — no regressions detected. |
|
Visualization tests for WebGPU |
|
Looks like there's failures that I didn't see locally due to WebGPU implementation differences. I'm on it :) |
Use textureSampleLevel for GPU particle color-gradient lookups in the WGSL vertex shader so WebGPU validation does not reject implicit-derivative sampling in the vertex stage. Also fills the TSDoc comments and parameter docs required by the TypeDoc CI gate for the WebGPU/GU3D APIs touched by this PR.
|
Ran the CI pipeline locally where I have Chrome Canary and Edge Dev installed. Key pass signals: New things worth watching:
|
There was a problem hiding this comment.
Pull request overview
Adds native WGSL shader paths for WebGPU execution in GUI3D fluent/handle materials and GPU particle rendering, plus related effect error handling and focused unit coverage.
Changes:
- Adds WGSL shader sources for GUI3D fluent, fluent button, fluent backplate, handle, and GPU particle render shaders.
- Updates material/particle effect creation to select
ShaderLanguage.WGSLunder WebGPU and import WGSL shader modules asynchronously. - Adds unit coverage for selected GUI3D and GPU particle WebGPU effect creation paths, and fixes WGSL snippets in mesh debug plugin material.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
packages/dev/gui/test/unit/gui3DWebGPUShaders.test.ts |
Adds GUI3D material WebGPU shader-language tests. |
packages/dev/gui/src/3D/materials/handle/wgsl/handle.vertex.fx |
Adds HandleMaterial WGSL vertex shader. |
packages/dev/gui/src/3D/materials/handle/wgsl/handle.fragment.fx |
Adds HandleMaterial WGSL fragment shader. |
packages/dev/gui/src/3D/materials/handle/handleMaterial.ts |
Selects WGSL shader language for HandleMaterial on WebGPU. |
packages/dev/gui/src/3D/materials/fluentButton/wgsl/fluentButton.vertex.fx |
Adds FluentButtonMaterial WGSL vertex shader. |
packages/dev/gui/src/3D/materials/fluentButton/wgsl/fluentButton.fragment.fx |
Adds FluentButtonMaterial WGSL fragment shader. |
packages/dev/gui/src/3D/materials/fluentButton/fluentButtonMaterial.ts |
Passes shader language and WGSL initialization for FluentButtonMaterial effects. |
packages/dev/gui/src/3D/materials/fluentBackplate/wgsl/fluentBackplate.vertex.fx |
Adds FluentBackplateMaterial WGSL vertex shader. |
packages/dev/gui/src/3D/materials/fluentBackplate/wgsl/fluentBackplate.fragment.fx |
Adds FluentBackplateMaterial WGSL fragment shader. |
packages/dev/gui/src/3D/materials/fluentBackplate/fluentBackplateMaterial.ts |
Passes shader language and WGSL initialization for FluentBackplateMaterial effects. |
packages/dev/gui/src/3D/materials/fluent/wgsl/fluent.vertex.fx |
Adds FluentMaterial WGSL vertex shader. |
packages/dev/gui/src/3D/materials/fluent/wgsl/fluent.fragment.fx |
Adds FluentMaterial WGSL fragment shader. |
packages/dev/gui/src/3D/materials/fluent/fluentMaterial.ts |
Passes shader language and WGSL initialization for FluentMaterial effects. |
packages/dev/core/test/unit/Particles/gpuParticleSystemAgeGradients.test.ts |
Adds GPU particle WebGPU render shader-language test. |
packages/dev/core/src/ShadersWGSL/gpuRenderParticles.vertex.fx |
Adds GPU particle render WGSL vertex shader. |
packages/dev/core/src/ShadersWGSL/gpuRenderParticles.fragment.fx |
Adds GPU particle render WGSL fragment shader. |
packages/dev/core/src/Particles/gpuParticleSystem.ts |
Selects WGSL render shaders for GPU particles under WebGPU. |
packages/dev/core/src/Materials/meshDebugPluginMaterial.ts |
Fixes WGSL syntax/interpolation in mesh debug plugin snippets. |
packages/dev/core/src/Materials/effect.ts |
Reports async shader preparation failures through effect compilation error handling. |
| fn lineVertex(uv: vec2f, rate: f32, highlightTransform: vec4f) -> vec3f { | ||
| let angle2: f32 = rate * 2.0 * 3.1416; | ||
| let sinAngle2: f32 = sin(angle2); | ||
| let cosAngle2: f32 = cos(angle2); | ||
| let xformUV: vec2f = uv * highlightTransform.xy + highlightTransform.zw; | ||
| return vec3f(0.0, cosAngle2 * xformUV.x - sinAngle2 * xformUV.y, 0.0); |
| shaderLanguage: this._shaderLanguage, | ||
| extraInitializationsAsync: this._shadersLoaded | ||
| ? undefined | ||
| : async () => { | ||
| if (this.shaderLanguage === ShaderLanguage.WGSL) { | ||
| await Promise.all([import("./wgsl/fluentButton.vertex"), import("./wgsl/fluentButton.fragment")]); |
Preserve the WGSL line-highlight timing parameter so native WebGPU uses the same disabled highlight state as the GLSL shader. This keeps the GUI3D slate shader correction in the existing GUI3D/WebGPU PR without bundling the separate font metric fallback.
80c829a to
697d3b5
Compare
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
🟢 Memory Leak Test Results13 passed, 0 leaked out of 13 scenarios 🟢 All memory leak tests passed — no leaks detected. Passed Scenarios (13)
|
|
Visualization tests for WebGPU |
|
WebGL2 visualization test reporter: |
⚡ Performance Test Results🟢 All performance tests passed — no regressions detected. |
|
sorry for the thrash, I'm going through all the screenshot tests semi-manually on multiple devices (M4 Mac, iPhone XS, Apple Watch SE2) and tightening up differences. there's actually a number of these tests that should be failing in BabylonNative's bgfx backend already due to differences with browser render, but the pixel match threshold is so wide that they've been missed. I'm just focused on WebGPU for right now, but I'll file issues for the WebGL differences as well in case they're important enough for others to follow up on. |
|
Moving all active PRs to draft for the next 24 to 48 hours. |
|
Please make sure to merge from master. Apologies for the many merge conflicts. please make sure to put the code in the right place |
|
Merged latest master (9.9.1) into the branch and reconciled the WebGPU changes into the tree-shaken Local validation with the reconciled 18460 + 18463 patches:
Fresh PR checks currently show GitGuardian passing, with Azure/Mergify entries neutral/skipping rather than failing. |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Summary
This adds WebGPU/WGSL shader paths for Babylon.js features that currently still create GLSL effects under WebGPU:
shaderLanguage: WGSLwhen running on a WebGPU engine.HandleMaterialselects WGSL under WebGPU.GPUParticleSystemrender shaders now have WGSL vertex/fragment shaders and create the render effect withshaderLanguage: WGSLunder WebGPU.Why
These paths are visible in browsers through the WebGPU renderer, but runtimes that do not ship a GLSL-to-WGSL fallback need Babylon.js to select native WGSL shader sources. The new paths keep WebGL behavior unchanged and only opt into WGSL for WebGPU engines.
Browser WebGPU impact
This improves browser WebGPU robustness for these Babylon.js-owned paths, but it may not always show up as a visible before/after in browsers. Browser WebGPU builds can often hide this gap because the WebGPU engine has GLSL processing / TWGSL fallback support. These built-in GUI3D and GPU-particle paths should still use native WGSL when the engine is already running WebGPU.
With this change, GUI3D fluent/handle materials and
GPUParticleSystemrender effects select native WGSL sources under WebGPU. That removes fallback/translation dependency for these paths, keeps WebGL behavior unchanged, and makes browser WebGPU behavior line up better with stricter WebGPU runtimes that only accept WGSL. This does not translate arbitrary user-provided GLSL registered throughEffect.ShadersStore/createEffectForParticles; those custom snippets still need WGSL sources or an explicit fallback path.Native screenshot evidence and current limitation
These screenshots were captured from a BabylonNative WebGPU/wgpu-native macOS ASan+UBSan Playground build using the UMD output from this branch. For the GUI3D run, BabylonNative's local GUI3D shader shim was disabled in the app bundle so the screenshot validates the WGSL sources from this PR.
Important limitation: the BabylonNative screenshot runner marks the GUI3D cases as passing because the pixel delta is below its global 2.5% threshold, but visual inspection shows GUI3D text/icons are still missing. This PR fixes the missing WGSL shader path / readiness failure for the GUI3D materials; it does not yet prove full GUI3D visual parity.
GUI3D SpherePanel, with material surfaces rendered but text still missing:
GPU Particles - Basic Properties - Size:
Validation
npm ci(completed; local Node 26 emitted the repo engine warning for>=20.17.0 <23.0.0)npm run build:assetsnpm run build:sourcenpx eslint packages/dev/core/src/Particles/gpuParticleSystem.ts packages/dev/core/test/unit/Particles/gpuParticleSystemAgeGradients.test.ts packages/dev/gui/src/3D/materials/fluent/fluentMaterial.ts packages/dev/gui/src/3D/materials/fluentBackplate/fluentBackplateMaterial.ts packages/dev/gui/src/3D/materials/handle/handleMaterial.ts packages/dev/gui/test/unit/gui3DWebGPUShaders.test.ts --quietnpx vitest run --project=unit packages/dev/core/test/unit/Particles/gpuParticleSystemAgeGradients.test.ts packages/dev/gui/test/unit/gui3DWebGPUShaders.test.ts packages/dev/core/test/unit/Engines/WebGPU/webgpuShaderProcessorWGSL.test.ts(35 tests passed)npx nx build babylonjs --outputStyle=staticnpx nx build babylonjs-gui --outputStyle=staticgit -c core.whitespace=cr-at-eol diff --checkAdditional native smoke validation with the built UMD output in a BabylonNative WebGPU/wgpu-native macOS ASan+UBSan Playground build:
Note
This does not attempt to translate arbitrary user-provided GLSL registered through
Effect.ShadersStore/createEffectForParticles. Those custom shader snippets still need a WGSL source or an explicit GLSL fallback path.