9.2. Desaturazione costante

5
Il tuo voto: Nessuno Media: 5 (1 vote)

Il processo di desaturazione ha l'effetto di conservare la luminosità dell'immagine, ma di rimuovere tutte le informazioni sul colore, facendola apparire in gradazioni di grigio. Il codice di questo effetto è utilizzato raramente in modo autonomo, più spesso fa parte di un processo più complesso come: il calcolo della luminosità media del viewport (utile nel rendering HDR); la colorizzazione; se applicato come shader nel rendering delle interfaccie utente distingue i controlli abilitati da quelli inattivi ecc... Il termine costante indica che la desaturazione non è legata ad altri parametri ed è eseguita esattamente nello stesso modo per tutti i pixel dello schermo.

Per convertire un colore in una gradazione di grigio non è possibile calcolare la media aritmetica delle tre componenti di un colore perchè in questo modo l'intensita risultante non sarebbe equivalente a quella del colore originario. Le tre componenti fondamentali hanno infatti una differente influenza sull'occhio umano, per questo sono state calcolate delle costanti indipendenti dal mezzo di visualizzazione. Moltiplicando le costanti con le rispettive componenti del colore originario ed eseguendo la loro somma otterremo l'intensità corretta:

intensità = R · kR + G · kG + B · kB
con kR = 0.2125, kG = 0.7154, kB = 0.0721

Nel codice HLSL questo calcolo si presta ad essere scritto in modo efficiente come il prodotto scalare di due vettori ( dot(a, b) ), uno dei quali contiene il colore e l'altro le costanti di intensità. In opzione è possibile eseguire un'interpolazione lineare tra l'intensità calcolata ed il colore originario rendendo possibile una desaturazione parziale.

  1 // Sampler dell'immagine sorgente
  2 sampler2D sourceSampler;
  3 
  4 // Inverso della dimensione del viewport
  5 uniform float2 invViewSize;
  6 
  7 // Intensità della desaturazione
  8 uniform float desatStrength;
  9 
 10 // Costanti di luminanza per le componenti di un colore
 11 const float4 luminanceConstants = float4(0.2125, 0.7154, 0.0721, 0.0000);
 12 
 13 float4 ps_main(float2 TexCoords : TEXCOORD0) : COLOR0
 14 {
 15     // Recupero le informazioni dai render-targets per il pixel corrente
 16     float4 color = tex2D(sourceSampler, TexCoords);
 17 
 18     // Calcolo intensità corrispondente
 19     float intensity = dot(color, luminanceConstants);
 20 
 21     // Interpolazione tra colore ed intensità equivalente
 22     return lerp(color, intensity, desatStrength);
 23 }

Risultato della desaturazione: