mirror of
https://github.com/patriciogonzalezvivo/thebookofshaders
synced 2024-11-03 23:15:23 +00:00
Merge pull request #180 from yvan-sraka/fr-07
Corrects some mistakes in the French translation of Chapter 07
This commit is contained in:
commit
a1a4fb71bf
147
07/README-fr.md
147
07/README-fr.md
@ -2,39 +2,39 @@
|
|||||||
|
|
||||||
## Formes
|
## Formes
|
||||||
|
|
||||||
Enfin! Tous ce que nous avons appris nous a mené jusqu'à ce moment!
|
Enfin ! Tous ce que nous avons appris nous a mené jusqu'à ce moment !
|
||||||
Nous avons vu la plupart des bases, des types et des fonctions,
|
Nous avons vu la plupart des bases, des types et des fonctions,
|
||||||
nous avons répété nos fonctions de formes à une dimension, il est temps de faire marcher tout ça ensemble et vous êtes paré!
|
nous avons répété nos fonctions de formes à une dimension, il est temps de faire marcher tout ça ensemble et vous êtes paré !
|
||||||
Dans ce chapitre, vous apprendrez à dessiner des formes, de façon procédurale et en parallèle sur un GPU.
|
Dans ce chapitre, vous apprendrez à dessiner des formes, de façon procédurale et en parallèle sur un GPU.
|
||||||
|
|
||||||
### Rectangle
|
### Rectangle
|
||||||
|
|
||||||
Imaginons que nous avons un papier millimétré, comme à l'école, et nos devoirs consistent à dessiner un carré.
|
Imaginons que nous avons un papier millimétré, comme à l'école, et nos devoirs consistent à dessiner un carré.
|
||||||
la taille de la feuille est 10x10 et le carré doit mesurer 8x8, comment faire?
|
La taille de la feuille est 10x10 et le carré doit mesurer 8x8, comment faire ?
|
||||||
|
|
||||||
![](grid_paper.jpg)
|
![](grid_paper.jpg)
|
||||||
|
|
||||||
A priori nous allons colorier tout sauf: la première et la dernière rangée et la première et la dernière colonne, c'est bien ça?
|
A priori nous allons colorier tout sauf : la première et la dernière rangée et la première et la dernière colonne, c'est bien cela ?
|
||||||
|
|
||||||
En quoi est-ce lié aux shaders?
|
En quoi est-ce lié aux shaders ?
|
||||||
Chaque petit carré du papier millimétré est un thread (un pixel, ou fragment).
|
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.
|
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*.
|
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.
|
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.
|
||||||
Mais à présent, comment utiliser ces valeurs *x* et *y* normalisées pour dessiner un carré au centre du canvas?
|
Mais à présent, comment utiliser ces valeurs *x* et *y* normalisées pour dessiner un carré au centre du canvas ?
|
||||||
|
|
||||||
Commençons par utiliser un pseudocode se servant d'une condition ```if/else``` sur toute la taille du canvas.
|
Commençons par utiliser un pseudocode se servant d'une condition `if/else` sur toute la taille du canvas.
|
||||||
Le procédé est très proche de la démarche que nous avons eu avec le papier millimétré.
|
Le procédé est très proche de la démarche que nous avons eu avec le papier millimétré.
|
||||||
|
|
||||||
```glsl
|
```glsl
|
||||||
if ( (X SUPERIEUR A 1) AND (Y SUPERIEUR A 1) )
|
if ( (X SUPERIEUR A 1) AND (Y SUPERIEUR A 1) )
|
||||||
dessine en blanc
|
dessine en blanc
|
||||||
else
|
else
|
||||||
dessine en noir
|
dessine en noir
|
||||||
```
|
```
|
||||||
|
|
||||||
Nous avons une meilleure idée du code qu'il va falloir produire, nous allons remplacer les ```if``` par des [```step()```](../glossary/?search=step)
|
Nous avons une meilleure idée du code qu'il va falloir produire, nous allons remplacer les `if` par des [`step()`](../glossary/?search=step)
|
||||||
et au lieu d'utiliser 10x10, nous utiliserons les valeurs *x* et *y* normalisées entre 0.0 et 1.0:
|
et au lieu d'utiliser 10x10, nous utiliserons les valeurs *x* et *y* normalisées entre 0.0 et 1.0 :
|
||||||
|
|
||||||
```glsl
|
```glsl
|
||||||
uniform vec2 u_resolution;
|
uniform vec2 u_resolution;
|
||||||
@ -54,69 +54,69 @@ void main(){
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
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)```).
|
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) renvoient 1.0, le résultat sera 1.0, sinon, ce sera 0.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`) renvoient 1.0, le résultat sera 1.0, sinon, ce sera 0.0.
|
||||||
Cela nous permet de dessiner 2 lignes noires, une en bas et une à gauche du canvas.
|
Cela nous permet de dessiner 2 lignes noires, une en bas et une à gauche du canvas.
|
||||||
|
|
||||||
[NDT]En règle générale et bien que ce ne soit pas interdit, il est déconseillé d'utiliser les ```if``` dans un shader.
|
En règle générale et bien que ce ne soit pas interdit, il est déconseillé d'utiliser les `if` dans un shader.
|
||||||
ça peut paraître contre-intuitif mais la raison est simple, si on fait un ```if``` (ce qu'on appelle un *conditional branching*),
|
ça peut paraître contre-intuitif mais la raison est simple, si on fait un `if` (ce qu'on appelle un *conditional branching*),
|
||||||
le programme va devoir évaluer les 2 branches de toutes façons et cette évaluation va ralentir (voire anéantir) le bénifice d'utiliser le GPU.
|
le programme va devoir évaluer les 2 branches de toutes façons et cette évaluation va ralentir (voire anéantir) le bénifice d'utiliser le GPU.
|
||||||
Une stratégie pour parer à ce problème est de structurer le code de manière à éliminer les conditions, donc les branches.
|
Une stratégie pour parer à ce problème est de structurer le code de manière à éliminer les conditions, donc les branches.
|
||||||
En l'occurrence, se servir du résultat (0 ou 1) de ```step()``` et le multiplier par une autre variable (la couleur par exemple).
|
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.
|
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.[/NDT]
|
C'est une technique que voue retrouverez souvent dans les shaders.
|
||||||
|
|
||||||
![](rect-01.jpg)
|
![](rect-01.jpg)
|
||||||
|
|
||||||
Dans l'exemple ci-dessus, nous répétons la même opération sur chaque axe gauche et bas.
|
Dans l'exemple ci-dessus, nous répétons la même opération sur chaque axe gauche et bas.
|
||||||
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:
|
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 :
|
||||||
|
|
||||||
```glsl
|
```glsl
|
||||||
vec2 limites = step(vec2(0.1),st);
|
vec2 limites = step(vec2(0.1),st);
|
||||||
float pct = limites.x * limites.y;
|
float pct = limites.x * limites.y;
|
||||||
```
|
```
|
||||||
|
|
||||||
Nous avons à présent deux limites de notre rectangle: gauche et bas. Occupons nous des deux autres: haut et droite, regardez le code suivant:
|
Nous avons à présent deux limites de notre rectangle : gauche et bas. Occupons nous des deux autres : haut et droite, regardez le code suivant :
|
||||||
|
|
||||||
<div class="codeAndCanvas" data="rect-making.frag"></div>
|
<div class="codeAndCanvas" data="rect-making.frag"></div>
|
||||||
|
|
||||||
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).
|
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 `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".
|
||||||
|
|
||||||
![](rect-02.jpg)
|
![](rect-02.jpg)
|
||||||
Notez qu'aux *lignes 18 et 22*, tous les côtés sont multipliés entre eux, ce qui revient à écrire:
|
Notez qu'aux *lignes 18 et 22*, tous les côtés sont multipliés entre eux, ce qui revient à écrire :
|
||||||
|
|
||||||
```glsl
|
```glsl
|
||||||
vec2 bl = step(vec2(0.1),st); // bas-gauche
|
vec2 bl = step(vec2(0.1),st); // bas-gauche
|
||||||
vec2 tr = step(vec2(0.1),1.0-st); // haut-droit
|
vec2 tr = step(vec2(0.1),1.0-st); // haut-droit
|
||||||
color = vec3(bl.x * bl.y * tr.x * tr.y);
|
color = vec3(bl.x * bl.y * tr.x * tr.y);
|
||||||
```
|
```
|
||||||
|
|
||||||
Intéressant n'est ce pas?
|
Intéressant n'est ce pas ?
|
||||||
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.
|
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.
|
||||||
|
|
||||||
Avant d'aller plus loin, essayez les choses suivantes:
|
Avant d'aller plus loin, essayez les choses suivantes :
|
||||||
|
|
||||||
* Changer la taille et les proportions du rectangle.
|
* Changer la taille et les proportions du rectangle.
|
||||||
|
|
||||||
* Utilisez [```smoothstep()```](../glossary/?search=smoothstep) au lieu de [```step()```](../glossary/?search=step). Notez comme les arêtes passent d'un rendu net à flou.
|
* Utilisez [`smoothstep()`](../glossary/?search=smoothstep) au lieu de [`step()`](../glossary/?search=step). Notez comme les arêtes passent d'un rendu net à flou.
|
||||||
|
|
||||||
* Réimplémentez les conditions en utilisant [```floor()```](../glossary/?search=floor).
|
* Réimplémentez les conditions en utilisant [`floor()`](../glossary/?search=floor).
|
||||||
|
|
||||||
* Conservez votre version préférée et faites-en une version réutilisable, si possible une fonction flexible et efficace (pas de *if* par exemple).
|
* Conservez votre version préférée et faites-en une version réutilisable, si possible une fonction flexible et efficace (pas de *if* par exemple).
|
||||||
|
|
||||||
* Créez un fonction qui dessine uniquement l'extérieur du rectangle.
|
* Créez une fonction qui dessine uniquement l'extérieur du rectangle.
|
||||||
|
|
||||||
* 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).
|
* 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).
|
||||||
|
|
||||||
![Piet Mondria - Tableau (1921)](mondrian.jpg)
|
![Piet Mondria - Tableau (1921)](mondrian.jpg)
|
||||||
|
|
||||||
### Cercles
|
### Cercles
|
||||||
|
|
||||||
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*.
|
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.
|
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.
|
||||||
|
|
||||||
Comment?
|
Comment ?
|
||||||
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.
|
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)
|
![](compass.jpg)
|
||||||
@ -126,24 +126,24 @@ Pour ce faire, nous allons donc calculer la distance de chaque fragment au centr
|
|||||||
|
|
||||||
![](circle.jpg)
|
![](circle.jpg)
|
||||||
|
|
||||||
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).
|
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é.
|
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é.
|
||||||
|
|
||||||
![](hypotenuse.png)
|
![](hypotenuse.png)
|
||||||
|
|
||||||
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.
|
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.
|
||||||
Le code suivant contient ces trois fonctions et démontre sans surprise que les trois renvoient le même résultat.
|
Le code suivant contient ces trois fonctions et démontre sans surprise que les trois renvoient le même résultat.
|
||||||
|
|
||||||
* Commentez et décommentez les blocs pour utiliser les différentes manières de calculer la distance.
|
* Commentez et décommentez les blocs pour utiliser les différentes manières de calculer la distance.
|
||||||
|
|
||||||
<div class="codeAndCanvas" data="circle-making.frag"></div>
|
<div class="codeAndCanvas" data="circle-making.frag"></div>
|
||||||
|
|
||||||
Dans l'exemple ci-dessus, nous mappons la distance au centre du canvas sur la Valeur (la luminosité) du pixel de sortie.
|
Dans l'exemple ci-dessus, nous mappons la distance au centre du canvas sur la *valeur* (la luminosité) du pixel de sortie.
|
||||||
Plus on est proche du centre, moins la distance est grande donc plus le pixel est sombre.
|
Plus on est proche du centre, moins la distance est grande donc plus le pixel est sombre.
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
|
||||||
Prenez un moment pour observer et demandez vous:
|
Prenez un moment pour observer et demandez vous :
|
||||||
|
|
||||||
* Que peut-on déduire de ça?
|
* Que peut-on déduire de ça?
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ Prenez un moment pour observer et demandez vous:
|
|||||||
|
|
||||||
* Modifiez le code suivant pour faire tenir le dégradé complet du cercle à l'intérieur du canvas.
|
* Modifiez le code suivant pour faire tenir le dégradé complet du cercle à l'intérieur du canvas.
|
||||||
|
|
||||||
[NDT]en fait, la plus grande distance entre un pixel et le centre est: ```sqrt( 2.0 ) * .5``` soit environ *0.7071* [/NDT]
|
**Note :** Pour être exact, la plus grande distance entre un pixel et le centre est : `sqrt( 2.0 ) * .5` soit environ *0.7071* !
|
||||||
|
|
||||||
### Champ de distance (Distance field)
|
### Champ de distance (Distance field)
|
||||||
|
|
||||||
@ -167,21 +167,21 @@ Cette technique s'appelle un "champ de distances" (Distance Field) et s'applique
|
|||||||
|
|
||||||
Essayez les choses suivantes:
|
Essayez les choses suivantes:
|
||||||
|
|
||||||
* Utilisez [```step()```](../glossary/?search=step) pour passer toutes les valeurs supérieures à 0.5 en blanc et toutes les autres en noir.
|
* Utilisez [`step()`](../glossary/?search=step) pour passer toutes les valeurs supérieures à 0.5 en blanc et toutes les autres en noir.
|
||||||
|
|
||||||
* Inverser les couleurs d'avant plan et d'arrière plan.
|
* Inverser les couleurs d'avant plan et d'arrière plan.
|
||||||
|
|
||||||
* Utilisez [```smoothstep()```](../glossary/?search=smoothstep) et changez les paramètres pour ajouter un contour flou au cercle.
|
* Utilisez [`smoothstep()`](../glossary/?search=smoothstep) et changez les paramètres pour ajouter un contour flou au cercle.
|
||||||
|
|
||||||
* Quand vous obtenez un résultat satisfaisant, créez une fonction que vous pourrez réutiliser.
|
* Quand vous obtenez un résultat satisfaisant, créez une fonction que vous pourrez réutiliser.
|
||||||
|
|
||||||
* Ajoutez de la couleur.
|
* Ajoutez de la couleur.
|
||||||
|
|
||||||
* 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).
|
* 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 !
|
||||||
|
|
||||||
* Comment déplacer ce cercle? pouvez vous le déplacer et placer plusieurs cercles sur le même canvas?
|
* Comment déplacer ce cercle ? Pouvez vous le déplacer et placer plusieurs cercles sur le même canvas ?
|
||||||
|
|
||||||
* Que se passe-t'il quand on combine plusieurs champs de distances en utilisant différentes fonctions et opérations?
|
* Que se passe-t'il quand on combine plusieurs champs de distances en utilisant différentes fonctions et opérations ?
|
||||||
|
|
||||||
```glsl
|
```glsl
|
||||||
pct = distance(st,vec2(0.4)) + distance(st,vec2(0.6));
|
pct = distance(st,vec2(0.4)) + distance(st,vec2(0.6));
|
||||||
@ -191,17 +191,16 @@ pct = max(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
|
|||||||
pct = pow(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
|
pct = pow(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
|
||||||
```
|
```
|
||||||
|
|
||||||
* Faites trois compositions avec ces techniques, si elles bougent, c'est encore mieux!
|
* Faites trois compositions avec ces techniques, si elles bougent, c'est encore mieux !
|
||||||
|
|
||||||
#### Pour la boîte à outils
|
#### Pour la boîte à outils
|
||||||
|
|
||||||
La fonction [```sqrt()```](../glossary/?search=sqrt) - comme toutes les fonctions qui en dépendent - est assez gourmande en ressources.
|
La fonction [`sqrt()`](../glossary/?search=sqrt) - comme toutes les fonctions qui en dépendent - est assez gourmande en ressources.
|
||||||
Voici autre une technique permettant de créer un champ de distances basée sur la fonction [```dot()```](../glossary/?search=dot).
|
Voici autre une technique permettant de créer un champ de distances basée sur la fonction [`dot()`](../glossary/?search=dot).
|
||||||
|
|
||||||
<div class="codeAndCanvas" data="circle.frag"></div>
|
<div class="codeAndCanvas" data="circle.frag"></div>
|
||||||
|
|
||||||
[NDT]```dot()``` renvoie le produit scalaire de deux vecteurs: ```dot(a,b)=a.x * b.x + a.y * b.y;```[/NDT]
|
`dot()` renvoie le produit scalaire de deux vecteurs: `dot(a,b) = a.x * b.x + a.y * b.y;`
|
||||||
|
|
||||||
|
|
||||||
### Propriétés utiles des champs de Distances
|
### Propriétés utiles des champs de Distances
|
||||||
|
|
||||||
@ -216,16 +215,16 @@ Prenez le code suivant:
|
|||||||
<div class="codeAndCanvas" data="rect-df.frag"></div>
|
<div class="codeAndCanvas" data="rect-df.frag"></div>
|
||||||
|
|
||||||
On commence par déplacer le système de coordonnées au centre et à le diviser par deux pour obtenir des valeurs comprises entre -1 et 1.
|
On commence par déplacer le système de coordonnées au centre et à le diviser par deux pour obtenir des valeurs comprises entre -1 et 1.
|
||||||
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.
|
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.
|
||||||
Le motif du champ de distances se répète en cercles concentriques, à la manière d'un jardin zen.
|
Le motif du champ de distances se répète en cercles concentriques, à la manière d'un jardin zen.
|
||||||
|
|
||||||
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).
|
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.
|
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.
|
||||||
|
|
||||||
[NDT]en fait il n'y a qu'un seul point, pas '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*[NDT]
|
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* !
|
||||||
|
|
||||||
Essayez à présent de décommenter la *ligne 21*, nous utilisons cette fois la fonction [```max()```](../glossary/?search=max).
|
Essayez à présent de décommenter la *ligne 21*, nous utilisons cette fois la fonction [`max()`](../glossary/?search=max).
|
||||||
Le résultat est un rectangle aux bords arrondis.
|
Le résultat est un rectangle aux bords arrondis.
|
||||||
Remarquez comme les anneaux du champ de distance deviennent de plus en plus lissse à mesure qu'ils s'éloignent du centre.
|
Remarquez comme les anneaux du champ de distance deviennent de plus en plus lissse à mesure qu'ils s'éloignent du centre.
|
||||||
|
|
||||||
@ -238,17 +237,17 @@ Enfin, décommentez les *ligne 27 à 29* une par une pour comprendre les différ
|
|||||||
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:
|
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:
|
||||||
|
|
||||||
```glsl
|
```glsl
|
||||||
vec2 pos = vec2(0.5)-st;
|
vec2 pos = vec2(0.5)-st;
|
||||||
float r = length(pos)*2.0;
|
float r = length(pos)*2.0;
|
||||||
float a = atan(pos.y,pos.x);
|
float a = atan(pos.y,pos.x);
|
||||||
```
|
```
|
||||||
|
|
||||||
Nous avons ré-utilisé une partie de cette formule au début du chapitre pour dessiner un cercle.
|
Nous avons ré-utilisé une partie de cette formule au début du chapitre pour dessiner un cercle.
|
||||||
Nous calculions la distance en nous servant de [```length()```](../glossary/?search=length).
|
Nous calculions la distance en nous servant de [`length()`](../glossary/?search=length).
|
||||||
Maintenant que nous en savons plus sur les champs de distances, nous pouvons dessiner de nouvelles formes grâce aux coordonnées polaires.
|
Maintenant que nous en savons plus sur les champs de distances, nous pouvons dessiner de nouvelles formes grâce aux coordonnées polaires.
|
||||||
|
|
||||||
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.
|
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!
|
Comment moduler cette longueur ? Avec des fonctions de formes bien sûr !
|
||||||
|
|
||||||
Ci-dessous, vous trouverez les mêmes fonctions dans un espace cartésien et dans un espace polaire (entre les *lignes 21 et 25* du shader).
|
Ci-dessous, vous trouverez les mêmes fonctions dans un espace cartésien et dans un espace polaire (entre les *lignes 21 et 25* du shader).
|
||||||
Décommentez les fonctions une par une dans les deux démos pour comprendre les relations qui existent entre les deux systèmes de coordonnées.
|
Décommentez les fonctions une par une dans les deux démos pour comprendre les relations qui existent entre les deux systèmes de coordonnées.
|
||||||
@ -261,16 +260,16 @@ Décommentez les fonctions une par une dans les deux démos pour comprendre les
|
|||||||
|
|
||||||
<div class="codeAndCanvas" data="polar.frag"></div>
|
<div class="codeAndCanvas" data="polar.frag"></div>
|
||||||
|
|
||||||
Essayez de:
|
Essayez de :
|
||||||
|
|
||||||
* Animer les formes.
|
* Animer les formes.
|
||||||
* Combiner différentes fonctions de formes pour *creuser des trous* dans les formes pour faire des fleurs, des flocons et des engrenages.
|
* Combiner différentes fonctions de formes pour *creuser des trous* dans les formes pour faire des fleurs, des flocons et des engrenages.
|
||||||
* Utilisez la fonction ```plot()``` du chapitre sur les fonctions de forme pour ne garder que le contour.
|
* Utilisez la fonction `plot()` du chapitre sur les fonctions de forme pour ne garder que le contour.
|
||||||
|
|
||||||
### Combinatoires
|
### Combinatoires
|
||||||
|
|
||||||
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.
|
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.
|
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.
|
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).
|
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).
|
||||||
@ -279,15 +278,15 @@ Pour plus d'informations, vous pouvez vous référer [au code suivant](http://th
|
|||||||
|
|
||||||
* En reprenant cet exemple, créez une fonction qui reçoit une position et un nombre de côtés et retourne la valeur du champ de distance correspondant.
|
* En reprenant cet exemple, créez une fonction qui reçoit une position et un nombre de côtés et retourne la valeur du champ de distance correspondant.
|
||||||
|
|
||||||
* Mélangez les champs de distances en utilisant [```min()```](../glossary/?search=min) et [```max()```](../glossary/?search=max).
|
* Mélangez les champs de distances en utilisant [`min()`](../glossary/?search=min) et [`max()`](../glossary/?search=max).
|
||||||
|
|
||||||
* Choisissez un logo géométrique et reproduisez le avec des champs de distance.
|
* Choisissez un logo géométrique et reproduisez le avec des champs de distance.
|
||||||
|
|
||||||
Félicitations!
|
Félicitations !
|
||||||
Vous avez fait le plus dur!
|
Vous avez fait le plus dur !
|
||||||
Faites une pause et laissez décanter ces nouveaux concepts.
|
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.
|
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.
|
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.
|
Maintenant que vous savez comment dessiner des formes, je suis sûr que ça va vous donner des idées.
|
||||||
Au prochain chapitre, nous apprendrons à déplacer, à appliquer des rotations et à changer d'échelle pour créer des compositions!
|
Au prochain chapitre, nous apprendrons à déplacer, à appliquer des rotations et à changer d'échelle pour créer des compositions !
|
||||||
|
Loading…
Reference in New Issue
Block a user