WebGPU计算着色器必须用<script type="text/wgsl">声明,浏览器据此识别并交由device.createShaderModule()编译;直接写JS标签或错误type将失效,且调度工作组数与@workgroup_size乘积须不小于缓冲区元素数。

WebGPU 计算着色器不能直接在 HTML 里“写”,script 标签里放 @compute 代码会完全无效——浏览器根本不认识 WGSL,也不会自动编译它。
WGSL 代码必须用 <script type="text/wgsl"> 声明
HTML 中嵌入 WGSL 的唯一合法方式是显式声明 MIME 类型。浏览器靠这个识别“这不是 JS,别执行,留着等 WebGPU API 拿去编译”。
-
<script type="text/wgsl" id="computeShader">是标准写法,id用于后续document.getElementById('computeShader').textContent提取源码 - 不能写成
type="wgsl"或type="shader",这些类型会被忽略或触发 CORS 预检失败 - 不能把 WGSL 写在
<script>外部(比如注释里、<textarea>里),createShaderModule({ code: ... })只接受字符串,不接受 DOM 节点
device.createShaderModule() 才真正编译 WGSL
HTML 只负责“存”,真正解析和验证 WGSL 的是 GPU 设备。常见错误是传了空字符串、拼错变量名、或用了不支持的语法(比如 WGSL 1.0 不支持 break 在循环外)。
- 编译失败时
createShaderModule不抛异常,但后续createComputePipeline会静默失败,需检查device.pushErrorScope('validation')+device.popErrorScope() - 调试阶段建议把 WGSL 字符串先
console.log出来,确认换行、缩进、分号都符合规范(WGSL 对空格不敏感,但对结构体字段顺序、;和,位置很严格) - 如果用构建工具(如 Vite),可提前用
wgsl-validatorCLI 校验,避免 runtime 报错后才定位
计算管线调度必须匹配缓冲区大小
WGSL 里 @workgroup_size(64) 定义了每个工作组线程数,而 JS 里 encoder.dispatchWorkgroups(16) 决定总工作组数——两者相乘得实际并行调用总数,必须 ≥ 缓冲区元素个数,否则部分数据不会被处理。
立即学习“前端免费学习笔记(深入)”;
- 例如:处理 1000 个 float 的数组,
@workgroup_size(64)→ 至少要dispatchWorkgroups(16)(64×16=1024),不能只 dispatch 15 组(960 - 常见坑:
global_id.x超出缓冲区边界时没加越界检查,导致 GPU 写入非法地址,整个页面崩溃或黑屏 - 正确防护写法:在 WGSL
main函数开头加if (global_id.x >= ARRAY_LENGTH) { return; }
最易被忽略的是绑定组(bindGroup)生命周期——它必须在 dispatchWorkgroups 前创建,且所引用的缓冲区不能在 dispatch 期间被 queue.writeBuffer 或重新映射,否则行为未定义。



















