Sebagai developer WebGL, Anda mungkin merasa takut dan bersemangat untuk mulai menggunakan WebGPU, penerus WebGL yang menghadirkan perkembangan API grafis modern ke web.
Sangat meyakinkan mengetahui bahwa WebGL dan WebGPU memiliki banyak konsep inti yang sama. Kedua API ini memungkinkan Anda menjalankan program kecil yang disebut shader di GPU. WebGL mendukung shader verteks dan fragmen, sedangkan WebGPU juga mendukung shader komputasi. WebGL menggunakan OpenGL Shading Language (GLSL), sedangkan WebGPU menggunakan WebGPU Shading Language (WGSL). Meskipun kedua bahasa ini berbeda, konsep dasarnya sebagian besar sama.
Dengan mempertimbangkan hal itu, artikel ini menyoroti beberapa perbedaan antara WebGL dan WebGPU, untuk membantu Anda memulai.
Status global
WebGL memiliki banyak status global. Beberapa setelan berlaku untuk semua operasi rendering, seperti tekstur dan buffer mana yang terikat. Anda menetapkan status global ini dengan memanggil berbagai fungsi API, dan status tersebut akan tetap berlaku hingga Anda mengubahnya. Status global di WebGL adalah sumber utama error, karena mudah lupa untuk mengubah setelan global. Selain itu, status global membuat berbagi kode menjadi sulit, karena developer harus berhati-hati agar tidak secara tidak sengaja mengubah status global dengan cara yang memengaruhi bagian kode lainnya.
WebGPU adalah API stateless, dan tidak mempertahankan status global. Sebagai gantinya, konsep pipeline digunakan untuk merangkum semua status rendering yang bersifat global di WebGL. Pipeline berisi informasi seperti gabungan, topologi, dan atribut yang akan digunakan. Pipeline tidak dapat diubah. Jika ingin mengubah beberapa setelan, Anda harus membuat pipeline lain. WebGPU juga menggunakan encoder perintah untuk mengelompokkan perintah dan mengeksekusinya dalam urutan yang direkam. Hal ini berguna dalam pemetaan bayangan, misalnya, di mana dalam satu kali melewati objek, aplikasi dapat merekam beberapa aliran perintah, satu untuk setiap peta bayangan cahaya.
Singkatnya, karena model status global WebGL membuat pembuatan library dan aplikasi yang kuat dan dapat dikomposisikan menjadi sulit dan rentan, WebGPU secara signifikan mengurangi jumlah status yang perlu dilacak oleh developer saat mengirim perintah ke GPU.
Tidak ada lagi sinkronisasi
Di GPU, pengiriman perintah dan penungguannya secara sinkron biasanya tidak efisien, karena dapat mengosongkan pipeline dan menyebabkan gelembung. Hal ini terutama berlaku di WebGPU dan WebGL, yang menggunakan arsitektur multi-proses dengan driver GPU yang berjalan dalam proses terpisah dari JavaScript.
Misalnya, di WebGL, memanggil gl.getError()
memerlukan IPC sinkron dari proses JavaScript ke proses GPU dan kembali. Hal ini dapat menyebabkan gelembung di sisi CPU saat kedua proses berkomunikasi.
Untuk menghindari gelembung ini, WebGPU didesain agar sepenuhnya asinkron. Model error dan semua operasi lainnya terjadi secara asinkron. Misalnya, saat Anda membuat tekstur, operasi akan langsung berhasil, meskipun tekstur sebenarnya adalah error. Anda hanya dapat menemukan error secara asinkron. Desain ini membuat komunikasi lintas proses bebas dari bubble dan memberikan performa yang andal untuk aplikasi.
Shader komputasi
Shader komputasi adalah program yang berjalan di GPU untuk melakukan komputasi tujuan umum. Fitur ini hanya tersedia di WebGPU, bukan WebGL.
Tidak seperti shader verteks dan fragmen, shader ini tidak terbatas pada pemrosesan grafis, dan dapat digunakan untuk berbagai tugas, seperti machine learning, simulasi fisika, dan komputasi ilmiah. Shader komputasi dieksekusi secara paralel oleh ratusan atau bahkan ribuan thread, sehingga sangat efisien untuk memproses set data besar. Pelajari komputasi GPU dan detail selengkapnya dalam artikel komprehensif tentang WebGPU ini.
Pemrosesan frame video
Memproses frame video menggunakan JavaScript dan WebAssembly memiliki beberapa kekurangan: biaya penyalinan data dari memori GPU ke memori CPU, dan paralelisme terbatas yang dapat dicapai dengan pekerja dan thread CPU. WebGPU tidak memiliki batasan tersebut, sehingga sangat cocok untuk memproses frame video berkat integrasinya yang erat dengan API WebCodecs.
Cuplikan kode berikut menunjukkan cara mengimpor VideoFrame sebagai tekstur eksternal di WebGPU dan memprosesnya. Anda dapat mencoba demo ini.
// Init WebGPU device and pipeline...
// Configure canvas context...
// Feed camera stream to video...
(function render() {
const videoFrame = new VideoFrame(video);
applyFilter(videoFrame);
requestAnimationFrame(render);
})();
function applyFilter(videoFrame) {
const texture = device.importExternalTexture({ source: videoFrame });
const bindgroup = device.createBindGroup({
layout: pipeline.getBindGroupLayout(0),
entries: [{ binding: 0, resource: texture }],
});
// Finally, submit commands to GPU
}
Portabilitas aplikasi secara default
WebGPU mengharuskan Anda meminta limits
. Secara default, requestDevice()
menampilkan GPUDevice yang mungkin tidak cocok dengan kemampuan hardware perangkat fisik, tetapi lebih cocok dengan penyebut umum terendah dan wajar dari semua GPU. Dengan mewajibkan developer meminta batas perangkat, WebGPU memastikan bahwa aplikasi akan berjalan di sebanyak mungkin perangkat.
Penanganan kanvas
WebGL otomatis mengelola kanvas setelah Anda membuat konteks WebGL dan menyediakan atribut konteks seperti alpha, antialias, colorSpace, depth, preserveDrawingBuffer, atau stencil.
Di sisi lain, WebGPU mengharuskan Anda mengelola kanvas sendiri. Misalnya, untuk mencapai antialiasing di WebGPU, Anda akan membuat tekstur multisample dan merendernya. Kemudian, Anda akan menyelesaikan tekstur multisample ke tekstur biasa dan menggambar tekstur tersebut ke kanvas. Pengelolaan manual ini memungkinkan Anda menghasilkan output ke sebanyak kanvas yang Anda inginkan dari satu objek GPUDevice. Sebaliknya, WebGL hanya dapat membuat satu konteks per kanvas.
Lihat demo WebGPU Multiple Canvases.
Sebagai catatan tambahan, browser saat ini memiliki batasan jumlah kanvas WebGL per halaman. Pada saat penulisan, Chrome dan Safari hanya dapat menggunakan hingga 16 kanvas WebGL secara bersamaan; Firefox dapat membuat hingga 200 kanvas. Di sisi lain, tidak ada batasan jumlah kanvas WebGPU per halaman.

Pesan error yang bermanfaat
WebGPU menyediakan stack panggilan untuk setiap pesan yang ditampilkan dari API. Artinya, Anda dapat dengan cepat melihat lokasi terjadinya error dalam kode, yang berguna untuk men-debug dan memperbaiki error.
Selain menyediakan stack panggilan, pesan error WebGPU juga mudah dipahami dan dapat ditindaklanjuti. Pesan error biasanya menyertakan deskripsi error dan saran tentang cara memperbaiki error tersebut.
WebGPU juga memungkinkan Anda menyediakan label
kustom untuk setiap objek WebGPU. Label ini kemudian digunakan oleh browser dalam pesan GPUError, peringatan konsol, dan alat developer browser.
Dari nama ke indeks
Di WebGL, banyak hal yang terhubung berdasarkan nama. Misalnya, Anda dapat mendeklarasikan variabel seragam bernama myUniform
di GLSL dan mendapatkan lokasinya menggunakan gl.getUniformLocation(program, 'myUniform')
. Hal ini berguna karena Anda akan mendapatkan error jika salah mengetik nama variabel seragam.
Di sisi lain, di WebGPU, semuanya terhubung sepenuhnya berdasarkan offset atau indeks byte (sering disebut lokasi). Anda bertanggung jawab untuk menyinkronkan lokasi kode di WGSL dan JavaScript.
Pembuatan mipmap
Di WebGL, Anda dapat membuat mip level 0 tekstur, lalu memanggil gl.generateMipmap()
. Kemudian, WebGL akan membuat semua level mip lainnya untuk Anda.
Di WebGPU, Anda harus membuat mipmap sendiri. Tidak ada fungsi bawaan untuk melakukan hal ini. Lihat diskusi spesifikasi untuk mempelajari lebih lanjut keputusan tersebut. Anda dapat menggunakan library praktis seperti webgpu-utils untuk membuat mipmap atau mempelajari cara melakukannya sendiri.
Buffer penyimpanan dan tekstur penyimpanan
Buffer seragam didukung oleh WebGL dan WebGPU, serta memungkinkan Anda meneruskan parameter konstan berukuran terbatas ke shader. Buffer penyimpanan, yang sangat mirip dengan buffer uniform, hanya didukung oleh WebGPU dan lebih andal serta fleksibel daripada buffer uniform.
Data buffer penyimpanan yang diteruskan ke shader dapat jauh lebih besar daripada buffer seragam. Meskipun spesifikasi menyatakan bahwa binding buffer seragam dapat berukuran hingga 64 KB (lihat
maxUniformBufferBindingSize
) , ukuran maksimum binding buffer penyimpanan setidaknya 128 MB di WebGPU (lihatmaxStorageBufferBindingSize
).Buffer penyimpanan dapat ditulis, dan mendukung beberapa operasi atomik, sedangkan buffer seragam hanya bersifat baca saja. Hal ini memungkinkan penerapan algoritma baru.
Binding buffer penyimpanan mendukung array berukuran runtime untuk algoritma yang lebih fleksibel, sementara ukuran array buffer uniform harus disediakan di shader.
Tekstur penyimpanan hanya didukung di WebGPU, dan merupakan tekstur yang sama dengan buffer penyimpanan untuk buffer seragam. Tekstur ini lebih fleksibel daripada tekstur biasa, mendukung penulisan akses acak (dan pembacaan juga pada masa mendatang).
Perubahan buffer dan tekstur
Di WebGL, Anda dapat membuat buffer atau tekstur, lalu mengubah ukurannya kapan saja dengan gl.bufferData()
dan gl.texImage2D()
.
Di WebGPU, buffer dan tekstur tidak dapat diubah. Artinya, Anda tidak dapat mengubah ukuran, penggunaan, atau formatnya setelah dibuat. Anda hanya dapat mengubah isinya.
Perbedaan konvensi spasi
Di WebGL, rentang ruang klip Z adalah dari -1 hingga 1. Di WebGPU, rentang ruang klip Z adalah dari 0 hingga 1. Artinya, objek dengan nilai z 0 adalah yang paling dekat dengan kamera, sedangkan objek dengan nilai z 1 adalah yang paling jauh.
WebGL menggunakan konvensi OpenGL, dengan sumbu Y ke atas dan sumbu Z ke arah penampil. WebGPU menggunakan konvensi Metal, dengan sumbu Y ke bawah dan sumbu Z keluar dari layar. Perhatikan bahwa arah sumbu Y adalah ke bawah dalam koordinat framebuffer, koordinat viewport, dan koordinat fragmen/piksel. Di ruang klip, arah sumbu Y tetap ke atas seperti di WebGL.
Ucapan terima kasih
Terima kasih kepada Corentin Wallez, Gregg Tavares, Stephen White, Ken Russell, dan Rachel Andrew yang telah meninjau artikel ini.
Saya juga merekomendasikan WebGPUFundamentals.org untuk mempelajari perbedaan antara WebGPU dan WebGL secara mendalam.