WebGL डेवलपर के तौर पर, WebGPU का इस्तेमाल शुरू करने से आपको डर और उत्साह दोनों महसूस हो सकते हैं. WebGPU, WebGL का नया वर्शन है. इसमें वेब पर आधुनिक ग्राफ़िक्स एपीआई की सुविधाएं मिलती हैं.
यह जानकर खुशी होती है कि WebGL और WebGPU में कई बुनियादी कॉन्सेप्ट एक जैसे हैं. दोनों एपीआई की मदद से, GPU पर शेडर नाम के छोटे प्रोग्राम चलाए जा सकते हैं. WebGL, वर्टिक्स और फ़्रैगमेंट शेडर के साथ काम करता है. वहीं, WebGPU, कंप्यूट शेडर के साथ भी काम करता है. WebGL, OpenGL Shading Language (GLSL) का इस्तेमाल करता है, जबकि WebGPU, WebGPU Shading Language (WGSL) का इस्तेमाल करता है. हालांकि, दोनों भाषाएं अलग-अलग हैं, लेकिन इनमें मौजूद कॉन्सेप्ट ज़्यादातर एक जैसे हैं.
इस बात को ध्यान में रखते हुए, इस लेख में WebGL और WebGPU के बीच के कुछ अंतरों के बारे में बताया गया है. इससे आपको इनका इस्तेमाल शुरू करने में मदद मिलेगी.
ग्लोबल स्टेटस
WebGL में बहुत सारी ग्लोबल स्टेटस होती हैं. कुछ सेटिंग, रेंडरिंग के सभी ऑपरेशन पर लागू होती हैं. जैसे, कौनसे टेक्सचर और बफ़र बाउंड किए गए हैं. इस ग्लोबल स्टेटस को सेट करने के लिए, अलग-अलग एपीआई फ़ंक्शन को कॉल किया जाता है. यह तब तक लागू रहता है, जब तक इसे बदला नहीं जाता. WebGL में ग्लोबल स्टेटस, गड़बड़ियों का मुख्य सोर्स होता है. इसकी वजह यह है कि ग्लोबल सेटिंग में बदलाव करना आसानी से भूल जाता है. इसके अलावा, ग्लोबल स्टेट की वजह से कोड शेयर करना मुश्किल हो जाता है. ऐसा इसलिए, क्योंकि डेवलपर को इस बात का ध्यान रखना पड़ता है कि ग्लोबल स्टेट में ऐसा बदलाव न हो जिससे कोड के दूसरे हिस्सों पर असर पड़े.
WebGPU एक स्टेटलेस एपीआई है और यह ग्लोबल स्टेट को मैनेज नहीं करता. इसके बजाय, यह पाइपलाइन के कॉन्सेप्ट का इस्तेमाल करके, WebGL में ग्लोबल तौर पर मौजूद रेंडरिंग स्टेटस को शामिल करता है. पाइपलाइन में, ब्लेंडिंग, टोपोलॉजी, और एट्रिब्यूट के इस्तेमाल से जुड़ी जानकारी होती है. पाइपलाइन में बदलाव नहीं किया जा सकता. अगर आपको कुछ सेटिंग बदलनी हैं, तो आपको एक और पाइपलाइन बनानी होगी. WebGPU, निर्देशों को एक साथ बैच करने और उन्हें उसी क्रम में लागू करने के लिए, कंडेम एन्कोडर का भी इस्तेमाल करता है जिस क्रम में उन्हें रिकॉर्ड किया गया था. यह शैडो मैपिंग में मददगार होता है. उदाहरण के लिए, ऑब्जेक्ट पर एक बार में, ऐप्लिकेशन कई कमांड स्ट्रीम रिकॉर्ड कर सकता है. हर लाइट के शैडो मैप के लिए एक स्ट्रीम.
खास जानकारी के तौर पर, WebGL के ग्लोबल स्टेट मॉडल की वजह से, मज़बूत और कॉम्पोज़ की जा सकने वाली लाइब्रेरी और ऐप्लिकेशन बनाना मुश्किल और संवेदनशील हो गया था. वहीं, WebGPU ने स्टेट की संख्या को काफ़ी कम कर दिया है. इसकी वजह से, डेवलपर को GPU को निर्देश भेजते समय स्टेट पर नज़र रखने की ज़रूरत नहीं पड़ती.
अब सिंक न करें
आम तौर पर, जीपीयू पर निर्देश भेजने और उनके सिंक होने का इंतज़ार करने की प्रोसेस में ज़्यादा समय लगता है. इसकी वजह यह है कि इससे पाइपलाइन फ़्लश हो सकती है और बबल बन सकते हैं. यह बात खास तौर पर WebGPU और WebGL के लिए सही है. ये कई प्रोसेस वाले आर्किटेक्चर का इस्तेमाल करते हैं. इसमें GPU ड्राइवर, JavaScript से अलग प्रोसेस में चलता है.
उदाहरण के लिए, WebGL में gl.getError()
को कॉल करने के लिए, JavaScript प्रोसेस से GPU प्रोसेस और वापस JavaScript प्रोसेस में सिंक्रोनस IPC की ज़रूरत होती है. दोनों प्रोसेस के बीच कम्यूनिकेशन होने की वजह से, सीपीयू साइड पर बबल बन सकता है.
इन बबल से बचने के लिए, WebGPU को पूरी तरह से असाइनोक्रोनस बनाया गया है. गड़बड़ी का मॉडल और अन्य सभी कार्रवाइयां, एक साथ नहीं होतीं. उदाहरण के लिए, कोई टेक्स्चर बनाने पर, ऐसा लगता है कि वह तुरंत बन गया है. भले ही, असल में टेक्स्चर में कोई गड़बड़ी हो. गड़बड़ी का पता सिर्फ़ असिंक्रोनस तरीके से लगाया जा सकता है. इस डिज़ाइन की मदद से, अलग-अलग प्रोसेस के बीच कम्यूनिकेशन को आसानी से मैनेज किया जा सकता है. साथ ही, ऐप्लिकेशन की परफ़ॉर्मेंस भी बेहतर होती है.
कंप्यूट शेडर
कंप्यूट शेडर ऐसे प्रोग्राम होते हैं जो सामान्य काम के लिए गणना करने के लिए, जीपीयू पर चलते हैं. ये सिर्फ़ WebGPU में उपलब्ध हैं, WebGL में नहीं.
वेरटेक्स और फ़्रैगमेंट शेडर के उलट, ये सिर्फ़ ग्राफ़िक्स प्रोसेसिंग तक सीमित नहीं हैं. इनका इस्तेमाल कई तरह के टास्क के लिए किया जा सकता है. जैसे, मशीन लर्निंग, फ़िज़िक्स सिम्युलेशन, और साइंटिफ़िक कंप्यूटिंग. कंप्यूट शेडर, सैकड़ों या हज़ारों थ्रेड के साथ एक साथ काम करते हैं. इस वजह से, ये बड़े डेटासेट को प्रोसेस करने में काफ़ी असरदार होते हैं. GPU कंप्यूट के बारे में ज़्यादा जानने के लिए, WebGPU के बारे में इस लेख को पढ़ें.
वीडियो फ़्रेम प्रोसेस करना
JavaScript और WebAssembly का इस्तेमाल करके वीडियो फ़्रेम प्रोसेस करने में कुछ समस्याएं आती हैं: डेटा को जीपीयू मेमोरी से सीपीयू मेमोरी में कॉपी करने में लगने वाला समय और वर्कर्स और सीपीयू थ्रेड की मदद से सीमित पैरलल प्रोसेसिंग. WebGPU में ये सीमाएं नहीं हैं. इसलिए, यह वीडियो फ़्रेम को प्रोसेस करने के लिए बेहतरीन है. इसकी वजह यह है कि यह WebCodecs एपीआई के साथ बेहतर तरीके से इंटिग्रेट होता है.
नीचे दिए गए कोड स्निपेट में, WebGPU में किसी VideoFrame को बाहरी टेक्सचर के तौर पर इंपोर्ट करने और उसे प्रोसेस करने का तरीका बताया गया है. इस डेमो को आज़माएं.
// 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
}
डिफ़ॉल्ट रूप से ऐप्लिकेशन को एक डिवाइस से दूसरे डिवाइस पर ले जाने की सुविधा
WebGPU, limits
का अनुरोध करने के लिए मजबूर करता है. डिफ़ॉल्ट रूप से, requestDevice()
एक ऐसा GPUDevice दिखाता है जो हो सकता है कि फ़िज़िकल डिवाइस के हार्डवेयर की क्षमताओं से मेल न खाए. हालांकि, यह सभी जीपीयू के लिए एक सही और कम से कम कॉमन डेनोमिनेटर होता है. डेवलपर को डिवाइस की सीमाओं का अनुरोध करने की ज़रूरत होती है. इससे WebGPU यह पक्का करता है कि ऐप्लिकेशन ज़्यादा से ज़्यादा डिवाइसों पर चल सकें.
कैनवस मैनेज करना
WebGL कॉन्टेक्स्ट बनाने और alpha, antialias, colorSpace, depth, preserveDrawingBuffer या स्टेंसिल जैसे कॉन्टेक्स्ट एट्रिब्यूट देने के बाद, WebGL कैनवस को अपने-आप मैनेज करता है.
दूसरी ओर, WebGPU में कैनवस को खुद मैनेज करना पड़ता है. उदाहरण के लिए, WebGPU में ऐंटी-ऐलिऐसिंग (ऐलिऐसिंग को कम करने की तकनीक) का इस्तेमाल करने के लिए, आपको मल्टीसैंपल टेक्सचर बनाना होगा और उसे रेंडर करना होगा. इसके बाद, मल्टीसैंपल टेक्सचर को रेगुलर टेक्सचर में बदलें और उस टेक्सचर को कैनवस पर ड्रॉ करें. मैन्युअल मैनेजमेंट की मदद से, एक ही GPUDevice ऑब्जेक्ट से जितने चाहें उतने कैनवस पर आउटपुट किया जा सकता है. इसके उलट, WebGL हर कैनवस के लिए सिर्फ़ एक कॉन्टेक्स्ट बना सकता है.
WebGPU के कई कैनवस के डेमो को देखें.
ध्यान दें कि फ़िलहाल, ब्राउज़र में हर पेज पर WebGL कैनवस की संख्या सीमित होती है. फ़िलहाल, Chrome और Safari एक साथ सिर्फ़ 16 WebGL कैनवस का इस्तेमाल कर सकते हैं. वहीं, Firefox 200 तक कैनवस बना सकता है. वहीं, हर पेज पर WebGPU कैनवस की संख्या पर कोई सीमा नहीं है.
गड़बड़ी के काम के मैसेज
WebGPU, एपीआई से मिले हर मैसेज के लिए कॉल स्टैक उपलब्ध कराता है. इसका मतलब है कि आपके पास यह देखने का विकल्प है कि आपके कोड में गड़बड़ी कहां हुई है. यह जानकारी, गड़बड़ियों को डीबग करने और उन्हें ठीक करने में काम की होती है.
कॉल स्टैक उपलब्ध कराने के अलावा, WebGPU के गड़बड़ी के मैसेज को समझना और उन पर कार्रवाई करना भी आसान है. आम तौर पर, गड़बड़ी के मैसेज में गड़बड़ी की जानकारी और उसे ठीक करने के सुझाव शामिल होते हैं.
WebGPU की मदद से, हर WebGPU ऑब्जेक्ट के लिए पसंद के मुताबिक label
भी दिया जा सकता है. इसके बाद, ब्राउज़र इस लेबल का इस्तेमाल GPUError मैसेज, कंसोल की चेतावनियों, और ब्राउज़र डेवलपर टूल में करता है.
नामों से इंडेक्स तक
WebGL में, कई चीज़ें नाम से जुड़ी होती हैं. उदाहरण के लिए, GLSL में myUniform
नाम का यूनिफ़ॉर्म वैरिएबल तय किया जा सकता है और gl.getUniformLocation(program, 'myUniform')
का इस्तेमाल करके उसकी जगह की जानकारी पाई जा सकती है. यह सुविधा तब काम आती है, जब यूनिफ़ॉर्म वैरिएबल का नाम गलत तरीके से टाइप किया जाता है.
दूसरी ओर, WebGPU में, सब कुछ पूरी तरह से बाइट ऑफ़सेट या इंडेक्स से जुड़ा होता है. इसे अक्सर जगह कहा जाता है. WGSL और JavaScript में कोड की जगहों को सिंक रखना आपकी ज़िम्मेदारी है.
मिपमैप जनरेट करना
WebGL में, टेक्सचर का लेवल 0 एमआईपी बनाया जा सकता है और फिर gl.generateMipmap()
को कॉल किया जा सकता है. इसके बाद, WebGL आपके लिए अन्य सभी एमआईपी लेवल जनरेट करेगा.
WebGPU में, आपको खुद ही मिपमैप जनरेट करने होंगे. ऐसा करने के लिए, कोई बिल्ट-इन फ़ंक्शन उपलब्ध नहीं है. फ़ैसले के बारे में ज़्यादा जानने के लिए, स्पेसिफ़िकेशन की चर्चा देखें. एमआईपीमैप जनरेट करने के लिए, webgpu-utils जैसी लाइब्रेरी का इस्तेमाल किया जा सकता है. इसके अलावा, खुद भी यह तरीका सीखा जा सकता है.
स्टोरेज बफ़र और स्टोरेज टेक्सचर
यूनिफ़ॉर्म बफ़र, WebGL और WebGPU, दोनों के साथ काम करते हैं. साथ ही, इनकी मदद से शेडर में सीमित साइज़ के कॉन्सटैंट पैरामीटर पास किए जा सकते हैं. स्टोरेज बफ़र, यूनिफ़ॉर्म बफ़र से काफ़ी मिलते-जुलते हैं. ये सिर्फ़ WebGPU पर काम करते हैं. साथ ही, ये यूनिफ़ॉर्म बफ़र से ज़्यादा बेहतर और सुविधाजनक होते हैं.
शेडर को भेजा गया स्टोरेज बफ़र डेटा, यूनिफ़ॉर्म बफ़र से काफ़ी बड़ा हो सकता है. स्पेसिफ़िकेशन के मुताबिक, यूनिफ़ॉर्म बफ़र बाइंडिंग का साइज़ 64 केबी तक हो सकता है (
maxUniformBufferBindingSize
देखें). हालांकि, WebGPU में स्टोरेज बफ़र बाइंडिंग का ज़्यादा से ज़्यादा साइज़ कम से कम 128 एमबी होता है (maxStorageBufferBindingSize
देखें).स्टोरेज बफ़र में डेटा लिखा जा सकता है और कुछ परमाणु ऑपरेशन किए जा सकते हैं. वहीं, यूनिफ़ॉर्म बफ़र सिर्फ़ पढ़ने के लिए होते हैं. इससे, एल्गोरिदम की नई क्लास लागू की जा सकती हैं.
स्टोरेज बफ़र बाइंडिंग, ज़्यादा सुविधाजनक एल्गोरिदम के लिए रनटाइम साइज़ वाले ऐरे के साथ काम करती हैं. वहीं, यूनिफ़ॉर्म बफ़र ऐरे के साइज़ को शेडर में देना होता है.
स्टोरेज टेक्सचर सिर्फ़ WebGPU में काम करते हैं. ये टेक्सचर के लिए वैसे ही हैं जैसे स्टोरेज बफ़र, यूनिफ़ॉर्म बफ़र के लिए होते हैं. ये सामान्य टेक्सचर के मुकाबले ज़्यादा फ़्लेक्सिबल होते हैं. साथ ही, ये रैंडम ऐक्सेस राइटिंग (और आने वाले समय में रीडिंग) के साथ काम करते हैं.
बफ़र और टेक्स्चर में बदलाव
WebGL में, बफ़र या टेक्स्चर बनाया जा सकता है. इसके बाद, gl.bufferData()
और gl.texImage2D()
का इस्तेमाल करके, किसी भी समय इसका साइज़ बदला जा सकता है.
WebGPU में, बफ़र और टेक्सचर में बदलाव नहीं किया जा सकता. इसका मतलब है कि इन्हें बनाने के बाद, इनका साइज़, इस्तेमाल या फ़ॉर्मैट नहीं बदला जा सकता. आपके पास सिर्फ़ उनके कॉन्टेंट में बदलाव करने का विकल्प होता है.
स्पेस के कॉन्फ़्रेंस में अंतर
WebGL में, Z क्लिप स्पेस की रेंज -1 से 1 तक होती है. WebGPU में, Z क्लिप स्पेस की रेंज 0 से 1 तक होती है. इसका मतलब है कि z वैल्यू 0 वाले ऑब्जेक्ट, कैमरे के सबसे नज़दीक होते हैं. वहीं, z वैल्यू 1 वाले ऑब्जेक्ट सबसे दूर होते हैं.
WebGL, OpenGL कन्वेंशन का इस्तेमाल करता है. इसमें Y ऐक्सिस ऊपर की ओर और Z ऐक्सिस दर्शक की ओर होता है. WebGPU, Metal कन्वेंशन का इस्तेमाल करता है. इसमें Y ऐक्सिस नीचे की ओर और Z ऐक्सिस स्क्रीन से बाहर होता है. ध्यान दें कि फ़्रेमबफ़र कोऑर्डिनेट, व्यूपोर्ट कोऑर्डिनेट, और फ़्रैगमेंट/पिक्सल कोऑर्डिनेट में Y ऐक्सिस की दिशा नीचे की ओर होती है. क्लिप स्पेस में, Y ऐक्सिस की दिशा अब भी WebGL की तरह ऊपर की ओर है.
आभार
इस लेख की समीक्षा करने के लिए, Corentin Wallez, Gregg Tavares, Stephen White, Ken Russell, और Rachel Andrew का धन्यवाद.
हमारा सुझाव है कि WebGPU और WebGL के बीच के अंतर के बारे में ज़्यादा जानने के लिए, WebGPUFundamentals.org पर जाएं.