Teoria di base dell'illuminazione

La possibilità di aggiungere illuminazione alla nostra scena è senza dubbio una prospettiva interessante e alza notevolmente il livello di realismo della scena stessa, è necessario comprendere la teoria che ne sta alla base per poterla sfruttare al meglio.

La luce e'un elemento fondamentale per rappresentare la realtà, infatti guardandoci intorno possiamo notare che tutti gli oggetti vengono in qualche modo influenzati da essa.
La luce è considerata in fisica come una serie di onde elettromagnetiche (percepibili dai nostri occhi) che viaggiano in linea retta. D'altraparte alcuni materiali, in maniera diversa, hanno la possibiltà di deviare la luce. Questo fenomeno, detto riflessione, è molto frequente e si ottiene ad esempio accendendo un lampadario all'interno di una stanza:
gran parte della luce che noi vediamo è quella che viene riflessa dai muri e non quella che effetivamente scaturisce dal lampadino.
I raggi di luce, riflessi e non, vanno a modificare i colori degli oggetti che vengono colpiti.
Il procedimento che viene utilizzato dal software per calcolare l'effetto dell'illuminazione su un oggetto si basa sull'angolo compreso tra il vettore della luce, cioè il vettore che parte dal poligono e punta verso la posizione della luce, e il vettore normale del poligono.
Il vettore normale è un vettore perpendicolare alla superficie del poligono ed èimportantissimo per una vasta gamma di operazioni. Se l'angolo compreso tra i due vettori è uguale a 0 significa che la luce colpisce perpendicolarmente il poligono il cui colore sarà schiarito, se, al contrario, l'angolo è maggiore di 90 allora il poligono non sara illuminato e il suo colore apparirà più scuro (un angolo di 90 gradi significa che i raggi sono paralleli alla superficie).

Calcolare il vettore normale
Il primo obiettivo è calcolare il vettore normale di ogni poligono che è dato dal prodotto vettoriale di due vettori appartenenti al esso. Supponendo di avere un triangolo con i vertici v1 v2 e v3 dobbiamo prima trovare i due vettori U, V appartenenti al triangolo e poi calcolarne il prodotto vettoriale.

Calcolo dei vettori:

U = v2 - v1;
V = v3 - v2;

Il prodotto vettoriale:

N = U x V;
N.x = U.y * V.z - U.z * V.y
N.y = U.z * V.x - U.x * V.z
N.z = U.x * V.y - U.y * V.x

Calcolare l'illuminazione
Il calcolo dell'illuminazione viene eseguita in modo efficiente da OpenGL ma è utile comprenderne il funzionamento. La formula che si utilizza per calcolare l'angolo, e quindi la quantità di luce su un determinato poligono, è la seguente:
        
cos(alfa) = L * N / |L| * |N|

L èil vettore della luce;
N èil vettore normale del poligono;
|L| e |N| sono i moduli (la forza) dei vettori;

Questa operazione deve essere eseguita per ogni faccia del poligono, è quindi necessario ottimizzarla.
Per migliorare notevolmente le prestazioni basta considerare L e N vettori unitari (di forza uno).
Il procedimento per rendere un vettore qualsiasi un vettore di forza unitaria prende il nome di normalizzazione.
Si calcola la forza del vettore

|N| = sqrt(N.x^2 + N.y^2 + N.z^2)

poi si dividono tutte le componenti del vettore per tale forza:

N.x = N.x / |N|  
N.y = N.y / |N|
N.z = N.z / |N|

Si ottiene in questo modo il vettore normalizzato.
La formula ora è meno complessa:

cos(alfa) = L * N

Il valore cos(alfa) viene utilizzato da OpenGL per decidere da quanta luce è colpito un determinato poligono e agire di conseguenza sul colore.    

Tecniche di illuminazione
Avendo calcolato il vettore normale per ogni poligono possiamo dar vita a una illuminazione detta Flat Shading, questo tipo di illuminazione seppur relativamente veloce ha il difetto di far apparire gli oggetti come sfaccettati, infatti il valore cos(alfa) risultato dal calcolo viene esteso in modo uniforme sull'intero poligono. In realtà questo non è vero perchè all'interno dello stesso poligono possono esserci diverse sfumature.
Una tecnica in grado di colmare queste lacune e il Goraud Shading, nel quale l'attenzione passa dal poligono ai vari vertici che lo compongono.
Per implementare il Goraud Shading dobbiamo specificare un vettore normale non più per ogni poligono bensì per ogni vertice del poligono. Si tratta quindi di un calcolo più oneroso. Al fine di elaborare correttamente un vettore normale per ogni vertice (anche se matematicamente calcolare il vettore normale di un vertice non ha senso) si esegue la media dei vettori normali di ogni poligono a cui quel vertice appartiene.

Nv = N1 + N2 + N3 + ... Nn / n

Nv è il vettore normale riferito al vertice
Ni sono i normali dei poligoni che hanno in comune il vertice
n è il numero di poligoni che hanno in comune il vertice
Il risultato ottenuto è senza dubbio migliore.

Specificare i vettori normali
Mentre OpenGL si occupa di gestire direzione, intensità e colori delle luci a noi tocca indicare i vettori normali. Dobbiamo ricordarci di normalizzare il vettore prima di passarlo ad OpenGL.
Le funzioni che dobbiamo utilizzare per indicare i normal vectors sono:

glNormal3{bsifd}(TYPEx, TYPEy, TYPEz);
glNormal3{bsifd}v(TYPEnv* vector);

Il seguente codice disegna un triangolo e indica il relativo normal vector.

glBegin(GL_TRIANGLES);
glNormal3f(0.0, 1.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, -1.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
  
Naturalmente i normal vectors vengono influenzati da tutte le operazioni di rotazione e traslazione applicate all'oggetto, e necessario però porre attenzione ad operazioni di scaling che potrebbero modificare la lunghezza del vettore. Prima di queste operazioni si deve attivare il parametro GL_NORMALIZE che indica ad OpenGL di provvedere a ri-normalizzare i normal vectors.

Privacy Policy