Color-management.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <!DOCTYPE html>
  2. <html lang="pt-br">
  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>Gerenciamento de cor</h1>
  45. <h2>O que é um espaço de cor?</h2>
  46. <p>
  47. Cada espaço de cor é uma coleção de várias decisões de design, escolhidas em conjunto para dar suporte a uma
  48. grande variedade de cores, satisfazendo as restrições técnicas relacionadas à precisão e a tecnologia das telas. Ao criar um recurso 3D ou ao montar recursos 3D em uma cena, é
  49. importante saber quais são essas propriedades e como as propriedades de um espaço de cores se relacionam
  50. com outros espaços de cor na cena.
  51. </p>
  52. <figure class="float">
  53. <img src="resources/srgb_gamut.png" alt="">
  54. <figcaption>
  55. Cores sRGB e ponto branco (D65) exibidos no diagrama de referência cromaticidade CIE 1931.
  56. A região colorida representa uma projeção 2D da gama sRGB, que é um volume 3D.
  57. Fonte: <a href="https://en.wikipedia.org/wiki/SRGB" target="_blank" rel="noopener">Wikipedia</a>
  58. </figcaption>
  59. </figure>
  60. <ul>
  61. <li>
  62. <b>
  63. Cores primárias:</b> As cores primárias (por exemplo, vermelho, verde, azul) não são absolutas; elas são
  64. selecionadas a partir do espectro visível com base em restrições de precisão limitada e
  65. capacidades dos dispositivos de exibição disponíveis. As cores são expressas como uma proporção das cores primárias.
  66. </li>
  67. <li>
  68. <b>Ponto branco:</b> a maioria dos espaços de cores é projetada de forma que uma soma igualmente ponderada das
  69. primárias <i>R = G = B</i> parecerão sem cor, ou "acromáticas". A aparência
  70. de valores acromáticos (como branco ou cinza) dependem da percepção humana, que por sua vez depende
  71. fortemente no contexto do observador. Um espaço de cor especifica seu "ponto branco" para equilibrar
  72. essas necessidades. O ponto branco definido pelo espaço de cores sRGB é
  73. [link:https://en.wikipedia.org/wiki/Illuminant_D65 D65].
  74. </li>
  75. <li>
  76. <b>Transfer functions:</b> depois de escolher a gama de cores e um modelo de cores, ainda precisamos
  77. definir mapeamentos ("transfer functions") de valores numéricos para o espaço de cores. <i>r = 0,5</i>
  78. representa 50% menos iluminação física do que <i>r = 1.0</i>? Ou 50% menos brilhante, conforme percebido
  79. por um olho humano médio? São coisas diferentes, e essa diferença pode ser representada como
  80. uma função matemática. As transfer functions podem ser <i>lineares</i> ou <i>não lineares</i>, dependendo
  81. dos objetivos do espaço de cores. sRGB define transfer functions não lineares. Aquelas
  82. funções são às vezes aproximadas como <i>funções gamma</i>, mas o termo "gamma" é
  83. ambíguo e deve ser evitado neste contexto.
  84. </li>
  85. </ul>
  86. Esses três parâmetros — cores primárias, ponto branco e transfer functions — definem um espaço de cores,
  87. cada um escolhido para objetivos particulares. Tendo definido os parâmetros, alguns termos adicionais
  88. são úteis:
  89. <ul>
  90. <li>
  91. <b>Modelo de cores:</b> Sintaxe para identificar numericamente as cores dentro da gama de cores escolhida —
  92. um sistema de coordenadas para cores. No three.js estamos preocupados principalmente com o modelo de cor RGB,
  93. tendo três coordenadas <i>r, g, b ∈ [0,1]</i> ("domínio fechado") ou
  94. <i>r, g, b ∈ [0,∞]</i> ("domínio aberto"), cada um representando uma fração de uma cor primária.
  95. Outros modelos de cores (HSL, Lab, LCH) são comumente usados ​​para controle artístico.
  96. </li>
  97. <li>
  98. <b>Gama de cores:</b> uma vez que as cores primárias e um ponto branco tenham sido escolhidos, eles representam
  99. um volume dentro do espectro visível (uma "gama"). Cores fora deste volume ("fora da gama")
  100. não podem ser expressas por valores RGB de domínio fechado [0,1]. No domínio aberto [0,∞], a gama é
  101. tecnicamente infinita.
  102. </li>
  103. </ul>
  104. <p>
  105. Considere dois espaços de cores muito comuns: [page:SRGBColorSpace] ("sRGB") e
  106. [page:LinearSRGBColorSpace] ("Linear-sRGB"). Ambos usam as mesmas cores primárias e ponto branco,
  107. e, portanto, têm a mesma gama de cores. Ambos usam o modelo de cores RGB. Eles diferem apenas
  108. nas transfer functions — Linear-sRGB é linear em relação à intensidade da luz física.
  109. sRGB usa as transfer functions sRGB não lineares e se assemelha mais à maneira que
  110. o olho humano percebe a luz e a capacidade de resposta de dispositivos de exibição comuns.
  111. </p>
  112. <p>
  113. Essa diferença é importante. Cálculos de iluminação e outras operações de renderização devem
  114. geralmente ocorrem em um espaço de cores linear. No entanto, cores lineares são menos eficientes para
  115. armazenar em uma imagem ou framebuffer e não parecem corretas quando vistas por um observador humano.
  116. Como resultado, as texturas de entrada e a imagem final renderizada geralmente usarão o método não linear
  117. do espaço de cores sRGB.
  118. </p>
  119. <blockquote>
  120. <p>
  121. ℹ️ <i><b>AVISO:</b> Embora alguns monitores modernos sejam compatíveis com gamas mais amplas, como Display-P3,
  122. as APIs gráficas da plataforma web dependem em grande parte do sRGB. Aplicativos que usam three.js
  123. hoje normalmente usarão apenas os espaços de cores sRGB e Linear-sRGB.</i>
  124. </p>
  125. </blockquote>
  126. <h2>Atribuições dos espaços de cores</h2>
  127. <p>
  128. Fluxos de trabalho lineares - necessários para métodos modernos de renderização - geralmente envolvem mais de
  129. um espaço de cores, cada um atribuído a uma função específica. Espaços de cores lineares e não lineares são
  130. apropriados para diferentes funções, como explicado abaixo.
  131. </p>
  132. <h3>Input do espaço de cores</h3>
  133. <p>
  134. Cores fornecidas ao three.js — de seletores de cores, texturas, modelos 3D e outras fontes —
  135. cada um tem um espaço de cor associado. Aqueles que ainda não estão na cor de trabalho Linear-sRGB,
  136. devem ser convertidos e as texturas devem receber a atribuição <i>texture.colorSpace</i> correta.
  137. Certas conversões (para cores hexadecimais e CSS em sRGB) podem ser feitas automaticamente se
  138. o modo de gerenciamento de cores herdado é desabilitado antes de inicializar as cores:
  139. </p>
  140. <code>
  141. THREE.ColorManagement.enabled = true;
  142. </code>
  143. <ul>
  144. <li>
  145. <b>Materiais, luzes e shaders:</b> cores nos materiais, luzes e shaders armazenam
  146. componentes RGB no espaço de cores de trabalho Linear-sRGB.
  147. </li>
  148. <li>
  149. <b>Cores de vértices:</b> [page:BufferAttribute BufferAttributes] armazena componentes RGB no
  150. Espaço de cores de trabalho linear-sRGB.
  151. </li>
  152. <li>
  153. <b>Texturas de cores:</b> PNG ou JPEG [page:Texture Textures] contendo informações de cores
  154. (como .map ou .emissiveMap) usam o espaço de cores sRGB de domínio fechado e devem ser anotados com
  155. <i>texture.colorSpace = SRGBColorSpace</i>. Formatos como OpenEXR (às vezes usado para .envMap ou
  156. .lightMap) usam o espaço de cores Linear-sRGB indicado com <i>texture.colorSpace = LinearSRGBColorSpace</i>,
  157. e podem conter valores no domínio aberto [0,∞].
  158. </li>
  159. <li>
  160. <b>Texturas não coloridas:</b> Texturas que não armazenam informações de cores (como .normalMap
  161. ou .roughnessMap) não têm um espaço de cores associado e geralmente usam a textura (padrão)
  162. como <i>texture.colorSpace = NoColorSpace</i>. Em casos raros, dados sem cor
  163. podem ser representados com outras codificações não lineares por motivos técnicos.
  164. </li>
  165. </ul>
  166. <blockquote>
  167. <p>
  168. ⚠️ <i><b>AVISO:</b> Muitos formatos para modelos 3D não funcionam de forma correta ou consistente
  169. na definição das informações do espaço de cores. Enquanto o three.js tenta lidar com a maioria dos casos, problemas
  170. são comuns com formatos de arquivo mais antigos. Para melhores resultados, use glTF 2.0 ([page:GLTFLoader])
  171. e teste modelos 3D em visualizadores on-line antecipadamente para confirmar que o recurso em si está correto.</i>
  172. </p>
  173. </blockquote>
  174. <h3>Espaço de cores de trabalho</h3>
  175. <p>
  176. Renderização, interpolação e muitas outras operações devem ser executadas em um domínio aberto
  177. do espaço de cores de trabalho linear, no qual os componentes RGB são proporcionais a iluminação
  178. física. No three.js, o espaço de cores de trabalho é Linear-sRGB.
  179. </p>
  180. <h3>Output do espaço de cores</h3>
  181. <p>
  182. A saída para um dispositivo de exibição, imagem ou vídeo pode envolver a conversão do domínio aberto
  183. do espaço de cores de trabalho linear-sRGB para outro espaço de cores. Essa conversão pode ser feita em
  184. uma passagem de renderização principal ([page:WebGLRenderer.outputColorSpace]), ou durante o pós-processamento.
  185. </p>
  186. <code>
  187. renderer.outputColorSpace = THREE.SRGBColorSpace; // optional with post-processing
  188. </code>
  189. <ul>
  190. <li>
  191. <b>Tela:</b> as cores gravadas em um canvas WebGL para exibição devem estar no espaço sRGB
  192. colorido.
  193. </li>
  194. <li>
  195. <b>Imagem:</b> as cores gravadas em uma imagem devem usar o espaço de cores apropriado para
  196. o formato e o uso. Imagens totalmente renderizadas gravadas em texturas PNG ou JPEG geralmente
  197. usam o espaço de cores sRGB. Imagens contendo emissão, mapas de luz ou outros dados não
  198. confinados ao intervalo [0,1] geralmente usarão o espaço de cores Linear-sRGB de domínio aberto,
  199. e um formato de imagem compatível como OpenEXR.
  200. </li>
  201. </ul>
  202. <blockquote>
  203. <p>
  204. ⚠️ <i><b>AVISO:</b>
  205. Os render targets podem usar sRGB ou Linear-sRGB. sRGB faz
  206. melhor uso de precisão limitada. No domínio fechado, 8 bits geralmente são suficientes para sRGB
  207. enquanto que ≥12 bits (meio flutuante) podem ser necessários para Linear-sRGB. Se mais tarde
  208. os estágios pipeline precisarem de entrada Linear-sRGB, as conversões adicionais podem ter um pequeno
  209. custo de desempenho.</i>
  210. </p>
  211. </blockquote>
  212. <p>
  213. Custom materials based on [page:ShaderMaterial] and [page:RawShaderMaterial] have to implement their own output color space conversion.
  214. For instances of `ShaderMaterial`, adding the `colorspace_fragment` shader chunk to the fragment shader's `main()` function should be sufficient.
  215. </p>
  216. <h2>Trabalhando com instâncias THREE.Color</h2>
  217. <p>
  218. Métodos de leitura ou modificação de instâncias [page:Color] assumem que os dados já estão no
  219. espaço de cores de trabalho three.js, Linear-sRGB. Os componentes RGB e HSL são
  220. representações diretas de dados armazenados pela instância Color e nunca são convertidos
  221. implicitamente. Os dados de cores podem ser convertidos explicitamente com <i>.convertLinearToSRGB()</i>
  222. ou <i>.convertSRGBToLinear()</i>.
  223. </p>
  224. <code>
  225. // RGB components (no change).
  226. color.r = color.g = color.b = 0.5;
  227. console.log( color.r ); // → 0.5
  228. // Manual conversion.
  229. color.r = 0.5;
  230. color.convertSRGBToLinear();
  231. console.log( color.r ); // → 0.214041140
  232. </code>
  233. <p>
  234. Com <i>ColorManagement.enabled = true</i> definido (recomendado), determinadas conversões
  235. são feitas automaticamente. Como as cores hexadecimais e CSS geralmente são sRGB, métodos [page:Color]
  236. irão converter automaticamente essas entradas de sRGB para Linear-sRGB em setters, ou
  237. converter de Linear-sRGB para sRGB ao retornar hexadecimal ou CSS de getters.
  238. </p>
  239. <code>
  240. // Hexadecimal conversion.
  241. color.setHex( 0x808080 );
  242. console.log( color.r ); // → 0.214041140
  243. console.log( color.getHex() ); // → 0x808080
  244. // CSS conversion.
  245. color.setStyle( 'rgb( 0.5, 0.5, 0.5 )' );
  246. console.log( color.r ); // → 0.214041140
  247. // Override conversion with 'colorSpace' argument.
  248. color.setHex( 0x808080, LinearSRGBColorSpace );
  249. console.log( color.r ); // → 0.5
  250. console.log( color.getHex( LinearSRGBColorSpace ) ); // → 0x808080
  251. console.log( color.getHex( SRGBColorSpace ) ); // → 0xBCBCBC
  252. </code>
  253. <h2>Erros comuns</h2>
  254. <p>
  255. Quando uma cor ou textura individual é configurada incorretamente, ela aparecerá mais escura ou mais clara do que
  256. esperado. Quando o espaço de cores de saída do renderizador está mal configurado, a cena inteira pode aparecer
  257. mais escura (por exemplo, conversão ausente para sRGB) ou mais clara (por exemplo, uma conversão dupla para sRGB com
  258. pós-processamento). Em cada caso, o problema pode não ser uniforme e simplesmente aumentar/diminuir
  259. a iluminação não resolve.
  260. </p>
  261. <p>
  262. Um problema mais sutil aparece quando <i>ambos</i> os espaços de cores de entrada e saída
  263. estão incorretos — os níveis gerais de brilho podem ser bons, mas as cores podem mudar
  264. inesperadamente sob iluminação diferente, ou o sombreamento pode parecer mais estourado e menos suave
  265. do que o pretendido. Esses dois erros não fazem um acerto, e é importante que o trabalho
  266. espaço de cores funcional seja linear ("cena referida") e o espaço de cores de saída seja não linear
  267. ("exibição referida").
  268. </p>
  269. <h2>Leitura adicional</h2>
  270. <ul>
  271. <li>
  272. <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>, de Larry Gritz and Eugene d'Eon
  273. </li>
  274. <li>
  275. <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>, de John Novak
  276. </li>
  277. <li>
  278. <a href="https://hg2dc.com/" target="_blank" rel="noopener">The Hitchhiker's Guide to Digital Color</a>, de Troy Sobotka
  279. </li>
  280. <li>
  281. <a href="https://docs.blender.org/manual/en/latest/render/color_management.html" target="_blank" rel="noopener">Color Management</a>, Blender
  282. </li>
  283. </ul>
  284. </body>
  285. </html>