如果你做過前端可視化——比如 3D 地球、圖表大屏、資產拓撲圖——大概率碰過 Three.js 與 WebGL。但 WebGL 已經是十多年前的標準了,瀏覽器圖形的下一站叫 WebGPU:更接近現代 GPU 的設計、更低的 CPU 開銷,還能把 GPU 當平行運算器用。這篇我們從零開始,把第一個 WebGPU 程式跑起來,再接回 Three.js 看看實戰怎麼落地。
一、WebGPU 是什麼?和 WebGL 差在哪?
可以把 WebGL 想成「模仿老式 OpenGL 的相容層」,而 WebGPU 是「原生對接現代圖形 API(Vulkan / Metal / D3D12)」的新通道。
- 效能:管線(Pipeline)預先編譯驗證,每幀 CPU 開銷大幅下降,大量 draw call 不再是噩夢。
- Compute Shader:不只畫圖,還能跑通用平行運算——粒子模擬、物理、資料預處理都在 GPU 上完成。
- 支援度:Chrome / Edge 113+ 已預設支援,Safari 與 Firefox 也已跟進;舊瀏覽器仍需 WebGL 降級方案。
重點:WebGPU 不是 WebGL 的升級版,而是全新 API。設計思路從「全域狀態機」轉為「顯式管線與資源綁定」,心智模型完全不同。
二、步驟 1:檢測支援,取得 Adapter 與 Device
一切從 navigator.gpu 開始。先判斷瀏覽器支不支援,再依序取得轉接器與邏輯設備:
if (!navigator.gpu) {
alert('此瀏覽器不支援 WebGPU,請降級 WebGL');
}
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
特別注意:device 可能因驅動重置而遺失(lost)。正式專案要監聽 device.lost 事件,做設備重建與狀態恢復。
三、步驟 2:設定 Canvas Context 與渲染管線
接著讓 canvas 的 context 綁定 device,並建立管線。著色器用 WGSL——WebGPU 專屬的著色器語言:
const context = canvas.getContext('webgpu');
const format = navigator.gpu.getPreferredCanvasFormat();
context.configure({ device, format, alphaMode: 'opaque' });
const shader = device.createShaderModule({
code: `
@vertex
fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
var pos = array<vec2f, 3>(
vec2f(0.0, 0.6), vec2f(-0.6, -0.6), vec2f(0.6, -0.6));
return vec4f(pos[i], 0.0, 1.0);
}
@fragment
fn fs() -> @location(0) vec4f {
return vec4f(0.1, 0.7, 0.9, 1.0);
}
`
});
const pipeline = device.createRenderPipeline({
layout: 'auto',
vertex: { module: shader, entryPoint: 'vs' },
fragment: { module: shader, entryPoint: 'fs',
targets: [{ format }] }
});
注意這裡只有「建立」管線,還沒畫任何東西——這就是 WebGPU 的顯式哲學:所有狀態先宣告清楚,執行時零歧義。
四、步驟 3:編碼指令,送出渲染
真正畫圖靠三步:建 CommandEncoder → 開 RenderPass → submit:
const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({
colorAttachments: [{
view: context.getCurrentTexture().createView(),
clearValue: { r: 0.05, g: 0.06, b: 0.1, a: 1 },
loadOp: 'clear',
storeOp: 'store',
}]
});
pass.setPipeline(pipeline);
pass.draw(3); // 畫 3 個頂點
pass.end();
device.queue.submit([encoder.finish()]);
跑起來,canvas 上會出現一個青色三角形——你的第一個 WebGPU 渲染完成。重點:每一幀都是「編碼指令 → 一次性提交」的模式,encoder 用完即棄,不可重複 submit。
五、實戰落地:接回 Three.js 與專案選型
手寫管線適合理解原理,但業務專案不用從零造輪子:
- Three.js WebGPURenderer:把 WebGLRenderer 換成 WebGPURenderer,場景程式碼幾乎不動,底層自動走 WebGPU,不支援時降級 WebGL2。3D 地球、情報大屏這類既有專案遷移成本最低。
- TSL(Node Material):Three.js 的節點材質系統,一套材質程式碼同時編譯成 WGSL 與 GLSL,兩種後端都能跑。
- Compute 場景:十萬級粒子、即時物理模擬,用 compute shader 代替 CPU 循環,幀率提升非常可觀。
特別注意:WebGPU 要求安全上下文(HTTPS 或 localhost),本地開發沒問題,部署正式環境前記得確認。
小結:WebGPU 把瀏覽器變成了現代 GPU 的一等公民——顯式管線、compute shader、更低開銷。建議路徑:先用 Three.js WebGPURenderer 白撿紅利,再視需求深入 WGSL 與 compute 實戰。
互動話題:你的專案有沒有被 WebGL 效能卡過脖子(十萬粒子、3D 地球掉幀)?留言聊聊,下篇可以展開講 compute shader 粒子實戰!