Merge pull request #178 from yvan-sraka/fr-05

Corrects some mistakes in the French translation of Chapter 05
pull/181/head
Patricio Gonzalez Vivo 7 years ago committed by GitHub
commit 323828f0cb

@ -1,7 +1,7 @@
# Dessin Algorithmique
## fonctions de formes
## Fonctions de formes
Ce chapitre aurait pu s'appeler "la palissade de monsieur Miyagi" (ndt [pour ceux qui n'étaient pas nés en 1984](https://fr.wikipedia.org/wiki/Karat%C3%A9_Kid_(film,_1984))).
Ce chapitre aurait pu s'appeler "la palissade de monsieur Miyagi" ([pour ceux qui n'étaient pas nés en 1984](https://fr.wikipedia.org/wiki/Karat%C3%A9_Kid_(film,_1984))).
Au chapitre précédent, nous avons *mappé* les coordonnées *x* et *y* *normalisées* sur les canaux *rouge* et *vert*.
Nous avons créé une *fonction* qui prend un vecteur à deux dimensions (x et y) et retourne un vecteur à quatre dimensions (r, g, b et a).
@ -12,21 +12,21 @@ Plus vous passerez de temps à apprendre et à maîtriser ces fonctions, plus vo
![The Karate Kid (1984)](mr_miyagi.jpg)
Le code suivant sera notre palissade.
Sur cette palissade, nous visualisons la valeur normalisée de la position *x* (```st.x```) de deux façons: la luminosité (c'est le joli dégradé du noir au blanc en arrière plan) et une ligne verte dessinée par dessus (dans ce cas, la valeur *x* est assignée directement à *y*).
Ne vous focalisez pas trop sur la fonction ```plot``` pour l'instant, nous y reviendrons en détail dans un moment.
Sur cette palissade, nous visualisons la valeur normalisée de la position *x* (`st.x`) de deux façons : la luminosité (c'est le joli dégradé du noir au blanc en arrière plan) et une ligne verte dessinée par dessus (dans ce cas, la valeur *x* est assignée directement à *y*).
Ne vous focalisez pas trop sur la fonction `plot` pour l'instant, nous y reviendrons en détail dans un moment.
<div class="codeAndCanvas" data="linear.frag"></div>
**Note**: Le constructeur du type ```vec3```, un vecteur à 3 dimensions (r,g,b ou x,y,z ; c'est la même chose), "comprend" que vous allez le construire avec la même valeur pour les trois canaux/dimensions.
il est donc possible d'ecrire ```vec3 color = vec3( y );``` pour construire un vecteur à 3 dimensions. Ce vecteur aura la valeur ```y``` assignée à chaque canal/dimension soit: ```color.x = color.y = color.z = y``` ou ```color.r = color.g = color.b = y``` (puisqu'on peut accéder aux variables du vecteur des 2 manières).
Le constructeur du type ```vec4``` en revanche, "comprend" que vous allez le construire, soit en passant quatre valeurs dinstinctes: ```vec4( 0.,0.5,1.,1.)```, soit en lui passant un ```vec3``` et un ```float``` (un nombre) : ```vec4( color, 1.)```.
Dans notre cas, la valeur du second paramètre (le ```float```), permet de gérer l'*opacité* aussi appelé l'*alpha*.
**Note**: Le constructeur du type `vec3`, un vecteur à 3 dimensions (`r,g,b` ou `x,y,z` ; c'est la même chose), "comprend" que vous allez le construire avec la même valeur pour les trois canaux / dimensions.
Il est donc possible d'ecrire `vec3 color = vec3(y);` pour construire un vecteur à 3 dimensions. Ce vecteur aura la valeur `y` assignée à chaque canal / dimension soit : `color.x = color.y = color.z = y` ou `color.r = color.g = color.b = y` (puisqu'on peut accéder aux variables du vecteur des 2 manières).
Le constructeur du type `vec4` en revanche, "comprend" que vous allez le construire, soit en passant quatre valeurs dinstinctes : `vec4(0., 0.5, 1., 1.)`, soit en lui passant un `vec3` et un `float` (un nombre) : `vec4(color, 1.)`.
Dans notre cas, la valeur du second paramètre (le `float`), permet de gérer l'*opacité* aussi appelé l'*alpha*.
Référez vous aux lignes 20 et 26 dans l'exemple ci-dessus pour bien voir la différence de construction des 2 types.
Ce code sera votre palissade ; il est important de bien l'observer et de bien le comprendre.
Vous reviendrez souvent dans cet espace entre *0.0* and *1.0* pour maîtriser l'art de le transformer et de sculpter cette ligne.
Vous reviendrez souvent dans cet espace entre *0.0* et *1.0* pour maîtriser l'art de le transformer et de sculpter cette ligne.
La relation entre *x* et *y* ( la luminosité du dégradé ), s'appelle une *interpolation*.
La relation entre *x* et *y* (la luminosité du dégradé), s'appelle une *interpolation*.
Comme on passe une seule valeur (*y*) à la variable *color*, on obtient un niveau de gris et comme la valeur de *x* est *normalisée*, elle est comprise entre *0.0* et *1.0*, on obtient un dégradé du noir (*x=0.*) au blanc (*x=1.*).
L'*interpolation* est un principe fondamental ; elle nous permet de faire passer progressivement une valeur de *A* vers *B* en fonction d'une troisième valeur *T* normalisée entre *0.0* et *1.0*.
La ligne verte reflète ce qui se passe lors de l'interpolation, en l'occurrence, c'est une ligne droite puisque *x* passe de *0.0* à *1.0* de façon linéaire (*x* va de *0.0* à *1.0* de façon continue).
@ -34,88 +34,87 @@ A partir de là, nous pouvons utiliser des fonctions mathématiques pour *sculpt
<div class="codeAndCanvas" data="expo.frag"></div>
Intéressant n'est-ce-pas? A la ligne 19, au lieu de ```5.0``` essayez différents exposants, par exemple: 20.0, 2.0, 1.0, 0.0, 0.2 et 0.02.
Intéressant n'est-ce-pas ? A la ligne 19, au lieu de `5.0` essayez différents exposants, par exemple: `20.0`, `2.0`, `1.0`, `0.0`, `0.2` et `0.02`.
Comprendre la relation qui existe entre la valeur et l'exposant va nous être très utile.
Ce genre de fonction mathématique nous donne un contrôle sur l'*expressivité* du code, c'est une sorte d'acupuncture qui permet de contrôle les flux de valeurs.
[```pow()```](../glossary/?search=pow) est une fonction native de GLSL et il y en a de nombreuses autres.
[`pow()`](../glossary/?search=pow) est une fonction native de GLSL et il y en a de nombreuses autres.
La plupart sont accélérées matériellement, ce qui signifie que si on les utilise bien et avec parcimonie, elle permettent au code de s'exécuter plus vite.
Essayez de remplacer la fonction ```pow()``` ligne 19 par: [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log) ou [```sqrt()```](../glossary/?search=sqrt).
Certaines de ces fonctions deviennent vraiment intéressantes quand on les utilise avec PI. Vous pouvez voir que j'ai déclaré une macro qui remplacera chaque appel à ```PI``` par la valeur ```3.14159265359```.
par exemple: ```sin( st.x * PI )```, produira une parabole, ```pow( sin( st.x * PI ), 5. )``` effectuera un *pincement* de la parabole.
Essayez de remplacer la fonction `pow()` ligne 19 par: [`exp()`](../glossary/?search=exp), [`log()`](../glossary/?search=log) ou [`sqrt()`](../glossary/?search=sqrt).
Certaines de ces fonctions deviennent vraiment intéressantes quand on les utilise avec PI. Vous pouvez voir que j'ai déclaré une macro qui remplacera chaque appel à `PI` par la valeur `3.14159265359`.
Par exemple : `sin(st.x * PI)`, produira une parabole, `pow(sin(st.x * PI), 5.)` effectuera un *pincement* de la parabole.
### Step et Smoothstep
GLSL propose également des fonctions d'interpolation natives et accélrées matériellement.
La fonction [```step()```](../glossary/?search=step) prend 2 paramètres, le premier est une *limite* ou un *seuil* et le second est la valeur à tester.
Toute valeur inférieure au *seuil* renverra ```0.0``` tandis que toute valeur supérieure au *seuil* renverra ```1.0```.
La fonction [`step()`](../glossary/?search=step) prend 2 paramètres, le premier est une *limite* ou un *seuil* et le second est la valeur à tester.
Toute valeur inférieure au *seuil* renverra `0.0` tandis que toute valeur supérieure au *seuil* renverra `1.0`.
essayez de changer la valeur de *seuil* à la ligne 20 du code suivant.
Essayez de changer la valeur de *seuil* à la ligne 20 du code suivant :
<div class="codeAndCanvas" data="step.frag"></div>
L'autre fonction d'interpolation s'appelle [```smoothstep()```](../glossary/?search=smoothstep).
L'autre fonction d'interpolation s'appelle [`smoothstep()`](../glossary/?search=smoothstep).
Avec deux nombres *A* et *B* et une valeur d'interpolation *T* comprise entre *0.0* et *1.0*, elle nous permet de passer de progressivement (et en souplesse) de *A* à *B* en fonction de *T*.
les deux premiers arguments sont les *bornes* ( *A* et *B* ) et le troisième est la valeur d'interpolation (*T*).
Les deux premiers arguments sont les *bornes* (*A* et *B*) et le troisième est la valeur d'interpolation (*T*).
<div class="codeAndCanvas" data="smoothstep.frag"></div>
Dans l'exemple ci-dessus, ligne 12, vous remarquez qu'on a utilisé ```smoothstep()``` depuis le début dans la fonction ```plot()``` qui permet de dessiner la ligne verte.
Dans l'exemple ci-dessus, ligne 12, vous remarquez qu'on a utilisé `smoothstep()` depuis le début dans la fonction `plot()` qui permet de dessiner la ligne verte.
Pour chaque position le long de l'axe des *x*, cette fonction crée une *bosse* à un endroit précis de l'axe des *y*.
Comment? en combinant deux appels à [```smoothstep()```](../glossary/?search=smoothstep).
Remplacez la ligne 20 par la fonction suivante et regardez l'arrière plan, on dirait une ligne floutée non?
En rapprochant les valeurs de *seuil* des ```smoothstep()``` ( *0.45,0.5* et *0.5,0.55* par exemple), la ligne devient plus fine et moins floue.
Comment ? en combinant deux appels à [`smoothstep()`](../glossary/?search=smoothstep).
Remplacez la ligne 20 par la fonction suivante et regardez l'arrière plan, on dirait une ligne floutée non ?
En rapprochant les valeurs de *seuil* des `smoothstep()` (*0.45, 0.5* et *0.5, 0.55* par exemple), la ligne devient plus fine et moins floue.
```glsl
float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x);
float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x);
```
### Sinus et Cosinus
Le mieux, si vous voulez utiliser les maths pour animer ou passer d'une valeur à une autre, c'est d'être copain avec les sinus/cosinus.
Le mieux, si vous voulez utiliser les maths pour animer ou passer d'une valeur à une autre, c'est d'être copain avec les sinus et cosinus.
Ces deux fonctions trigonométriques combinées permettent de dessiner des cercles qui sont plus utiles que le couteau suisse de MacGyver.
Il est important de comprendre ce qu'elles font et comment les combiner.
Dans un mouchoir de poche, à partir d'un angle en radians (1 radian = PI / 180), le [cosinus](../glossary/?search=cos) renvoie la position *x* et le [sinus](../glossary/?search=sin) renvoie la position *y* d'un point sur un cercle de rayon 1.
Le fait que ces fonctions renvoient des valeurs *normalisées* (entre -1 et 1) de manière très 'continue' ou très 'souple', en fait un outil indispensable.
Le fait que ces fonctions renvoient des valeurs *normalisées* (entre -1 et 1) de manière très "continue" ou très "souple", en fait un outil indispensable.
![](sincos.gif)
S'il est difficile de comprendre cette relation entre sinus/cosinus et le cercle unitaire (de rayon 1), l'animation ci-dessus la résume assez bien visuellement.
S'il est difficile de comprendre cette relation entre sinus / cosinus et le cercle unitaire (de rayon 1), l'animation ci-dessus la résume assez bien visuellement.
<div class="simpleFunction" data="y = sin(x);"></div>
Regardez attentivement cette sinusoïde et surtout comment la valeur *y* oscille entre -1 et 1.
Comme nous l'avons vu sur l'exemple du temps au chapitre 3, on peut utiliser cette propriété temporelle de [```sin()```](../glossary/?search=sin) pour animer une valeur.
Si vous regardez cet exemple dans un navigateur, vous pouvez changer le code de la forumle ci-dessus pour voir comment la sinusoïde change (n'oubliez pas le point-virule en fin de ligne).
Comme nous l'avons vu sur l'exemple du temps au chapitre 3, on peut utiliser cette propriété temporelle de [`sin()`](../glossary/?search=sin) pour animer une valeur.
Si vous regardez cet exemple dans un navigateur, vous pouvez changer le code de la formule ci-dessus pour voir comment la sinusoïde change (n'oubliez pas le point-virule en fin de ligne).
Essayez les changements suivants et regardez ce qui se passe:
Essayez les changements suivants et regardez ce qui se passe :
* ajoutez le temps (```u_time```) à *x* avant de calculer ```sin```. Retenez ce **mouvement** le long des *x*.
* Ajoutez le temps (`u_time`) à *x* avant de calculer `sin`. Retenez ce **mouvement** le long des *x*.
* Multipliez *x* par ```PI``` avant de calculer ```sin```. remarquez comme les deux *phases* **rétrécissent** de manière à ce que chaque cycle (tour complet) se répète entre deux valeurs entières.
* Multipliez *x* par `PI` avant de calculer `sin`. remarquez comme les deux *phases* **rétrécissent** de manière à ce que chaque cycle (tour complet) se répète entre deux valeurs entières.
* Multipliez le temps (```u_time```) par *x* avant de calculer ```sin```. remarquez comme la **fréquence** entre phases se compresse. Notez qu'u_time peut déjà avoir une valeur très élevée, rendant le graphe illisible.
* Multipliez le temps (`u_time`) par *x* avant de calculer `sin`. remarquez comme la **fréquence** entre phases se compresse. Notez qu'`u_time` peut déjà avoir une valeur très élevée, rendant le graphe illisible.
* Ajoutez 1.0 à [```sin(x)```](../glossary/?search=sin). Notez que toutes les vagues se **déplacent** vers le haut et comme toutes les valeurs sont maintenant comprises entre 0 et 2.
* Ajoutez 1.0 à [`sin(x)`](../glossary/?search=sin). Notez que toutes les vagues se **déplacent** vers le haut et comme toutes les valeurs sont maintenant comprises entre 0 et 2.
* Multipliez [```sin(x)```](../glossary/?search=sin) par 2.0 et notez comme l'**amplitude** doubles de taille.
* Multipliez [`sin(x)`](../glossary/?search=sin) par 2.0 et notez comme l'**amplitude** doubles de taille.
* calculez la valeur absolue ([```abs()```](../glossary/?search=abs)) de ```sin(x)```, on dirait que le tracé **rebondit**.
* Calculez la valeur absolue ([`abs()`](../glossary/?search=abs)) de `sin(x)`, on dirait que le tracé **rebondit**.
* Utilisez la partie fractionnelle (uniquement les chiffres après la virgule) ([```fract()```](../glossary/?search=fract)) du résultat de [```sin(x)```](../glossary/?search=sin).
* Utilisez la partie fractionnelle (uniquement les chiffres après la virgule) ([`fract()`](../glossary/?search=fract)) du résultat de [`sin(x)`](../glossary/?search=sin).
* Ajoutez l'entier le plus grand ([```ceil()```](../glossary/?search=ceil)) à l'entier le plus petit ([```floor()```](../glossary/?search=floor)) du résultat de [```sin(x)```](../glossary/?search=sin) pour obtenir des *créneaux* entre -1 et 1.
* Ajoutez l'entier le plus grand ([`ceil()`](../glossary/?search=ceil)) à l'entier le plus petit ([`floor()`](../glossary/?search=floor)) du résultat de [`sin(x)`](../glossary/?search=sin) pour obtenir des *créneaux* entre -1 et 1.
### quelques fonctions indispensables
### Quelques fonctions indispensables
A la fin de l'exercice précédent, nous avons présenté quelques nouvelles fonctions, nous allons maintenant les tester.
Pour ce faire, décommentez une ligne à la fois dans la liste suivante.
Essayez de comprendre comment chacune fonctionne et comment vous pourriez les combiner.
Vous vous demandez sans doute mais... pourquoi?
Vous vous demandez sans doute mais... pourquoi ?
Une petite recherche de "generative art" sur Google vous apportera la réponse.
Gardez à l'esprit que ces fonctions sont votre palissade, nous apprenons à maîtriser le mouvement sur une dimension, de bas en haut, puis de haut en bas.
Bientôt, nous utiliserons, deux, trois et même quatre dimensions!
@ -132,24 +131,24 @@ Bientôt, nous utiliserons, deux, trois et même quatre dimensions!
//y = min(0.0,x); // renvoie le plus petit chiffre entre 0 et x
//y = max(0.0,x); // renvoie le plus grand chiffre entre 0 et x"></div>
### fonctions de formes avancées
### Fonctions de formes avancées
[Golan Levin](http://www.flong.com/) a écrit quelques articles très instructifs sur des fonctions plus complexes.
Les porter en GLSL est une bonne idée si vous souhaitez construire votre boîte à outils.
* [fonctions Polynomiales: www.flong.com/texts/code/shapers_poly](http://www.flong.com/texts/code/shapers_poly/)
* Fonctions Polynomiales : [www.flong.com/texts/code/shapers_poly](http://www.flong.com/texts/code/shapers_poly/)
* [fonctions Exponentielles: www.flong.com/texts/code/shapers_exp](http://www.flong.com/texts/code/shapers_exp/)
* Fonctions Exponentielles : [www.flong.com/texts/code/shapers_exp](http://www.flong.com/texts/code/shapers_exp/)
* [fonctions Circulaires & Elliptiques: www.flong.com/texts/code/shapers_circ](http://www.flong.com/texts/code/shapers_circ/)
* Fonctions Circulaires & Elliptiques : [www.flong.com/texts/code/shapers_circ](http://www.flong.com/texts/code/shapers_circ/)
* [fonctions de Bezier et autres fonctions paramétriques: www.flong.com/texts/code/shapers_bez](http://www.flong.com/texts/code/shapers_bez/)
* Fonctions de Bezier et autres fonctions paramétriques : [www.flong.com/texts/code/shapers_bez](http://www.flong.com/texts/code/shapers_bez/)
Comme un chef qui collectionnerait les épices et autres ingrédients exotiques, les artistes digitaux et les codeurs créatifs en particulier aiment travailler leurs propres fonctions de forme.
[Iñigo Quiles](http://www.iquilezles.org/) a écrit une liste de [fonctions utiles](http://www.iquilezles.org/www/articles/functions/functions.htm).
Après avoir lu [cet article](http://www.iquilezles.org/www/articles/functions/functions.htm) regardez leur traduction en GLSL.
Notez bien les petits changements nécessaires, comme le "." (point) sur les floats et l'utilisation des conventions de nommage GLSL pour les fonctions C ; par exemple ```powf()``` devient ```pow()```:
Notez bien les petits changements nécessaires, comme le "." (point) sur les floats et l'utilisation des conventions de nommage GLSL pour les fonctions C ; par exemple `powf()` devient `pow()`:
* [Impulse](../edit.php#05/impulse.frag)
* [Cubic Pulse](../edit.php#05/cubicpulse.frag)
@ -161,7 +160,7 @@ Pour vous motiver, voici un exemple élégant, fait par [Danguafer](https://www.
<iframe width="800" height="450" frameborder="0" src="https://www.shadertoy.com/embed/XsXXDn?gui=true&t=10&paused=true" allowfullscreen></iframe>
au prochain chapitre, nous utiliserons ces nouveaux mouvements. D'abord pour mélanger des couleurs, puis pour dessiner des formes.
Au prochain chapitre, nous utiliserons ces nouveaux mouvements. D'abord pour mélanger des couleurs, puis pour dessiner des formes.
#### Exercices
@ -176,14 +175,14 @@ Souvenez vous que plus vous pratiquerez, meilleur sera votre karaté.
Voici quelques outils qui simplifient la visualisation des fonctions.
* Grapher: si vous avez un MAC, tapez ```grapher``` dans spotlight et vous pourrez utiliser cet outil très pratique.
* Grapher : si vous avez MacOS, tapez `grapher` dans Spotlight et vous pourrez utiliser cet outil très pratique.
![OS X Grapher (2004)](grapher.png)
* [GraphToy](http://www.iquilezles.org/apps/graphtoy/): [Iñigo Quilez](http://www.iquilezles.org), encore lui, a créé un outil pour visualiser les fonctions GLSL en WebGL.
* [GraphToy](http://www.iquilezles.org/apps/graphtoy/) : [Iñigo Quilez](http://www.iquilezles.org), encore lui, a créé un outil pour visualiser les fonctions GLSL en WebGL.
![Iñigo Quilez - GraphToy (2010)](graphtoy.png)
* [Shadershop](http://tobyschachman.com/Shadershop/): [Toby Schachman](http://tobyschachman.com/) a créé cet outil génial qui permet de construire des fonctions de façon très intuitive.
* [Shadershop](http://tobyschachman.com/Shadershop/) : [Toby Schachman](http://tobyschachman.com/) a créé cet outil génial qui permet de construire des fonctions de façon très intuitive.
![Toby Schachman - Shadershop (2014)](shadershop.png)

Loading…
Cancel
Save