ILLUMINAZIONE ( E COLORE ) ========================== LUCE DISABILITATA - Ogni vertice ha il suo colore (assegnato con glColor) - Ogni punto facente parte di una primitiva 1D (GL_LINES,...) o 2D (GL_TRIANGLES, GL_POLYGON,...) ha 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 --> anche 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' LUCE ABILITATA Ogni punto e' colorato con: - un colore che dipende dalla luce che lo colpisce (proprieta' della sorgente luminosa che emette la luce) e dalla capacita' di risposta alla luce della primitiva di cui fa parte (proprieta' del materiale di cui e' fatta la primitiva) - un'intensita' che dipende dalle due cose di cui sopra, ed evcentualmente dall'inclinazione con cui la luce lo colpisce (angolo tra direzione della luce e direzione della normale alla primitiva in quel punto) Fattori che entrano in gioco: - Dalla parte delle primitive: Proprieta' di materiale (glMaterial) e normali (glNormal) specificate mentre definisco la primitiva - Dalla parte delle luci: Proprieta' delle sorgenti luminose (glLight) e modello di illuminazione (glLightModel) TIPI DI LUCE Luce ambiente: proviene da tutte le direzioni, viene riflessa da una primitiva in tutte le direzioni allo stesso modo. Provenendo da tutte le direzioni, colpisce con la stessa intensita' ogni punto indipendentemente dalla sua normale. Non utile a creare effetto 3D Luce diffusa: proviene da una direzione in particolare, viene riflessa in tutte le direzioni. Colpisce ogni punto con intensita' che dipende dall'angolo formato dalla direzione della luce con la normale in quel punto. E' quella che crea effetto 3D Luce speculare: proviene da una direzione in particolare, viene riflessa in una direzione in particolare. Crea effetti di "luccichio" tipo metalli o vetro Ogni sorgente luminosa contiene queste tre componenti di luce, e ciascuna componente puo' avere colore e intensita' diversa. Inoltre e' prevista 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). NORMALI Per specificare una primitiva OpenGL pongo tra glBegin e glEnd una serie di glVertex inframezzate da assegnazione di attributi OpenGL, del tipo di attributi che valgono "vertice per vertice". Tra gli attributi "vertice per vertice" abbiamo visto il colore corrente (assegnato con glColor). Un altro e' la normale corrente (assegnata con glNormal). Come il colore, ogni vertice ha la sua normale, e la normale di un punto (non vertice) di una primitiva e' ottenuta per interpolazione). - stessa normale per tutti i vertici di un poligono --> il poligono appare come una faccia piana - normali diverse --> il poligono assume un'apparenza curva 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). OpenGL non sa dedurre l'inclinazione di una faccia dalle posizioni dei suoi vertici, ha bisogno che il programmatore gliela fornisca con le normali! Assegnazione della normale corrente: glNormal3f() oppure glNormal3fv() ...varie forme analogamente a quanto visto per glVertex... Normalizzazione automatica delle normali (funzionalita' di OpenGL): glEnable(GL_NORMALIZE); - consente di passare a glNormal vettori di norma non necessariamnete = 1. - utile se le primitive subiscono trasformazioni di scalatura dopo essere state definite. Infatti anche le normali, come le ccordinate dei vertici, sono "geometria", e subiscono le trasformazioni geometriche; quindi, possono risultare non piu' "normali" dopo la trasformazione PROPRIETA' DI MATERIALE glMaterialf(,,); e glMateriali, glMaterialfv, glMaterialiv, dove f/i --> e' un float / un intero v --> e' un array di float / interi = GL_FRONT, GL_BACK o GL_FRONT_AND_BACK per assegnare proprieta' di alle front faces, le back faces, o a entrambe e sono illustrati dalla seguente tabella: (scalare o vettore) ------------------------------------------------------------------------- GL_AMBIENT vettore di componenti RGBA, default (0.2,0.2,0.2,1) frazione di luce ambiente ricevuta che la primitiva riflette, per ogni colore ------------------------------------------------------------------------- GL_DIFFUSE vettore di componenti RGBA, default (0.8,0.8,0.8,1) frazione di luce diffusa ricevuta che la primitiva riflette, per ogni colore ------------------------------------------------------------------------- GL_SPECULAR vettore di componenti RGBA, default (0,0,0,1) frazione di luce speculare ricevuta che la primitiva riflette, per ogni colore ------------------------------------------------------------------------- GL_AMBIENT_AND_DIFFUSE per assegnare in un colpo GL_AMBIENT e GL_DIFFUSE con lo stesso vettore RGB ------------------------------------------------------------------------- GL_EMISSION vettore di componenti RGBA, default (0,0,0,1) componenti della luce emessa dalla primitiva stessa ------------------------------------------------------------------------- GL_SHININESS intero tra 0 e 128 intensita' della luce speculare riflessa ------------------------------------------------------------------------- OpenGL prevede primitive che "brillano di luce propria" definita dalla proprieta' GL_EMISSION. Nota: componenti RGB = 0,0,0 implicano luce "nera", ovvero nessuna luce (o nessuna componente di quel tipo nella luce). PROPRIETA' DELLE SORGENTI LUMINOSE Posso definire una o piu' sorgenti luminose e, dopo averle definite, abilitarle/disabilitarle (per default disabilitate). TIPI DI SORGENTI: - All'infinito (raggi luminosi paralleli): posizionate in punto (x,y,z,w) con w=0 - In un punto (raggi che escono dal punto in tutte le direzioni): posizionate in punto (x,y,z,w) con w=1 - Spot light (in un punto, con solo un cono di luce uscente): in un punto (x,y,z,w) con w=1, e con "angolo di apertura" limitato Nota: La posizione della luce e' soggetta alle trasformazioni come tutte le primitive geometriche, in particolare e' soggetta alla matrice MODELVIEW corrente. E' possibile ottenere luci che si spostano facendo precedere la definizione della loro posizione da una qualche trasformazione. Invece, trasformazioni poste dopo la definizione della luce (ma prima della definizione degli oggetti della scena) non cambiano la posizione della luce ma muovono solo la scena a luce ferma. Definizione sorgenti: glLightf(,,); e glLighti, glLightfv, glLightiv, dove f/i,v con stesso funzionamento che in glMaterial. = GL_LIGHT0, GL_LIGHT1,... (OpenGL fornisce almento 7 luci) e sono illustrati dalla seguente tabella: (scalare o vettore) ------------------------------------------------------------------------- GL_AMBIENT vettore di componenti RGBA, default (0,0,0,1) valori di luce ambiente emessa dalla sorgente ------------------------------------------------------------------------- GL_DIFFUSE vettore di componenti RGBA, default (1,1,1,1) per GL_LIGHT0 e (0,0,0,1) per le altre valori di luce diffusa emessa dalla sorgente ------------------------------------------------------------------------- GL_SPECULAR vettore di componenti RGBA, default (1,1,1,1) per GL_LIGHT0 e (0,0,0,1) per le altre valori di luce speculare emessa dalla sorgente ------------------------------------------------------------------------- GL_POSITION vettore di coordinate (x,y,z,w) posizione della luce, w=1 per posizione in un punto (x,y,z) al finito, w=0 per posizione all'infinito nella direzione del vettore (x,y,z) ------------------------------------------------------------------------- GL_SPOT_CUTOFF intero in 0..90, oppure 180 (default) angolo di apertura del cono per luci spot (180 = cono che coincide con tutto lo spazio, ovvero luce non spot) ------------------------------------------------------------------------- GL_SPOT_EXPONENT intero in 0..128 esprime quanto e' "focalizzata" una luce spot ------------------------------------------------------------------------- GL_CONSTANT_ATTENUATION 1 GL_LINEAR_ATTENUATION valore reale >=0, default = 0 GL_QUADRATIC_ATTENUATION 0 specifica come la luce viene attenuata al crescere della distanza dalla sorgente luminosa; a distanza d la luce e' attenuata di fattore = 1 / ( constant_att + d*linear_att + d^2*qadratic_att) il default significa no attenuazione. Non ha influenza per luci all'infinito ------------------------------------------------------------------------- MODELLO DI ILLUMINAZIONE glLightModelf(,) oppure glLightModeli, glLightModelfv, glLightModeliv ------------------------------------------------------------------------- GL_LIGHT_MODEL_AMBIENT vettore di componenti RGBA della luce ambiente "di sfondo" (default 0.2,0.2,0.2,1) ------------------------------------------------------------------------- GL_LIGHT_MODEL_TWO_SIDE 0 oppure 1 (default = 0) 0 --> illumina solo front faces (in oggetti "chiusi" le back faces non si vedono...) ------------------------------------------------------------------------- GL_LIGHT_MODEL_LOCAL_VIEWER 0 oppure 1 (default = 0) 0 --> non tiene conto della posizione del punto di vista nel calcolo delle riflessioni speculari (meno accurato ma piu veloce) ------------------------------------------------------------------------- NOTA BENE In presenza di luci, il colore apparente di on 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 paramatri di materiale seguano il valore attuale del colore assegnato con glColor ABILITAZIONI glEnable(GL_LIGHTING); per abilitare il calcolo delle luci glEnable(GL_LIGHTi); per abilitare l'i-esima luce glEnable(GL_COLOR_MATERIAL); per abilitare che il colore del materiale segua in ogni momento il colore corrente COSE DA FARE PER OTTENERE UNA SCENA ILLUMINATA - Abilitare l'illuminazione e tutte le luci che si intendono usare, usando glEnable(GL_LIGHTING) e glEnable(GL_LIGHTi) per i=0... - Definire eventualmente i parametri modello di illuminazione, usando glLightModel (se non vanno bene quelli di default) - Definire i parametri di ciascuna luce che si intende usare, usando glLight(GL_LIGHTi,....) - Definire il materiale di ciascuna primitiva che si vuole tracciare, usando glMaterial(....). Nota: il materiale e' parte dello stato corrente di OpenGL e ha effetto su tutte le primitive che seguono a partire dal punto dove viene assegnato. Inoltre e' di quegli attributi che POSSONO essere assegnati tra glBegin e glEnd (e' proprieta' del singolo vertice).