WebGL से WebGPU तक

François Beaufort
François Beaufort

WebGL डेवलपर के रूप में, आपको WebGPU का इस्तेमाल शुरू करने में घबराहट और खुशी हो सकती है. WebGPU, WebGL का सबसे सही वर्शन है, जो वेब पर मॉडर्न ग्राफ़िक एपीआई को बेहतर बनाता है.

हमें यह जानकर भरोसा होता है कि WebGL और WebGPU के कई मुख्य सिद्धांत हैं. दोनों एपीआई, आपको जीपीयू पर शेडर नाम के छोटे प्रोग्राम चलाने की अनुमति देते हैं. WebGL, वर्टेक्स और फ़्रैगमेंट शेडर के साथ काम करता है, जबकि WebGPU, कंप्यूट शेडर के साथ भी काम करता है. WebGL, OpenGL शेडिंग लैंग्वेज (GLSL) का इस्तेमाल करता है, जबकि WebGPU, WebGPU शेडिंग लैंग्वेज (WGSL) का इस्तेमाल करता है. हालांकि, दोनों भाषाएं अलग-अलग हैं, लेकिन बुनियादी कॉन्सेप्ट ज़्यादातर एक जैसे हैं.

इस बात को ध्यान में रखते हुए, यह लेख WebGL और WebGPU के बीच के कुछ अंतरों को हाइलाइट करता है, ताकि आपको इस्तेमाल शुरू करने में मदद मिल सके.

ग्लोबल स्टेट

WebGL में बहुत सी वैश्विक स्थिति मौजूद है. कुछ सेटिंग सभी रेंडरिंग ऑपरेशन पर लागू होती हैं, जैसे कि कौनसी टेक्सचर और बफ़र बाउंड हैं. इस ग्लोबल स्टेट को अलग-अलग एपीआई फ़ंक्शन को कॉल करके सेट किया जाता है. यह स्थिति तब तक लागू रहती है, जब तक इसे बदला नहीं जाता. WebGL में ग्लोबल स्थिति, गड़बड़ियों का मुख्य स्रोत है, क्योंकि ग्लोबल सेटिंग को बदलना भूलना आसान हो जाता है. इसके अलावा, ग्लोबल स्टेट कोड शेयर करना मुश्किल बना देता है, क्योंकि डेवलपर को इस बात का ध्यान रखना चाहिए कि वे ग्लोबल स्टेट को इस तरह न बदलें कि कोड के दूसरे हिस्सों पर असर पड़े.

WebGPU, एक स्टेटलेस एपीआई है और यह किसी ग्लोबल स्टेट का रखरखाव नहीं करता है. इसके बजाय, यह WebGL में वैश्विक रूप से मौजूद रेंडर करने की सभी स्थिति को एनकैप्सुलेट करने के लिए, पाइपलाइन के सिद्धांत का इस्तेमाल करता है. पाइपलाइन में यह जानकारी शामिल होती है कि किस तरह की ब्लेंडिंग, टोपोलॉजी, और एट्रिब्यूट का इस्तेमाल करना है. पाइपलाइन में बदलाव नहीं किया जा सकता. अगर आपको कुछ सेटिंग में बदलाव करना है, तो आपको एक और पाइपलाइन बनानी होगी. WebGPU, कमांड को एक साथ बैच करने और उन्हें रिकॉर्ड किए गए क्रम में एक्ज़ीक्यूट करने के लिए, कमांड एन्कोडर का भी इस्तेमाल करता है. यह शैडो मैपिंग में उपयोगी होता है. उदाहरण के लिए, जहां ऑब्जेक्ट के ऊपर एक ही पास में ऐप्लिकेशन कई कमांड स्ट्रीम रिकॉर्ड कर सकता है. जैसे, हर लाइट के शैडो मैप के लिए एक.

संक्षेप में, WebGL के ग्लोबल स्टेट मॉडल ने मज़बूत, कंपोज़ेबल लाइब्रेरी और ऐप्लिकेशन बनाने को मुश्किल और नाज़ुक बना दिया है, WebGPU ने जीपीयू को निर्देश भेजते समय, डेवलपर के लिए ज़रूरी स्थिति को काफ़ी कम कर दिया.

अब और सिंक न करें

आम तौर पर, जीपीयू पर, निर्देश भेजने और सिंक्रोनस रूप से उनका इंतज़ार करने में मुश्किल होती है. ऐसा इसलिए, क्योंकि इससे पाइपलाइन साफ़ हो सकती है और बबल बन सकता है. खास तौर पर, यह WebGPU और WebGL के मामले में सही है. यहां एक मल्टी-प्रोसेस आर्किटेक्चर का इस्तेमाल किया जाता है, जिसमें जीपीयू ड्राइवर JavaScript से अलग प्रोसेस में चल रहा होता है.

उदाहरण के लिए, WebGL में gl.getError() को कॉल करने के लिए, JavaScript प्रोसेस से जीपीयू प्रोसेस तक सिंक्रोनस IPC की ज़रूरत होती है. इस वजह से, दोनों प्रोसेस के बातचीत करने पर सीपीयू में बबल की समस्या आ सकती है.

इन बबल से बचने के लिए, WebGPU को पूरी तरह से एसिंक्रोनस तरीके से डिज़ाइन किया गया है. गड़बड़ी वाला मॉडल और अन्य सभी कार्रवाइयां, एसिंक्रोनस रूप से होती हैं. उदाहरण के लिए, जब कोई टेक्सचर बनाया जाता है, तो कार्रवाई तुरंत सफल होती है. भले ही, टेक्सचर असल में कोई गड़बड़ी हो. गड़बड़ी का पता सिर्फ़ एसिंक्रोनस तरीके से लगाया जा सकता है. यह डिज़ाइन क्रॉस-प्रोसेस कम्यूनिकेशन को बबल-फ़्री रखता है और ऐप्लिकेशन को भरोसेमंद परफ़ॉर्मेंस देता है.

कंप्यूट शेडर

कंप्यूट शेडर ऐसे प्रोग्राम होते हैं जो अलग-अलग कामों के लिए इस्तेमाल होने वाले कंप्यूटेशन के लिए जीपीयू पर चलते हैं. वे सिर्फ़ WebGPU में उपलब्ध हैं, WebGL नहीं.

वर्टेक्स और फ़्रैगमेंट शेडर से अलग, ये ग्राफ़िक प्रोसेसिंग तक सीमित नहीं हैं. इनका इस्तेमाल मशीन लर्निंग, फ़िज़िक्स सिम्युलेशन, और साइंटिफ़िक कंप्यूटिंग जैसे कई तरह के कामों के लिए किया जा सकता है. कंप्यूट शेडर को सैकड़ों या हज़ारों थ्रेड के साथ-साथ चलाया जाता है. इस वजह से, वे बड़े डेटासेट को प्रोसेस कर सकते हैं. GPU कंप्यूट के बारे में जानें. साथ ही, WebGPU के बारे में ज़्यादा जानकारी देने वाला यह लेख पढ़ें.

वीडियो फ़्रेम प्रोसेस हो रहा है

JavaScript और WebAssembly का इस्तेमाल करके, वीडियो फ़्रेम को प्रोसेस करने में कुछ खामियां हैं. जैसे, जीपीयू मेमोरी से सीपीयू मेमोरी में डेटा कॉपी करने का खर्च. साथ ही, वर्कर और सीपीयू थ्रेड की मदद से मिल सकने वाली सीमित समानता. WebGPU में वे सीमाएं नहीं हैं, क्योंकि WebCodecs API के साथ इसका बेहतरीन इंटिग्रेशन होने की वजह से यह वीडियो फ़्रेम प्रोसेस करने के लिए सबसे सही विकल्प है.

नीचे दिए गए कोड स्निपेट में, 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() एक ऐसा जीपीयू डिवाइस दिखाता है जो हो सकता है कि फ़िज़िकल डिवाइस के हार्डवेयर की क्षमताओं से मेल न खाए. इसके बजाय, यह सभी जीपीयू का एक उचित और सबसे कम कॉमन डिनोमिनेटर दिखाता है. डेवलपर को डिवाइस की तय सीमा से ज़्यादा का अनुरोध करना पड़ता है. इससे WebGPU यह पक्का करता है कि ऐप्लिकेशन ज़्यादा से ज़्यादा डिवाइसों पर चलेंगे.

कैनवस हैंडलिंग

WebGL आपके द्वारा WebGL संदर्भ बनाए जाने और संदर्भ की विशेषताएं जैसे अल्फ़ा, एंटीएलिया, colorSpace, गहराई,,draचिंगBuffer या स्टेन्सिल को अपने आप प्रबंधित कर देता है.

दूसरी ओर, WebGPU के लिए ज़रूरी है कि आप कैनवस को खुद मैनेज करें. उदाहरण के लिए, WebGPU में एंटी-एलियासिंग पाने के लिए, आपको एक मल्टीसैंपल टेक्सचर बनाना होगा और उसे रेंडर करना होगा. इसके बाद, मल्टीसैंपल टेक्सचर को सामान्य टेक्सचर में बदलें और उस टेक्सचर को कैनवस पर खींचें. इस मैन्युअल मैनेजमेंट की मदद से, एक GPUDevice ऑब्जेक्ट से, जितने चाहें उतने कैनवस बनाए जा सकते हैं. वहीं दूसरी ओर, WebGL हर कैनवस के लिए सिर्फ़ एक संदर्भ बना सकता है.

WebGPU के एक से ज़्यादा कैनवस का डेमो देखें.

एक और बात, ब्राउज़र में फ़िलहाल हर पेज के लिए WebGL कैनवस की एक सीमा तय है. लिखते समय, Chrome और Safari एक साथ 16 WebGL कैनवस तक ही उपयोग कर सकते हैं; Firefox उनमें से 200 तक कैनवस बना सकता है. वहीं दूसरी ओर, हर पेज पर WebGPU कैनवस की संख्या की कोई सीमा नहीं है.

Safari, Chrome, और Firefox ब्राउज़र में WebGL कैनवस की ज़्यादा से ज़्यादा संख्या दिखाने वाला स्क्रीनशॉट
Safari, Chrome, और Firefox (बाएं से दाएं) में WebGL कैनवस की ज़्यादा से ज़्यादा संख्या (बाएं से दाएं) - डेमो.

काम की गड़बड़ी के मैसेज

WebGPU, एपीआई से मिलने वाले हर मैसेज के लिए एक कॉल स्टैक उपलब्ध कराता है. इसका मतलब है कि आपके पास तुरंत यह देखने का विकल्प होता है कि आपके कोड में कहां गड़बड़ी हुई है. यह गड़बड़ियों को डीबग करने और ठीक करने में मददगार होती है.

WebGPU में गड़बड़ी के मैसेज मिलने के साथ-साथ, उन्हें आसानी से समझा जा सकता है और उन पर कार्रवाई की जा सकती है. गड़बड़ी के मैसेज में आम तौर पर गड़बड़ी का ब्यौरा और गड़बड़ी को ठीक करने के तरीके के सुझाव शामिल होते हैं.

WebGPU की मदद से, हर WebGPU ऑब्जेक्ट के लिए पसंद के मुताबिक label उपलब्ध कराया जा सकता है. इसके बाद, ब्राउज़र इस लेबल का इस्तेमाल जीपीयू से मिले मैसेज, कंसोल की चेतावनियों, और ब्राउज़र डेवलपर टूल में करता है.

नाम से लेकर इंडेक्स तक

WebGL में, कई चीज़ें नाम से जुड़ी होती हैं. उदाहरण के लिए, जीएलएसएल में myUniform नाम के यूनिफ़ॉर्म वैरिएबल का एलान किया जा सकता है और gl.getUniformLocation(program, 'myUniform') का इस्तेमाल करके इसकी जगह की जानकारी हासिल की जा सकती है. यह उस समय सबसे काम आता है, जब एक जैसे वैरिएबल का नाम गलत टाइप किया जाता है और आपको गड़बड़ी का मैसेज मिलता है.

दूसरी ओर, WebGPU में सब कुछ पूरी तरह से बाइट ऑफ़सेट या इंडेक्स (इसे अक्सर location कहा जाता है) से कनेक्ट होता है. WGSL और JavaScript में कोड के लिए जगहों की जानकारी सिंक रखना आपकी ज़िम्मेदारी है.

Mipmap जनरेशन

WebGL में, आप टेक्स्चर का लेवल 0 mip बना सकते हैं और फिर 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 है, वे कैमरे के सबसे नज़दीक हैं और 1 की वैल्यू वाले ऑब्जेक्ट, कैमरे के सबसे करीब हैं.

WebGL और WebGPU में Z क्लिप स्पेस रेंज का इलस्ट्रेशन.
WebGL और WebGPU में Z क्लिप स्पेस.

WebGL फ़ॉर्मैट में OpenGL कन्वेंशन का इस्तेमाल करता है, जहां Y ऐक्सिस ऊपर होता है और Z ऐक्सिस व्यूअर की तरफ़ होता है. WebGPU में मेटल कन्वेंशन का इस्तेमाल किया जाता है. इसमें Y ऐक्सिस नीचे की ओर और Z ऐक्सिस स्क्रीन से बाहर होते हैं. ध्यान दें कि फ़्रेम बफ़र कोऑर्डिनेट, व्यूपोर्ट कोऑर्डिनेट, और फ़्रैगमेंट/पिक्सल कोऑर्डिनेट में Y ऐक्सिस की दिशा नीचे की ओर होती है. क्लिप स्पेस में, Y ऐक्सिस की दिशा उसी तरह से दिख रही है जैसे WebGL में होता है.

स्वीकार की गई

इस लेख को पढ़ने के लिए, कोरेंटिन वॉलेज़, ग्रेग तवारिस, स्टीफ़न व्हाइट, केन रसेल, और रेचल एंड्रयू का धन्यवाद.

WebGPU और WebGL के बीच के अंतर को अच्छी तरह से समझने के लिए, मेरा सुझाव है कि WebGPUFundamentals.org का इस्तेमाल करें.