WebGPU vs TypeGPU 交互式对比
通过可交互的实时演示,直观对比两者在 GPU 执行性能、开发体验与类型安全性上的真实差异——性能完全一致,差距全在工程效率。
目录
按章节顺序排列,点击直接跳转。
需要 Chrome 113+ / Edge 113+ / Safari 17+ 才能体验 GPU 实时演示;内存布局、代码对比与性能图表在不支持 WebGPU 时也可正常交互。
关键洞察
GPU 执行性能完全一致,真正的差异在开发效率、类型安全与内存布局管理。
TypeGPU 是 WebGPU 的上层类型安全封装,两者在 GPU 上的 执行性能完全一致——因为 TypeGPU 在构建时把 TypeScript 编译为 WGSL, 运行时直接调用原生 WebGPU API。真正的差异体现在开发效率、类型安全和内存布局管理上。 本页所有演示均在浏览器中实时运行,你可以拖动滑块、切换模式亲手验证。
实时渲染对比
拖动滑块、切换演示模式,两侧画布用同一套粒子系统并行渲染,读数逐帧刷新。
内存布局对比
同一份 Particle 结构体:一边手动计算 offset 与 stride,一边由 typed-binary 自动对齐。
点击按钮修改结构体字段顺序,观察手动布局如何容易出错。 vec3f 实际占 16 字节(含 4 字节填充)!
- [*]WGSL 结构体手写字符串 / 类型生成
- [*]offset 与 stride手动计算 / 自动推导
- [*]vec3f 对齐16 bytes(含填充)
- [*]字段顺序变更改 3 处 / 改 1 处
- [*]错误发现时机运行时异常 / 编译时报错
代码复杂度实时对比
同一功能的两种写法:着色器、管线配置与内存布局三处并排对照。
相同功能:原生 WebGPU 约 142 行有效代码,TypeGPU 约 48 行。 切换标签页查看着色器、管线配置与内存布局三处的写法差异。
GPU 执行性能历史(证明两者性能一致)
粒子数量增加时,WebGPU 与 TypeGPU 的 GPU 执行时间曲线完全重合。
随着粒子数量增加,WebGPU 和 TypeGPU 的 GPU 执行时间曲线完全重合, 证明 TypeGPU 的运行时性能与原生 WebGPU 相同。差异仅体现在 CPU 侧的开发效率上。
吞吐与开销
RATIO着色器代码走查
页面上实时运行的着色器:WebGPU 侧手写 WGSL,TypeGPU 侧由 TypeScript 编译出同一份 WGSL。
struct Particle { pos: vec2f, vel: vec2f, color: vec3f, life: f32,}; @binding(0) @group(0) var<storage, read_write> particles: array<Particle>;@binding(1) @group(0) var<uniform> params: vec4f; @compute @workgroup_size(64)fn computeMain(@builtin(global_invocation_id) id: vec3u) { let idx = id.x; let count = u32(params.x); if (idx >= count) { return; } var p = particles[idx]; let dt = params.y; let load = u32(params.z); let mode = u32(params.w); if (mode == 0u) { p.pos = p.pos + p.vel * dt; p.vel.y = p.vel.y - 0.5 * dt; if (p.pos.y < -1.0) { p.pos.y = -1.0; p.vel.y = p.vel.y * -0.8; } if (p.pos.x < -1.0 || p.pos.x > 1.0) { p.vel.x = p.vel.x * -0.9; p.pos.x = clamp(p.pos.x, -1.0, 1.0); } } else if (mode == 1u) { let dir = vec2f(0.0, 0.0) - p.pos; let dist = length(dir); if (dist > 0.01) { p.vel = p.vel + normalize(dir) * 3.0 * dt; } p.pos = p.pos + p.vel * dt; p.vel = p.vel * 0.995; } else { p.pos = p.pos + p.vel * dt; p.vel = p.vel * 0.999; if (length(p.pos) > 1.0) { p.vel = p.vel * -0.95; p.pos = normalize(p.pos) * 0.98; } } var dummy = 0.0; for (var i = 0u; i < load; i = i + 1u) { dummy = dummy + sin(f32(i) * 0.01 + p.pos.x) * 0.0001; } p.pos.x = p.pos.x + dummy; p.life = p.life - dt * 0.15; if (p.life <= 0.0) { p.life = 1.0; let seed = f32(idx); p.pos = vec2f(fract(sin(seed * 12.9898) * 43758.5453) * 2.0 - 1.0, fract(sin(seed * 78.233) * 43758.5453) * 2.0 - 1.0); p.vel = vec2f(fract(sin(seed * 43.123) * 23421.0) * 2.0 - 1.0, fract(sin(seed * 91.456) * 12345.0) * 2.0 - 1.0) * 0.5; } particles[idx] = p;}
struct VertexOut { @builtin(position) pos: vec4f, @location(0) color: vec3f, @location(1) life: f32,}; @vertexfn vertexMain(@location(0) pos: vec2f, @location(1) vel: vec2f, @location(2) color: vec3f, @location(3) life: f32) -> VertexOut { var out: VertexOut; out.pos = vec4f(pos, 0.0, 1.0); out.color = color; out.life = life; return out;} @fragmentfn fragmentMain(@location(0) color: vec3f, @location(1) life: f32) -> @location(0) vec4f { let alpha = smoothstep(0.0, 0.2, life); return vec4f(color * (0.5 + life * 0.5), alpha * 0.9);}
- [*]particle buffer32 bytes / vertex
- [*]attributespos · vel · color · life
- [*]workgroup64 invocations
- [*]compute pass1 dispatch / frame
- [*]topologypoint-list
核心结论
性能一致、类型前移、效率三倍——差距全部落在工程侧。
GPU 性能:完全一致
TypeGPU 在构建时将 TypeScript 编译为 WGSL,运行时直接调用原生 WebGPU API。GPU 执行性能与原生 WebGPU 完全一致,无额外开销。上图中的双曲线重合证明了这一点。
类型安全:编译时捕获
TypeGPU 消除了 JS 与 WGSL 之间的类型断层。缓冲区类型、着色器参数、内存布局在编译时即被验证,错误在代码编写阶段就被捕获,而不是在运行时以奇怪的画面异常呈现。
开发效率:提升 3 倍
相同功能下 TypeGPU 代码量减少 60% 以上。无需手动计算偏移量、无需维护 WGSL 字符串、无需担心内存对齐陷阱。团队中的任何 TypeScript 开发者都能参与 GPU 编程。