بصفتك مطوّر WebGL، قد تشعر بالرهبة والحماس لبدء استخدام WebGPU، وهي الإصدار الأحدث من WebGL الذي يقدّم مزايا واجهات برمجة تطبيقات الرسومات الحديثة على الويب.
من المطمئن معرفة أنّ WebGL وWebGPU تشتركان في العديد من المفاهيم الأساسية. تتيح لك كلتا واجهتَي برمجة التطبيقات تشغيل برامج صغيرة تُعرف باسم برامج التظليل على وحدة معالجة الرسومات. تتيح WebGL استخدام برامج تظليل الرؤوس والكسور، بينما تتيح WebGPU أيضًا استخدام برامج تظليل الحوسبة. تستخدم WebGL لغة OpenGL Shading Language (GLSL)، بينما تستخدم WebGPU لغة WebGPU Shading Language (WGSL). على الرغم من اختلاف اللغتَين، فإنّ المفاهيم الأساسية متشابهة في الغالب.
مع أخذ ذلك في الاعتبار، تسلّط هذه المقالة الضوء على بعض الاختلافات بين WebGL وWebGPU لمساعدتك في البدء.
الحالة العامة
تتضمّن WebGL الكثير من الحالة العامة. تنطبق بعض الإعدادات على جميع عمليات العرض، مثل أنواع النسيج والمخازن المؤقتة التي يتم ربطها. يمكنك ضبط هذه الحالة العامة من خلال استدعاء وظائف مختلفة في واجهة برمجة التطبيقات، وستظل سارية إلى أن تغيّرها. تُعدّ الحالة العامة في WebGL مصدرًا رئيسيًا للأخطاء، إذ من السهل نسيان تغيير إعداد عام. بالإضافة إلى ذلك، تجعل الحالة العامة مشاركة الرموز البرمجية أمرًا صعبًا، إذ يجب على المطوّرين توخّي الحذر لعدم تغيير الحالة العامة عن طريق الخطأ بطريقة تؤثّر في أجزاء أخرى من الرمز البرمجي.
WebGPU هي واجهة برمجة تطبيقات غير مرتبطة بحالة، ولا تحتفظ بحالة عامة. بدلاً من ذلك، تستخدم WebGPU مفهوم خط الأنابيب لتغليف كل حالة العرض التي كانت عامة في WebGL. تحتوي سلسلة المعالجة على معلومات مثل نوع الدمج والطوبولوجيا والسمات التي سيتم استخدامها. لا يمكن تغيير مسار العرض. إذا أردت تغيير بعض الإعدادات، عليك إنشاء مسار معالجة آخر. تستخدم WebGPU أيضًا أدوات ترميز الأوامر لتجميع الأوامر وتنفيذها بالترتيب الذي تم تسجيلها به. ويكون ذلك مفيدًا في عملية ربط الظلال مثلاً، حيث يمكن للتطبيق تسجيل عدة سلاسل أوامر في عملية واحدة على العناصر، واحدة لكل خريطة ظل.
باختصار، بما أنّ نموذج الحالة العامة في WebGL جعل إنشاء مكتبات وتطبيقات قوية وقابلة للتركيب أمرًا صعبًا وهشًا، قلّل WebGPU بشكل كبير من مقدار الحالة التي يحتاج المطوّرون إلى تتبّعها أثناء إرسال الأوامر إلى وحدة معالجة الرسومات.
إيقاف المزامنة
على وحدات معالجة الرسومات، يكون إرسال الأوامر وانتظارها بشكل متزامن غير فعّال عادةً، لأنّ ذلك قد يؤدي إلى إفراغ خط الأنابيب وتكوين فقاعات. وينطبق ذلك بشكل خاص على WebGPU وWebGL اللذين يستخدمان بنية متعددة العمليات مع برنامج تشغيل وحدة معالجة الرسومات الذي يعمل في عملية منفصلة عن JavaScript.
في WebGL مثلاً، يتطلّب استدعاء gl.getError()
إجراء اتصال بين العمليات (IPC) متزامن من عملية JavaScript إلى عملية وحدة معالجة الرسومات (GPU) والعودة. يمكن أن يؤدي ذلك إلى حدوث فقاعة على مستوى وحدة المعالجة المركزية أثناء تواصل العمليتَين.
لتجنُّب هذه الفقاعات، تم تصميم WebGPU ليكون غير متزامن تمامًا. يتم تنفيذ نموذج الخطأ وجميع العمليات الأخرى بشكل غير متزامن. على سبيل المثال، عند إنشاء نسيج، يبدو أنّ العملية قد نجحت على الفور، حتى إذا كان النسيج في الواقع خطأ. يمكنك رصد الخطأ بشكل غير متزامن فقط. يحافظ هذا التصميم على خلوّ فقاعة التواصل بين العمليات من الأخطاء ويمنح التطبيقات أداءً موثوقًا به.
برامج التظليل الحسابية
برامج تظليل الحوسبة هي برامج يتم تشغيلها على وحدة معالجة الرسومات لإجراء عمليات حسابية للأغراض العامة. تتوفّر هذه الميزات في WebGPU فقط، وليس في WebGL.
وعلى عكس برامج تظليل الرؤوس وبرامج تظليل الأجزاء، لا تقتصر على معالجة الرسومات، ويمكن استخدامها في مجموعة متنوعة من المهام، مثل التعلّم الآلي ومحاكاة الفيزياء والحوسبة العلمية. يتم تنفيذ برامج التظليل الحسابية بالتوازي من خلال مئات أو حتى آلاف سلاسل التعليمات، ما يجعلها فعّالة جدًا في معالجة مجموعات البيانات الكبيرة. يمكنك الاطّلاع على معلومات حول حساب وحدة معالجة الرسومات ومزيد من التفاصيل في هذه المقالة الشاملة حول WebGPU.
معالجة إطار الفيديو
تتضمّن معالجة لقطات الفيديو باستخدام JavaScript وWebAssembly بعض العيوب، مثل تكلفة نسخ البيانات من ذاكرة وحدة معالجة الرسومات إلى ذاكرة وحدة المعالجة المركزية، والتوازي المحدود الذي يمكن تحقيقه باستخدام العاملين وthreads في وحدة المعالجة المركزية. لا تتضمّن WebGPU هذه القيود، ما يجعلها مناسبة جدًا لمعالجة إطارات الفيديو بفضل تكاملها الوثيق مع واجهة برمجة التطبيقات WebCodecs.
يوضّح مقتطف الرمز البرمجي التالي كيفية استيراد VideoFrame كنسيج خارجي في WebGPU ومعالجته. يمكنك تجربة هذا العرض التوضيحي.
// 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 إدارة لوحة الرسم تلقائيًا بعد إنشاء سياق WebGL وتوفير سمات السياق، مثل alpha أو antialias أو colorSpace أو depth أو preserveDrawingBuffer أو stencil.
من ناحية أخرى، تتطلّب WebGPU منك إدارة لوحة العرض بنفسك. على سبيل المثال، لتحقيق التنعيم في WebGPU، عليك إنشاء نسيج متعدد العينات وعرضه. بعد ذلك، عليك تحويل نسيج العيّنات المتعددة إلى نسيج عادي ورسم هذا النسيج على لوحة الرسم. تتيح لك هذه الإدارة اليدوية إخراج المحتوى إلى أي عدد تريده من لوحات العرض من عنصر GPUDevice واحد. في المقابل، يمكن لـ WebGL إنشاء سياق واحد فقط لكل لوحة عرض.
يمكنك الاطّلاع على العرض التوضيحي الخاص بلوحات متعدّدة في WebGPU.
تجدر الإشارة إلى أنّ المتصفّحات تفرض حاليًا حدًا أقصى لعدد لوحات WebGL لكل صفحة. في وقت كتابة هذا المقال، يمكن لمتصفّحَي Chrome وSafari استخدام ما يصل إلى 16 لوحة WebGL في الوقت نفسه، بينما يمكن لمتصفّح Firefox إنشاء ما يصل إلى 200 لوحة. من ناحية أخرى، ما مِن حدّ أقصى لعدد لوحات العرض في WebGPU لكل صفحة.

رسائل الخطأ المفيدة
توفّر WebGPU حزمة استدعاء لكل رسالة يتم إرجاعها من واجهة برمجة التطبيقات. وهذا يعني أنّه يمكنك الاطّلاع بسرعة على مكان حدوث الخطأ في التعليمات البرمجية، ما يكون مفيدًا لتصحيح الأخطاء وحلّها.
بالإضافة إلى توفير حزمة استدعاء، يسهل أيضًا فهم رسائل الخطأ في WebGPU واتّخاذ إجراء بشأنها. تتضمّن رسائل الخطأ عادةً وصفًا للخطأ واقتراحات حول كيفية إصلاحه.
تتيح لك WebGPU أيضًا توفير label
مخصّص لكل عنصر WebGPU. يستخدم المتصفّح هذا التصنيف بعد ذلك في رسائل GPUError، وتحذيرات وحدة التحكّم، وأدوات المطوّرين في المتصفّح.
من الأسماء إلى الفهارس
في WebGL، يتم ربط العديد من العناصر بالأسماء. على سبيل المثال، يمكنك تعريف متغيّر موحّد باسم myUniform
في GLSL والحصول على موقعه باستخدام gl.getUniformLocation(program, 'myUniform')
. ويكون ذلك مفيدًا لأنّه سيظهر لك خطأ إذا أخطأت في كتابة اسم المتغيّر الموحّد.
من ناحية أخرى، في WebGPU، يتم ربط كل شيء بالكامل بإزاحة البايت أو الفهرس (يُطلق عليه غالبًا اسم الموقع). وتقع على عاتقك مسؤولية الحفاظ على مزامنة المواقع الجغرافية للرمز في WGSL وJavaScript.
إنشاء صور mipmap
في WebGL، يمكنك إنشاء مستوى 0 من خريطة MIP الخاصة بنسيج معيّن، ثم استدعاء gl.generateMipmap()
. ستنشئ WebGL بعد ذلك جميع مستويات mip الأخرى نيابةً عنك.
في WebGPU، عليك إنشاء خرائط mip بنفسك. لا تتوفّر دالة مضمّنة لإجراء ذلك. يمكنك الاطّلاع على مناقشة المواصفات لمعرفة المزيد عن القرار. يمكنك استخدام مكتبات مفيدة مثل webgpu-utils لإنشاء خرائط mip أو التعرّف على كيفية تنفيذ ذلك بنفسك.
مخازن مؤقتة للتخزين ونسيج التخزين
تتوافق المخازن المؤقتة الموحّدة مع كلّ من WebGL وWebGPU، وتتيح لك تمرير مَعلمات ثابتة ذات حجم محدود إلى برامج التظليل. لا تتوافق مخازن البيانات مع WebGPU إلا إذا كانت تشبه مخازن البيانات الموحّدة، وهي أكثر فعالية ومرونة من مخازن البيانات الموحّدة.
يمكن أن تكون مخازن البيانات المؤقتة للتخزين التي يتم تمريرها إلى برامج التظليل أكبر بكثير من مخازن البيانات المؤقتة الثابتة. على الرغم من أنّ المواصفات تنص على أنّ عمليات ربط المخازن المؤقتة الموحّدة يمكن أن يصل حجمها إلى 64 كيلوبايت (راجِع
maxUniformBufferBindingSize
)، فإنّ الحد الأقصى لحجم عملية ربط المخزن المؤقت هو 128 ميغابايت على الأقل في WebGPU (راجِع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.
الإقرارات
نشكر "كورنتين واليز" و"غريغ تافاريس" و"ستيفن وايت" و"كين راسل" و"راشيل أندرو" على مراجعة هذه المقالة.
أنصحك أيضًا بزيارة WebGPUFundamentals.org للتعمّق في الاختلافات بين WebGPU وWebGL.