David Madore's WebLog: Tentative pitoyable pour faire du WebGL

Index of all entries / Index de toutes les entréesXML (RSS 1.0) • Recent comments / Commentaires récents

Entry #1989 [older|newer] / Entrée #1989 [précédente|suivante]:

(samedi)

Tentative pitoyable pour faire du WebGL

Comme je me plaignais avant-hier que les navigateurs Web n'étaient pas capables d'afficher, dans canvas sur une machine moderne, 6720 lignes en 40ms (expérimentalement, mon Firefox met plutôt 500ms pour les tracer), quelqu'un m'a suggéré : tu devrais essayer de faire du WebGL (l'interface JavaScript d'OpenGL). Après tout, c'est une idée raisonnable, pour tirer parti des monstres que tous les ordinateurs modernes incluent en matière de carte graphique, et qui s'ils arrivent à afficher les images de Call of The Warrior's Duty Warfare Badass VII The Return Unleashed avec un zillion de polygones plus textures, devraient ne faire qu'une bouchée de mes 240 points fussent-ils en 8 dimensions. Enfin, ça c'est la théorie.

D'abord, WebGL c'est une horreur pour ce qui est des incantations propitiatoires qu'il faut prononcer avant de pouvoir tracer la moindre ligne : une première incantation récupérer l'élément canvas, une deuxième incantation pour obtenir le contexte WebGL, une troisième pour créer un shader de vertex, une quatrième pour le compiler, une cinquième pour créer un shader de fragment, une sixième pour le compiler, une septière pour créer un programme, une huitième pour attacher le shader de vertex qu'on vient de compiler au programme, une neuvième pour faire pareil pour le shader de fragment, une dixième pour linker le programme, une onzième pour demander à l'utiliser, une douzième pour obtenir l'adresse de telle variable qu'on a utilisée dans le shader afin de pouvoir y binder des données… et je n'en suis qu'au tout début, on dirait que ça a été créé par quelqu'un qui était payé à la ligne de code que les gens écriraient sans son système. Heureusement, j'ai trouvé un tutorial pas trop mauvais et un programme d'exemple d'où partir.

Une bonne nouvelle, en revanche, c'est que quelque chose est prévu pour faire justement ce que je veux, à savoir préciser les coordonnées d'un certain nombre de points (au hasard, 240) et les réutiliser dans un grand nombre de lignes (au hasard 6720). Ça au moins c'est bien.

Mais alors l'autre truc avec WebGL, c'est qu'il est impossible de savoir exactement où on en est : chaque navigateur a son implémentation qui change tout le temps, mais ça dépend aussi du système d'exploitation sous-jacent, de l'environnement graphique, du pilote de la carte graphique, de la carte graphique elle-même, et d'un trillion de variables de configuration de chacune de ces choses dont on ne sait jamais au juste ce qu'elles font. Et toutes les explications en ligne sont à prendre avec des pincettes parce que justement les navigateurs changent tout le temps (par exemple, il y a un certain temps, si je voulais utiliser WebGL, je devais utiliser la variable d'environnement MOZ_GLX_IGNORE_BLACKLIST pour demander à Firefox de s'il te plaît, ignore le fait que ma carte graphique a des pilotes un peu pourris, et essaie quand même ; maintenant il paraît que ce n'est plus nécessaire). Et impossible de savoir si ça marche vraiment : parce que si tel ou tel truc n'est pas supporté, on pourrait très bien retombé sur une implémentation en logiciel, qui fait qu'on ne sait pas très bien ce qu'on teste. On peut vaguement se dire que si ça va très lentement on est tombé dans l'implémentation logicielle et que si ça plante la machine on est tombé dans l'implémentation matérielle qui ne marche pas, mais ces deux critères sont incertains et de toute façon ce qu'on veut c'est que ça marche.

Pour arranger le tout, la spécification WebGL est inexistante puisqu'elle se base sur la spécification OpenGL ES 2.0, qui doit elle-même se baser sur la sécification OpenGL 2.0, qui à son tour s'appuie sur OpenGL 1.0, ou quelque chose comme ça, je n'y comprends pas grand-chose, et je n'ai pas vraiment envie de lire 5000 pages de doc pour savoir quoi faire (surtout si chaque niveau se définit par une pile de différences et de références par rapport au niveau précédent). Et je ne comprends pas vraiment la manière dont s'agencent les petits bouts, OpenGL, OpenGL ES, GLX, EGL, WGL, etc.

Bref, j'ai quand même pondu une page : elle est ici (comme l'adresse en .tmp le signale, cette page est susceptible de disparaître sans préavis : si elle vous plaît, faites-en une copie, si vous arrivez trop tard, consultez archive.org). Ça fait quelque chose (si ça plante votre navigateur, d'ailleurs, ne venez pas vous plaindre, c'est le principal effet répertorié de WebGL), mais ça ne fait pas ce que je veux.

Enfin, chez moi, ça ne marche pas sous Chrome (je ne sais pas pourquoi : j'ai eu beau essayer avec --enable-webgl --ignore-gpu-blacklist il me dit bien qu'il trouve une accélération 3D mais il refuse de créer un contexte WebGL), et sous Firefox ça affiche un gros blob noir dont on devine une vague ressemblance avec ce que je veux, mais d'abord je n'ai pas réussi (et même pas vraiment essayé) de tracer les points, juste les lignes, et de toute façon le problème le plus sérieux est qu'il n'y a pas d'antialiasing, donc on n'y voit rien du tout parce que les lignes sont trop épaisses.

Pourtant, je crois bien avoir explicitement demandé à WebGL de faire de l'antialiasing et de tracer des droites d'une épaisseur de 0.25 pixels — si quelqu'un connaît WebGL et peut lire mon code, je serai ravi d'avoir confirmation — et normalement si j'en crois ce bug (et le fait qu'il soit marqué comme fixed pour Firefox 10, qui est bien ce que j'ai) ainsi que cette page, l'antialiasing dans WebGL devrait marcher sous mon Firefox 10, y compris sous Linux, mais visiblement ce n'est pas le cas. Je réesserai sur une machine utilisant une carte graphique différente (nVidia), mais je suis sceptique.

(Peut-être que je suis censé faire plus pour demander des lignes antialiasées que gl.lineWidth(0.25) et gl.enable(gl.SAMPLE_COVERAGE), mais comme je ne comprends pas vraiment ce que ces choses font, je suis perplexe. Par exemple, cette page suggère que peut-être je devrais essayer gl.enable(gl.LINE_SMOOTH) mais je suis tout embrouillé — je crois vaguement comprendre qu'il y a deux implémentations totalement indépendantes de l'antialiasing sous OpenGL, le multisampling et LINE_SMOOTH, mais je ne suis pas sûr.)

Enfin, si certains de mes lecteurs voient quelque chose de joli, c'est-à-dire avec des droites très fines comparables au dessin de l'entrée précédente, et pas un gros pâté noir, je veux bien savoir ce qu'ils ont comme configuration logicielle et matérielle.

↑Entry #1989 [older|newer] / ↑Entrée #1989 [précédente|suivante]

Recent entries / Entrées récentesIndex of all entries / Index de toutes les entrées