Si vous connaissez la Programmation Orientée Objet, vous aurez remarqué que nous accédons aux données des vecteurs comme on le ferait avec des `struct` en C, grâce à des **accesseurs / mutateurs** (**getters / setters** en anglais).
Bien que cette pratique soit méconnue, il es possible d'utiliser des `struct` en GLSL, [plus d'informations ici](https://github.com/KhronosGroup/WebGL/blob/master/sdk/tests/conformance/glsl/misc/shader-with-array-of-structs-uniform.html).
Dans l'exemple ci dessus, *x*, *y* et *z* permettent d'**accéder** aux 3 valeurs contenues dans l'objet `red` de type `vec3`, ce sont les **accesseurs** aux propriétés de `red`.
Définir une couleur avec *x*, *y* et *z* peut être un peu déroutant, c'est pourquoi il existe différentes manières d'accéder aux valeurs des propriétés des vectuers.
Les valeurs de `.x`, `.y` et `.z` peuvent être récupérées avec les **accesseurs**`.r`, `.g` et `.b`, ou `.s`, `.t` et `.p`. (`.s`, `.t` et `.p` sont généralement utilisées pour encoder les coordonnées spatiales des textures, nous verrons ça dans les chapitres suivants).
Il est également possible d'accéder aux valeurs des propriétés des vecteurs par leur position d'index dans l'objet: `[0]`, `[1]` and `[2]`.
On peut les utiliser ces **accesseurs** de façon indépendante ; le code suivant crée un clone *newColor* du vecteur *color* en utilisant chaque fois un accesseur différent.
Il est possible de combiner les propriétés en **concaténant** les accesseurs : si on veut exploiter les valeurs `.r`, `.g` et `.b` d'un vecteur 4 sans se soucier de `.a` (l'alpha), on peut écrire :
On va utiliser les valeurs `.x` et `.y` de *color* pour construire un `vec3` dont les valeurs `.r` et `.g` seront les mêmes que les valeurs `.r` et `.g` du vecteur *color* et où la valeur `.b` sera `1.0`.
Un exemple d'utilisation, si on veut décrire un rectangle, on peut se servir soit de 2 `vec2` décrivant respectivement le coin supérieur gauche et le coin inférieur droit,
ou bien, utiliser un seul `vec4` dont l'**accesseur** `.xy` renverra un `vec2` décrivant le coin supérieur gauche, et l'**accesseur** `.zw` renverra un `vec2` décrivant le coin inférieur droit.
Ces différentes manière d'accéder aux variables à l'intérieur des vecteurs sont simplement là pour nous aider à écrire un code lisible.
Cette souplesse d'utilisation est le point d'entrée qui vous permettra de penser aux espaces cartésiens (le "vrai" espace) et colorimétriques de façon interchangeable.
La concaténation prend tout son sens lorsqu'on veut pouvoir combiner des vecteurs dans un ordre arbitraire pour les mélanger (cette propriété s'appelle le *swizzle*).
```glsl
vec3 jaune, magenta, vert;
// crée le jaune
jaune.rg = vec2(1.0); // Assigne 1. au canaux rouges et vert du vecteur jaune
jaune[2] = 0.0; // Assigne 0. au canal bleu du vecteur jaune
// crée le magenta
magenta = jaune.rbg; // Assigne the valeur en intervertissant le vert et le bleu ( rbg au lieu de rgb )
// crée le vert
vert.rgb = jaune.bgb; // Assigne le canal bleu du jaune (0) aux canaux rouges et bleus
```
#### Pour la boîte à outils
Si vous êtes incapables de choisir des couleurs par le biais des chiffres, c'est normal ; cela peut être très contre-intuitif.
Heureusement pour nous, il existe de nombreux programmes qui nous simplifient la tâche.
En GLSL, il existe une fonction extrêmement utile [`mix()`](../glossary/?search=mix), qui permet de mélanger deux valeurs en fonction d'un pourcentage.
Observez la ligne 18: notez que nous utilisons la valeur absolue (`abs()`) d'une fonction de sinus (`sin()`) prenant le temps en argument pour contrôler le mélange entre `colorA` et `colorB`.
* Quelle couleur représente le mieux cette émotion ? Comment apparaît-elle ? Comment disparaît-elle ?
* Pensez à une autre émotion et à la couleur correspondante, changez les couleur A et B dans le code puis utilisez les fonctions de formes pour opérer la transition.
Vous pouvez utiliser [cet exemple](../edit.php#06/easing.frag) comme base de recherche mais les meilleures transitions seront celles que vous ferez vous mêmes.
On ne peut pas parler de couleur sans parler d'espace colorimétrique. Vous le savez sans doute, il existe plusieurs façons d'organiser les canaux rouge, vert, bleu.
[HSB](http://en.wikipedia.org/wiki/HSL_and_HSV) signifie "Hue, Saturation, Brightness (ou Value)" soit en bon français "Teinte, Saturation, Luminosité", c'est une manière plus intuitive d'organiser les couleurs.
En indexant la Teinte (Hue) sur la position en *x* et la Luminosité (Brigthness) sur la position en *y*, nous obtenons un spectre des couleurs complet.
Cette distribution spatiale des couleurs peut être très pratique ; il est plus simple de choisir une couleur dans un espace HSB que dans un espace RGB.
<divclass="codeAndCanvas"data="hsb.frag"></div>
### HSB et coordonnées polaires
A l'origine, HSB a été conçu pour être représenté dans un système de coordonnées polaires.
Par opposition à un système de coordonnées cartésien décrit par 2 axes *X* et *Y* orthogonaux, un système de coordonnées polaires, est décrit par des *angles* et des *rayons*.
Pour dessiner notre fonction HSB, nous devons obtenir la position du centre du canvas de manière à connaître l'*angle* et la *distance* de chaque fragment au centre.
Pour cela nous allons utiliser la méthode [`length()`](../glossary/?search=length) et [`atan(y,x)`](../glossary/?search=atan) qui est l'équivalent GLSL de la méthode `atan2(y,x)`.
Lorsqu'on utilise des vecteurs avec des fonctions trigonométriques les variables de type `vec2`, `vec3` et `vec4` sont considérées comme des vecteurs géométriques même si elles représentent des couleurs.
Nous commencerons à traiter les couleurs et les vecteurs géométriques de façon similaire, en fait, vous devriez comprendre assez vite que cette flexibilité d'utilisation est une force.
**Note :** Si vous vous demandez s'il existe d'autres fonctions géométriques que [`length`](../glossary/?search=length)
comme : [`distance()`](../glossary/?search=distance), [`dot()`](../glossary/?search=dot), [`cross`](../glossary/?search=cross), [`normalize()`](../glossary/?search=normalize), [`faceforward()`](../glossary/?search=faceforward), [`reflect()`](../glossary/?search=reflect) et [`refract()`](../glossary/?search=refract), la réponse est oui.
GLSL expose également des méthodes pour comparer les vecteurs entres eux : [`lessThan()`](../glossary/?search=lessThan), [`lessThanEqual()`](../glossary/?search=lessThanEqual), [`greaterThan()`](../glossary/?search=greaterThan), [`greaterThanEqual()`](../glossary/?search=greaterThanEqual), [`equal()`](../glossary/?search=equal) et [`notEqual()`](../glossary/?search=notEqual).
Ligne 27, [`atan(y,x)`](../glossary/?search=atan) nous retourne un angle en radians compris entre *-PI* et *PI* (~-3.14 to ~3.14), pour le normaliser, nous devons diviser cet angle par *2 x PI*, la macro `TWO_PI` en début de code nous permet de stocker cette valeur.
En divisant l'angle par `TWO_PI`, nous obtenons un chiffre compris entre *-0.5* (`-PI / TWO_PI`) et *0.5* (`PI / TWO_PI`) auquel il nous suffit d'ajouter 0.5 pour qu'il soit compris entre *0.0* et *1.0*.
Le rayon (la distance du centre au fragment) retournera une valeur max de 0.5 en *x* et en *y* (parce que nous calculons la distance depuis le centre du canvas),
nous devons donc doubler cette valeur (en la multipliant par 2) pour obtenir un *rayon* compris entre *0.0* et *1.0*.
Vous voyez que tout est question de ramener les valeurs dans l'espace entre *0.0* et *1.0*, un espace *normalisé*.
* Si vous regardez attentivement la roue des couleurs qu'utilisent les sélecteurs de couleurs (voir l'image ci-dessous), ils affichent un spectre différent basé sur du RYB.
Pouvez vous trouver un moyen d'arranger ça de manière à obtenir exactement le meme rendu que sur l'image ? Indice: c'est un bon moment pour vous servir des fonctions de formes.
* Lisez [le livre de Josep's Alvers : L'Interaction des Couleurs](http://www.goodreads.com/book/show/111113.Interaction_of_Color) et servez vous des exemples suivants pour vous entraîner à reproduire ses exemples.
C'est ce qu'on appelle un [*qualifier*](http://www.shaderific.com/glsl-qualifiers/#inputqualifier) et dans ce cas précis, cela signifie que la variable est en lecture seule.
Dans les exemples suivants, nous verrons qu'il est également possible de donner les *qualifiers*`out` et `inout` aux variables passées aux fonctions.
Cette dernière, `inout`, est équivalente à passer un argument *par référence* en C ; cela nous donne la possibilité de modifier la valeur de la variable passée en argument.
Vous ne le savez pas encore et vous pourriez ne pas le croire mais nous avons à présent tout ce qu'il nous faut pour dessiner à peu près n'importe quoi.