WebGL geliştiricisi olarak, modern grafik API'lerinin avantajlarını web'e getiren WebGL'nin halefi WebGPU'yu kullanmaya başlamak hem korkutucu hem de heyecan verici olabilir.
WebGL ve WebGPU'nun birçok temel kavrama sahip olduğunu bilmek rahatlatıcıdır. Her iki API de GPU'da gölgelendirici adı verilen küçük programlar çalıştırmanıza olanak tanır. WebGL, köşe ve parça gölgelendiricileri desteklerken WebGPU, hesaplama gölgelendiricilerini de destekler. WebGL, OpenGL Gölgelendirme Dili'ni (GLSL) kullanırken WebGPU, WebGPU Gölgelendirme Dili'ni (WGSL) kullanır. İki dil farklı olsa da temel kavramlar çoğunlukla aynıdır.
Bu makalede, WebGL ve WebGPU arasındaki bazı farklar vurgulanmaktadır.
Global durum
WebGL'de çok sayıda genel durum vardır. Bazı ayarlar (ör. hangi dokuların ve arabelleklerin bağlanacağı) tüm oluşturma işlemleri için geçerlidir. Bu genel durumu çeşitli API işlevlerini çağırarak ayarlarsınız ve siz değiştirene kadar geçerli kalır. WebGL'deki genel durum, genel bir ayarı değiştirmeyi unutmanın kolay olması nedeniyle önemli bir hata kaynağıdır. Ayrıca, geliştiricilerin global durumu yanlışlıkla kodun diğer bölümlerini etkileyecek şekilde değiştirmemeye dikkat etmesi gerektiğinden global durum, kod paylaşımını zorlaştırır.
WebGPU, durum bilgisi olmayan bir API'dir ve genel bir durum bilgisini korumaz. Bunun yerine, WebGL'de küresel olan tüm oluşturma durumunu kapsüllemek için ardışık düzen kavramını kullanır. Bir ardışık düzen, kullanılacak harmanlama, topoloji ve özellikler gibi bilgileri içerir. Ardışık düzen sabittir. Bazı ayarları değiştirmek istiyorsanız başka bir ardışık düzen oluşturmanız gerekir. WebGPU ayrıca, komutları toplu olarak düzenlemek ve bunları kaydedildikleri sırayla yürütmek için komut kodlayıcıları kullanır. Bu, örneğin, nesneler üzerinde tek bir geçişte uygulamanın her ışık gölge haritası için bir tane olmak üzere birden fazla komut akışı kaydedebildiği gölge haritalama işleminde yararlıdır.
Özetlemek gerekirse, WebGL'nin küresel durum modeli güçlü, derlenebilir kitaplıklar ve uygulamalar oluşturmayı zorlaştırır ve kırılgan hale getirirken WebGPU, geliştiricilerin GPU'ya komut gönderirken takip etmesi gereken durum miktarını önemli ölçüde azaltmıştır.
Başka senkronizasyon yok
GPU'larda komut gönderip bunları senkronize olarak beklemek genellikle verimli değildir. Bu işlem, ardışık düzeni temizleyip kabarcıklar oluşmasına neden olabilir. Bu durum özellikle, GPU sürücüsünün JavaScript'ten ayrı bir işlemde çalıştığı çok işlemli bir mimari kullanan WebGPU ve WebGL'de geçerlidir.
Örneğin, WebGL'de gl.getError()
çağrısı için JavaScript işleminden GPU işlemine ve geriye doğru senkronize bir IPC gerekir. Bu durum, iki işlem iletişim kurarken CPU tarafında baloncuk oluşmasına neden olabilir.
Bu baloncukları önlemek için WebGPU tamamen eşzamansız olacak şekilde tasarlanmıştır. Hata modeli ve diğer tüm işlemler eşzamansız olarak gerçekleşir. Örneğin, bir doku oluşturduğunuzda doku aslında bir hata olsa bile işlem hemen başarılı görünür. Hatayı yalnızca eşzamansız olarak keşfedebilirsiniz. Bu tasarım, işlemler arası iletişimi balonsuz tutar ve uygulamalara güvenilir performans sağlar.
İşlem gölgelendiricileri
Compute gölgelendiriciler, genel amaçlı hesaplamalar yapmak için GPU'da çalışan programlardır. Bunlar WebGL'de değil, yalnızca WebGPU'de kullanılabilir.
Nokta ve parçacık gölgelendiricilerden farklı olarak, grafik işlemeyle sınırlı değildir ve makine öğrenimi, fizik simülasyonu ve bilimsel hesaplama gibi çeşitli görevler için kullanılabilir. Bilgisayar gölgelendiricileri yüzlerce hatta binlerce iş parçacığı tarafından paralel olarak yürütülür. Bu da onları büyük veri kümelerini işleme konusunda son derece verimli kılar. GPU hesaplama hakkında daha fazla bilgi edinmek için WebGPU ile ilgili bu kapsamlı makaleyi inceleyin.
Video karesi işleme
JavaScript ve WebAssembly'i kullanarak video karelerini işlemenin bazı dezavantajları vardır: Verileri GPU belleğinden CPU belleğine kopyalamanın maliyeti ve çalışanlar ile CPU iş parçacıkları kullanılarak elde edilebilecek sınırlı paralellik. WebGPU'da bu tür sınırlamalar yoktur. Bu nedenle, WebCodecs API'siyle sıkı entegrasyonu sayesinde video karelerini işlemek için mükemmel bir seçenektir.
Aşağıdaki kod snippet'inde, bir VideoFrame'in WebGPU'da harici bir doku olarak nasıl içe aktarılacağı ve işlenmesi gösterilmektedir. Bu demoyu deneyebilirsiniz.
// 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
}
Varsayılan olarak uygulama taşınabilirliği
WebGPU, sizi limits
isteğinde bulunmaya zorlar. Varsayılan olarak requestDevice()
, fiziksel cihazın donanım özellikleriyle eşleşmeyen bir GPUDevice döndürür. Bunun yerine, tüm GPU'ların makul ve en düşük ortak paydasını döndürür. WebGPU, geliştiricilerin cihaz sınırlarını istemesini zorunlu kılarak uygulamaların mümkün olduğunca çok cihazda çalışmasını sağlar.
Tuvalleri işleme
WebGL bağlamı oluşturduktan ve alpha, antialias, colorSpace, depth, preserveDrawingBuffer veya stencil gibi bağlam özellikleri sağladıktan sonra WebGL, tuvali otomatik olarak yönetir.
Öte yandan WebGPU, tuvali kendinizin yönetmenizi gerektirir. Örneğin, WebGPU'da kenar yumuşatma elde etmek için çok örnekli bir doku oluşturup bu dokuda oluşturma işlemi yaparsınız. Ardından, çok örnekli dokuyu normal bir dokuya çözer ve bu dokuyu tuvale çizersiniz. Bu manuel yönetim, tek bir GPUDevice nesnesinden istediğiniz kadar kanvas oluşturmanıza olanak tanır. Öte yandan, WebGL her tuval için yalnızca bir bağlam oluşturabilir.
WebGPU Çoklu Tuvaller demosuna göz atın.
Ayrıca, tarayıcıların şu anda sayfa başına WebGL tuvali sayısıyla ilgili bir sınırı vardır. Bu makalenin yazıldığı sırada Chrome ve Safari aynı anda en fazla 16 WebGL kanvası kullanabilirken Firefox 200'e kadar kanvas oluşturabilir. Öte yandan, sayfa başına WebGPU kanvası sayısıyla ilgili bir sınırlama yoktur.
Faydalı hata mesajları
WebGPU, API'den döndürülen her mesaj için bir çağrı yığını sağlar. Bu sayede, hatanın kodunuzda nerede oluştuğunu hızlıca görebilirsiniz. Bu, hata ayıklama ve hataları düzeltme konusunda yararlı bir özelliktir.
WebGPU hata mesajları, çağrı yığınının yanı sıra kolay anlaşılır ve uygulanabilirdir. Hata mesajları genellikle hatanın açıklamasını ve hatanın nasıl düzeltileceğine dair öneriler içerir.
WebGPU, her bir WebGPU nesnesi için özel label
sağlamanıza da olanak tanır. Bu etiket daha sonra tarayıcı tarafından GPUError mesajlarında, konsol uyarılarında ve tarayıcı geliştirici araçlarında kullanılır.
Adlardan dizinlere
WebGL'de birçok şey adlarla bağlanır. Örneğin, GLSL'de myUniform
adlı bir tekdüze değişken tanımlayabilir ve gl.getUniformLocation(program, 'myUniform')
kullanarak konumunu alabilirsiniz. Bu, üniforma değişkeninin adını yanlış yazarsanız hata almanız nedeniyle kullanışlıdır.
Öte yandan WebGPU'da her şey bayt uzaklığı veya dizin ile (genellikle location olarak adlandırılır) tamamen birbirine bağlıdır. WGSL ve JavaScript'teki kod konumlarını senkronize tutmanın sorumluluğu size aittir.
Mipmap oluşturma
WebGL'de, bir doku için 0. seviye mip oluşturabilir ve ardından gl.generateMipmap()
işlevini çağırabilirsiniz. WebGL, diğer tüm MIP düzeylerini sizin için oluşturur.
WebGPU'de MIP haritalarını kendiniz oluşturmanız gerekir. Bu işlemi gerçekleştirecek yerleşik bir işlev yoktur. Karar hakkında daha fazla bilgi edinmek için özellik tartışmasına göz atın. MIP haritası oluşturmak için webgpu-utils gibi kullanışlı kitaplıkları kullanabilir veya bunu kendi başınıza nasıl yapacağınızı öğrenebilirsiniz.
Depolama tamponları ve depolama dokuları
Tekdüzen tamponlar hem WebGL hem de WebGPU tarafından desteklenir ve sınırlı boyuttaki sabit parametreleri gölgelendiricilere iletmenize olanak tanır. Tek tip arabelleklere çok benzeyen depolama arabellekleri, yalnızca WebGPU tarafından desteklenir ve tek tip arabelleklerden daha güçlü ve esnektir.
Gölgelendiricilere iletilen depolama arabelleklerindeki veriler, tekdüze arabelleklerden çok daha büyük olabilir. Teknik açıdan tek tip arabellek bağlamalarının boyutunun en fazla 64 KB olabileceği (bkz.
maxUniformBufferBindingSize
) olsa da depolama arabellek bağlamasının maksimum boyutu WebGPU'da en az 128 MB'tır (bkz.maxStorageBufferBindingSize
).Depolama arabellekleri yazılabilirdir ve bazı atomik işlemleri destekler. Tekdüzen arabellekler ise yalnızca salt okunurdur. Bu, yeni algoritma sınıflarının uygulanmasına olanak tanır.
Depolama arabellek bağlamaları, daha esnek algoritmalar için çalışma zamanı boyutundaki dizileri destekler. Gölgelendiricide ise tek tip arabellek dizisi boyutlarının sağlanması gerekir.
Depolama dokuları yalnızca WebGPU'de desteklenir ve depolama arabelleklerinin tekdüze arabelleklere olan ilişkisi gibi dokularla ilişkilidir. Normal dokulardan daha esnektirler ve rastgele erişim yazma işlemlerini (ve gelecekte okuma işlemlerini de) desteklerler.
Arabellek ve doku değişiklikleri
WebGL'de bir arabellek veya doku oluşturabilir ve ardından boyutunu istediğiniz zaman sırasıyla gl.bufferData()
ve gl.texImage2D()
ile değiştirebilirsiniz.
WebGPU'da tamponlar ve dokular değiştirilemez. Bu nedenle, oluşturulduktan sonra boyutlarını, kullanımlarını veya biçimlerini değiştiremezsiniz. Yalnızca içeriklerini değiştirebilirsiniz.
Alan sözleşmesi farklılıkları
WebGL'de Z klip alanı aralığı -1 ile 1 arasındadır. WebGPU'de Z kırpma alanı aralığı 0 ile 1 arasındadır. Bu, z değeri 0 olan nesnelerin kameraya en yakın, z değeri 1 olan nesnelerin ise en uzak olduğu anlamına gelir.
WebGL, Y ekseninin yukarı ve Z ekseninin izleyiciye doğru olduğu OpenGL kuralını kullanır. WebGPU, Y ekseninin aşağı ve Z ekseninin ekranın dışında olduğu Metal kuralını kullanır. Y ekseni yönünün, çerçeve ara belleği koordinatında, görüntü alanı koordinatında ve parça/piksel koordinatında aşağı olduğunu unutmayın. Klip alanında, Y ekseni yönü WebGL'de olduğu gibi yukarı doğrudur.
Teşekkür ederiz
Bu makaleyi inceleyen Corentin Wallez, Gregg Tavares, Stephen White, Ken Russell ve Rachel Andrew'a teşekkür ederiz.
WebGPU ile WebGL arasındaki farklara ayrıntılı bir şekilde göz atmak için WebGPUFundamentals.org adresini de ziyaret edebilirsiniz.