123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- <!DOCTYPE html>
- <html lang="fr">
- <head>
- <meta charset="utf-8">
- <base href="../../../" />
- <script src="page.js"></script>
- <link type="text/css" rel="stylesheet" href="page.css" />
- <style>
- blockquote {
- font-size: 0.8em;
- line-height: 1.5em;
- margin-left: 0;
- border-left: 4px solid #cccccc;
- padding: 1em 2em 1em 2em;
- }
- blockquote p:first-child {
- margin-top: 0;
- }
- blockquote p:last-child {
- margin-bottom: 0;
- }
- figure {
- width: 100%;
- margin: 1em 0;
- font-style: italic;
- }
- figure img {
- width: 100%;
- }
- figure.float {
- float: right;
- max-width: 30%;
- margin: 1em;
- }
- @media all and ( max-width: 640px ) {
- figure.float {
- float: none;
- max-width: 100%;
- }
- }
- </style>
- </head>
- <body>
- <h1>Gestion des couleurs ([name])</h1>
- <h2>Qu'est ce qu'un espace colorimétrique?</h2>
- <p>
- 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.
- </p>
- <figure class="float">
- <img src="resources/srgb_gamut.png" alt="">
- <figcaption>
- 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: <a href="https://en.wikipedia.org/wiki/SRGB" target="_blank" rel="noopener">Wikipedia</a>
- </figcaption>
- </figure>
- <ul>
- <li>
- <b>Couleurs primaires:</b> 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.
- </li>
- <li>
- <b>Point blanc:</b> La plupart des espaces colorimétriques sont conçus de telle manière qu'une somme équivalente
- de couleurs primaires <i>R = G = B</i> 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].
- </li>
- <li>
- <b>Fonctions de transfert:</b> 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 <i>r = 0.5</i>
- représente 50% moins d'illumination physique que <i>r = 1.0</i>? 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 <i>linéaires</i> ou <i>non-linéaires</i>, 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 <i>fonctions gamma</i>, mais le terme "gamma" est
- ambigu et doit-être évité dans ce contexte.
- </li>
- </ul>
- 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:
- <ul>
- <li>
- <b>Le modèle de couleur:</b> 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 <i>r, g, b ∈ [0,1]</i> ("domaines fermés") ou
- <i>r, g, b ∈ [0,∞]</i> ("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.
- </li>
- <li>
- <b>La gamme de couleurs:</b> 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.
- </li>
- </ul>
- <p>
- 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.
- </p>
- <p>
- 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.
- </p>
- <blockquote>
- <p>
- ℹ️ <i><b>NOTE:</b> 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.</i>
- </p>
- </blockquote>
- <h2>Rôle des espaces colorimétriques</h2>
- <p>
- 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.
- </p>
- <h3>Espaces colorimétriques d'entrée</h3>
- <p>
- 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 <i>texture.colorSpace</i>.
- 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:
- </p>
- <code>
- THREE.ColorManagement.enabled = true;
- </code>
- <ul>
- <li>
- <b>Matériaux, lumières, et shaders:</b> Les couleurs des matériaux, lumières, et shaders stockent
- des composantes RGB dans l'espace colorimétrique sRGB-Linéaire.
- </li>
- <li>
- <b>Vertex colors:</b> [page:BufferAttribute BufferAttributes] stocke
- des composantes RGB dans l'espace colorimétrique sRGB-Linéaire.
- </li>
- <li>
- <b>Textures colorées:</b> 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
- <i>texture.colorSpace = SRGBColorSpace</i>. Des formats comme OpenEXR (parfois utilisés par .envMap pi
- .lightMap) utilisent l'espace colorimétrique sRGB-Linéaire indiqué par <i>texture.colorSpace = LinearSRGBColorSpace</i>,
- et peuvent contenir des valeurs du domaine ouvert [0,∞].
- </li>
- <li>
- <b>Textures non-colorées:</b> 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)
- <i>texture.colorSpace = NoColorSpace</i>. 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.
- </li>
- </ul>
- <blockquote>
- <p>
- ⚠️ <i><b>ATTENTION:</b> 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.</i>
- </p>
- </blockquote>
- <h3>Espaces colorimétriques fonctionnels</h3>
- <p>
- 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.
- </p>
- <h3>L'espace colorimétrique de sortie</h3>
- <p>
- 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.
- </p>
- <code>
- renderer.outputColorSpace = THREE.SRGBColorSpace; // optional with post-processing
- </code>
- <ul>
- <li>
- <b>Affichage:</b> Les couleurs envoyées à un canvas WebGL pour affichage doivent-être dans l'espace colorimétrique
- sRGB.
- </li>
- <li>
- <b>Image:</b> 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.
- </li>
- </ul>
- <blockquote>
- <p>
- ⚠️ <i><b>ATTENTION:</b> 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.</i>
- </p>
- </blockquote>
- <p>
- 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.
- </p>
- <h2>Utiliser des instances de THREE.Color</h2>
- <p>
- 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 <i>.convertLinearToSRGB()</i>
- ou <i>.convertSRGBToLinear()</i>.
- </p>
- <code>
- // 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
- </code>
- <p>
- Avec <i>ColorManagement.enabled = true</i> 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.
- </p>
- <code>
- // 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
- </code>
- <h2>Erreurs communes</h2>
- <p>
- 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.
- </p>
- <p>
- Un problème plus subtil peut se produire quand <i>à la fois</i> 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").
- </p>
- <h2>Lectures additionnelles</h2>
- <ul>
- <li>
- <a href="https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-24-importance-being-linear" target="_blank" rel="noopener">GPU Gems 3: The Importance of Being Linear</a>, par Larry Gritz et Eugene d'Eon
- </li>
- <li>
- <a href="https://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/" target="_blank" rel="noopener">What every coder should know about gamma</a>, par John Novak
- </li>
- <li>
- <a href="https://hg2dc.com/" target="_blank" rel="noopener">The Hitchhiker's Guide to Digital Color</a>, par Troy Sobotka
- </li>
- <li>
- <a href="https://docs.blender.org/manual/en/latest/render/color_management.html" target="_blank" rel="noopener">Color Management</a>, Blender
- </li>
- </ul>
- </body>
- </html>
|