Art algorithmique: les leçons de mes erreurs de code
Les plateformes éducatives, les fondations, les institutions culturelles se sont engouffrées dans ce narratif avec l'enthousiasme des convaincus. Dix minutes, trois copier-coller, et vous voilà créateur.
La réalité, quand on regarde ce qui sort effectivement de ces formations, ressemble à autre chose. Des sketches qui s'effondrent au bout de trente secondes. Des écouteurs d'événements qui prolifèrent sans qu'on les ait jamais déclarés. Une console saturée de messages que personne n'a appris à déchiffrer. Ce ne sont pas des accidents: ce sont les conséquences directes d'un enseignement qui préfère la promesse au fondamental. Ce texte n'est pas une leçon de morale. C'est un inventaire — partial, partial par construction — des erreurs qui jonchent le chemin de quiconque apprend à coder ses images. Avec, quand c'est possible, ce qu'elles enseignent vraiment.
Le piège de la boucle draw(): quand l'image se retourne contre elle-même
Dans p5.js, tout repose sur une boucle qui se répète sans relâche: draw(). Chaque image par seconde, le navigateur réexécute ce que vous y avez écrit. La tentation du débutant est d'y mettre « ce qui doit s'afficher » — c'est-à-dire, souvent, de créer directement l'objet qu'on veut voir à l'écran.
C'est précisément là que le piège se referme. Une particule, un cercle, une forme: tout objet instancié dans draw() est instancié à chaque frame. Soixante fois par seconde. Très vite, le ramasse-miettes ne suit plus. Le navigateur dégrade son taux de rafraîchissement, l'image devient saccadée, puis l'onglet finit par demander grâce. L'impact précis sur le nombre d'images par seconde dépend de la machine et du navigateur — il n'existe pas de chiffre universel à colporter — mais la trajectoire est, elle, constante.
La règle, contre-intuitive pour qui vient du monde statique, est simple: tout ce qui peut être créé une fois doit l'être en dehors de draw(). Les objets persistants se déclarent en variable globale ou dans setup(). draw() ne crée plus, elle met à jour. Quand un objet doit disparaître, on le retire explicitement du tableau qui le contient — on ne compte pas sur le hasard du cycle mémoire pour faire le ménage.
Un sketch qui crée ses objets dans draw() n'est pas un sketch vivant: c'est un sketch qui se suicide, frame après frame.Trois patterns à surveiller particulièrement:
- L'ajout d'écouteurs d'événements (
mousePressed(),keyPressed(), etc.) à l'intérieur d'une fonction qui se répète — chaque passage en ajoute un nouveau, sans jamais supprimer les précédents. Le navigateur finit par exécuter cent fois le même callback pour un seul clic. - L'instanciation de tableaux ou de classes utilitaires au cœur de la boucle d'animation, alors qu'ils devraient vivre une fois pour toutes.
- L'utilisation massive de
createVector()ou d'objets géométriques instanciés à la volée, là où des scalaires suffiraient pour décrire le mouvement.
Ce n'est pas qu'une affaire de vitesse. C'est une affaire d'intention artistique: un code qui se traîne, c'est un regard qui ne sait pas où aller.
Du hasard à la cohérence: pourquoi noise() n'est pas random()
Les tutoriels commencent presque tous par random(). C'est commode, c'est spectaculaire, ça donne vite des résultats visuellement « intéressants ». C'est aussi, le plus souvent, un contresens artistique complet.
random() produit des valeurs indépendantes les unes des autres. Deux appels successifs à random() n'ont aucune raison de se ressembler. Pour un feu d'artifice, une dispersion atomique, une ponctuation visuelle: parfait. Pour un paysage, un mouvement de caméra, une atmosphère: désastreux.
noise(), dans p5.js, fait exactement le contraire. Elle renvoie une valeur entre 0 et 1, mais cette valeur est continue: des coordonnées voisines produisent des résultats voisins. Le résultat, c'est ce qu'on appelle un bruit de Perlin — un signal organique, où l'aléatoire se déploie par transitions plutôt que par saccades. La fonction est déterministe: pour des coordonnées identiques, elle rend la même valeur. Elle n'a rien du « hasard » au sens où l'entendent les présentations trop rapides.
| Critère | noise() | random() |
|---|---|---|
| Plage de retour | 0 à 1 | Paramétrable (par défaut [0, 1)) |
| Corrélation entre valeurs voisines | Forte, continue | Aucune, indépendante |
| Reproductibilité | Déterministe (avec noiseSeed()) | Indéterminée par défaut |
| Effet visuel | Transitions douces, reliefs | Dispersion, granularité |
| Usage pertinent | Paysages, ambiances, flux | Particules,, choix ponctuels |
Le choix entre les deux fonctions n'est pas une affaire de goût. C'est une affaire de posture artistique. Celui qui n'emploie que random() réduit son œuvre à une série d'événements sans mémoire; celui qui prend la main sur noise() commence à écrire du temps plutôt que des points. Ce n'est pas la même œuvre.
Le Friendly Error System, ou la pédagogie par bandage
p5.js intègre un mécanisme nommé Friendly Error System (FES). Son rôle: valider les paramètres transmis aux fonctions de la bibliothèque et produire un message explicite dans la console quand quelque chose ne va pas. Une fonction appelée avec un type inattendu, un argument manquant, un nom de fonction mal orthographié — le FES transforme l'erreur brute en phrase lisible.
L'intention est bonne. L'effet, sur le long terme, est discutable. En remplaçant l'erreur cryptique par un message rassurant, le FES crée une dépendance: on apprend à corriger le symptôme sans comprendre la pathologie. On fixe la ligne, on relance, on admire le résultat. Le code reste opaque.
Trois lectures possibles du même outil:
- Lecture optimiste: un pédagogue qui sécurise l'apprentissage et désamorce la panique de la console rouge, particulièrement pour des publics non-ingénieurs.
- Lecture neutre: une couche d'abstraction qui rend la bibliothèque plus accueillante, au même titre qu'un typage dynamique plutôt que strict.
- Lecture critique: un dispositif qui permet aux formations de vendre « vous comprendrez tout » sans jamais enseigner le fonctionnement réel de la machine — une béquille qui protège l'institution plus que l'élève.
Les trois lectures sont vraies en même temps. C'est précisément ce qui rend l'outil intéressant: il n'est ni bon ni mauvais en soi. Il est ce qu'on en fait. Et ce qu'on en fait, dans la plupart des cursus, c'est une béquille pédagogique — pas un tremplin vers la compréhension.
Le choix du mode de rendu: Canvas 2D ou WebGL?
Avant même de parler de performance, il faut parler d'architecture. p5.js propose deux modes de rendu principaux: un mode Canvas 2D, par défaut, et un mode WebGL, activé par un troisième argument du constructeur. Le premier dessine des formes en deux dimensions à l'aide des API classiques du navigateur. Le second décharge une partie du travail sur le processeur graphique et ouvre l'accès aux shaders, à la 3D, à des effets qu'on ne peut pas obtenir autrement.
| Critère | Canvas 2D (createCanvas(w, h)) | WebGL (createCanvas(w, h, WEBGL)) |
|---|---|---|
| Dimension | 2D | 2D et 3D |
| Accès aux shaders | Non | Oui |
| Performance pour 2D plat | Suffisante jusqu'à plusieurs milliers de formes | Surcoût initial, gain marginal |
| Complexité pédagogique | Faible | Élevée |
| Quand basculer | Quand le visuel reste plan | Dès qu'apparaissent la 3D, les shaders, les textures |
Le piège classique consiste à rester en Canvas 2D par habitude, même quand le projet appelle la 3D ou des effets de pixels avancés — au prix de bidouilles impossibles et de frustration croissante. Le piège inverse, plus moderne, consiste à basculer en WebGL par snobisme technique, alors que le projet n'en a pas besoin — et à payer le prix d'une complexité non maîtrisée, de coordonnées qui ne sont plus celles qu'on croyait, de mathématiques qu'on n'a jamais apprises.
Le choix du mode de rendu engage le projet entier. Il se prend tôt, et il s'assume — ou il se regrette plus tard, au moment où l'œuvre refuse d'aller où on l'espérait.
De Processing à p5.js: un héritage qui dérange
Processing a été créé en 2001, au MIT Media Lab, par Casey Reas et Ben Fry. L'idée: donner aux artistes un environnement de programmation où la pensée se traduit directement en image, sans les intermédiaires techniques qui filtrent d'ordinaire l'intention. p5.js, développé par Lauren Lee McCarthy à partir de 2013, transpose cette philosophie dans le navigateur. JavaScript remplace Java. Le canvas HTML remplace la fenêtre Processing. L'idée, elle, voyage — ainsi que la grammaire, et la promesse.
L'héritage est encombrant. Les formations qui enseignent p5.js comme « le code créatif pour tous » héritent en réalité d'un outil conçu dans un laboratoire d'élite, par des chercheurs qui pensaient leur pratique depuis dix ans déjà. Elles en gardent la syntaxe, l'esthétique pédagogique, la promesse d'accessibilité. Elles en retirent, le plus souvent, la profondeur théorique qui rendait Processing utile aux artistes qui s'en sont emparés.
Résultat: des cohortes entières d'« artistes numériques » qui sortent de formation en sachant manipuler ellipse() et background(), mais qui n'ont jamais ouvert un shader, jamais lu la documentation d'une transformation affine, jamais compris ce qu'est un espace de coordonnées. Ce n'est pas un problème technique. C'est un problème politique: la démocratisation d'un outil sans démocratisation de son arrière-plan produit, mécaniquement, une main-d'œuvre créative qui connaît la surface mais pas la profondeur.
Le code créatif est un art de la patience: celle d'apprendre à désapprendre ce que les tutoriels vous ont appris trop vite.
Ce que ces erreurs finissent par enseigner
Reste une question, et elle est plus inconfortable que les autres.
Les erreurs décrites ici ne sont pas des fautes individuelles. Ce sont des fautes de transmission. Quelqu'un, quelque part, a décidé qu'on pouvait enseigner l'art algorithmique en dix leçons, en omettant la gestion mémoire, en survolant les espaces de coordonnées, en présentant random() comme l'alpha et l'oméga du hasard. Ce quelqu'un a touché un public — des milliers de personnes — et ce public produit aujourd'hui des œuvres qui s'effondrent, qui se répètent, qui ne savent pas ce qu'elles font.
La question n'est pas de savoir si vous ferez des erreurs en codant vos images. Vous en ferez. La question est de savoir qui vous les a enseignées, et à quel prix. Et — surtout — si vous accepterez de les regarder en face, plutôt que de laisser une console bienveillante les effacer à votre place.




