Couverture de l'article Trucs et astuces WebGL

Vous avez choisi de créer une application WebGL, félicitations ! Nous allons vous donner ci-dessous des trucs et astuces qui pourront vous faire gagner du temps, éviter des galères et même améliorer la qualité et la performance de votre bijou.

Prendre le temps de développer ses outils de debug

Des bons outils de debug sont IN-DIS-PEN-SABLES ! Croyez-moi, vous allez peut-être investir quelques heures pour les développer, mais ils vous feront gagner un temps considérable par la suite. Vous pourrez aussi vous rendre compte de certaines fuites de performances invisibles au premier regard.

1 - Tout savoir sur sa scène 3D

Vos outils devront mettre à nu au possible le contenu de votre scène 3D. Une bonne ergonomie est d’afficher ce qui se trouve sous votre souris. Voici ce que j’utilise à titre personnel : debug info

 

Cette interface me permet rapidement d’identifier à quel mesh et material j’ai affaire. Je peux aussi vérifier son nombre de poly/vertices, car des opérations comme le CSG peuvent créer des maillages trop complexes et induire des problèmes de performances. J’ai également un aperçu des canaux UV pour vérifier la bonne application des textures en ce point.

(Anecdote : cette fonctionnalité m’a permis d’identifier un problème visuel que j’aurais eu beaucoup de mal à détecter autrement. En effet, un maillage était légèrement trop sombre, et incohérent avec la lumière incidente. Par hasard, j’ai survolé ma souris sur ce maillage et me suis rendu compte que toutes ses coordonnées UV2 étaient à 0, alors que la lightmap était activée. Ainsi, le pixel en bas à gauche de la lightmap, gris, était appliqué sur tout le maillage, l’assombrissant entièrement. J’ai donc remappé le modèle dans l’espace UV2, et miracle, la lumière fut ! )

2 - Debugger un shader

C’est là que la prise de tête commence. Debugger un shader peut être la source de nombreuses crises de nerfs si on ne sait pas par où commencer. En effet, oubliez le console.log ou les breakpoints si précieux, votre seul moyen de debugger un shader sera d’afficher des couleurs à l’écran dans le fragment shader. Oui, le rouge bien flashy, alias vec4(1.0, 0.0, 0.0, 1.0) sera votre ami. Rien ne vaut l’exemple :

  • Cas pratique : Mon image/objet ne ressemble à rien, ou pire, est tout noir. 0 ) Vérifiez tout d’abord que vous n’avez aucun warning WebGL dans votre console Javascript. Si vous en avez, le souci vient probablement de vos appels WebGL (attribute manquant etc…) 1 ) Vérifiez que votre shader est bien impliqué. Faites un simple gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); à la fin de votre fragment shader. Ceci équivaut au fameux console.log("coucou"); qui vérifie que votre code est bien appelé. Si vous obtenez un(e) image/objet entièrement rouge, votre shader est bien utilisé. Sinon, vérifiez côté Javascript que vous faites le nécessaire, comme résumé simplement ici. 2 ) Isolez maintenant une par une vos données en entrée. N’hésitez pas à afficher même le plus simple, comme par exemple les attributes. Un gl_FragColor = vec4(uv.x, uv.y, 0.0, 1.0); ou encore gl_FragColor = vec4(normal.x, normal.y, normal.z, 1.0); devrait vous afficher des couleurs cohérentes. Attention, vous devrez ramener vos données dans l’intervalle [0:1] pour qu’elles soient correctement affichées. Dans l’exemple ci-dessus, des valeurs négatives de normales s’afficheront noires, utilisez la valeur absolue. Pour la position, divisez/multipliez-la par un facteur lambda pour l’obtenir dans l’intervalle [0:1]. N’hésitez pas à tâtonner, le but est de localiser le souci, pas d’avoir un beau rendu de couleurs. 3 ) Si toutes vos données d’entrée sont cohérentes, le souci est alors dans les instructions de votre shader. Le plus courant est d’oublier que vous avez des valeurs hors de l’intervalle [0:1]. Aussi, si vous obtenez une sorte de motif répété, il est fort probable que vous ayez affaire à des erreurs de précision numérique. N’oubliez pas que chaque canal sur une texture (si vous n’utilisez pas de texture à précision flottante) est codé sur 8bits. C’est très peu de valeurs différentes pour représenter des grandeurs physiques comme la profondeur !

NB : Les navigateurs intègrent maintenant des outils pour aider au debug des shaders, comme pouvoir modifier en direct le code de votre shader et le recompiler. Ceci peut être pratique, mais attention, ils ne sont pas dépourvus de bugs ! Celui de Firefox par exemple vous fera des misères si vous changez un accès à une texture dans un texture2D vers une autre texture. L’accès se fera toujours dans la texture d’index 0, quelle que soit la texture invoquée !! (à vérifier cependant si c’est toujours d’actualité, ce bug a peut-être été corrigé depuis)

Garder un oeil sur la complexité de sa scène

Maintenant que vous avez de beaux outils de debug, il est très important de monitorer en permanence la complexité de sa scène. Les indicateurs sont les suivants :

  • Nombre d’objets
  • Nombre de matériaux affichés
  • Nombre de faces
  • Nombre de vertices

Je ne vais pas vous donner des indicateurs limites, car ces nombres varient énormément en fonction de la configuration que vous ciblez (n’oubliez pas aussi les smartphones et tablettes !). Mes recommandations sont les suivantes :

  • Partagez au maximum vos matériaux entre objets. Si votre framework est bien fait (comme Babylon.js ;p ), un système de cache accélèrera votre rendu si les matériaux successifs sont identiques.
  • Réduisez votre nombre d’objets au minimum nécessaire. Pour cela j’ai déjà fait un article sur le sujet.
  • Simplifiez votre géométrie - réduisez votre nombre de faces/sommets. Si votre application est plus avancée, considérez un système de LOD.

Ombres ou occlusion ambiante ?

Les ombres coûtent cher. Mettre en place la technique de shadow mapping implémentée dans tous les framework WebGL qui se respectent vous coûtera un DC (draw call) en plus par objet. Vous doublez donc implicitement la complexité de la scène si tous vos objets projettent des ombres. Dans certains cas, il est possible de précalculer ce qu’on appelle l’occlusion ambiante. Cette technique peut vous offrir des ombres plus réalistes, et à moindre coût, vu que tout est précalculé. Ci dessous, nous avons précalculé l’occlusion ambiante sur des plans en dessous de chaque meuble sur Wanaplan. Ce plan se déplace avec le meuble. Comparez la qualité avec l’ancienne technique de shadow mapping. En plus cette technique coûte beaucoup moins cher en temps CPU !

Sans Ambient Occlusion :

 

Avec Ambient Occlusion :

plan3D_withAO

Utiliser un shader de traitement d’image

Vous voulez flouter une image ? Dessiner un contour autour d’un objet ? Appliquer de l’antialiasing ? Toutes ces opérations se font merveilleusement bien via des fragment shaders. Aussi je vous conseille de développer une classe qui vous permettra l’application d’un shader sur la totalité de l’écran. Cette classe répondra à tous vos besoins de traitement de l’image, si tant est que vous sachiez manipuler les shaders.

Voici une partie de mon implémentation, qui me simplifie la vie comme vous avez pas idée :

IP.Render = function(effect, inTex, outTex, engine, _uniformCb) {
        var gl = engine._gl;

        if (!inTex || !outTex || !effect || !engine) {
            console.warn("[ImageProcessor] Render : at least one parameter is missing, aborting.")
            return;
        }

        if (!effect.isReady() || !inTex.isReady() || !outTex.isReady()) {
            return;
        }

        gl.useProgram(effect.getProgram());

        // Only created once
        if (screenQuadVBO == null) {
            // These vertices make a simple unscaled quad
            var verts = [
                1.0, 1.0, -1.0, 
                1.0, -1.0, -1.0,
                -1.0, -1.0, 1.0, 
                -1.0, 1.0, 1.0
            ];
            screenQuadVBO = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, screenQuadVBO);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
        }

        // Bind the framebuffer to the output RenderTarget's framebuffer
        engine.bindFramebuffer(outTex._texture);

        // Bind the vertices
        gl.bindBuffer(gl.ARRAY_BUFFER, screenQuadVBO);
        gl.enableVertexAttribArray(effect.getAttributeLocationByName("position"));
        gl.vertexAttribPointer(effect.getAttributeLocationByName("position"), 2, gl.FLOAT, false, 0, 0);

        // _uniformCb is a callback where the uniforms are set
        // Use what you need for your shader
        if (_uniformCb)
            _uniformCb(effect);
        // In my fragment shader, i'll always have 2 uniform automatically set : 
        //     textureSampler, which will be the input texture
        //     texelSize, which will be the actual texel size, as displayed on the screen
        effect.setTexture("textureSampler", inTex);
        effect.setFloat2("texelSize", 1 / wanaplan.getWidth(), 1 / wanaplan.getHeight());

        gl.drawArrays(gl.TRIANGLES, 0, 6);

        // Cleanup:
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
        engine.unBindFramebuffer(outTex);
    };

A partir de là, une fois mes shaders codés et compilés dans mon effect, je spécifie la texture d’entrée inTex, la texture de sortie outTex, le contexte gl, et mon callback pour régler mes uniforms avant le dessin _uniformCb. Et je récupère ma texture passée sous mon merveilleux shader.

Attendre WebGL 2 avec impatience

WebGL2 nous réserve des merveilles en termes de possibilités. Cet article (de 2013 quand même…) nous résume ce qui est dans la spec.

En bref, les techniques suivantes seront exploitables en production :

  • Des buffers d’uniforms qui, bien utilisés vont permettre d’accélérer les draw calls et donc autoriser plus d’objets/matériaux sur la scène.
  • Le deferred rendering qui permet d’afficher de nombreuses lumières point.
  • L’antialiasing MSAA sur les renderTargets hors écran. Cette feature va éviter l’aliasing horrible qui existe actuellement sur tous les postProcess comme la profondeur de champ ou encore le SSAO
  • Des techniques d’illumination globale. Je vous recommande d’ailleurs cet excellent article de Florian Boesch, qui implémente une technique à base d’irradiance, de lightmapping et de lightprobes dans WebGL (+extensions).
  • Bien d’autres choses encore…
  • Couverture de l'article #2 - Module Federation et Vue à l'ère de l'IA : retour de la MadVue 2026
    #2 - Module Federation et Vue à l'ère de l'IA : retour de la MadVue 2026

    Il y a 3 mois

    Voici la seconde partie de mon retour sur la MadVue 2026, la conférence Vue.js qui s'est tenue à Madrid le 22 mai 2026. Si vous avez manqué le début, la première partie est juste ici :

    Après les fondations de l'application Vue moderne, on change d'échelle et d'époque. Dans cet article, on va voir comment partager des composants entre plusieurs applications Vue avec Module Federation, puis trois talks consacrés à Vue et l'intelligence artificielle : faire générer une interface en direct par un LLM, préparer son projet Vue pour les agents, et enfin apprendre le frontend à l'ère de l'IA.

    C'est parti !

    Photo de Louis GOURAIN auteur de l'article

    Louis GOURAIN

    Lire la suite
  • Couverture de l'article #1 - Temps réel, URLs typées, formulaires et toolchain : retour de la MadVue 2026
    #1 - Temps réel, URLs typées, formulaires et toolchain : retour de la MadVue 2026

    Il y a 3 mois

    Le 22 mai 2026, je me suis rendu à Madrid pour la MadVue 2026, la conférence espagnole dédiée à l'écosystème Vue.js. Une journée dense, neuf talks, et une tendance de fond très claire : entre une grosse moitié orientée IA et expérience développeur et une autre consacrée aux fondations qui rendent nos applications soutenables.

    Dans cette série de deux articles, je reviens sur l'ensemble des talks. En les lisant, vous aurez l'impression d'y avoir assisté.

    Cet article est le premier des deux, vous pourrez retrouver chaque partie de cette série ici :

    Dans ce premier article, on pose les fondations d'une application Vue moderne : on verra comment faire du temps réel proprement, comment en finir avec le parsing manuel des paramètres d'URL, un tout nouveau modèle pour construire ses composants de formulaire, l'avènement d'une toolchain JavaScript unifiée (Oxc, Rolldown), et ce qui nous attend avec Nuxt 5.

    Beaucoup de sujets à traiter, alors c'est parti !

    Photo de Louis GOURAIN auteur de l'article

    Louis GOURAIN

    Lire la suite
  • Couverture de l'article #4 - Construire un DOM Virtuel, les différentes méthodes de rendu et bien écrire ses tests : retour de la Vue.js Amsterdam 2023
    #4 - Construire un DOM Virtuel, les différentes méthodes de rendu et bien écrire ses tests : retour de la Vue.js Amsterdam 2023

    Il y a 3 ans

    Pour la première fois, Wanadev s’est rendu à la plus grosse conférence annuelle autour de Vue.js : la Vue.js Amsterdam 2023. J’ai eu l’honneur d’assister à la 5ème édition, couronnée par le retour d’Evan You, le créateur de Vue.js et Vite, en personne.

    Dans cette série de quatre articles, je vais vous faire revivre ces deux jours de conférences. En les lisant, vous aurez l’impression d’y avoir assisté !

    Cet article est le troisième des quatre, vous pourrez retrouver chaque partie de cette série ici :

    Dans cet article nous allons voir comment construire un Virtual DOM, on parlera des différentes façons de faire du rendu dans le web, de comment écrire des bons tests et plein d’autres choses.

    Beaucoup de sujets à traiter, alors, c’est parti !

    Photo de Louis GOURAIN auteur de l'article

    Louis GOURAIN

    Lire la suite
  • Couverture de l'article #3 - Vue.js en 2023, l'avenir de Vue Router, les patterns avec Pinia  : retour de la Vue.js Amsterdam 2023
    #3 - Vue.js en 2023, l'avenir de Vue Router, les patterns avec Pinia : retour de la Vue.js Amsterdam 2023

    Il y a 3 ans

    Pour la première fois, Wanadev s’est rendu à la plus grosse conférence annuelle autour de Vue.js : la Vue.js Amsterdam 2023. J’ai eu l’honneur d’assister à la 5ème édition, couronnée par le retour d’Evan You, le créateur de Vue.js et Vite, en personne.

    Dans cette série de quatre articles, je vais vous faire revivre ces deux jours de conférences. En les lisant, vous aurez l’impression d’y avoir assisté !

    Cet article est le troisième des quatre, vous pourrez retrouver chaque partie de cette série ici :

    Dans cet article on va parler de Vue en 2023, de patterns Pinia, du futur de vue-router, de l’écosystème Vue et de TypeScript avec Vue.

    Beaucoup de sujets à traiter, alors, c’est parti !

    Photo de Louis GOURAIN auteur de l'article

    Louis GOURAIN

    Lire la suite
  • Couverture de l'article #2 - Nuxt.js, l'art de la composition, accessibilité : retour de la Vue.js Amsterdam 2023
    #2 - Nuxt.js, l'art de la composition, accessibilité : retour de la Vue.js Amsterdam 2023

    Il y a 4 ans

    Pour la première fois, Wanadev s’est rendu à la plus grosse conférence annuelle autour de Vue.js : la Vue.js Amsterdam 2023. J’ai eu l’honneur d’assister à la 5ème édition, couronnée par le retour d’Evan You, le créateur de Vue.js et Vite, en personne.

    Dans cette série de quatre articles, je vais vous faire revivre ces deux jours de conférences. En les lisant, vous aurez l’impression d’y avoir assisté !

    Cet article est le second des quatre, vous pourrez retrouver chaque partie de cette série ici :

    Dans cet article on va parler de Nuxt en 2023, d’un client Mastodon fait avec Nuxt, d’expérience développeur sur Nuxt, de Nitropack, de CSS-in-TS, de comment concevoir ses composants Vue.js, d’accessibilité et de maintenance d’écosystème open-source en entreprise.

    Beaucoup de sujets à traiter, alors c’est parti !

    Photo de Louis GOURAIN auteur de l'article

    Louis GOURAIN

    Lire la suite
  • Couverture de l'article #1 - NPM Package, PlayWright, Google LightHouse : retour de la Vue.js Amsterdam 2023
    #1 - NPM Package, PlayWright, Google LightHouse : retour de la Vue.js Amsterdam 2023

    Il y a 4 ans

    Pour la première fois, Wanadev s’est rendu à la plus grosse conférence annuelle autour de Vue.js : la Vue.js Amsterdam 2023. J’ai eu l’honneur d’assister à la 5ème édition, couronnée par le retour d’Evan You, le créateur de Vue.js et Vite, en personne.

    Dans cette série de quatre articles, je vais vous faire revivre ces deux jours de conférences. En les lisant, vous aurez l’impression d’y avoir assisté !

    Cet article est le premier des quatre, vous pourrez retrouver chaque partie de cette série ici :

    Dans cet article, nous allons parler de Rock’n Roll, voir comment créer son package NPM, découvrir PlayWright pour tester ses applications de bout en bout, parler de commerce international, déconstruire les idées reçues sur Google Lighthouse et aborder le sujet de la performance sous Vue.js.

    Beaucoup de sujets à traiter, alors c’est parti !

    Photo de Louis GOURAIN auteur de l'article

    Louis GOURAIN

    Lire la suite