Color-management.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. <!DOCTYPE html>
  2. <html lang="it">
  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>Gestione del colore ([name])</h1>
  45. <h2>Cos'è lo spazio colore?</h2>
  46. <p>
  47. Ogni spazio colore è una collezione di diverse decisioni progettuali,
  48. scelte insieme per supportare un'ampia gamma di colori e al contempo
  49. soddisfare i vincoli tecnici legati alla precisione e alle tecnologie di
  50. visualizzazione. Quando si crea una risorsa 3D, o si assemblano delle
  51. risorse 3D insieme in una scena, è importante sapere quali sono queste
  52. proprietà e come le proprietà di uno spazio colore si relazionano con
  53. altri spazi colore nella scena.
  54. </p>
  55. <figure class="float">
  56. <img src="resources/srgb_gamut.png" alt="" />
  57. <figcaption>
  58. Colori sRGB e il punto di bianco (D65) visualizzati nel diagramma
  59. cromatico di riferimento CIE 1931. La regione colorata rappresenta una
  60. proiezione 2D della gamma sRGB, che è un volume 3D. Fonte:
  61. <a
  62. href="https://en.wikipedia.org/wiki/SRGB"
  63. target="_blank"
  64. rel="noopener"
  65. >Wikipedia</a
  66. >
  67. </figcaption>
  68. </figure>
  69. <ul>
  70. <li>
  71. <b>Colori primari:</b> I colori primari (rosso, verde, blu) non sono
  72. assoluti; vengono selezionati dallo spettro visibile in base ai vincoli
  73. di precisione limitata e alla capacità dei dispositivi di
  74. visualizzazione disponibili. I colori sono espressi come rapporto tra i
  75. colori primari.
  76. </li>
  77. <li>
  78. <b>Punto di bianco:</b> La maggior parte degli spazi colore è progettata
  79. in modo tale che una somma equamente ponderata di primari
  80. <i>R = G = B</i> appaia priva di colore o "acromatica". L'aspetto dei
  81. valori cromatici (come il bianco o il grigio) dipende dalla percezione
  82. umana, che a sua volta dipende fortemente dal contesto dell'osservatore.
  83. Uno spazio colore specifica il suo "punto di bianco" per bilanciare
  84. queste esigenze. Il punto di bianco definito dallo spazio colore sRGB è
  85. <a href="https://en.wikipedia.org/wiki/Illuminant_D65" target="_blank"
  86. >D65</a
  87. >.
  88. </li>
  89. <li>
  90. <b>Funzioni di trasferimento (transfer functions):</b> Dopo aver scelto
  91. la gamma cromatica e un modello di colore, dobbiamo ancora definire le
  92. mappature ("funzioni di trasferimento") dei valori numerici da/verso lo
  93. spazio colore. R = 0,5 rappresenta il 50% in meno di illuminazione
  94. fisica rispetto a <i>r = 1,0</i>? O il 50% in meno di luminosità, come
  95. percepito da un occhio umano medio? Sono cose diverse e questa
  96. differenza può essere rappresentata come una funzione matematica. Le
  97. funzioni di trasferimento possono essere <i>lineari</i> o
  98. <i>non lineari</i>, a seconda degli obiettivi dello spazio colore. sRGB
  99. definisce funzioni di trasferimento non lineari. Queste funzioni sono
  100. talvolta approssimate come <i>funzioni gamma</i>, ma il termine "gamma"
  101. è ambiguo e dovrebbe essere evitato in questo contesto.
  102. </li>
  103. </ul>
  104. Questi tre parametri - colori primari, punto di bianco e funzioni di
  105. trasferimento - definiscono uno spazio colore, ognuno scelto per obiettivi
  106. specifici. Dopo aver definito i parametri, sono utili alcuni termini
  107. aggiuntivi:
  108. <ul>
  109. <li>
  110. <b>Modello di colore:</b> Sintassi per identificare numericamente i
  111. colori all'interno della gamma cromatica scelta - un sistema di
  112. coordinate per i colori. In three.js ci occupiamo principalmente del
  113. modello di colore RGB, con tre coordinate
  114. <i>r, g, b ∈ [0,1]</i> ("dominio chiuso") o
  115. <i>r, g, b ∈ [0,∞]</i> ("dominio aperto") che rappresentano ciascuna una
  116. frazione di un colore primario. Altri modelli di colore (HSL, Lab, LCH)
  117. sono comunemente utilizzati per il controllo artistico.
  118. </li>
  119. <li>
  120. <b>Gamma di colori:</b> Quando i colori primari e il punto di bianco
  121. sono stati scelti, questi rappresentano un volume all'interno dello
  122. spettro visibile (un "gamut"). I colori che non rientrano in questo
  123. volume ("fuori gamut") non possono essere espressi dai valori RGB del
  124. dominio chiuso [0,1]. Nel dominio aperto [0,∞], il gamut è tecnicamente
  125. infinito.
  126. </li>
  127. </ul>
  128. <p>
  129. Consideriamo due spazi colori comuni: [page:SRGBColorSpace] ("sRGB") e
  130. [page:LinearSRGBColorSpace] ("Linear-sRGB"). Entrambi usano gli stessi
  131. colori primari e lo stesso punto di bianco, e quindi hanno la stessa gamma
  132. di colori. Entrambi utilizzano il modello di colore RGB. Sono diversi solo
  133. nelle funzioni di trasferimento - Linear-sRGB è lineare rispetto
  134. all'intensità della luce fisica, mentre sRGB utilizza le funzioni di
  135. trasferimento non lineari di sRGB e si avvicina maggiormente al modo in
  136. cui l'occhio umano percepisce la luce e alla reattività dei comuni
  137. dispositivi di visualizzazione.
  138. </p>
  139. <p>
  140. Questa differenza è importante. I calcoli di illuminazione e altre
  141. operazioni di rendering devono generalmente avvenire in uno spazio di
  142. colore lineare. Tuttavia, i colori lineari sono meno efficienti da
  143. memorizzare in un'immagine o in un framebuffer e non hanno un aspetto
  144. corretto quando vengono osservati da un osservatore umano. Di conseguenza,
  145. le texture di input e l'immagine finale renderizzata utilizzano
  146. generalmente lo spazio di colore sRGB non lineare.
  147. </p>
  148. <blockquote>
  149. <p>
  150. ℹ️
  151. <i
  152. ><b>ATTENZIONE:</b> Anche se alcuni display moderni supportano gamme
  153. più ampie come Display-P3, le API grafiche della piattaforma web si
  154. basano in gran parte su sRGB. Le applicazioni che utilizzano three.js
  155. oggi utilizzano in genere solo gli spazi colore sRGB e Linear-sRGB.
  156. </i>
  157. </p>
  158. </blockquote>
  159. <h2>Ruoli degli spazi colore</h2>
  160. <p>
  161. Un flusso di lavoro lineare - richiesto per moderni metodi di rendering -
  162. generalmente coinvolge più di uno spazio di colore, ognuno assegnato ad un
  163. ruolo specifico. Spazi colore lineari o non lineari sono adatti a ruoli
  164. diversi, come spiegato di seguito.
  165. </p>
  166. <h3>Input color space</h3>
  167. <p>
  168. I colori forniti a three.js - dai color picker, dalle texture, dai modelli
  169. 3D e da altre risorse - hanno ciascuno uno spazio colore associato. Quelli
  170. che non sono già nello spazio colore di lavoro Linear-sRGB devono essere
  171. convertiti e alle texture deve essere assegnata la corretta assegnazione
  172. <i>texture.colorSpace</i>. Alcune conversioni (per i colori esadecimali e
  173. CSS in sRGB) possono essere effettuate automaticamente se la modalità di
  174. gestione del colore legacy è disabilitata prima dell'inizializzazione dei
  175. colori:
  176. </p>
  177. <code> THREE.ColorManagement.enabled = true; </code>
  178. <ul>
  179. <li>
  180. <b>Materiali, luci, e shader:</b> I colori nei materiali, nelle luci e
  181. negli shader memorizzano i componenti RGB nello spazio colore di lavoro
  182. Linear-sRGB.
  183. </li>
  184. <li>
  185. <b>Colori dei vertici:</b> [page:BufferAttribute BufferAttributes]
  186. memorizza i componenti RGB nello spazio colore di lavoro Linear-sRGB.
  187. </li>
  188. <li>
  189. <b>Colori delle texture:</b> Le [page:Texture Texture] PNG o JPEG
  190. contenti informazioni sul colore (come .map o .emissiveMap) usano lo
  191. spazio colore sRGB a dominio chiuso, e devono essere annotate con
  192. <i>texture.colorSpace = SRGBColorSpace</i>. I formati come OpenEXR (a volte
  193. usati per .envMap o .lightMap) utilizzano lo spazio colore Linear-sRGB
  194. indicato con <i>texture.colorSpace = LinearSRGBColorSpace</i>, e possono
  195. contenere valori nel dominio aperto [0,∞].
  196. </li>
  197. <li>
  198. <b>Texture non a colori:</b> Le texture che non memorizzano informazioni
  199. relative ai colori (come .normalMap o .roughnessMap) non hanno associato
  200. uno spazio colore, e generalmente usano l'annotazione (predefinita)
  201. <i>texture.colorSpace = NoColorSpace</i>. In rari casi, i dati non a
  202. colori possono essere rappresentati con altre codifiche non lineari per
  203. motivi tecnici.
  204. </li>
  205. </ul>
  206. <blockquote>
  207. <p>
  208. ⚠️
  209. <i
  210. ><b>ATTENZIONE:</b> Molti formati per modelli 3D non definiscono
  211. correttamente o in modo coerente le informazioni sullo spazio colore.
  212. Sebbene three.js tenti di gestire la maggior parte dei casi, i
  213. problemi sono spesso con i file con formati meno recenti. Per ottenere
  214. un miglior risultato bisogna utilizzare il formato glTF 2.0
  215. ([page:GLTFLoader]) e prima bisogna testare i modelli 3D in
  216. visualizzatori online per confermare che la risorsa stessa sia
  217. corretta.
  218. </i>
  219. </p>
  220. </blockquote>
  221. <h3>Spazio colore di lavoro</h3>
  222. <p>
  223. Rendering, interpolazione e molte altre operazioni devono essere eseguite
  224. in uno spazio colore di lavoro lineare, nel quale i componenti RGB sono
  225. proporzionali all'illuminazione fisica. In three.js, lo spazio colore di
  226. lavoro è Linear-sRGB.
  227. </p>
  228. <h3>Output color space</h3>
  229. <p>
  230. L'output su un dispositivo di visualizzazione, a un'immagine o a un video,
  231. può comportare la conversione dallo spazio colore di lavoro Linear-sRGB di
  232. dominio aperto a un altro spazio di colore. Questa conversione può essere
  233. eseguita nel passaggio di rendering principale
  234. ([page:WebGLRenderer.outputColorSpace]), o durante il post-processing.
  235. </p>
  236. <code>
  237. renderer.outputColorSpace = THREE.SRGBColorSpace; // optional with post-processing
  238. </code>
  239. <ul>
  240. <li>
  241. <b>Display:</b> I colori scritti in un canvas WebGL per i display devono
  242. essere nello spazio colore sRGB.
  243. </li>
  244. <li>
  245. <b>Immagine:</b> I colori scritti su un'immagine devono utilizzare lo
  246. spazio colore appropriato per il formato e per il suo uso. Le immagini
  247. completamente renderizzate scritte per texture PNG o JPEG generalmente
  248. usano lo spazio colore sRGB. Immagini contenenti emissioni, mappe di
  249. luce, o altri dati non limitati all'intervallo [0,1] utilizzaranno
  250. generalmente lo spazio colore Linear-sRGB a dominio aperto, e un formato
  251. immagine compatibile come OpenEXR.
  252. </li>
  253. </ul>
  254. <blockquote>
  255. <p>
  256. ⚠️
  257. <i
  258. ><b>ATTENZIONE:</b> I target di rendering possono utilizzare sia sRGB
  259. che Linear-sRGB. sRGB utilizza meglio la precisione limitata. Nel
  260. dominio chiuso, 8 bit sono sufficienti per sRGB mentre ≥12 (mezzo
  261. float) possono essere richiesti per Linear-sRGB. Se gli stadi
  262. successivi delle pipeline richiedono un ingresso Linear-sRGB, le
  263. conversioni aggiuntive possono avere un piccolo costo in termini di
  264. prestazioni.</i
  265. >
  266. </p>
  267. </blockquote>
  268. <p>
  269. Custom materials based on [page:ShaderMaterial] and [page:RawShaderMaterial] have to implement their own output color space conversion.
  270. For instances of `ShaderMaterial`, adding the `colorspace_fragment` shader chunk to the fragment shader's `main()` function should be sufficient.
  271. </p>
  272. <h2>Lavorare con le istanze di THREE.Color</h2>
  273. <p>
  274. I metodi di lettura o modifica delle istanze [page:Color] presuppongono
  275. che i dati siano già nello spazio colore di lavoro di three.js,
  276. Linear-sRGB. I componenti RGB e HSL sono rappresentazioni dirette dei dati
  277. memorizzati dall'istanza Color, e non sono mai convertiti implicitamente.
  278. I dati di Color possono essere esplicitamenre convertiti con
  279. <i>.convertLinearToSRGB()</i> o <i>.convertSRGBToLinear()</i>.
  280. </p>
  281. <code>
  282. // RGB components (no change).
  283. color.r = color.g = color.b = 0.5;
  284. console.log( color.r ); // → 0.5
  285. // Manual conversion.
  286. color.r = 0.5;
  287. color.convertSRGBToLinear();
  288. console.log( color.r ); // → 0.214041140
  289. </code>
  290. <p>
  291. Con <i>ColorManagement.enabled = true</i> impostato (consigliato),
  292. alcune conversioni vengono effettuate automaticamente. Poiché i colori
  293. esadecimali e CSS sono generalmente sRGB, i metodi [page:Color]
  294. convertiranno automaticamente questi input da sRGB a Linear-sRGB nei
  295. setter, oppure convertiranno da Linear-sRGB a sRGB quando restituiscono
  296. output esadecimali o CSS dai getter.
  297. </p>
  298. <code>
  299. // Hexadecimal conversion.
  300. color.setHex( 0x808080 );
  301. console.log( color.r ); // → 0.214041140
  302. console.log( color.getHex() ); // → 0x808080
  303. // CSS conversion.
  304. color.setStyle( 'rgb( 0.5, 0.5, 0.5 )' );
  305. console.log( color.r ); // → 0.214041140
  306. // Override conversion with 'colorSpace' argument.
  307. color.setHex( 0x808080, LinearSRGBColorSpace );
  308. console.log( color.r ); // → 0.5
  309. console.log( color.getHex( LinearSRGBColorSpace ) ); // → 0x808080
  310. console.log( color.getHex( SRGBColorSpace ) ); // → 0xBCBCBC
  311. </code>
  312. <h2>Errori comuni</h2>
  313. <p>
  314. Quando un singolo colore o una texture non sono configurati correttamente,
  315. apparirà più scuro o più chiaro del previsto. Quando lo spazio colore di
  316. output del renderer non è configurato correttamente, l'intera scena
  317. potrebbe essere più scura (ad es. manca la conversione ad sRGB) o più
  318. chiara (ad es. una doppia conversione a sRGB con post-processing). In ogni
  319. caso il problema potrebbe non essere uniforme e semplicemente
  320. aumentare/dimunire la luminosità non lo risolverebbe.
  321. </p>
  322. <p>
  323. Un problema più sottile si verifica quando <i>entrambi</i> lo spazio colore di
  324. input e quello di output non sono corretti - i livelli di luminosità complessivi
  325. potrebbero andare bene, ma i colori potrebbero cambiare in modo imprevisto in
  326. condizioni di illuminazione diversa o l'ombreggiatura potrebbe apparire più sbiadita
  327. e meno morbida del previsto. Questi due errori non fanno una cosa giusta, ed è importante
  328. che lo spazio colore di lavoro sia lineare ("riferito alla scena") e che lo spazio di colore
  329. dell'output sia non lineare ("riferito alla visualizzazione").
  330. </p>
  331. <h2>Ulteriori letture</h2>
  332. <ul>
  333. <li>
  334. <a
  335. href="https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-24-importance-being-linear"
  336. target="_blank"
  337. rel="noopener"
  338. >GPU Gems 3: The Importance of Being Linear</a
  339. >, di Larry Gritz and Eugene d'Eon
  340. </li>
  341. <li>
  342. <a
  343. href="https://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/"
  344. target="_blank"
  345. rel="noopener"
  346. >What every coder should know about gamma</a
  347. >, di John Novak
  348. </li>
  349. <li>
  350. <a href="https://hg2dc.com/" target="_blank" rel="noopener"
  351. >The Hitchhiker's Guide to Digital Color</a
  352. >, di Troy Sobotka
  353. </li>
  354. <li>
  355. <a
  356. href="https://docs.blender.org/manual/en/latest/render/color_management.html"
  357. target="_blank"
  358. rel="noopener"
  359. >Color Management</a
  360. >, Blender
  361. </li>
  362. </ul>
  363. </body>
  364. </html>