Hi folks! I recently upgraded my project using SelectionOutlineLayer from the standard Engine to WebGPUEngineusing the same options as the Playground does:
const engine = new BABYLON.WebGPUEngine(canvas, {
enableAllFeatures: true,
setMaximumLimits: true,
enableGPUDebugMarkers: true,
});
But it failed to render due to the 2 issues below:
Issue #1: DepthRenderer - “PushDebugGroup called 1 time(s) without a corresponding PopDebugGroup”
Initially, it was failing to render with:
babylon.js:1 BJS - [18:22:53]: [Frame 28] WebGPU uncaptured error (1): [object GPUValidationError] - PushDebugGroup called 1 time(s) without a corresponding PopDebugGroup. - While encoding [RenderPassEncoder "DepthRenderer - RenderPass"].End(). - While finishing [CommandEncoder "render"]. Debug group stack: > "Render to DepthRenderer (face #0 layer #0)" > "Depth renderer"
The mention of DepthRenderermade me look into the source code for SelectionOutlineLayerand indeed it calls scene.enableDepthRenderer():
public constructor(name: string, scene?: Scene, options?: Partial<ISelectionOutlineLayerOptions>) {
// ...
this._scene.enableDepthRenderer();
}
To isolate the issue, I temporarily commented out all SelectionOutlineLayercode in my project and ran scene.enableDepthRenderer()just by itself. Indeed, it gave the same error above.
So I asked Claude to find the issue, and it said:
const engine = new BABYLON.WebGPUEngine(canvas, { enableAllFeatures: true, setMaximumLimits: true, enableGPUDebugMarkers: false, // Disable to prevent DepthRenderer debug group imbalance });This is the simplest fix - the
PushDebugGroup/PopDebugGroupcalls only happen when enableGPUDebugMarkers istrue. Disabling it stops the error entirely with no other side effects since it’s only used for GPU profiling in browser dev tools.
Indeed, after setting enableGPUDebugMarkers: false, the scene was able to render. I don’t know if I’m doing something very wrong by disabling this, but I moved on and then ran into a 2nd issue:
Issue #2: Error parsing WGSL - “struct member position not found”
With scene.enableDepthRenderer()now seeming to work using the workaround above, I then uncommented all of the SelectionOutlineLayercode in my project.
It failed to render with the error:
babylon.js:1 BJS - [18:37:24]: [Frame 54] WebGPU uncaptured error (1): [object GPUValidationError] - Error while parsing WGSL: :65:28 error: struct member position not found var positionUpdated: vec3f=input.position; ^^^^^^^^^^^^^^ - While calling [Device "BabylonWebGPUDevice0"].CreateShaderModule([ShaderModuleDescriptor ""vertex""]).
Again, I asked Claude to resolve the issue, and it said:
The depth renderer uses an internal effect that references
input.position, which is invalid WGSL. The WGSL version should usevertexInputs.positioninstead.The Fix: Patch the WGSL Shader Before Calling
enableDepthRenderer():for (const [key, shader] of Object.entries(BABYLON.ShaderStore.ShadersStoreWGSL)) { if (typeof shader === 'string' && shader.includes('input.position')) { console.warn(`Patching broken WGSL shader: ${key}`); BABYLON.ShaderStore.ShadersStoreWGSL[key] = shader.replaceAll('input.position', 'vertexInputs.position'); } }
Indeed, the scene was able to render after this! ![]()
The shader files that it modified were:
Patching broken WGSL shader: gaussianSplattingVertexShader
Patching broken WGSL shader: gaussianSplattingDepthVertexShader
Patching broken WGSL shader: pickingVertexShader
Patching broken WGSL shader: glowMapGenerationVertexShader
Patching broken WGSL shader: glowMapMergeVertexShader
Patching broken WGSL shader: layerVertexShader
Patching broken WGSL shader: lensFlareVertexShader
Patching broken WGSL shader: shadowMapVertexShader
Patching broken WGSL shader: backgroundVertexShader
Patching broken WGSL shader: proceduralVertexShader
Patching broken WGSL shader: hdrFilteringVertexShader
Patching broken WGSL shader: hdrIrradianceFilteringVertexShader
Patching broken WGSL shader: colorVertexShader
Patching broken WGSL shader: meshUVSpaceRendererVertexShader
Patching broken WGSL shader: meshUVSpaceRendererFinaliserVertexShader
Patching broken WGSL shader: particlesVertexShader
Patching broken WGSL shader: kernelBlurVertexShader
Patching broken WGSL shader: fxaaVertexShader
Patching broken WGSL shader: fluidRenderingParticleDepthVertexShader
Patching broken WGSL shader: fluidRenderingParticleThicknessVertexShader
Patching broken WGSL shader: fluidRenderingParticleDiffuseVertexShader
Patching broken WGSL shader: depthPixelShader
Patching broken WGSL shader: depthVertexShader
Patching broken WGSL shader: geometryVertexShader
Patching broken WGSL shader: boundingBoxRendererVertexShader
Patching broken WGSL shader: lineVertexShader
Patching broken WGSL shader: iblVoxelSlabDebugVertexShader
Patching broken WGSL shader: spritesVertexShader
Question
Although the scene now renders with SelectionOutlineLayer, I don’t know if it’s wrong to be using these 2 workarounds.
Even more confusing is that SelectionOutlineLayerworks well with WebGPU in the Playground without these 2 workarounds:
I tried my best to match the WebGPU setup between the Playground and my local project, but my local project requires these 2 workarounds while the Playground does not. Is there something I’m missing?
If anyone could please help, I would much appreciate it
Thank you!!
