Connaissez-vous WebGPU ?

WebGPU est une API Javascript développée par le groupe de travail GPU for the Web du W3C. Cette API JavaScript est optimisée pour les calculs complexes et les rendus 3D qui a pour vocation de devenir la future norme pour la 3D sur navigateur.

WebGPU est disponible depuis le 06 avril dans Chrome 113 sur ChromeOS, macOS et Windows, et prochainement sur d’autres plateformes comme Linux et Android. Plusieurs sites et kits de développement ont déjà annoncé leur compatibilité avec WebGPU comme Babylon.js, Unity et SketchFab.

Voyons ensemble comment fonctionne WebGPU et ce qu’il nous apporte…

WebGPU s’appuie sur les API natives utilisant la carte graphique (comme Vulkan, Metal, DirectX) qui permettent d’avoir plus de contrôle sur la couche basse dans les flux de traitements graphiques, contrairement à WebGL qui s’appuie sur la surcouche OpenGL et qui implique beaucoup de traitements intermédiaires pour compenser l'absence d'accès direct aux couches basses.

~Architecture WebGPU~

Notions à connaître

Dans cette introduction, nous avons cité quelques mots et abréviations cryptiques que nous allons clarifiés:

GPU signifie Graphic Processing Unit, cela correspond au processeur de la carte graphique de votre ordinateur. Le GPU est spécialisé pour les traitements graphiques (fonctions mathématiques), l’encodage ou décodage de flux videos et surtout les calculs massivement parallélisables. Le GPU permet de générer (appelé aussi “rendre” ou “faire un rendu”) des représentations 2D ou 3D de scènes réalistes à très haute vitesse. En moyenne, un GPU doit générer 60 images par seconde, c'est-à-dire qu’il doit traiter les 2 millions de pixels d’une image HD en ~16ms.

L'abréviation GPU s’oppose à CPU pour Central Processing Unit et qui est le processeur principal de l’ordinateur. Le CPU est conçu pour le traitement séquentiel des données (fonctions logiques), de l'exécution des programmes et de la gestion de la mémoire et des entrées/sorties.

Chaque programme (bureautique, jeu vidéo, simulateur 3D, visualiseur de produits, …) a besoin que ses traitements logiques et mathématiques soient correctement répartis, entre respectivement le CPU et le GPU, pour ne pas saturer l’un ou l’autre avec des fonctions pour lesquelles il n’est pas adapté.

WebGL est une spécification d’API créée par le Khronos Group en 2011 pour la programmation 3D dynamique et utilisable directement dans des pages ou applications HTML5 sans l’utilisation de plugins (les plus anciens de nos lecteurs se souviendront des ActiveX, de Macromedia Flash et des applets Java). Elle permet d'utiliser une version allégée du standard 3D OpenGL.

De par son âge, WebGL a été largement adopté et est supporté par la majorité des navigateurs web, y compris sur mobile.

Bien que répandu, certains aspects de sa conception limitent considérablement son usage et sa performance, il faut ainsi que les développeurs fassent preuve d’astuces ou utilisent des frameworks tiers comme ThreeJS, BabylonJS, PlayCanvas pour contourner ces limitations.

Pourquoi avoir de la 3D dans son navigateur ?

L’utilisation d’un moteur de rendu 3D dans un navigateur web ouvre le champ à des cas d’usages variés tels que:

  • permettre l'accès à des jeux et expériences marketing au rendu visuel qualitatif sans les phases d’installation d’application et de déploiement des mises à jour

  • la visualisation 3D comme la cartographie 3D (Google Maps, StreetView,...) ou les applications de visualisation et conception (Ikea Kitchen Planner, SketchFab, …)

  • la réalité augmentée sur navigateur pour l’essayage "virtuel" de produit

Pourquoi la 3D est lente dans un navigateur ?

Les principaux traitements qu’un moteur 3D doit effectuer sont les chargements des objets 3D (composés de milliers voir millions de facettes), le chargement de leurs textures, le calcul de transformation en géométrie 3D pour faire un rendu cohérent des objets en fonction de leur position et des sources de lumières virtuelles dans la scène en incluant ombres et reflets.

Le plus gros travail est sans conteste la multiplication des matrices de transformation 3D (tableau de nombres et de vecteurs) qui servent au calcul des translations, rotations, mises à l'échelle de chaque facette de chaque objet. Ces traitements sont complexes et doivent être fait plusieurs dizaines de fois par seconde pour donner une expérience fluide.

Déporter les calculs sur le GPU avec les Compute Shaders

WebGL n'ayant pas d'API directe pour les calculs avancés sur les matrices. Le contournement habituel est d’utiliser des “Compute Shaders”. Il s’agit de convertir au préalable les données du calcul en image (chaque pixel correspond à une donnée) et de demander à la carte graphique de lire l’image et de lui appliquer le calcul via un shader, qui correspond à une liste d’opérations.

Pour arriver à faire un “compute shader”, il faut convertir les données d’entrée en image (1) puis l’envoyer au GPU en tant que texture (2). Cette texture est ensuite traitée de manière synchrone avec un “pixel shader” (3) qui effectue un calcul réel. Ici, le terme synchrone signifie que l’ensemble du moteur JavaScript et donc la page web sont bloqués en attendant la fin de l’exécution et aucune autre opération n’est possible en parallèle.

Le résultat du calcul ressort sous la forme d'un ensemble de pixels dans un élément HTML <canvas> (4) qui doit être lu, là aussi de manière synchrone (via la fonction getPixelsData) (5) et chaque couleur de pixel doit être convertie pour obtenir les vrais valeurs des résultats (6).

Le processus est donc complexe et intense que ce soit au niveau du CPU ou du GPU.

~Fonctionnement d'un Compute Shader en WebGL~

Que nous apporte WebGPU ?

Avec WebGPU, nous gardons l'astuce des Compute shaders mais le processus est largement simplifié. Il est possible de préparer (1) rapidement les données du calcul sous la forme d’un bloc (dit buffer) et de le charger sur le GPU sans conversion complexe (2).

Le calcul (3) est ensuite effectué de manière asynchrone (à l’image de la compilation de shaders asynchrone que propose Vulkan) et ne bloque donc pas le flux d’exécution principal JavaScript (thread). Les résultats sont ensuite reçus directement par le CPU (4).

Il n’y a plus besoin d’utiliser la balise HTML<canvas> qui avait de son côté une limite sur la taille des images et donc le nombre maximal de pixels pouvant être chargés.

Les appels lents et coûteux à getPixelsData pour lire chaque pixel et la conversion de leur valeur sont aussi évités.

~Fonctionnement d'un Compute Shader en WebGPU~


La promesse de WebGPU est donc de réaliser efficacement ses calculs complexes tout en libérant le CPU pour garder une expérience fluide.

Les courbes ci-dessous comparent les durées nécessaires pour faire des calculs sur des matrices de plus en plus larges. Ces durées sont mesurées pour des traitements faits en JavaScript pur (donc CPU), avec WebGL et avec WebGPU.

~<a href="https://pixelscommander.com/javascript/webgpu-computations-performance-in-comparison-to-webgl/">Comparaison</a> du temps de traitements par CPU pur (JS), WebGL, WebGPU~

  • En jaune, l’évolution de la durée des calculs faits en utilisant uniquement le CPU (JavaScript). Nous constatons que la durée augmente exponentiellement et nous arrêtons les tests CPU un peu avant les calculs sur des matrices > 1000 et qui nécessitent d’attendre plusieurs secondes pour un résultat.

  • En bleu, nous utilisons uniquement WebGL et nous atteignons 1 seconde de délai à partir des matrices > 2500

  • En rouge, WebGPU maintient un temps inférieur à 1 seconde même pour des matrices de taille 6000 donc un facteur x2 par rapport à WebGL et x6 par rapport à un traitement CPU

Autre exemple avec un comparatif visuel entre une scène 3D bénéficiant de WebGL puis de WebGPU.

~Une même scène 3D rendue avec WebGL (à gauche) et WebGPU (gauche) - Cliquez sur l'image pour voir l'animation~

A gauche, la scène utilisant WebGL s’affiche à hauteur de 7 images par seconde et consomme 130ms du temps CPU pour chaque image.

A droite, la scène WebGPU s’affiche à hauteur de 15 images par seconde et utilise seulement 0.6ms du temps CPU pour chaque image.

Le gain de performance et l’amélioration de la fluidité sont flagrants.

Les principaux gains de WebGPU face à WebGL sont:

  • La simplification du processus de création des compute shaders pour les développeurs

  • La simplification du flux d'exécution des compute shaders pour le processeur

  • La gestion séparée des ressources. Trois contextes différents sont fournis par l’API - GPUDevice, GPUCommandEncoder et GPUCommandBuffer - qui servent respectivement à créer des ressources comme des textures, à encoder des commandes et à gérer la file d’attente d’exécution sur le GPU. Le résultat peut être rendu (visualisé) dans une fenêtre dédiée ou sans rendu lors de l'exécution de tâches de calcul non graphique par exemple.

  • Une gestion différente des statuts avec les objets GPURenderPipeline et GPUComputePipeline qui permettent de combiner différents états prédéfinis par le développeur afin d’optimiser les calculs.

  • Un modèle de liaison de tâches semblable aux Resources Pools utilisés par Vulkan. Pour regrouper les ressources, WebGPU utilise l’objet GPUBindGroup pour lier des commandes et objets du même type utilisés dans les shaders. La création de tels groupes permet au navigateur de traiter des opérations en amont, lors du chargement.

Est-ce utile si je ne fais pas de 3D ?

Un autre avantage à noter est l’utilisation de la puissance du GPU dans un contexte non 3D. L’émergence de l’IA et même de la blockchain a permis de saisir à quel point la puissance algorithmique des cartes graphiques dépassait largement celle des CPU grâce à une conception matérielle dédiée au calcul mathématique et permettant une forte parallélisation.

De l’IA dans mon navigateur ?

L’apprentissage automatique (machine learning) est devenu une utilisation majeure des GPU et l’accès quasi-direct au GPU via WebGPU permet d’envisager des scénarios d’IA au sein même du navigateur web.

Bien sûr, nous n’irons pas jusqu’à faire un entraînement complet d’un modèle de machine learning dans un navigateur car les traitements seront plus efficaces sur le Cloud ou sur des machines spécialisés.

Exécution dans le navigateur

La phase dite "utile" du machine learning est son exécution (classification, prédiction) dans le contexte de l’utilisateur. Cette exécution du modèle IA au sein même du navigateur est facilitée - sans besoin d’installer d’applications ou prérequis techniques natifs (comme Python) - tout en conservant des performances équivalentes aux exécutions natives.

C’est est un gain indéniable pour le déploiement de l’intelligence artificielle dans des scénarios variés comme la reconnaissance d'images, l'analyse du comportement et la génération de contenu.

Fine-tuning dans le navigateur

Dans le cas de modèles pré-entrainés - comme la reconnaissance de visages ou de gestes -  il est possible grâce à WebGPU de spécialiser (fine-tune) le modèle directement depuis le navigateur avec les données fournies par l’utilisateur. Le modèle personnalisé est ensuite conservé dans le cache du navigateur sans fuite de données chez un hébergeur.

D'un pierre deux coups : la Réalité Augmentée

En soulageant le CPU et en optimisant les traitements GPU, une grande quantité de ressources sont libérées pour faire autre chose. L’utilisateur n’est plus contraint d’attendre l’exécution du modèle pour continuer à utiliser l’application tout en voyant l’autonomie de sa batterie fondre.

Les scénarios évidents sont ceux tirant partie de la réalité augmentée où il faut traiter en parallèle le flux de la caméra de l’utilisateur et l’affichage d’éléments 3D à l’écran.

Que ce soit de l’essayage virtuel (virtual try-on) de maquillage (Beauty Tech : ModiFace de L’Oréal, Perfect Corp, Chanel…) ou d’accessoires vestimentaires (Lunettes Silhouette, Hugo Boss, Nike, …), le rendu est souvent saccadé avec seulement 10 images par seconde et un usage processeur trop élevé pour le résultat obtenu.

L’utilisation de WebGPU permet ainsi d’optimiser drastiquement l’utilisation des ressources disponibles et de créer - enfin - des expériences fluides de Réalité Augmentée sur le Web.

Conclusion

Un écosystème dynamique de bibliothèques et frameworks a été construit autour de WebGL, et cette même communauté a adopté WebGPU. Le support de WebGPU est implémenté dans de nombreuses bibliothèques 3D populaires Javascript à tel point que profiter des avantages de WebGPU se fait par un simple changement de paramètre dans le code.

Toutefois, les véritables gains de performances se feront sentir quand les créateurs/développeurs prendront totalement en main cette nouvelle API et que le code de leurs applications web sera optimisé en conséquence.

Les prochains mois s’annoncent passionnants avec une convergence évidente de la réalité augmentée et de l’intelligence artificielle au sein des navigateurs sur ordinateur, sur mobile et sur casque AR/VR.

Sources

Le W3C a publié les premières versions de la norme WebGPU

WebGPU and Why It’s Exciting

WebGPU: Unlocking modern GPU access in the browser

WebGPU computations performance in comparison to WebGL

GitHub - gpuweb/gpuweb: Where the GPU for the Web work happens!

SIMD oeprations in WebGPU