# Gestion des couleurs ([name])

## Qu'est ce qu'un espace colorimétrique?

Chaque espace colorimétrique est un ensemble de plusieurs décisions de design, choisies ensemble pour supporter un large éventail de couleurs tout en satisfaisant les contraites techniques liées à la précision et aux technologies d'affichage. Lors de la création d'un asset 3D, ou l'assemblage d'assets 3D ensemble dans une scène, il est important de savoir quelles sont ces propriétés, et comment les propriétés d'un espace colorimétrique se rapporte aux autres espaces colorimétriques de la scène.

Les couleurs sRGB et le point blanc (D65) affichées dans le modèle CIE 1931 chromaticity diagram. Les régions colorées représentent une projection 2D de la gamme sRGB, qui est un volume 3D. Source: Wikipedia

- Couleurs primaires: Les couleurs primaires (e.g. rouge, vert, bleu) ne sont pas absolues; elle sont sélectionnées depuis le spectre visible basé sur les contraintes de la précision limitée et les capacités des appareils d'affichage disponibles. Les couleurs sont exprimées comme un ratio des couleurs primaires.
- Point blanc: La plupart des espaces colorimétriques sont conçus de telle manière qu'une somme équivalente de couleurs primaires R = G = B apparaissent comme n'ayant pas de couleurs, ou "achromatique". L'apparition des valeurs chromatiques (comme le blanc ou le gris) dépend de la perception humaine, qui dépend elle-même fortement du contexte d'observation. Un espace colorimétrique spécifie son "point blanc" pour équilibrer ces besoins. Le point blanc définit par l'espace colorimétrique sRGB est [link:https://en.wikipedia.org/wiki/Illuminant_D65 D65].
- Fonctions de transfert: Après avoir choisir la gamme de couleur et le modèle de couleur, il nous reste à toujours définir le mapping ("fonctions de transfert") des valeurs numériques de l'espace colorimétrique. Est-ce-que r = 0.5 représente 50% moins d'illumination physique que r = 1.0? Ou 50% de luminosité en moins, comme perçu par l'oeil humain moyen? Ce sont différentes choses, et ces différences peuvent être représentées par une fonction mathématique. Les fonctions de transfert peuvent être linéaires ou non-linéaires, selon les objectifs de l'espace colorimétrique. Le sRGB définit des fonctions de transfert non-linéaires. Ces fonctions fonctions sont parfois approximées en fonctions gamma, mais le terme "gamma" est ambigu et doit-être évité dans ce contexte.

Ces trois paramètres — les couleurs primaires, le point blanc, et les fonctions de transfert — définissent un espace colorimétrique, chacun est choisi pour un objectif particulier. Après avoir défini les paramètres, quelques termes supplémentaires sont utiles:

- Le modèle de couleur: La syntaxe pour identifier naturellement les couleurs au sein de la gamme de couleur choisie — un système de coordonnées pour les couleurs. Dans three.js nous utilisons princpalement le système de couleurs RGB, ayant trois coordonnées r, g, b ∈ [0,1] ("domaines fermés") ou r, g, b ∈ [0,∞] ("domaine ouvert") chacune représentant une fraction d'une couleur primaire. D'autres modèles de couleurs (HSL, Lab, LCH) sont communément utilisés pour un contrôle artistique.
- La gamme de couleurs: Une fois que les couleurs primaires et le point blanc ont été choisis, ils représentent un volume parmis le spectre visible (une "gamme"). Les couleurs qui ne sont pas dans ce volume ("hors de la gamme") ne peuvent pas être exprimées par un domaine fermé [0,1] de valeurs RGB. Dans le domaine ouvert [0,∞], la gamme est théoriquement infinie.

Considérons deux espaces colorimétriques très communs: [page:SRGBColorSpace] ("sRGB") et [page:LinearSRGBColorSpace] ("sRGB-Linéaire"). Les deux utilisent les mêmes primaires et point blanc, et donc ont la même gamme de couleur. Le deux utilisent le modèle RGB. Leur seule différence sont les fonctions de transfert — Le sRGB-Linéaire est linéaire et respecte l'intensité physique de la lumière. Le sRGB utilise les fonctions de transfert non-linéaire du sRGB, et reproduit de manière plus proche la façon dont l'oeil humain perçoit la lumière et la réactivité des écrans.

Cette différence est imporante. Les calculs de lumières et les autres opérations de rendu doivent généralement se produire dans un espace de lumière linéaire. Cependant, les espaces colorimétriques linéaires sont moins efficaces dans le stockage d'images ou de framebuffer, et semblent incorrects qiuand ils sont vus par un humain. Par conséquent, les textures d'entrée et l'image du rendu final vont généralement utiliser l'espace colorimétrique sRGB non-linéaire.

> ℹ️ NOTE: Alors que certains écrans modernes supportent des gammes plus larges comme Display-P3, les APIs graphiques du web reposent largement sur le sRGB. Les applications utilisant three.js aujourd'hui utilisent généralement uniquement le sRGB et les espaces colorimétriques sRGB-linéaires.

## Rôle des espaces colorimétriques

Workflows linéaires — requis pour les méthodes de rendu modernes — ils impliquent généralement plus d'un espace de couleur, chacun assigné à un rôle particulier. Les espace colorimétriques linéaires et non-linéaires sont appropriés pour différents usages, expliqués ci-dessous.

### Espaces colorimétriques d'entrée

Les couleurs fournies à three.js — par les sélecteurs de couleurs, les textures, les modèles 3D, et d'autres sources — ont toutes un espace colorimétrique associé. Celles qui ne sont pas déjà dans l'espace colorimétrique sRGB-Linéaire doivent-être converties, et les textures doivent recevoir les bonnes consignes de texture.colorSpace. Certaines conversions (pour l'héxadecimal et les couleurs CSS en sRGB) peuvent être automatisées si l'héritage de la gestion des couleurs est désactivé avant l'initialisation des couleurs:

`THREE.ColorManagement.enabled = true;`

- Matériaux, lumières, et shaders: Les couleurs des matériaux, lumières, et shaders stockent des composantes RGB dans l'espace colorimétrique sRGB-Linéaire.
- Vertex colors: [page:BufferAttribute BufferAttributes] stocke des composantes RGB dans l'espace colorimétrique sRGB-Linéaire.
- Textures colorées: PNG ou JPEG [page:Texture Textures] contiennent des informations de couleurs (comme .map ou .emissiveMap) utilisant le domaine fermé de l'espace colorimétrique sRGB, et doivent être annotés avec texture.colorSpace = SRGBColorSpace. Des formats comme OpenEXR (parfois utilisés par .envMap pi .lightMap) utilisent l'espace colorimétrique sRGB-Linéaire indiqué par texture.colorSpace = LinearSRGBColorSpace, et peuvent contenir des valeurs du domaine ouvert [0,∞].
- Textures non-colorées: Les textures qui ne stockent aucune information de couleur (comme .normalMap ou .roughnessMap) n'ont pas d'espace colorimétrique associé, et utilisent généralement l'annotation de texture (par défaut) texture.colorSpace = NoColorSpace. Dans de rares cas, les données ne concernant pas la couleur peuvent être représentées par d'autres encodages non-linéaires pour des raisons techniques.

> ⚠️ ATTENTION: Plusieurs formats de modèles 3D ne définissent par correctement ou de manière cohérente les informations des espaces colorimétriques. Malgré le fait que three.js tente de gérer la plupart des situations, les problèmes sont communs avec les formats de fichiers plus anciens. Pour de meilleurs résultats, utilisez glTF 2.0 ([page:GLTFLoader]) et testez vos modèles 3D dans des visualiseurs en ligne relativement tôt pour vérifier que le modèle est correct en tant que tel.

### Espaces colorimétriques fonctionnels

Le rendu, l'interpolation, et plusieurs autres opérations doivent être performées dans un espace colorimétrique au domaine ouvert, dans lequel les composantes RGB sont proportionnelles à l'illumination physique. Dans three.js, l'espace colorimétrique est le sRGB-Linéaire.

### L'espace colorimétrique de sortie

La sortie d'un écran, d'une image, ou d'une vidéo peut impliquer la conversion depuis un espace colorimétrique sRGB-Linéaire au domaine ouvert vers un autre espace colorimétrique. Cette conversion peut être effectuée dans le pass principal du moteur de rendu ([page:WebGLRenderer.outputColorSpace]), ou durant le post-processing.

`renderer.outputColorSpace = THREE.SRGBColorSpace; // optional with post-processing`

- Affichage: Les couleurs envoyées à un canvas WebGL pour affichage doivent-être dans l'espace colorimétrique sRGB.
- Image: Les couleurs envoyées à une image doivent utiliser l'espace colorimétrique approprié au format et à l'utilisation. Les images entièrement rendues sur des textures au format PNG ou JPEG utilisent généralement l'espace colorimétrique sRGB. Les images contenant de l'émission, des light maps, ou d'autres données qui ne sont pas restreintes à l'intervalle [0,1] utiliseront généralement l'espace colorimétrique sRGB à domaine ouvert, et un format d'image compatible comme OpenEXR.

> ⚠️ ATTENTION: Les cibles de rendu doivent utiliser soit le sRGB soit le sRGB-Linéaire. Le sRGB gère mieux la précision limitée. Dans le domaine fermé, 8 bits suffisent généralement au sRGB tandis que ≥12 bits (demi float) peuvent être requis pour du sRGB-Linéaire. Si les étapes ultérieures du pipeline nécessitent une entrée en sRGB-Linéaire, les conversions additionnelles peuvent avoir un petit impact sur les performances.

Custom materials based on [page:ShaderMaterial] and [page:RawShaderMaterial] have to implement their own output color space conversion. For instances of `ShaderMaterial`, adding the `colorspace_fragment` shader chunk to the fragment shader's `main()` function should be sufficient.

## Utiliser des instances de THREE.Color

Les méthodes de lecture ou de modification des instances de [page:Color] partent du principe que les données sont déjà dans l'espace colorimétrique de three.js, le sRGB-Linéaire. Les composantes RGB et HSL sont des représentations directes de données stockées par l'instance Color, et ne sont jamais converties implicitement. Les données Color peuvent être explicitement converties avec .convertLinearToSRGB() ou .convertSRGBToLinear().

`// RGB components (no change). color.r = color.g = color.b = 0.5; console.log( color.r ); // → 0.5 // Manual conversion. color.r = 0.5; color.convertSRGBToLinear(); console.log( color.r ); // → 0.214041140`

Avec ColorManagement.enabled = true d'activé (recommandé), certaines conversions sont faites automatiquement. Parce que l'héxadécimal et les couleurs CSS sont généralement en sRGB, les méthodes [page:Color] vont automatiquement convertir ces entrées du sRGB au sRGB-Linéaire dans des setters, ou convertir depuis du sRGB-Linéaire au sRGB lors du renvoi de valeurs héxadécimales ou CSS depuis les getters.

`// Hexadecimal conversion. color.setHex( 0x808080 ); console.log( color.r ); // → 0.214041140 console.log( color.getHex() ); // → 0x808080 // CSS conversion. color.setStyle( 'rgb( 0.5, 0.5, 0.5 )' ); console.log( color.r ); // → 0.214041140 // Override conversion with 'colorSpace' argument. color.setHex( 0x808080, LinearSRGBColorSpace ); console.log( color.r ); // → 0.5 console.log( color.getHex( LinearSRGBColorSpace ) ); // → 0x808080 console.log( color.getHex( SRGBColorSpace ) ); // → 0xBCBCBC`

## Erreurs communes

Quand une couleur ou une texture individuelle est mal configurée, elle apparaîtra plus lumineuse ou plus sombre qu'attendu. Quand l'espace colorimétrique de sortie du moteur de rendu est mal configuré, la scène entière peut sembler plus sombre (e.g. conversion manquante vers le sRGB) ou plus lumineuse (e.g. une double conversion vers le sRGB avec du post-processing). Dans chaque cas le problème peut ne pas être uniforme, et simplement augmenter/diminuer peut ne pas le résoudre.

Un problème plus subtil peut se produire quand à la fois l'espace colorimétrique d'entrée et l'espace colorimétrique de sortie sont incorrects — les niveaux de luminosité globaux peuvent être corrects, mais les couleurs peuvent changer d'une manière inattendue sous différentes lumières, ou des ombres peuvent sembler plus abruptes et moins lisses que prévu. Ces deux erreurs assemblées ne forment pas une réussite, et il est important que l'espace colorimétrique soit linéaire ("scene referred") et que l'espace colorimétrique de sortie soit linéaire ("display referred").

## Lectures additionnelles

- GPU Gems 3: The Importance of Being Linear, par Larry Gritz et Eugene d'Eon
- What every coder should know about gamma, par John Novak
- The Hitchhiker's Guide to Digital Color, par Troy Sobotka
- Color Management, Blender