WebGPU 通过计算着色器并行处理图像、零拷贝纹理传递和轻量 DOM 更新,实现高效稳定的图像计算;支持异步提交、动态降级与双缓冲策略,显著优于 WebGL 的渲染绑定式处理。

WebGPU 能在图像计算环节真正甩开 WebGL 一大截,关键不在“画得快”,而在“算得专、交得准、展得稳”——它把图像处理从渲染管线里剥出来,交给计算着色器(Compute Shader)并行执行,再用零拷贝或低延迟纹理传递结果,最后配合 DOM 的轻量更新策略完成展示。整个过程主线程不卡、GPU不空转、内存不反复搬。
用计算着色器替代片段着色器做图像处理
WebGL 只能靠 fragment shader 在光栅化流程中顺带做图像计算,受限于渲染拓扑和采样约束;WebGPU 则允许你直接调度计算着色器,按需定义 workgroup 大小,逐像素/逐块处理输入纹理,并写入 storage texture 或 buffer。
- 用
texture_storage_2d<rgba8unorm, write>声明可写输出纹理,避免 render pass 开销 - 通过
dispatchWorkgroups(widthInGroups, heightInGroups)精确控制并行粒度,例如 1920×1080 图像可设为dispatchWorkgroups(30, 17)(每组 64 线程) - WGSL 中直接访问
textureLoad(input, uv, 0)和textureStore(output, uv, result),无格式转换开销
异步提交 + GPU-CPU 同步最小化
计算任务和主线程 UI 更新必须解耦。WebGPU 允许你在后台线程(如 Web Worker)中准备命令编码器,再将完成的 GPUCommandBuffer 提交到 device.queue,全程不阻塞渲染帧循环。
- 调用
device.queue.onSubmittedWorkDone监听计算完成,而非轮询或 await 阻塞 - 对输出纹理使用
GPUTextureUsage.COPY_SRC | GPUTextureUsage.RENDER_ATTACHMENT,既支持后续绘制,也便于读回(如需调试) - 避免频繁
copyExternalImageToTexture:原始图像用createImageBitmap+queue.copyExternalImageToTexture一次性上载,后续复用
DOM 展示走轻量路径,绕过重绘瓶颈
计算结果不需要塞进 canvas 再 drawImage;更优做法是让 canvas 作为 WebGPU 纹理的“视图容器”,或用 <img> + createObjectURL 快速呈现静态帧,动态场景则绑定 canvas 的 transferControlToOffscreen() 实现离屏合成。
- 将 WebGPU 输出纹理绑定到
HTMLCanvasElement的GPUCanvasContext,调用getContext('webgpu')后直接presentSurface显示,零 CPU 中转 - 若需叠加 DOM 元素(如标注、控件),用 CSS
position: absolute叠在 canvas 上层,不触发 canvas 重绘 - 对非实时快照类展示(如滤镜预览),可将 texture 读回为
ImageData,生成 Blob URL 赋给<img src="...">,比 canvas draw 更省内存
缓存与自适应策略补足体验
首次运行慢?设备能力差异大?这些不是 WebGPU 的缺陷,而是需要主动管理的维度。
- 着色器代码提前 fetch 并
localStorage.setItem('filter_wgsl_v2', code)缓存,跳过重复编译 - 根据
adapter.features.has('timestamp-query')或device.limits.maxComputeWorkgroupSizeX动态降级 workgroup size,低端设备改用 16×16 组而非 64 - 对连续视频流,启用双缓冲 texture:一个被计算着色器写入,另一个正被 canvas 呈现,用
device.queue.submit([...])切换引用,消除撕裂


















