Ogni spazio colore è una collezione di diverse decisioni progettuali, scelte insieme per supportare un'ampia gamma di colori e al contempo soddisfare i vincoli tecnici legati alla precisione e alle tecnologie di visualizzazione. Quando si crea una risorsa 3D, o si assemblano delle risorse 3D insieme in una scena, è importante sapere quali sono queste proprietà e come le proprietà di uno spazio colore si relazionano con altri spazi colore nella scena.
Consideriamo due spazi colori comuni: [page:SRGBColorSpace] ("sRGB") e [page:LinearSRGBColorSpace] ("Linear-sRGB"). Entrambi usano gli stessi colori primari e lo stesso punto di bianco, e quindi hanno la stessa gamma di colori. Entrambi utilizzano il modello di colore RGB. Sono diversi solo nelle funzioni di trasferimento - Linear-sRGB è lineare rispetto all'intensità della luce fisica, mentre sRGB utilizza le funzioni di trasferimento non lineari di sRGB e si avvicina maggiormente al modo in cui l'occhio umano percepisce la luce e alla reattività dei comuni dispositivi di visualizzazione.
Questa differenza è importante. I calcoli di illuminazione e altre operazioni di rendering devono generalmente avvenire in uno spazio di colore lineare. Tuttavia, i colori lineari sono meno efficienti da memorizzare in un'immagine o in un framebuffer e non hanno un aspetto corretto quando vengono osservati da un osservatore umano. Di conseguenza, le texture di input e l'immagine finale renderizzata utilizzano generalmente lo spazio di colore sRGB non lineare.
ℹ️ ATTENZIONE: Anche se alcuni display moderni supportano gamme più ampie come Display-P3, le API grafiche della piattaforma web si basano in gran parte su sRGB. Le applicazioni che utilizzano three.js oggi utilizzano in genere solo gli spazi colore sRGB e Linear-sRGB.
Un flusso di lavoro lineare - richiesto per moderni metodi di rendering - generalmente coinvolge più di uno spazio di colore, ognuno assegnato ad un ruolo specifico. Spazi colore lineari o non lineari sono adatti a ruoli diversi, come spiegato di seguito.
I colori forniti a three.js - dai color picker, dalle texture, dai modelli 3D e da altre risorse - hanno ciascuno uno spazio colore associato. Quelli che non sono già nello spazio colore di lavoro Linear-sRGB devono essere convertiti e alle texture deve essere assegnata la corretta assegnazione texture.colorSpace. Alcune conversioni (per i colori esadecimali e CSS in sRGB) possono essere effettuate automaticamente se la modalità di gestione del colore legacy è disabilitata prima dell'inizializzazione dei colori:
THREE.ColorManagement.enabled = true;
⚠️ ATTENZIONE: Molti formati per modelli 3D non definiscono correttamente o in modo coerente le informazioni sullo spazio colore. Sebbene three.js tenti di gestire la maggior parte dei casi, i problemi sono spesso con i file con formati meno recenti. Per ottenere un miglior risultato bisogna utilizzare il formato glTF 2.0 ([page:GLTFLoader]) e prima bisogna testare i modelli 3D in visualizzatori online per confermare che la risorsa stessa sia corretta.
Rendering, interpolazione e molte altre operazioni devono essere eseguite in uno spazio colore di lavoro lineare, nel quale i componenti RGB sono proporzionali all'illuminazione fisica. In three.js, lo spazio colore di lavoro è Linear-sRGB.
L'output su un dispositivo di visualizzazione, a un'immagine o a un video, può comportare la conversione dallo spazio colore di lavoro Linear-sRGB di dominio aperto a un altro spazio di colore. Questa conversione può essere eseguita nel passaggio di rendering principale ([page:WebGLRenderer.outputColorSpace]), o durante il post-processing.
renderer.outputColorSpace = THREE.SRGBColorSpace; // optional with post-processing
⚠️ ATTENZIONE: I target di rendering possono utilizzare sia sRGB che Linear-sRGB. sRGB utilizza meglio la precisione limitata. Nel dominio chiuso, 8 bit sono sufficienti per sRGB mentre ≥12 (mezzo float) possono essere richiesti per Linear-sRGB. Se gli stadi successivi delle pipeline richiedono un ingresso Linear-sRGB, le conversioni aggiuntive possono avere un piccolo costo in termini di prestazioni.
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.
I metodi di lettura o modifica delle istanze [page:Color] presuppongono che i dati siano già nello spazio colore di lavoro di three.js, Linear-sRGB. I componenti RGB e HSL sono rappresentazioni dirette dei dati memorizzati dall'istanza Color, e non sono mai convertiti implicitamente. I dati di Color possono essere esplicitamenre convertiti con .convertLinearToSRGB() o .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
Con ColorManagement.enabled = true impostato (consigliato), alcune conversioni vengono effettuate automaticamente. Poiché i colori esadecimali e CSS sono generalmente sRGB, i metodi [page:Color] convertiranno automaticamente questi input da sRGB a Linear-sRGB nei setter, oppure convertiranno da Linear-sRGB a sRGB quando restituiscono output esadecimali o CSS dai getter.
// 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
Quando un singolo colore o una texture non sono configurati correttamente, apparirà più scuro o più chiaro del previsto. Quando lo spazio colore di output del renderer non è configurato correttamente, l'intera scena potrebbe essere più scura (ad es. manca la conversione ad sRGB) o più chiara (ad es. una doppia conversione a sRGB con post-processing). In ogni caso il problema potrebbe non essere uniforme e semplicemente aumentare/dimunire la luminosità non lo risolverebbe.
Un problema più sottile si verifica quando entrambi lo spazio colore di input e quello di output non sono corretti - i livelli di luminosità complessivi potrebbero andare bene, ma i colori potrebbero cambiare in modo imprevisto in condizioni di illuminazione diversa o l'ombreggiatura potrebbe apparire più sbiadita e meno morbida del previsto. Questi due errori non fanno una cosa giusta, ed è importante che lo spazio colore di lavoro sia lineare ("riferito alla scena") e che lo spazio di colore dell'output sia non lineare ("riferito alla visualizzazione").