Been dealing with this for a while on a browser-based game and I'm genuinely not sure there's a clean answer. Every time a new shader program compiles for the first time mid-session, a new enemy type appearing or a new environment chunk loading, there's a noticeable hitch. Sometimes 30ms, sometimes 200ms depending on the GPU. Really kills the feel when your game is supposed to be snappy.
I know the "right" answer is supposed to be shader prewarming: render all your variants invisibly on load so they're already compiled by the time they're needed. I tried this. It works, sort of. But my variant count has grown enough that warming everything upfront adds around 4 seconds to initial load, which just trades one bad experience for a different one.
Things I've actually looked into:
- KHR_parallel_shader_compile, broadly supported now, lets you kick off compiles async and poll for completion. Helps with load-time stutter but doesn't really help when something triggers a new variant mid-session.
- Lazy warming during scene transitions: start compiling shaders for the next area behind a loading screen or fade. Works if your game has natural transition points. Mine doesn't always.
- Reducing variant count via uber-shaders with branching. The tradeoff is real and I've been avoiding it but maybe it's the only honest answer.
WebGPU's createRenderPipelineAsync() is supposedly the real fix here, async pipeline creation that actually returns a Promise and doesn't block the main thread. I haven't fully migrated yet but this is one of the things actively pushing me toward it.
Curious what people are actually shipping with. Is load-time warming just the accepted tax? Are you bucketing variants to only warm the hot paths? Anyone using WebGPU's async pipeline creation in production and finding it meaningfully better, or does it just move the hitch somewhere less visible?