# Ombreggiatura

L'ombreggiatura (in inglese shading), in computer grafica, è il modo in cui la luce interagisce con la mesh poligonale, in base all'assorbimento o la riflessione della luce, l'angolo di incidenza e l'angolo di visione, e altre caratteristiche.

## Aspetti teorici

Nella realtà, noi vediamo perché i nostri occhi rilevano la luce che rimbalza dagli oggetti. L'aspetto di una superficie è così determinato dal preciso modo in cui essa interagisce la luce, che è perciò determinato dalla struttura e dalla composizione del materiale.
Nel mondo reale, le superfici opache, come la roccia e la gomma, possiedono una struttura ruvida su scala microscopica. La luce rimbalza da essi in ogni direzione, e come risultato, la luce che si vede riflessa sembra non avere a che fare con la direzione da cui si sta guardando la superficie. Questa è chiamata riflessione diffusa (diffuse reflection, in inglese). Al contrario, le superfici lucide sono relativamente lisce, anche su scala microscopica. Questo significa che si vedrà una perfetta riflessione quando si guarda verso la superficie, e allo spostamento del punto di vista, ciò che è riflesso, cambia direzione. Questa è chiamata riflessione speculare (specular o mirror reflection, in inglese).
Nel mondo della computer grafica, comunque, spesso si prendono scorciatoie per ottenere l'aspetto dei materiali reali. Per esempio, considerando la riflessione speculare: nonostante sia possibile renderizzare riflessioni speculari, farlo è un'operazione più lenta rispetto al renderizzare riflessioni diffuse, perché ci sono algoritmi più semplici che approssimano l'effetto di riflessioni diffuse. Quindi renderizzare riflessioni diffuse può essere estremamente veloce, ma renderizzare riflessioni speculari richiede una intensiva elaborazione di ray tracing. Per aggirare questo problema, a volte si considerano solo le cose più ovvie che una superficie può riflettere, come le luci brillanti.
La maggior parte dei modelli di shading, in un modo o in un altro, sono progettati per catturare il processo di riflessione della luce.

## Modelli di Shading
### Flat Shading

Detto anche constant shading, è lo shading "numero zero". Ogni vertice di ogni triangolo della mesh poligonale, viene scelto come vertice chiave per quel triangolo. L'equazione di illuminazione viene eseguita per calcolare il valore di illuminazione per quel vertice, e l'intero triangolo viene investito con una copia di quel valore.
Il flat shading può essere appropriato per le piramidi, ma quando una mesh di triangoli approssima una superficie curva, come il caso del delfino, allora è richiesto un modello di shading più sofisticato. Per quanto si possa aumentare il numero di vertici della mesh, l'approssimazione resta sempre apparente, ed è anche ovviamente controproducente in termini di performance della computazione.

### Lambertian Shading

Il più semplice modello di shading è basato su una osservazione fatta da Johann Heinrich Lambert nel XVIII secolo: la quantità di energia proveniente da una sorgente luminosa che cade sull'area di una superficie dipende dall'angolo di incidenza della luce rispetto alla superficie. Una superficie che guarda direttamente verso una fonte luminosa riceve la massima illuminazione; una superficie tangente alla direzione della luce (o che guarda lontano dalla sorgente) non riceve alcuna illuminazione; e nel mezzo l'illuminazione è proporzionale al coseno dell'angolo $\theta$ fra la normale della superficie e la fonte luminosa. Questo porta al modello di shading di Lambert:
$L=k_{d}\,I\,\max(0,n\cdot l)$
dove $L$ è il colore del pixel; $k_{d}$ è il coefficiente di diffusione, o il colore della superficie; e $I$ è l'intensità della sorgente luminosa. Poiché $n$ e $l$ sono vettori unitari, possiamo usare $n\cdot l$ come una conveniente forma abbreviata (sia sulla carta che nel codice) per $\cos \theta$.
Questa equazione si applica separatamente ai tre canali di colore, in modo che la componente rossa del valore del pixel sia il prodotto della componente diffusa del rosso, l'intensità della sorgente luminosa rossa, e del prodotto dei vettori; lo stesso per il verde e il blu.
Il vettore $l$ è calcolato sottraendo il punto di intersezione fra il raggio e la superficie, dalla posizione della sorgente luminosa. Non bisogna dimenticare che $v$, $l$ e $n$ devono essere tutti dei vettori unitari; sbagliare nel normalizzare questi vettori è un errore molto comune nei calcoli di shading.

### Blinn-Phong Shading

Il Lambertian shading è indipendente dalla vista: il colore di una superficie non dipende dalla direzione da cui si sta guardando. Molte superfici reali mostrano alcuni gradi di brillantezza, producendo punti luce, o riflessioni speculari, che appaiono muoversi attorno alla superficie, man mano che il punto di vista cambia. Il Lambertian shading non produce alcun punto luce e comporta un aspetto molto opaco e pallido. Molti modelli di shading aggiungono una componente speculare al Lambertian shading; la parte lambertiana è così la componente diffusa.
Un modello molto semplice e ampiamente usato per i punti luce speculari fu proposto da Bui Tuong Phong nel 1975, e in seguito aggiornato - nella forma più comunemente usata oggi - da Jim Blinn nel 1976. Invece di interpolare i valori di illuminazione calcolati a ogni vertice (come nel Gouraud shading), il Blinn-Phong shading interpola la normale del vertice, la direzione della sorgente luminosa, e la direzione del punto di vista lungo un triangolo, e calcola la formula di illuminazione per ogni pixel. L'idea è di produrre una riflessione che sia alla sua maggiore brillantezza quando $v$ e $l$ sono simmetricamente posizionati lungo la normale della superficie, e ciò quando si verificherebbe la riflessione speculare; la riflessione quindi decresce lievemente all'allontanamento dei vettori da una configurazione speculare.
Possiamo dire quanto siamo vicini a una configurazione speculare confrontando il vettore $h$ (che biseziona l'angolo fra $v$ e $l$) alla normale della superficie. Se il vettore è presso la normale della superficie, la componente speculare dovrebbe essere brillante; se è lontano, dovrebbe essere fioca. Questo risultato è ottenuto dal calcolando il prodotto scalare fra $h$ e $n$ (bisogna ricordare che sono vettori unitari, quindi $n\cdot h$ è uguale a massimo a 1, quando i vettori sono uguali), e in seguito portando il risultato a una potenza $p>1$ per farlo decrescere velocemente. La potenza, o esponente di Phong, controlla l'apparente brillantezza della superficie. Il vettore $h$ in se stesso è facile da calcolare: poiché $v$ e $l$ hanno la stessa lunghezza, la loro somma è un vettore che biseziona l'angolo compreso fra essi, che richiede solo di essere normalizzato per produrre $h$.
Raccogliendo tutte queste informazioni, il modello di shading di Blinn-Phong è:
$h={\frac {v+l}{\|v+l\|}}\quad ;\quad L=k_{d}\,I\,\max(0,n\cdot l)+k_{s}\,I\,\max(0,n\cdot h)^{p}$
dove $k_{s}$ è il coefficiente speculare, il colore speculare, della superficie.

#### Equazione standard dello Shading

Il colore riflesso $K$ calcolato nel punto $Q$ su una superficie illuminata da $n$ luci è dato da:
$K=EM+DTA+\sum _{i=1}^{n}C_{i}[DT(N\cdot L_{i})+SG(N\cdot H_{i})^{p}(N\cdot L_{i}>0)]$
dove i prodotti scalari $N\cdot L$ e $N\cdot H_{i}$ sono fissati a zero, e le quantità coinvolte sono definite come segue:
* $D$ = colore della riflessione diffusa
* $S$ = colore della riflessione speculare
* $p$ = esponente speculare
* $A$ = colore della luce ambientale
* $E$ = colore dell'emissione
* $T$ = colore della texture map
* $G$ = colore della gloss map
* $M$ = colore della mappa di emissione
* $C_{i}$ = colore della i-esima luce su $Q$
* $L_{i}$ = vettore di direzione verso la i-esima luce
* $H_{i}$ = vettore a metà strada per l'i-esima luce
* $N$ = vettore normale

### Gouraud Shading

Il Gouraud shading, che prende il nome da Henri Gouraud, è un metodo usato in computer grafica per simulare i diversi effetti di luce e colore su un oggetto. In pratica, serve per ottenere un graduato cambio di colore su superfici a basso numero di poligoni (low-polygon) senza dover ricorrere alla pesantezza computazionale del calcolo pixel per pixel. Gouraud pubblicò questa ricerca per la prima volta nel 1971.
Il principio su cui si basa la tecnica di Gouraud è il seguente:
* Si determina la normale di ogni vertice di ogni poligono
* Si applica un modello di illuminazione a ogni vertice per calcolare l'intensità del vertice
* Si interpolano le intensità dei vertici usando l'interpolazione bilineare sulla superficie dei poligoni
Prima dell'avvento di hardware grafico capace di performare calcoli di illuminazione pixel per pixel, i colori diffusi e speculari erano calcolati solo a ogni vertice di una mesh triangolare. Questo metodo calcola i colori:$K_{primario}=E+DA+D\sum _{i=1}^{n}C_{i}\max\{N\cdot L_{i},0\}$$K_{secondario}=S\sum _{i=1}^{n}C_{i}\max\{N\cdot H_{i},0\}^{p}(N\cdot L_{i}>0)$dove:
* $D$ = colore della riflessione diffusa
* $S$ = colore della riflessione speculare
* $p$ = esponente speculare
* $A$ = colore della luce ambientale
* $E$ = colore dell'emissione
* $C_{i}$ = colore della i-esima luce su $Q$
* $L_{i}$ = vettore di direzione verso la i-esima luce
* $H_{i}$ = vettore a metà strada per l'i-esima luce
* $N$ = vettore normale
a ogni vertice e li interpola lungo la faccia del triangolo. Il colore $K$ di un pixel è in seguito calcolato usando l'equazione
$K=K_{primario}\circ T_{1}\circ T_{2}\circ \cdot \cdot \cdot \circ T_{k}+K_{secondario}$
dove ogni $T_{i}$ rappresenta un colore campionato da una delle $k$ texture map, e l'operazione $\circ$ è una delle diverse e disponibili operazioni di combinazione che includono la modulazione e l'addizione.
I punti di forza e di debolezza del Gouraud shading risiedono entrambi nell'uso che esso fa dell'interpolazione.
Interpolare i colori di vari pixel (conoscendone con precisione solo pochi) alleggerisce la computazione rispetto a modelli più sofisticati (come il Phong shading, da non confondere con l'omonimo modello di riflessione). Tuttavia gli effetti di luce localizzati (come punti di riflettenza, tipo la riflessione di una sorgente di luce su di una mela) non verranno renderizzati correttamente: se l'effetto è posizionato al centro del poligono, senza raggiungere i vertici, non apparirà come risultato del rendering di Gouraud; se lo stesso effetto è posizionato su di un vertice, verrà mostrato correttamente, ma verrà replicato in modo innaturale sui poligoni adiacenti. Il problema è facilmente riconoscibile se si renderizza una scena in cui la sorgente di luce si muove, spostando la riflessione presente sull'oggetto in questione, con il Gouraud shading si vedrebbe la riflessione allargarsi e stringersi continuamente, raggiungendo i picchi d'intensità nei vertici, e sparendo al centro dei poligoni.
Nonostante i problemi descritti, lo shading ideato da Gouraud è decisamente migliore del flat shading che richiede molta meno computazione, ma produce un risultato sfaccettato.

### Ambient Shading

Premessa: nel mondo reale, le superfici che non sono illuminate da sorgenti luminose, sono illuminate da riflessioni indirette da altre superfici.
Le superfici che non ricevono alcuna illuminazione saranno renderizzate come completamente nere, che spesso non è cosa desiderabile. Un crudo ma utile metodo euristico per evitare le ombre nere è aggiungere una componente costante al modello di shading, il cui contributo al colore del pixel dipende solo dall'incidenza sull'oggetto, senza alcuna dipendenza dalla geometria della superficie. Questo è conosciuto come ambient shading - dove le superfici sono illuminate dalla luce "ambientale" che arriva equamente da ogni parte. Per convenienza nella regolazione dei parametri, l'ambient shading è di solito espresso come il prodotto di un colore di superficie con colore di luce ambientale, in modo che l'ambient shading possa essere regolato sia per le superfici individuali, sia per tutte le superfici insieme. Insieme al modello di Blinn-Phong, l'ambient shading completa un semplice e utile modello di shading:
$L=k_{a}\,I_{a}+k_{d}\,I\max(0,n\cdot l)+k_{s}\,I\,\max(0,n\cdot h)^{n}$
dove $k_{a}$ è il coefficiente ambientale delle superfici, o "colore ambiente", e $I_{a}$ è l'intensità luminosa ambientale.