Color-management.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. <!DOCTYPE html>
  2. <html lang="fr">
  3. <head>
  4. <meta charset="utf-8">
  5. <base href="../../../" />
  6. <script src="page.js"></script>
  7. <link type="text/css" rel="stylesheet" href="page.css" />
  8. <style>
  9. blockquote {
  10. font-size: 0.8em;
  11. line-height: 1.5em;
  12. margin-left: 0;
  13. border-left: 4px solid #cccccc;
  14. padding: 1em 2em 1em 2em;
  15. }
  16. blockquote p:first-child {
  17. margin-top: 0;
  18. }
  19. blockquote p:last-child {
  20. margin-bottom: 0;
  21. }
  22. figure {
  23. width: 100%;
  24. margin: 1em 0;
  25. font-style: italic;
  26. }
  27. figure img {
  28. width: 100%;
  29. }
  30. figure.float {
  31. float: right;
  32. max-width: 30%;
  33. margin: 1em;
  34. }
  35. @media all and ( max-width: 640px ) {
  36. figure.float {
  37. float: none;
  38. max-width: 100%;
  39. }
  40. }
  41. </style>
  42. </head>
  43. <body>
  44. <h1>Gestion des couleurs ([name])</h1>
  45. <h2>Qu'est ce qu'un espace colorimétrique?</h2>
  46. <p>
  47. Chaque espace colorimétrique est un ensemble de plusieurs décisions de design, choisies ensemble pour supporter
  48. un large éventail de couleurs tout en satisfaisant les contraites techniques liées à la précision et aux technologies
  49. d'affichage. Lors de la création d'un asset 3D, ou l'assemblage d'assets 3D ensemble dans une scène, il est
  50. important de savoir quelles sont ces propriétés, et comment les propriétés d'un espace colorimétrique se rapporte
  51. aux autres espaces colorimétriques de la scène.
  52. </p>
  53. <figure class="float">
  54. <img src="resources/srgb_gamut.png" alt="">
  55. <figcaption>
  56. Les couleurs sRGB et le point blanc (D65) affichées dans le modèle CIE 1931 chromaticity
  57. diagram. Les régions colorées représentent une projection 2D de la gamme sRGB, qui est un
  58. volume 3D. Source: <a href="https://en.wikipedia.org/wiki/SRGB" target="_blank" rel="noopener">Wikipedia</a>
  59. </figcaption>
  60. </figure>
  61. <ul>
  62. <li>
  63. <b>Couleurs primaires:</b> Les couleurs primaires (e.g. rouge, vert, bleu) ne sont pas absolues; elle sont
  64. sélectionnées depuis le spectre visible basé sur les contraintes de la précision limitée et
  65. les capacités des appareils d'affichage disponibles. Les couleurs sont exprimées comme un ratio des couleurs primaires.
  66. </li>
  67. <li>
  68. <b>Point blanc:</b> La plupart des espaces colorimétriques sont conçus de telle manière qu'une somme équivalente
  69. de couleurs primaires <i>R = G = B</i> apparaissent comme n'ayant pas de couleurs, ou "achromatique". L'apparition
  70. des valeurs chromatiques (comme le blanc ou le gris) dépend de la perception humaine, qui dépend elle-même
  71. fortement du contexte d'observation. Un espace colorimétrique spécifie son "point blanc" pour équilibrer
  72. ces besoins. Le point blanc définit par l'espace colorimétrique sRGB est
  73. [link:https://en.wikipedia.org/wiki/Illuminant_D65 D65].
  74. </li>
  75. <li>
  76. <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
  77. le mapping ("fonctions de transfert") des valeurs numériques de l'espace colorimétrique. Est-ce-que <i>r = 0.5</i>
  78. représente 50% moins d'illumination physique que <i>r = 1.0</i>? Ou 50% de luminosité en moins, comme perçu
  79. par l'oeil humain moyen? Ce sont différentes choses, et ces différences peuvent être représentées par
  80. une fonction mathématique. Les fonctions de transfert peuvent être <i>linéaires</i> ou <i>non-linéaires</i>, selon
  81. les objectifs de l'espace colorimétrique. Le sRGB définit des fonctions de transfert non-linéaires. Ces fonctions
  82. fonctions sont parfois approximées en <i>fonctions gamma</i>, mais le terme "gamma" est
  83. ambigu et doit-être évité dans ce contexte.
  84. </li>
  85. </ul>
  86. Ces trois paramètres — les couleurs primaires, le point blanc, et les fonctions de transfert — définissent un
  87. espace colorimétrique, chacun est choisi pour un objectif particulier. Après avoir défini les paramètres, quelques termes supplémentaires
  88. sont utiles:
  89. <ul>
  90. <li>
  91. <b>Le modèle de couleur:</b> La syntaxe pour identifier naturellement les couleurs au sein de la gamme de couleur choisie —
  92. un système de coordonnées pour les couleurs. Dans three.js nous utilisons princpalement le système de couleurs RGB,
  93. ayant trois coordonnées <i>r, g, b ∈ [0,1]</i> ("domaines fermés") ou
  94. <i>r, g, b ∈ [0,∞]</i> ("domaine ouvert") chacune représentant une fraction d'une couleur
  95. primaire. D'autres modèles de couleurs (HSL, Lab, LCH) sont communément utilisés pour un contrôle artistique.
  96. </li>
  97. <li>
  98. <b>La gamme de couleurs:</b> Une fois que les couleurs primaires et le point blanc ont été choisis, ils représentent
  99. un volume parmis le spectre visible (une "gamme"). Les couleurs qui ne sont pas dans ce volume ("hors de la gamme")
  100. ne peuvent pas être exprimées par un domaine fermé [0,1] de valeurs RGB. Dans le domaine ouvert [0,∞], la gamme est
  101. théoriquement infinie.
  102. </li>
  103. </ul>
  104. <p>
  105. Considérons deux espaces colorimétriques très communs: [page:SRGBColorSpace] ("sRGB") et
  106. [page:LinearSRGBColorSpace] ("sRGB-Linéaire"). Les deux utilisent les mêmes primaires et point blanc,
  107. et donc ont la même gamme de couleur. Le deux utilisent le modèle RGB. Leur seule différence sont
  108. les fonctions de transfert — Le sRGB-Linéaire est linéaire et respecte l'intensité physique de la lumière.
  109. Le sRGB utilise les fonctions de transfert non-linéaire du sRGB, et reproduit de manière plus proche la façon dont
  110. l'oeil humain perçoit la lumière et la réactivité des écrans.
  111. </p>
  112. <p>
  113. Cette différence est imporante. Les calculs de lumières et les autres opérations de rendu doivent
  114. généralement se produire dans un espace de lumière linéaire. Cependant, les espaces colorimétriques linéaires sont moins efficaces
  115. dans le stockage d'images ou de framebuffer, et semblent incorrects qiuand ils sont vus par un humain.
  116. Par conséquent, les textures d'entrée et l'image du rendu final vont généralement utiliser l'espace colorimétrique
  117. sRGB non-linéaire.
  118. </p>
  119. <blockquote>
  120. <p>
  121. ℹ️ <i><b>NOTE:</b> Alors que certains écrans modernes supportent des gammes plus larges comme Display-P3,
  122. les APIs graphiques du web reposent largement sur le sRGB. Les applications utilisant three.js
  123. aujourd'hui utilisent généralement uniquement le sRGB et les espaces colorimétriques sRGB-linéaires.</i>
  124. </p>
  125. </blockquote>
  126. <h2>Rôle des espaces colorimétriques</h2>
  127. <p>
  128. Workflows linéaires — requis pour les méthodes de rendu modernes — ils impliquent généralement
  129. plus d'un espace de couleur, chacun assigné à un rôle particulier. Les espace colorimétriques linéaires et non-linéaires
  130. sont appropriés pour différents usages, expliqués ci-dessous.
  131. </p>
  132. <h3>Espaces colorimétriques d'entrée</h3>
  133. <p>
  134. Les couleurs fournies à three.js — par les sélecteurs de couleurs, les textures, les modèles 3D, et d'autres sources —
  135. ont toutes un espace colorimétrique associé. Celles qui ne sont pas déjà dans l'espace colorimétrique sRGB-Linéaire
  136. doivent-être converties, et les textures doivent recevoir les bonnes consignes de <i>texture.colorSpace</i>.
  137. Certaines conversions (pour l'héxadecimal et les couleurs CSS en sRGB) peuvent être automatisées si
  138. l'héritage de la gestion des couleurs est désactivé avant l'initialisation des couleurs:
  139. </p>
  140. <code>
  141. THREE.ColorManagement.enabled = true;
  142. </code>
  143. <ul>
  144. <li>
  145. <b>Matériaux, lumières, et shaders:</b> Les couleurs des matériaux, lumières, et shaders stockent
  146. des composantes RGB dans l'espace colorimétrique sRGB-Linéaire.
  147. </li>
  148. <li>
  149. <b>Vertex colors:</b> [page:BufferAttribute BufferAttributes] stocke
  150. des composantes RGB dans l'espace colorimétrique sRGB-Linéaire.
  151. </li>
  152. <li>
  153. <b>Textures colorées:</b> PNG ou JPEG [page:Texture Textures] contiennent des informations de couleurs
  154. (comme .map ou .emissiveMap) utilisant le domaine fermé de l'espace colorimétrique sRGB, et doivent être annotés avec
  155. <i>texture.colorSpace = SRGBColorSpace</i>. Des formats comme OpenEXR (parfois utilisés par .envMap pi
  156. .lightMap) utilisent l'espace colorimétrique sRGB-Linéaire indiqué par <i>texture.colorSpace = LinearSRGBColorSpace</i>,
  157. et peuvent contenir des valeurs du domaine ouvert [0,∞].
  158. </li>
  159. <li>
  160. <b>Textures non-colorées:</b> Les textures qui ne stockent aucune information de couleur (comme .normalMap
  161. ou .roughnessMap) n'ont pas d'espace colorimétrique associé, et utilisent généralement l'annotation de texture (par défaut)
  162. <i>texture.colorSpace = NoColorSpace</i>. Dans de rares cas, les données ne concernant pas la couleur
  163. peuvent être représentées par d'autres encodages non-linéaires pour des raisons techniques.
  164. </li>
  165. </ul>
  166. <blockquote>
  167. <p>
  168. ⚠️ <i><b>ATTENTION:</b> Plusieurs formats de modèles 3D ne définissent par correctement ou de manière cohérente
  169. les informations des espaces colorimétriques. Malgré le fait que three.js tente de gérer la plupart des situations, les problèmes
  170. sont communs avec les formats de fichiers plus anciens. Pour de meilleurs résultats, utilisez glTF 2.0 ([page:GLTFLoader])
  171. 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>
  172. </p>
  173. </blockquote>
  174. <h3>Espaces colorimétriques fonctionnels</h3>
  175. <p>
  176. Le rendu, l'interpolation, et plusieurs autres opérations doivent être performées dans un espace colorimétrique
  177. au domaine ouvert, dans lequel les composantes RGB sont proportionnelles
  178. à l'illumination physique. Dans three.js, l'espace colorimétrique est le sRGB-Linéaire.
  179. </p>
  180. <h3>L'espace colorimétrique de sortie</h3>
  181. <p>
  182. La sortie d'un écran, d'une image, ou d'une vidéo peut impliquer la conversion depuis un espace colorimétrique
  183. sRGB-Linéaire au domaine ouvert vers un autre espace colorimétrique. Cette conversion peut être effectuée dans
  184. le pass principal du moteur de rendu ([page:WebGLRenderer.outputColorSpace]), ou durant le post-processing.
  185. </p>
  186. <code>
  187. renderer.outputColorSpace = THREE.SRGBColorSpace; // optional with post-processing
  188. </code>
  189. <ul>
  190. <li>
  191. <b>Affichage:</b> Les couleurs envoyées à un canvas WebGL pour affichage doivent-être dans l'espace colorimétrique
  192. sRGB.
  193. </li>
  194. <li>
  195. <b>Image:</b> Les couleurs envoyées à une image doivent utiliser l'espace colorimétrique approprié au
  196. format et à l'utilisation. Les images entièrement rendues sur des textures au format PNG ou JPEG
  197. utilisent généralement l'espace colorimétrique sRGB. Les images contenant de l'émission, des light maps, ou d'autres données
  198. qui ne sont pas restreintes à l'intervalle [0,1] utiliseront généralement l'espace colorimétrique sRGB à domaine ouvert,
  199. et un format d'image compatible comme OpenEXR.
  200. </li>
  201. </ul>
  202. <blockquote>
  203. <p>
  204. ⚠️ <i><b>ATTENTION:</b> Les cibles de rendu doivent utiliser soit le sRGB soit le sRGB-Linéaire. Le sRGB gère
  205. mieux la précision limitée. Dans le domaine fermé, 8 bits suffisent généralement au sRGB
  206. tandis que ≥12 bits (demi float) peuvent être requis pour du sRGB-Linéaire. Si les étapes ultérieures
  207. du pipeline nécessitent une entrée en sRGB-Linéaire, les conversions additionnelles peuvent
  208. avoir un petit impact sur les performances.</i>
  209. </p>
  210. </blockquote>
  211. <p>
  212. Custom materials based on [page:ShaderMaterial] and [page:RawShaderMaterial] have to implement their own output color space conversion.
  213. For instances of `ShaderMaterial`, adding the `colorspace_fragment` shader chunk to the fragment shader's `main()` function should be sufficient.
  214. </p>
  215. <h2>Utiliser des instances de THREE.Color</h2>
  216. <p>
  217. Les méthodes de lecture ou de modification des instances de [page:Color] partent du principe que les données sont déjà
  218. dans l'espace colorimétrique de three.js, le sRGB-Linéaire. Les composantes RGB et HSL sont des représentations
  219. directes de données stockées par l'instance Color, et ne sont jamais converties
  220. implicitement. Les données Color peuvent être explicitement converties avec <i>.convertLinearToSRGB()</i>
  221. ou <i>.convertSRGBToLinear()</i>.
  222. </p>
  223. <code>
  224. // RGB components (no change).
  225. color.r = color.g = color.b = 0.5;
  226. console.log( color.r ); // → 0.5
  227. // Manual conversion.
  228. color.r = 0.5;
  229. color.convertSRGBToLinear();
  230. console.log( color.r ); // → 0.214041140
  231. </code>
  232. <p>
  233. Avec <i>ColorManagement.enabled = true</i> d'activé (recommandé), certaines conversions
  234. sont faites automatiquement. Parce que l'héxadécimal et les couleurs CSS sont généralement en sRGB, les méthodes [page:Color]
  235. vont automatiquement convertir ces entrées du sRGB au sRGB-Linéaire dans des setters, ou
  236. convertir depuis du sRGB-Linéaire au sRGB lors du renvoi de valeurs héxadécimales ou CSS depuis les getters.
  237. </p>
  238. <code>
  239. // Hexadecimal conversion.
  240. color.setHex( 0x808080 );
  241. console.log( color.r ); // → 0.214041140
  242. console.log( color.getHex() ); // → 0x808080
  243. // CSS conversion.
  244. color.setStyle( 'rgb( 0.5, 0.5, 0.5 )' );
  245. console.log( color.r ); // → 0.214041140
  246. // Override conversion with 'colorSpace' argument.
  247. color.setHex( 0x808080, LinearSRGBColorSpace );
  248. console.log( color.r ); // → 0.5
  249. console.log( color.getHex( LinearSRGBColorSpace ) ); // → 0x808080
  250. console.log( color.getHex( SRGBColorSpace ) ); // → 0xBCBCBC
  251. </code>
  252. <h2>Erreurs communes</h2>
  253. <p>
  254. Quand une couleur ou une texture individuelle est mal configurée, elle apparaîtra plus lumineuse ou plus sombre
  255. qu'attendu. Quand l'espace colorimétrique de sortie du moteur de rendu est mal configuré, la scène entière peut sembler
  256. plus sombre (e.g. conversion manquante vers le sRGB) ou plus lumineuse (e.g. une double conversion vers le sRGB avec du
  257. post-processing). Dans chaque cas le problème peut ne pas être uniforme, et simplement augmenter/diminuer
  258. peut ne pas le résoudre.
  259. </p>
  260. <p>
  261. Un problème plus subtil peut se produire quand <i>à la fois</i> l'espace colorimétrique d'entrée et
  262. l'espace colorimétrique de sortie sont incorrects — les niveaux de luminosité globaux peuvent être corrects, mais les couleurs peuvent changer
  263. d'une manière inattendue sous différentes lumières, ou des ombres peuvent sembler plus abruptes et moins lisses
  264. que prévu. Ces deux erreurs assemblées ne forment pas une réussite, et il est important que
  265. l'espace colorimétrique soit linéaire ("scene referred") et que l'espace colorimétrique de sortie soit linéaire
  266. ("display referred").
  267. </p>
  268. <h2>Lectures additionnelles</h2>
  269. <ul>
  270. <li>
  271. <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
  272. </li>
  273. <li>
  274. <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
  275. </li>
  276. <li>
  277. <a href="https://hg2dc.com/" target="_blank" rel="noopener">The Hitchhiker's Guide to Digital Color</a>, par Troy Sobotka
  278. </li>
  279. <li>
  280. <a href="https://docs.blender.org/manual/en/latest/render/color_management.html" target="_blank" rel="noopener">Color Management</a>, Blender
  281. </li>
  282. </ul>
  283. </body>
  284. </html>