WebGPU 是 2023 年 Web 的未來!
WebGPU 是用于 Web 的下一代圖形和計算 API。它提供對現(xiàn)代 GPU 的基礎(chǔ)訪問,從而在 Web 平臺上實現(xiàn)高性能 3D 圖形、圖像處理和通用計算。經(jīng)過多年的開發(fā)和測試,WebGPU 已經(jīng)到了推薦階段,可以被主流瀏覽器采用。谷歌宣布 Chrome 從版本 113 開始提供 WebGPU 支持,從而在 ChromeOS、Windows 和 macOS 設(shè)備上實現(xiàn)驚人的視覺效果和復雜的計算。
WebGPU 為 Web 開發(fā)開辟了很多新的可能性。它可以為身臨其境的虛擬世界、交互式數(shù)據(jù)可視化、高級圖像和視頻編輯、物理模擬、機器學習等提供支持——所有這些都在瀏覽器中運行。WebGPU 還支持圍繞 web 3、隱私和安全性的新用例,這在以前是不可行的。
Web 平臺繼續(xù)突破在線可能性的界限。借助 WebGPU 和 WebXR、WebTransport 和 WebCodecs 等相關(guān)標準,未來的 Web 將比以往任何時候都更加強大和開放。雖然這仍是一項新興技術(shù),但 WebGPU 展示了開放 Web 上圖形和計算的廣闊前景。
WebGPU 提供基礎(chǔ) API,需要了解圖形編程和 GPU 架構(gòu)才能有效使用。然而,在庫、工具和資源的幫助下,Web 開發(fā)人員可以使用 WebGPU。Babylon.js、Three.js、TensorFlow.js 和 Filament 等 WebGPU 采納者展示了如何將 WebGPU 包裝到更高級別的框架中,以構(gòu)建交互式 3D 場景、運行機器學習模型等。
WebGPU 的歷史
WebGPU 的誕生源于對更現(xiàn)代和高效的 Web 圖形 API 的需求,以取代基于 OpenGL API 家族的 WebGL。WebGL 在網(wǎng)頁上實現(xiàn)了許多令人驚嘆的體驗,例如 Google 地球、交互式音樂視頻、3D 房地產(chǎn)漫游等,但它也存在一些限制和挑戰(zhàn),例如:
- 缺乏對新 GPU 功能的支持,如計算著色器、光線追蹤、可變速率著色等。由
- 于需要驗證每個 API 調(diào)用并在 CPU 和 GPU 內(nèi)存之間復制數(shù)據(jù),因此具有高 CPU 開銷和內(nèi)存使用量。
- 由于 OpenGL 在不同的瀏覽器和平臺上的支持和優(yōu)化不同,導致性能和行為不一致。
2016 年,谷歌向 WebGL 工作組展示了一個 PPT,探討了構(gòu)建一個最終取代 WebGL 的新 API 的基本思想和原則,又名“WebGL Next”。該演示文稿提出了一個低級 API,它將公開現(xiàn)代 GPU 的底層功能,例如命令緩沖區(qū)、管道、描述符等。API 也將是顯式的,這意味著開發(fā)人員將對 GPU 資源的使用方式有更多的控制權(quán) 管理和同步。
2017 年,Apple 的 WebKit 團隊提議創(chuàng)建 W3C 社區(qū)組來設(shè)計 API。同時,他們基于 Apple Metal 中的概念,宣布了一項名為“WebGPU”的概念和提案的技術(shù)證明。WebGPU 名稱后來被社區(qū)采納為未來標準名稱。最初的提案已重命名為“WebMetal”以避免進一步混淆。
W3C 社區(qū)小組開始著手定義 WebGPU 規(guī)范和 API,Mozilla、Apple、Intel 和 Microsoft 等主要公司都做出了貢獻。該小組還收到了 Web 開發(fā)人員和行業(yè)專家的反饋。目標是創(chuàng)建一個 API:
- 安全:API 應(yīng)防止常見錯誤,如內(nèi)存泄漏、數(shù)據(jù)競爭或無效操作等,這些錯誤可能會導致崩潰或安全問題。
- 可移植:API 應(yīng)該在不同的瀏覽器和平臺上一致地工作,而不需要特定于供應(yīng)商的擴展或解決方法。
- 表現(xiàn)力:API 應(yīng)允許開發(fā)人員充分利用現(xiàn)代 GPU 的潛力,而不影響性能或靈活性。
Chromium 團隊于 2017 年初展示了名為 NXT 的第一個概念原型。NXT 實現(xiàn)了一個新的 API,它可以在帶有 OpenGL 的 Chromium 中運行,或者與 OpenGL 和 Metal 獨立運行。NXT 借鑒了所有 Vulkan、Direct3D 12 和 Metal 原生 API 的概念。
2020 年,WebGPU 進入第一個公共工作草案階段,這意味著該規(guī)范足夠穩(wěn)定,可以接受公眾審查和反饋。該規(guī)范定義了 JavaScript API 和基于 SPIR-V 的 WebGPU 著色語言 (WGSL),旨在與現(xiàn)有的著色語言(如 HLSL 和 GLSL)兼容。
在2021年,WebGPU 達到了候選推薦階段,這意味著規(guī)范已經(jīng)可以進行實現(xiàn)測試和互操作性評估。規(guī)范還定義了一些可選特性,這些特性可以根據(jù)瀏覽器的平臺支持進行啟用,例如深度鉗位、各向異性濾波、紋理壓縮 BC 等。
2023 年,WebGPU 進入提議推薦階段,這意味著該規(guī)范已準備好接受 W3C 主席的認可。該規(guī)范還定義了一些實驗性功能,瀏覽器可以在標志或前綴下啟用這些功能,例如光線追蹤或可變速率著色。
2023 年 4 月 6 日,Google 宣布 Chromium/Chrome 瀏覽器將從 Chromium/Chrome 113 開始在支持 Vulkan 的 ChromeOS 設(shè)備、macOS 和具有 Direct3D 12 的 Windows 設(shè)備上啟用 WebGPU 支持。對包括 Linux 和 Android 在內(nèi)的其他平臺的 WebGPU 支持將在之后進行添加。
WebGPU對Web 3開發(fā)的影響
WebGPU 對 Web 3 開發(fā)有這深遠的影響,因為它實現(xiàn)了 WebGL 不可能或不可行的新可能性和場景。WebGPU 的一些用例如下:
- 高性能圖形和計算:WebGPU 允許開發(fā)人員利用現(xiàn)代 GPU 的強大功能在 Web 上創(chuàng)建令人驚嘆的視覺效果和復雜的模擬。WebGPU 可以處理大量數(shù)據(jù)和并行計算,例如粒子系統(tǒng)、流體動力學、物理引擎、機器學習等。WebGPU 還可以支持高級渲染技術(shù),例如光線追蹤、陰影、反射、環(huán)境遮擋等。
- 跨平臺兼容性:WebGPU 在不同的瀏覽器和平臺上一致地工作,不需要供應(yīng)商特定的擴展或解決方法。WebGPU 還可以在支持 Vulkan、Metal 或 Direct3D 12 的移動設(shè)備上運行,這些設(shè)備涵蓋了大多數(shù)現(xiàn)代智能手機和平板電腦。這意味著開發(fā)人員可以創(chuàng)建在任何設(shè)備上都能流暢運行的 Web 應(yīng)用。
- 面向未來:WebGPU 旨在可擴展并適應(yīng)未來的 GPU 功能和技術(shù)。WebGPU 可以將新功能公開為可選擴展或?qū)嶒炐怨δ埽瑸g覽器可以根據(jù)其平臺支持啟用這些功能。這意味著開發(fā)人員可以使用最新和最強大的 GPU 功能,而無需等待標準趕上或冒兼容性問題的風險。
- Web 3:WebGPU 可以使 Web 應(yīng)用與去中心化網(wǎng)絡(luò)和協(xié)議進行交互,例如區(qū)塊鏈、IPFS 等。WebGPU 還可以支持 Web 上的安全和可驗證計算,例如零知識證明、同態(tài)加密等。這意味著開發(fā)人員可以創(chuàng)建更透明、更可靠、更有彈性的 Web 應(yīng)用。
- 元宇宙:WebGPU 可以使 Web 應(yīng)用能夠在 Web 上創(chuàng)建身臨其境的交互式虛擬世界和體驗。WebGPU 可以支持大型場景和環(huán)境、復雜的動畫和交互、逼真的光照和材料、空間音頻和觸覺等。這意味著開發(fā)人員可以創(chuàng)建更具吸引力、社交性和趣味性的 Web 應(yīng)用。
WebGPU 入門
要開始使用 WebGPU,需要一個支持它的瀏覽器(例如 Chrome 113 或更高版本)和一個具有兼容 GPU 的設(shè)備(例如支持 Vulkan 的 Chromebook)。還需要一些 JavaScript 和圖形編程的基本知識。
以下是使用 WebGPU 在 canvas 元素上繪制三角形的例子:
// 獲取 canvas 元素的引用
const canvas = document.getElementById("canvas");
// 從 canvas 獲取 WebGPU 上下文
const context = canvas.getContext("webgpu");
// 從上下文中獲取默認適配器 (GPU)
const adapter = await context.getAdapter();
// 從適配器獲取設(shè)備(GPU 的邏輯表示)
const device = await adapter.requestDevice();
// 從上下文中創(chuàng)建交換鏈(一組用于顯示幀的緩沖區(qū))
const swapChainFormat = "bgra8unorm";
const swapChain = context.configureSwapChain({
device,
format: swapChainFormat,
});
// 從設(shè)備創(chuàng)建著色器模塊(著色器代碼的容器)
const shaderModule = device.createShaderModule({
code: `
// 頂點著色器
[[stage(vertex)]]
fn main([[builtin(vertex_index)]] index: u32) -> [[builtin(position)]] vec4<f32> {
// 定義三角形頂點的位置
var positions: array<vec2<f32>, 3> = array<vec2<f32>, 3>(
vec2<f32>(0.0, 0.5),
vec2<f32>(-0.5, -0.5),
vec2<f32>(0.5, -0.5),
);
// 返回當前頂點的位置
return vec4<f32>(positions[index], 0.0, 1.0);
}
// 片段著色器
[[stage(fragment)]]
fn main() -> [[location(0)]] vec4<f32> {
// 返回三角形的顏色(紅色)
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`,
});
// 從設(shè)備創(chuàng)建管道(用于渲染的一系列操作)
const pipeline = device.createRenderPipeline({
// 指定頂點階段(著色器模塊和入口點)
vertex: {
module: shaderModule,
entryPoint: "main",
},
// 指定片段階段(著色器模塊和入口點)
fragment: {
module: shaderModule,
entryPoint: "main",
// 指定輸出格式和位置
targets: [
{
format: swapChainFormat,
},
],
},
// 指定原始拓撲(頂點如何連接)
primitive: {
topology: "triangle-list",
},
});
// 從設(shè)備創(chuàng)建命令編碼器(用于記錄命令的輔助對象)
const commandEncoder = device.createCommandEncoder();
// 從交換鏈中獲取當前紋理(緩沖區(qū))
const texture = swapChain.getCurrentTexture();
// 從命令編碼器創(chuàng)建渲染通道(一組用于渲染的命令)
const renderPass = commandEncoder.beginRenderPass({
// 指定輸出紋理和顏色
colorAttachments: [
{
view: texture.createView(),
loadValue: [0.5, 0.5, 0.5, 1], // gray
storeOp: "store",
},
],
});
// 為渲染過程設(shè)置 pipeline
renderPass.setPipeline(pipeline);
// 繪制三角形(3 個頂點,1 個實例)
renderPass.draw(3, 1, 0, 0);
// 結(jié)束渲染過程
renderPass.endPass();
// 從命令編碼器獲取命令緩沖區(qū)(命令的容器)
const commandBuffer = commandEncoder.finish();
// 將命令緩沖區(qū)提交到設(shè)備隊列(要執(zhí)行的命令列表)
device.queue.submit([commandBuffer]);
// 請求一個動畫幀來渲染下一幀
requestAnimationFrame(render);
WebGPU 資源和工具
要構(gòu)建 WebGPU,需要一些工具和資源來完成開發(fā)過程。可以使用的一些工具和資源如下:
- WebGPU 示例:WebGPU 示例和演示的集合,展示了如何使用 WebGPU 的各種功能和技術(shù)。可以瀏覽代碼、在線運行示例或?qū)⑺鼈兿螺d到本地計算機。這些示例還包括一個 WebGPU 幫助程序庫,可以簡化一些常見的任務(wù)和操作。地址:https://austineng.github.io/webgpu-samples/。
- WebGPU Playground:WebGPU 的在線編輯器和 Playground,可讓在瀏覽器中編寫和運行 WebGPU 代碼。還可以與其他人共享代碼。地址:https://webgpu-playground.netlify.app/。
- WebGPU 文檔:WebGPU 的官方文檔,解釋了 API 的概念、術(shù)語和功能。還可以在 WebGPU 上找到指向其他資源和教程的鏈接。地址:https://gpuweb.github.io/gpuweb/。
- WebGPU 著色語言 (WGSL) 規(guī)范:WGSL 的官方規(guī)范,WebGPU 的著色語言,它定義了 WGSL 的語法、語義和特性。還可以找到指向 WGSL 的其他資源和工具的鏈接。地址:https://gpuweb.github.io/gpuweb/wgsl/。
- WGSL Playground:WGSL 的在線編輯器,可讓在瀏覽器中編寫和運行 WGSL 代碼。還可以與其他人共享代碼。地址:https://timjones.io/wgsl-playground/。
使用這些工具和資源,可以了解有關(guān) WebGPU 的更多信息并創(chuàng)建自己的示例和應(yīng)用。還可以探索其他使用 WebGPU 的示例和項目,例如:
- Babylon.js:一個功能強大且功能豐富的 Web 3D 引擎,支持將 WebGPU 作為渲染后端。官網(wǎng):https://www.babylonjs.com/。
const engine = new BABYLON.WebGPUEngine(canvas);
await engine.initAsync();
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 3, new BABYLON.Vector3(0, 0, 0), scene);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2}, scene);
const material = new BABYLON.StandardMaterial("material", scene);
material.diffuseColor = new BABYLON.Color3(1, 0, 0);
sphere.material = material;
engine.runRenderLoop(() => {
scene.render();
});
- Three.js:一個流行的輕量級 Web 3D 庫,支持將 WebGPU 作為實驗性渲染器。官網(wǎng):https://threejs.org/
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
const renderer = new THREE.WebGPURenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({color: 0x00ff00});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
- Filament:基于物理的實時渲染引擎,適用于 Android、iOS、Windows、Linux、macOS 和 WebGL/WebGPU,支持高質(zhì)量圖形和光照效果。官網(wǎng):https://google.github.io/filament/。
const engine = Filament.Engine.create(canvas);
const scene = engine.createScene();
const camera = engine.createCamera();
const view = engine.createView();
view.setCamera(camera);
view.setScene(scene);
const skybox = engine.createSkyFromKtx('venetian_crossroads_2k_ibl.ktx');
scene.setSkybox(skybox);
const indirectLight = engine.createIblFromKtx('venetian_crossroads_2k_ibl.ktx');
scene.setIndirectLight(indirectLight);
const material = engine.createMaterial('lit.filamat');
const renderable = Filament.EntityManager.get().create();
scene.addEntity(renderable);
Filament.fetch('DamagedHelmet.glb', (buffer) => {
const loader = new Filament.gltfio.AssetLoader(engine);
const asset = loader.createAssetFromBinary(buffer);
loader.delete();
asset.getEntities().forEach((entity) => {
scene.addEntity(entity);
});
});
function render() {
requestAnimationFrame(render);
view.setViewport([0, 0, canvas.width, canvas.height]);
renderer.render(view);
}
render();
- TensorFlow.js:一個用于機器學習的 JavaScript 庫,支持 WebGPU 作為加速計算的后端。官網(wǎng):https://www.tensorflow.org/js/。
import * as tf from '@tensorflow/tfjs';
import '@tensorflow/tfjs-backend-webgpu';
await tf.ready();
tf.setBackend('webgpu');
const a = tf.tensor([1, 2, 3, 4]);
const b = tf.tensor([5, 6, 7, 8]);
const c = a.add(b);
c.print();
這些只是使用 WebGPU 的一些示例和項目。隨著 WebGPU 得到更廣泛的采用和支持們可以期待在未來看到更多使用 WebGPU 的驚人和創(chuàng)新的 Web 應(yīng)用。
小結(jié)
WebGPU 為 Web 平臺上的高級圖形和高性能計算提供了無限可能。盡管目前瀏覽器支持仍然有限,但 WebGPU 在如今是非常值得探索的,并且在未來只會變得更加強大和廣泛支持。Web 作為 3D、可視化、模擬等領(lǐng)域的一個引人注目的選擇繼續(xù)向前發(fā)展。