Aller au contenu principal
sports_esports Lab Canvas 2D Surfaces implicites Marching squares Zéro dépendance

Metaballs — l'iso-surface d'un champ scalaire rendue en Canvas 2D

Des blobs organiques qui fusionnent et se séparent, sans qu'aucune forme ne soit stockée nulle part : je place quelques boules invisibles, j'additionne leur champ scalaire (somme des contributions r²/d²) et j'en extrais la surface au-dessus d'un seuil par marching squares sur une grille échantillonnée. Tout l'enjeu tient dans le compromis résolution / performance. Zéro dépendance.

Souris : ajouter et déplacer une boule + / − : nombre de boules Espace : mettre en pause

Des surfaces qui n'existent nulle part dans le code

Un blob de metaballs n'est dessiné par personne : aucune forme, aucun cercle, aucun chemin n'est stocké quelque part. Je place seulement quelques boules invisibles qui se déplacent et rebondissent sur les bords. Ce qui apparaît à l'écran — ces gouttes ambre et indigo qui se rejoignent puis se séparent — est une surface implicite : elle est définie par une équation, pas par une géométrie, et je la reconstruis intégralement à chaque image.

Un champ scalaire, somme de contributions

Chaque boule émet un champ d'influence qui décroît avec la distance. En tout point de l'écran, j'additionne la contribution de toutes les boules selon une loi en inverse du carré de la distance (r² / d²) : très fort près d'un centre, faible au loin. Cette somme forme un champ scalaire continu — un relief invisible dont les sommets sont les boules et dont les vallées se comblent là où deux boules se rapprochent. C'est cette addition, et rien d'autre, qui fait fusionner les blobs de façon organique.

Le seuillage définit la surface

Reste à décider où se trouve la « peau » du blob. Je fixe un seuil : tout point où le champ dépasse cette valeur est à l'intérieur, tout point en dessous est à l'extérieur. La surface, c'est exactement la ligne de niveau où le champ vaut ce seuil — l'iso-surface. Quand deux boules s'approchent, leurs champs s'additionnent dans l'espace entre elles, la zone franchit le seuil, et les deux gouttes n'en forment plus qu'une. J'utilise ici deux seuils : un bas pour le halo indigo, un plus haut pour le cœur ambre, ce qui donne aux blobs leur relief.

Marching squares : extraire le contour, cellule par cellule

Évaluer le champ en chaque pixel puis en tracer la frontière serait ruineux. À la place, j'échantillonne le champ sur une grille régulière et j'applique l'algorithme du marching squares. Pour chaque petite cellule, je regarde lesquels de ses quatre coins sont au-dessus du seuil ; sur chaque arête qui relie un coin « dedans » à un coin « dehors », j'interpole linéairement le point de passage exact. Je remplis alors le polygone formé de ces coins et de ces points d'intersection. Mises bout à bout, ces cellules reconstituent un contour lisse — l'interpolation gomme l'effet d'escalier de la grille.

Le vrai sujet : le compromis résolution / performance

Toute la démo tient dans un arbitrage. Une grille fine suit la surface au plus près mais multiplie les points à évaluer à chaque image ; une grille grossière est quasi gratuite mais laisse voir ses facettes. Ici je travaille sur une grille au pas de dix pixels et je laisse l'interpolation faire le reste : le champ n'est calculé que sur quelques milliers de points au lieu de plusieurs centaines de milliers de pixels, et l'animation tient soixante images par seconde jusque sur mobile. C'est exactement le type de décision que j'apporte à un projet : trouver, chiffres en main, le point où la qualité perçue et le coût réel s'équilibrent, pour livrer une application à la fois fluide et tenable dans la durée.

Photo d'Emmanuel BALLERY, fondateur de x10

À propos de l'auteur

Emmanuel BALLERY est le fondateur de x10 solutions. Ces petits jeux sont surtout un plaisir de développeur, codés le week-end — pas une vitrine de mes missions, qui sont bien plus exigeantes. J'y soigne quand même la performance et la lisibilité, par habitude.

Voir plus arrow_forward
rocket_launch

Un vrai projet en tête ?

Ce petit jeu m'amuse, mais il ne dit pas grand-chose de mon métier : mes missions sont bien plus complexes. Si vous avez une application à concevoir ou à fiabiliser, c'est là que je suis vraiment utile.

Discuter de mon projet arrow_forward