Chaque petit carré du papier millimétré est un thread (un pixel, ou fragment).
chaque petit carré connaît sa position, comme des coordonnées sur un échiquier.
Dans les chapitres précédents, nous avons appris à nous servir des valeurs normalisées, par exemple, nous avons mappé ces positions *x* et *y* vers les canaux *rouge* et *vert*.
Comme nos valeurs étaient normalisées entre 0.0 and 1.0, on pouvait les utiliser comme des couleurs, ou dans les fonctions de formes, ou dans les interpolations.
La fonction [`step()`](../glossary/?search=step), va dessiner tous les pixels dont la valeur des *x* est inférieure à 0.1 en noir (`vec3(0.0)`) et tous les autres en blanc (`vec3(1.0)`).
Le fait de multiplier `gauche` par `bas` est équivalent à l'opérateur logique `AND` ; si les deux opérantions (`x<.1`et`y<.1`)renvoient1.0,lerésultatsera1.0,sinon,cesera0.0.
En l'occurrence, se servir du résultat (0 ou 1) de `step()` et le multiplier par une autre variable (la couleur par exemple).
Si le `step()` renvoie 1, la couleur se multipliera par 1 et restera la même, si le `step()` renvoie 0, la couleur se multipliera par 0 donc elle passe au noir.
C'est une technique que voue retrouverez souvent dans les shaders.
Nous pouvons économiser quelques lignes de code en passant les deux valeurs *x* et *y* au [`step()`](../glossary/?search=step) simultanément au lieu de faire deux appels à `step()` séparés, ce qui resemble à ça :
Décommentez les *lignes 21-22* et notez comment nous inversons les coordonnées de `st` (*1.0 - st*) et réutilisons le même appel à [`step()`](../glossary/?search=step).
Le `vec2 tr` contient à présent les réponses du test pour le coin haut droit. C'est l'équivalent numérique de : "retourner la page et appliquer la même procédure".
Le principe de cette technique est de se servir de [`step()`](../glossary/?search=step) et des multiplications comme d'opérateurs logiques et de retourner les coordonnées pour traiter les deux côtés de l'image.
* Utilisez [`smoothstep()`](../glossary/?search=smoothstep) au lieu de [`step()`](../glossary/?search=step). Notez comme les arêtes passent d'un rendu net à flou.
* Comment placer et déplacer plusieurs rectangles sur le canvas ? Si vous trouvez la réponse, tentez de créer une composition à la [Piet Mondrian](http://en.wikipedia.org/wiki/Piet_Mondrian).
Dessiner des carrés sur du papier millimétré est assez simple mais les cercles demandent un changement d'approche, notamment lorsqu'on doit traiter une masse de *pixels*.
Une solution est de *re-mapper* le système de coordonnées de manière à pouvoir utiliser la fonction [`step()`](../glossary/?search=step) pour dessiner un cercle.
Retournons à notre cours de math et à notre papier millimétré, on utilise un compas, on lui donne le bon rayon, on pose la pointe au centre du cercle et on trace le contour du cercle.
![](compass.jpg)
Traduire cette démarche dans un shader où chaque carré du papier est un pixel revient à *demander* à chaque pixel (ou thread ou fragment), s'il est à l'intérieur ou à l'extérieur du cercle.
Pour ce faire, nous allons donc calculer la distance de chaque fragment au centre de notre cercle.
Il existe plusieurs façons de calculer une distance. La plus simple est d'utiliser la fonction [`distance()`](../glossary/?search=distance), qui - en interne - calcule la longueur de la différence entre les deux points passés en arguments (dans notre cas, les coordonnées du pixel et la position du centre).
La fonction `length()` est simplement un raccourci pour [l'équation de l'hypoténuse](http://en.wikipedia.org/wiki/Hypotenuse) qui utilise la racine carrée [`sqrt()`](../glossary/?search=sqrt) de la somme des différences en *x* et *y*, au carré.
On peut donc utiliser indifféremment [`distance()`](../glossary/?search=distance), [`length()`](../glossary/?search=length) ou [`sqrt()`](../glossary/?search=sqrt) pour calculer la distance du pixel au centre du canvas.
Notez que les valeurs ne montent pas énorménent (jusqu'au blanc par exemple) parce que, la plus grande distance entre un pixel et le centre (`vec2(0.5, 0.5)`) dépasse péniblement 0.5.
Nous pouvons penser l'exemple ci-dessus comme étant une carte d'élévations ou les parties sombres seraient plus élevées.
Le dégradé du cercle ressemble à ce que serait un cone.
Imaginez vous au sommet de ce cone, la distance horizontale vers les bords du cone serait 0.5, elle est constante dans toutes les directions.
En choisissant à quelle hauteur on peut *couper* le cone, on obtiendra un disque plus ou moins grand.
![](distance-field.jpg)
En somme, on utilise une ré-interprétation de l'espace, en se basant sur la distance au centre plutôt que sur les coordonnées des pixels, pour créer des formes.
Cette technique s'appelle un "champ de distances" (Distance Field) et s'applique dans de nombreux contextes allant du dessin de contours à la 3D.
* Pouvez-vous animer le cercle pour qu'il grossisse et rapetisse ? Pour qu'il simule un battement de coeur ? Les animations du chapitre précédent vous aideront !
Les champs de distance permettent de dessiner à peu près n'importe quoi.
Evidemment, plus la forme est complexe, plus l'équation sera complexe mais une fois qu'on a la formule d'une forme en particulier, il devient assez simple de la combiner avec d'autres et/ou de lui appliquer des effets comme des bords lissés, ou plusieurs contours.
C'est pourquoi les champs de distances sont utilisés pour le rendu des polices de caractères: [Mapbox GL Labels](https://www.mapbox.com/blog/text-signed-distance-fields/), [Matt DesLauriers](https://twitter.com/mattdesl), [Material Design Fonts](http://mattdesl.svbtle.com/material-design-on-the-gpu) et [comme expliqué au chapitre 7 de "iPhone 3D Programming", O’Reilly](http://chimera.labs.oreilly.com/books/1234000001814/ch07.html#ch07_id36000921).
A la *ligne 24*, nous visualisons le champ de distances grâce à la fonction [`fract()`](../glossary/?search=fract) ce qui nous permet de mieux voir le motif qu'il crée.
Regardons la formule du champ de distances *ligne 19*. Nous calculons la distance entre chaque position et la coordonnée `( .3,.3 )` ( entre `st` et le vecteur `vec2(.3)`) pour chaque quadrant, c'est à ça que sert l'appel à [`abs()`](../glossary/?search=abs).
Si vous décommentez la *ligne 20*, vouz noterez que nous combinons les distances à ces 4 points en utilisant la fonction [`min()`](../glossary/?search=min) contre 0, ce qui produit un nouveau motif.
L'idée est qu'il n'y a qu'un seul point, et non '4', celui en haut à droite mais il est *reflété* dans les 3 autres *quadrants* du fait qu'on a changé la taille de l'espace *ligne 16* !
Remarquez comme les anneaux du champ de distance deviennent de plus en plus lissse à mesure qu'ils s'éloignent du centre.
Enfin, décommentez les *ligne 27 à 29* une par une pour comprendre les différentes utilisations du champ de distances.
### Formes polaires
![Robert Mangold - Untitled (2008)](mangold.jpg)
Au chapitre des couleurs, nous avons projeté (mappé) des coordonnées cartésiennes sur des coordonnées polaires en calculant un *rayon* et un *angle* entre chaque pixel et le centre grâce à la formule suivante:
La technique est un peu restrictive mais très simple : elle consiste à changer la valeur du *rayon* en fonction de l'*angle* pour obtenir une variété de formes.
Comment moduler cette longueur ? Avec des fonctions de formes bien sûr !
Nous venons de voir comment moduler le rayon d'un cercle en fonction d'un angle en utilisant la fonction [`atan()`](../glossary/?search=atan) pour dessiner différentes formes.
Voyons maintenant comment utiliser `atan()` avec un champ de distances de façon à pouvoir utiliser les effets qu'ils permettent.
L'astuce c'est d'utiliser le nombre de côtés d'un polygone régulier pour construire un champ de distances dans un espace polaire.
Pour plus d'informations, vous pouvez vous référer [au code suivant](http://thndl.com/square-shaped-shaders.html) par [Andrew Baldwin](https://twitter.com/baldand).
Faites une pause et laissez décanter ces nouveaux concepts.
Dessiner des formes dans une API de dessin, c'est facile mais ici c'est une autre histoire.
Au pays des shaders, dessiner des formes géométriques est un peu tordu et s'imposer la disciple nécessaire à la compréhension de ce paradigme est épuisant.
Maintenant que vous savez comment dessiner des formes, je suis sûr que ça va vous donner des idées.