Illuminazione in OpenGL

Note integrative al corso di Grafica Interattiva, corso di Laurea in Informatica, nuovo ordinamento.
A cura di Paola Magillo, DISI, Universita' degli Studi di Genova.

Ingredienti per l'illuminazione di una scena

Quando l'illuminazione e' disabilitata, ogni vertice ha il suo colore (assegnato con glColor), e ogni punto facente parte di una primitiva 1D (GL_LINES,...) o 2D (GL_TRIANGLES, GL_POLYGON,...) ha un colore ottenuto interpolando quello dei vertici della primitiva.

Ne segue che una primitiva ha un unico colore uniforme se i suoi vertici hanno tutti lo stesso colore. Quindi in 3D se tutte le facce di un solido hanno stesso colore, il solido appare come un'unica macchia di colore senza effetto di tridimensionalita'.

L'illuminazione si abilita con glEnable(GL_LIGHTING).

Quando l'illuminazione e' abilitata, ogni punto viene colorato con:

Fattori che entrano in gioco per colorare una primitiva:

Tipi di luce

Ogni sorgente luminosa contiene queste tre componenti di luce, e ciascuna componente puo' avere colore e intensita' diversa. Inoltre esiste una luce ambiente "di sfondo", indipendente dalle sorgenti luminose (attiva anche a sorgenti luminose spente).

Ogni materiale ha una sensibilita' particolare a ciascuna delle tre componenti della luce. Inoltre esistono materiali in grado di emettere luce propria (luce emessa).

Sorgenti luminose

Posso definire una o piu' sorgenti luminose e, dopo averle definite, abilitarle/disabilitarle (per default disabilitate).

Ogni sorgente e' caratterizzata da

Posizione

Si considerano sorgenti puntiformi. In base alla collocazione distinguiamo tre tipi di sorgenti:

La posizione della luce e' soggetta alle trasformazioni come tutte le primitive geometriche, in particolare e' soggetta alla matrice modelview corrente.

Luce emessa

Ogni sorgente luminosa emette tutti e tre i tipi di luce (ambiente, diffusa, speculare). Ciascun tipo ha un certo colore e intensita'.

La luce emessa da una sorgente e' descritta da una terna RGB per ogni tipo di luce.
Il colore e' dato dalla proporzione fra rosso, verde, blu. L'intensita' e' data dal valore assoluto.
Se un tipo di luce non e' emesso, la terna e' (0,0,0) = luce nera.

Istruzioni

Modello di illuminazione

Il modello di illuminazione controlla

Istruzioni

Materiale

Il materiale e' un attributo presente nello stato del sistema che influenza le primitive.

Il materiale stabilisce, per le primitive immediatamente seguenti:

Un materiale e' descritto da una terna RGB per ciascun tipo di luce, e una terna RGB per la luce emessa.
Se un tipo di luce non e' riflesso dal materiale, la terna e' (0,0,0) = nessuna riflessione.
Se il materiale non emette luce propria, la luce emessa e' (0,0,0) = luce nera.

Istruzioni

Normali

Nel caso di luce diffusa, l'intensita' dell'illuminazione dipende dall'angolo formato dalla direzione della luce con la normale alla superficie.
OpenGL NON calcola da solo le normali, bisogna fornirgliele.

La normale e' un attributo presente nello stato del sistema che influenza i verttici delle primitive.

Assegnazione della normale corrente

Tipicamente:

In realta' la normale e' uno di quegli attributi OpenGL che valgono "vertice per vertice" (come anche il colore). Posso assegnare una normale diversa a ogni vertice della stessa faccia. La normale per ciascun punto interno della faccia e' allora interpolata, cosicche' la normale cambia gradualmente all'interno della faccia.

Per default la normale corrente e' (0,0,0) e gli oggetti appaiono "piatti" (colorati di colore uniforme anche in presenza di luce diffusa, nonostante l'inclinazione diversa delle facce).

Normali non normali

Anche le normali, come le coordinate dei vertici, sono "geometria", e subiscono le trasformazioni geometriche.
Se una primitiva viene sottoposta a trasformazioni di scalatura, le normali possono risultare non piu' "normali" dopo la trasformazione.

L'istruzione glEnable(GL_NORMALIZE); abilita la normalizzazione automatica delle normali.

Risolve il problema citato sopra e inoltre consente di passare a glNormal vettori di norma non necessariamente = 1.

Interazione fra luce e materiale

Reazione alla luce ambiente: si moltiplicano componente per componente la terna RGB della luce ambiente e la terna RGB della reazione del materiale alla luce ambiente.

Reazione alla luce diffusa: si procede nello stesso modo che per la luce ambiente ma il risultato si moltiplica per il coseno dell'angolo formato dalla direzione della luce incidente con la normale alla primitiva (=1 se la luce incide perpendicolarmente, 0 se e' radente).

Reazione alla luce speculare: come per la luce diffusa ma alla luce riflessa e' attribuita una direzione di riflessione e si moltiplica anche per il coseno dell'angolo formato dalla luce riflessa con la direzione dello sguardo dell'osservatore.

Le reazioni ai tre tipi di luci si sommano fra loro e si sommano alla luce emessa.

Riepilogo

Per ottenere una scena illuminata bisogna:

Scorciatoia

In presenza di luci, il colore apparente di un oggetto e' determinato dal colore della luce che riflette, e apparentemente glColor non ha effetto.

Si puo' usare l'istruzione glColorMaterial per far si' che i parametri di materiale seguano il valore attuale del colore assegnato con glColor.