Sunteți pe pagina 1din 10

Lucrarea Nr.

4 MODELE DE REFLEXIE SI ILUMINARE

Redarea obiectelor tridimensionale prin suprafete colorate uniform creeaza imagini nerealiste si dificil de interpretat. De exemplu, o sfera neluminata arata la fel ca un disc bidimensional. Acest aspect nerealist se datoreaza faptului ca perceptia celei de-a treia dimensiuni este mult influientata de iluminarea obiectelor. n lumea reala, atunci cnd lumina provenita de la diferite surse de lumina cade asupra obiectelor opace, o parte este absorbita de obiect, iar o parte este reflectata. Ochiul percepe lumina reflectata de obiect, pentru a interpreta forma, culoarea si alte detalii ale obiectului. Pentru calculul iluminarii n grafica pe calculator trebuie sa fie definite sursele de lumina si interactiunea dintre lumina si suprafete. Un model de iluminare defineste natura luminii emise de o sursa de lumina, adica distributia intensitatii luminii emise. Un model de reflexie descrie interactiunea dintre lumina si o suprafata, n functie de proprietatile suprafetei si natura sursei de lumina. Modelele de iluminare si de reflexie n grafica pe calculator permit redarea acceptabila din punct de vedere al perceptiei umane a obiectelor tridimensionale proiectate n spatiul ecran bidimensional. Implementarea unui model de reflexie n procedeul de calculare a intensitatii culorii fiecarui pixel este cunoscuta sub numele de tehnica de umbrire. n grafica pe calculator se considera n mod simplificat ca intensitatea reflectata de o suprafata este compusa din trei componente: componenta de reflexie directionata (speculara), componenta de reflexie difuza directionata si componenta de reflexie difuza ideala. Primele doua componente se datoreaza reflexiei de prim ordin, iar componenta de reflexie difuza ideala se datoreaza reflexiilor multiple si a reflexiilor subsuprafetelor (fig. 4.1).
L Orientarea medie a suprafetei Reflexie de prim ordin L Reflexie multipla Reflexii ale subsuprafetelor

Fig. 4.1 Reflexii de prim ordin, reflexii multiple si reflexii ale subsuprafetelor

Valorile componentelor intensitatilor reflectate depind de rugozitatea suprafetei si de lungimea de unda a luminii. Daca suprafata ar fi oglinda perfecta, atunci singura componenta de lumina reflectata ar fi componenta directionata (speculara). Intensitatea acestei componente depinde de rugozitatea suprafetei: cu ct suprafata este mai neteda, cu att componenta speculara este mai mare. Componenta de difuzie directionata depinde de asemenea de reflexiile de prim ordin. Directiile de reflexie sunt mprastiate n semisfera centrata n punctul de incidenta, dar exista o directie preferintiala, care este directia reflexiei speculare pentru suprafetele cu rugozitate redusa. Componenta de difuzie ideala reflecta lumina n toate directiile n interiorul unei semisfere centrate n punctul de incidenta, datorita mprastierii provocate de subsuprafetele componente. Prin descompunerea functiei de reflexie bidirectionala n trei componente se poate dezvolta un model analitic bazat pe aspecte fizice, optice si geometrice, care sa permita simularea iluminarii si a reflexiei n grafica pe calculator. Modelul de reflexie Phong este cel mai cunoscut model n grafica pe calculator, care adopta o reprezentare empirica si fenomenologica, prin formule de calcul simple de imitare a comportarii teoretice a reflexiei luminii, descrise anterior.

4.1

MODELUL DE REFLEXIE PHONG

Modelul de reflexie Phong imita eficient modul real de reflexie, pna la un grad care produce o perceptie destul de buna a obiectelor iluminate si, de aceea, are o larga utilizare n grafica pe calculator. Modelul de reflexie Phong considera lumina reflectata de o suprafata ca fiind o combinatie liniara a trei componente: reflexia difuza, speculara si ambientala. Componenta de reflexie difuza corespunde componentei de reflexie difuza ideale descrise n subcapitolul precedent si este evaluata prin relatia:

I d = I i k d (L N ) = I i k d cos

(4.1)

unde Ii este intensitatea luminii incidente, L este vectorul unitate ndreptat catre sursa de lumina si N este vectorul unitate normal la suprafata n punctul de incidenta (fig. 4.2(a)). Pentru o suprafata plana, unghiul este constant, deci componenta de reflexie difuza este constanta. k este un coeficient de d reflexie (reflectanta) empiric, care depinde de lungimea de unda a luminii si de natura suprafetei. Dat fiind ca n reflexia difuza lumina este reflectata n toate directiile, aceasta componenta nu depinde de pozitia de observare. Daca exista mai multe surse de lumina, atunci:

I d = k d I i, n (L n N )
n

(4.2)

unde Ln este vectorul unitate n directia celei de-a n-a sursa de lumina. Componenta speculara a reflexiei n modelul Phong depinde de unghiul ntre directia de observare V si directia de oglindire R (fig. 4.2(b)). Daca se considera R si V vectorii unitate ai acestor directii, atunci:

I s = I i k s cosn = I i k s ( R V ) n
unde n este un indice care simuleaza rugozitatea suprafetei.

(4.3)

L N

L N R V

(a)

(b)

Fig. 4.2 (a) Reflexia difuza Phong. (b) Reflexia speculara Phong.

Pentru o suprafata oglinda perfecta, n tinde catre infinit si lumina este reflectata numai n directia de oglindire R, pentru care cos n =1. Pentru valori finite ale indicelui n, se genereaza un lob de reflexie, a carui grosime este o functie de rugozitatea suprafetei. Cu ct suprafata este mai lucioasa, cu att indicele n este mai mare pentru simularea reflexiei speculara cu lob ngust. Efectul reflexiei speculare n modelul Phong este acela de a produce o iluminare mai accentuata (highlight), care este reflexia sursei de lumina pe o arie a suprafetei, depinznd de valoarea lui n. Culoarea luminii reflectate specular poate fi diferita de culoarea luminii reflectate difuz. n modelele cele mai simple de reflexie speculara, se presupune ca aceasta componenta are culoarea sursei de lumina. De exemplu, o suprafata de culoare verde iluminata de o sursa de lumina alba produce o componenta de reflexie de difuzie de culoare verde, dar pata luminoasa de reflexie speculara are culoarea alba.

46

Componenta de lumina ambientala se adauga n modelul Phong pentru a simula iluminarea globala a scenei. Aceasta componenta permite iluminarea suprafetelor care nu sunt vizibile din sursa de lumina, dar sunt vizibile din punctul de observare. Fara componenta ambientala, suprafetele care nu sunt ndreptate catre o sursa de lumina ar fi redate complet negre, ceea ce ar crea un efect nerealist. Componenta ambientala aproximeaza iluminarea indirecta a suprafetelor, de exemplu datorita reflexiilor multiple fata de peretii unei incinte. Aceste reflexii sunt foarte de complicat de simulat, astfel nct modelul Phong le ignora si adauga o componenta de lumina ambientala constanta data de relatia:

Ig = Iaka

(4.4)

Prin nsumarea componentelor de lumina difuza, speculara si ambientala, se obtine iluminarea totala a unei suprafete:

I = I a k a + I i k d (L N) + k s (R V ) n

)
)

(4.5)

n modelul RGB de reprezentare a culorilor, relatia (4.5) se descompune n trei relatii, pentru fiecare componenta rosu, verde, albastru:

I r = I a k ar + I i k dr (L N) + k sr (R V ) n

I g = I a k ag + I i k dg (L N ) + k sg ( R V ) n I b = I a k ab + I i k db (L N ) + k sb (R V ) n

)
)

(4.6)

4.2

MODELE DE UMBRIRE

Aplicarea directa a relatiei (4.6) pentru calculul culorii fiecarui pixel necesita un timp de executie extrem de ridicat, care nu este acceptabil n grafica interactiva. De aceea, n sinteza de imagine se folosesc anumite metode simplificate de calcul al culorii fiecarui pixel, numite tehnici (modele) de umbrire. Tehnicile de umbrire depind de modul de reprezentare a obiectelor. Pentru obiectele modelate prin retea de poligoane, se folosesc mai multe modele de umbrire: umbrirea constanta (poligonala, flat), umbrirea Gouraud si umbrirea Phong. Umbrirea constanta admite calculul unei singure intensitati a culorii pentru fiecare suprafata poligonala; acest mod de calcul este posibil daca se admite ipoteza simplificatoare ca att sursele de lumina, ct si observatorul sunt la infinit. Umbrirea constanta produce discontinuitati de culoare la frontiera dintre suprafete. Calculul umbririi constante nseamna aplicarea formulelor Phong (4.6) pentru fiecare suprafata vizibila, o singura data pentru fiecare pozitie a observatorului. Umbrirea Gouraud. Pentru eliminarea discontinuitatilor de colorare care apar n umbrirea constanta, Gouraud a introdus o metoda de umbrire care-i poarta numele si care calculeaza intensitatea de culoare a pixelilor suprafetelor prin metode de interpolare, pornind de la intensitatile n vrfurile poligonului. Metoda incrementala de calcul al intensitatii de culoare a pixelilor este asemanatoare metodei de calcul al adncimii pixelilor folosita n algoritmul Z-buffer. n general, se aplica combinat transformarea de rastru, eliminarea suprafetelor ascunse si umbrirea Gouraud, ntr-un algoritm de baleiere pe linii generalizat. Umbrirea Gouraud este o tehnica de interpolare biliniara a intensitatii culorii, foarte simpla si economica, care atenueaza discontinuitatile de la frontiera poligoanelor prin care este reprezentat un obiect tridimensional, fara sa elimine complet aspectul poligonal al obiectelor. Intensitatea de culoare se calculeaza n vrfurile poligoanelor prin aplicarea relatiilor (4.6) de calcul al reflexiei n modelul Phong. Normala ntr-un vrf al unui poligon se calculeaza ca medie a normalelor tuturor poligoanelor care sunt adiacente vrfului:

Nv =
i =1

Ni m

(4.7)

47

Normalele n vrfurile poligoanelor sunt definite n sistemul de referinta model si ele sunt transformate n sistemul de referinta de observare prin aplicarea acelorasi transformari care se aplica vrfurilor: transformarea de instantiere si transformarea de observare. n sistemul de referinta de observare se calculeaza intensitatile n vrfurile poligoanelor si aceste valori sunt folosite pentru interpolare biliniara n algoritmul de conversie de baleiere pe linii a poligoanelor. Acest mod de calcul permite ca normalele n vrfuri sa fie calculate o singura data, la modelare, si memorate ca parte a modelului obiectului n baza de date grafice. Atunci cnd se decupeaza fetele obiectelor, pot sa apara vrfuri noi, care nu existau n modelul obiectului initial. Pentru aceste vrfuri se calculeaza normalele n noile vrfuri prin interpolare ntre normalele laturilor intersectate de planul de decupare. Interpolarea biliniara a intensitatilor de culoare a pixelilor unui poligon se executa n cadrul algoritmului de baleiere pe linii pornind de la intensitatile de culoare ale vrfurilor poligonului, calculate prin relatiile modelului de reflexie Phong. Desi acceptabila n multe aplicatii, att ca eficienta ct si ca realism de reprezentare, umbrirea Gouraud poate provoca unele anomalii provenind n primul rnd din calculul normalei ntr-un vrf prin medierea normalelor fetelor adiacente. O parte din deficientele tehnicii de umbrire Gouraud sunt eliminate n modelul de umbrire Phong. Modelul de umbrire Phong este, ca si modelul Gouraud, un model de calcul al intensitatii culorii prin interpolare biliniara, dar n acest model se interpoleaza normalele si se calculeaza exact intensitatea culorii. Umbrirea Phong este mai costisitoare din punct de vedere al operatiilor efectuate deoarece, pentru fiecare pixel, se aplica relatia de calcul (4.6), care contine produse scalare de vectori si nmultiri. Dar, din punct de vedere al calitatii imaginii generate, umbrirea Phong este mai buna, dat fiindca se calculeaza normale foarte apropiate de normala reala n fiecare punct al suprafetei. n tehnica de umbrire Phong se poate simula mult mai corect reflexia speculara (highlight). n subcapitolul urmator sunt prezentate modalitatile de programare a iluminarii n aplicatii grafice folosind biblioteca OpenGL.

4.3

FUNCTIILE OPENGL DE CALCUL AL ILUMINARII

Biblioteca OpenGL implementeaza modelul de reflexie Phong si modelele de umbrire poligonala si umbrire Gouraud. n mod implicit, sistemul de iluminare este inactivat si pentru desenarea primitivelor geometrice se foloseste culoarea curenta, specificata prin functia glColor#(). Pentru validarea iluminarii obiectelor, se activeaza sistemul de iluminare OpenGL prin apelul functiei glEnable (GL_LIGHTING). Pentru calculul iluminarii obiectelor trebuie sa fie definite: sursele de lumina; materialul suprafetelor; modelul de umbrire a suprafetelor.

4.3.1

DEFINIREA SURSELOR DE LUMINA

n OpenGL se pot defini mai multe surse de lumina punctiforme. Numarul de lumini admise variaza n functie de implementare, dar cel putin opt lumini sunt disponibile n orice biblioteca OpenGL. Fiecare sursa de lumina poate fi validata prin apelul functiei glEnable(GL_LIGHTi), unde i este indexul sursei de lumina. O sursa de lumina se caracterizeaza prin intensitate si pozitie n scena. Intensitatea unei surse de lumina se specifica pentru fiecare componenta de iluminare (ambientala, de difuzie si speculara) printr-un vector n spatiul culorilor n modelul RGBA. Pozitia unei surse se specifica printr-un vector n coordonate omogene corespunzatoare sistemului de referinta universal. Functia de definire a unui parametru al unei surse de lumina este functia glLight#() care are mai multe variante n functie de tipul argumentelor. De exemplu:
void glLightfv(GLenum light, GLenum pname, const GLfloat *params);

48

void glLightiv(GLenum light, GLenum pname, const GLint *params);

Argumentul light reprezinta indexul sursei de lumina si poate lua un nume simbolic de forma GL_LIGHT0, GL_LIGHT1, .GL_LIGHTi, unde 0 i < GL_MAX_LIGHTS. Numarul maxim de lumini depinde de implementarea bibliotecii. Argumentul pname specifica un parametru al sursei de lumina. Sunt acceptate mai multe valori, dintre care unele se refera la intensitate de culoare iar altele la pozitia sursei. Valorile GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR ale argumentului pname permit definirea componentelor intensitatii culorii sursei de lumina. n aceasta situatie, argumentul params reprezinta un pointer la un vector de patru valori (de tip ntreg sau virgula flotanta), care specifica intensitatile RGBA ale componentei de iluminare ambientala, difuza si, respectiv, speculara. Valorile implicite ale intensitatilor sunt (0.0, 0.0, 0.0, 1.0) pentru componenta ambientala si pentru componentele difuza si speculara a oricarei lumini cu exceptia luminii cu index 0, care au intensitatea difuza si speculara implicita (1.0, 1.0, 1.0, 1.0). n acest model de definire a sursei de lumina, componenta ambientala ( GL_AMBIENT) se refera la intensitatea RGBA pe care o sursa de lumina o adauga iluminarii globale a scenei. Componenta de iluminare difuza (GL_DIFFUSE) este cel mai apropiat mod de reprezentare a ceea ce se considera culoarea sursei de lumina. Componenta de iluminare speculara (GL_SPECULAR) afecteaza culoarea zonei stralucitoare (hightlight) a obiectelor luminate de sursa respectiva. Valoarea transparentei surselor de lumina ( alpha) este ignorata daca nu se valideaza calculul transparentei (color blending). Valoare GL_POSITION a argumentului pname permite definirea pozitiei sursei de lumina. n aceasta situatie, argumentul params este un pointer la un vector de patru numere (ntregi sau virgula flotanta) care reprezinta pozitia n coordonate omogene n sistemul de referinta universal a sursei de lumina. Acesta pozitie este transformata prin aplicarea valorii matricei de modelarevizualizare din momentul apelului functiei glLight#(), astfel nct sursa de lumina va avea coordonatele transformate n sistemul de referinta de observare, unde se calculeaza intensitatea n vrfurile primitivelor geometrice. Daca componenta w a pozitiei este diferita de 0 (w 0), atunci sursa este o sursa pozitionala si se foloseste localizarea acesteia pentru calculul directiei de iluminare a suprafetelor. Daca componenta w a pozitiei este 0, atunci lumina este tratata ca o lumina directionala plasata la infinit, n directia definita de componentele x, y, z si se utilizeaza aceasta directie pentru calculul componentelor de reflexie difuza si speculara. Pozitia implicita a unei surse este (0, 0, 1, 0), deci sursa este plasata la infinit pe axa z si ea lumineaza obiectele n directia z.

4.3.2

DEFINIREA PROPRIETATILOR MATERIALELOR

Pentru calculul intensitatii culorii unei suprafete, trebuie definiti coeficientii de reflexie pentru componentele de reflexie ambientala, difuza si speculara. Aceste proprietati sunt considerate proprietati de material al suprafetei si se specifica prin apelul uneia sau mai multora din cele patru variante ale functiei glMaterial#():
void glMaterialf(GLenum face,GLenum pname,GLfloat param); void glMaterialfv(GLenum face,GLenum pname,GLfloat *param);

n aceste functii, argumentul face este numele fetei si depinde de orientarea acesteia; poate lua ca valori constantele simbolice GL_FRONT, GL_BACK, GL_FRONT_AND_BACK. Argumentul pname specifica proprietatea materialului, care se defineste prin apelul functiei glMaterial#(). Acest argument poate lua valorile GL_AMBIENT, GL_DIFFUSE, GL_AMBIENT_AND_DIFFUSE, GL_SPECULAR, GL_SHININESS. Functia glMaterialf() se foloseste numai pentru setarea stralucirii (GL_SHININESS) la valoarea data prin argumentul param. Functia glMaterialfv() se foloseste pentru specificarea celorlalte proprietati. n general, param este un pointer la un vector de patru valori de tip ntreg sau cu virgula flotanta, care sunt componentele rosu, verde, albastru si alpha (transparenta) ale componentei de reflexie specificate prin parametrul pname(ambientala, difuza, speculara, emisie).

49

Reflexia difuza joaca cel mai important rol n culoarea pe care o prezinta o suprafata. Ea reprezinta culoarea pe care o are suprafata luminata direct si depinde de componenta de difuzie a luminii incidente, provenita de la una sau mai multe surse de lumina, de coeficientul de reflexie de difuzie (reflectanta de difuzie) a materialului si de unghiul dintre directia luminii si normala la suprafata. Pozitia de observare nu influenteaza componenta de difuzie a luminii reflectate. Reflexia ambientala afecteaza culoarea de ansamblu pe care o prezinta o suprafata si ea devine sesizabila atunci cnd suprafata nu este luminata direct. Ca si reflexia difuza, aceasta componenta nu depinde de pozitia de observare. Cele doua componente se specifica de cele mai multe ori cu aceeasi culoare (asa cum sunt suprafetele reale) folosind parametrul GL_AMBIENT_AND_DIFFUSE n apelul functiei glMaterial#(). Reflexia speculara produce iluminarea mai puternica (highlight) a unei zone a obiectului, n functie de pozitia de observare. OpenGL permite specificarea culorii produse de reflexia speculara (prin parametrul GL_SPECULAR) si a dimensiunii si stralucirii zonei prin parametrul GL_SHININESS. Functia glMaterial#() seteaza proprietatile materialului curent, care se aplica tuturor vrfurilor introduse dupa aceasta prin functiile glVertex#() sau prin diferite functii de modelare din biblioteca GLUT (de exemplu, glutSolidSphere()). Proprietatile materialului curent se mentin pna la urmatorul apel al functiei glMaterial#(). Calculele de iluminare se pot executa diferit pentru fetele orientate direct ( GL_FRONT) si cele orientate invers ( GL_BACK). sau pentru ambele (GL_FRONT_AND_BACK).

Teme - Exercitii
4.1. Definirea sistemului de iluminare. n mod implicit, biblioteca OpenGL reda fiecare suprafata (primitiva geometrica) folosind culoarea curenta. Pentru generarea unei imagini cu iluminare, trebuie : (a) sa se valideze sistemul de iluminare; (b) sa se valideze si sa se seteze cel putin o sursa de lumina; (c) sa se seteze un material curent. Daca s-a validat sistemul de iluminare, OpenGL foloseste pentru redarea fiecarei suprafete culoarea rezultata din interactiunea surselor de lumina existente cu materialul curent. Schimbnd materialul curent, se poate reda fiecare suprafata cu aspectul (culoarea) dorita. Pentru nceput se poate studia sistemul de iluminare folosind o singura sursa de lumina si un singur material (materialul curent). Pentru aceasta se definesc si se initializeaza parametrii sursei de lumina cu indice 0 (GL_LIGHT0) si parametrii materialului curent. ntr-un proiect GLUT, parametrii sursei si ai materialului se pot defini ca variabile globale astfel:
GLfloat light_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f}; GLfloat light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; GLfloat light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f}; GLfloat GLfloat GLfloat GLfloat mat_ambient[] = {0.1f, 0.1f, 0.1f, 1.0f}; mat_diffuse[] = {1.0f, 0.0f, 0.0f, 0.0f}; mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f}; mat_shininess = 50.0f; //alb //alb //alb // gri inchis // rosu // alb

n proiectul Lab3d, parametrii sursei de lumina si ai materialului curent se declara (de exemplu) variabile membre ale clasei CLab3dView:
GLfloat GLfloat GLfloat GLfloat light_ambient[4], light_diffuse[4]; light_specular[4],light_position[4]; mat_ambient[4], mat_diffuse[4]; mat_specular[4],mat_shininess;

Aceste variabile se initializeaza la constructia clasei cu aceleasi valori ca mai sus:


light_ambient[0] = 1.0f;

50

.. mat_shininess = 50.0f;

Validarea sistemul de iluminare si a sursei de lumina 0 se face n rutina Init() prin apelul functiilor:
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);

Setarea parametrilor de culoare ai sursei de lumina si ai materialului curent se face n rutina Init() prin apelul a functiilor:
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);

Daca fiecare suprafata are un material propriu, atunci materialul acesteia se memoreaza n modelul obiectului, iar la redare, functiile glMaterialfv() si glMaterialf() cu argumente valorile componentelor respective se apeleaza pentru fiecare suprafata, naintea functiei glBegin(). Setarea pozitiei sursei de lumina se face n functia de redare a scenei. Se considera pentru nceput o sursa de lumina directionala, plasata pe axa Oz a sistemului de referinta universal. Pozitia unei astfel de surse este: (0,0,1,0); coordonata w = 0 arata ca sursa se afla la infinit n directia z pozitiv; ea va ilumina obiectele dinspre z pozitiv n directia spre z negativ. OpenGL trateaza pozitia unei surse de lumina la fel cum este tratata pozitia primitivelor geometrice, adica pozitia unei surse este transformata cu aceleasi matrice de transformare ca si primitivele geometrice. Atunci cnd este apelata functia glLight#(GL_LIGHTi, GL_POSITION vect), pozitia sau directia este transformata cu matricea de modelare-vizualizare curenta si este memorata n coordonate n sistemul de referinta de observare. Matricea de proiectie nu modifica pozitia surselor de lunima. Dat fiind ca sursa de lumina este definita n sistemul de referinta universal, pozitia ei trebuie sa fie supusa transformarii de observare, la fel ca toate obiectele scenei, astfel nct, dupa transformarea de observare, att obiectele scenei ct si sursa de lumina sa fie pozitionate n sistemul de referina de observare unde se efectueaza calculele de iluminare. Asadar, introducerea functiei de pozitionare a unei surse de lumina trebuie sa se faca dupa transformarea de observare, naintea transformarilor de modelare ale obiectelor scenei. Introducerea pozitiei sursei de lumina n functia de redare DrawScene() din proiectul Lab3d va arata astfel:
void CLab3dView::DrawScene(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); // Transformarea de observare glRotatef(-angleZv, 0.0,0.0,1.0); glRotatef(-angleXv, 1.0,0.0,0.0); glRotatef(-angleYv, 0.0,1.0,0.0); glTranslatef(-Xv, -Yv, -Zv); // Sursa de lumina fixa (in sistemul de referinta universal) glLightfv(GL_LIGHT0, GL_POSITION, light_position); // Transformarea de modelare (pozitionare) a obiectelor scenei glTranslatef(Xs,Ys,Zs); glRotatef(angleYs, 0.0,1.0,0.0); glRotatef(angleXs, 1.0,0.0,0.0); glRotatef(angleZs, 0.0,0.0,1.0);

51

glColor3f(currentR, currentG, currentB); // culoarea curenta switch (m_scene){ case TEAPOT: glutTeapot(1.0); break; } glPopMatrix(); glFinish(); SwapBuffers(wglGetCurrentDC()); }

ntr-un proiect GLUT, se introduce n mod asemanator functia glLightfv(GL_LIGHT0, GL_POSITION, light_position), n functia de redare Display(), dupa transformarea de observare. La executia programului se va observa iluminarea obiectelor si diferenta fata de aceleasi obiecte redate fara iluminare. 4.2. Studierea modelelor de umbrire. Modelul de umbrire se defineste prin apelul functiei glShadeModel(GLenum mode), unde argumentul mode poate lua una din valorile GL_FLAT, pentru modelul de umbrire poligonala, sau GL_SMOOTH, pentru modelul de umbrire Gouraud. Valoarea implicita este GL_SMOOTH. Daca nu este validat sistemul de iluminare, atunci culoarea care se atribuie vrfurilor primitivelor geometrice este culoarea curenta, setata prin apelul unei functii glColor#(). Daca s-a definit modelul de umbrire poligonala (GL_FLAT), primitivele geometrice se genereaza de culoare constanta. Daca s-a definit modelul de umbrire Gouraud (GL_SMOOTH), atunci culorile definite n vrfuri se folosesc pentru calculul intensitatii culorii pixelilor primitivei prin interpolarea biliniara. Daca s-a validat sistemul de iluminare, atunci n modelul de umbrire poligonala, fiecare suprafata are o culoare constanta care depinde de culoarea sursei (surselor) de lumina si a materialului. Daca s-a definit modelul de umbrire Gouraud, atunci intensitatea de culoare a fiecarui pixel al fiecarei suprafete este calculata prin interpolare bilineara n functie de intensitatile de culoare din vrfurile suprafetei. Acestea, la rndul lor, se obtin din interactiunea sursei de lumina cu materialul suprafetei si din pozitia suprafetei fata de sursa de lumina. Observati diferenta imaginii generate cu modelul de umbrire constanta si cu modelul de umbrire Gouraud. n proiectul Lab3d introduceti o comanda de meniu care sa modifice modelul de umbrire. 4.3. Studierea proprietatilor surselor de lumina si ale materialelor. Culoarea obiectului redat depinde de combinatia de culori, pe toate cele trei componente (ambientala, difuza si speculara) a sursei de lumina si ai materialului. Modificnd valorile parametrilor de culoare ai sursei de lumina si ai materialului veti observa combinatiile obtinute si influienta fiecareia dintre componente. Experimentati reflexia speculara prin modificarea culorii speculare a sursei de lumina si a materialului si prin modificarea stralucirii materialului (GL_SHININESS). n proiectul Lab3D introduceti comenzi de meniu pentru modificarea componentelor de culoare ale sursei de lumina si ai materialului. La comanda respectiva se va lansa un dialog de tipul CColorDialog, prin care se poate selecta culoarea dorita a fiecarei componente. Prin alegerea parametrilor de culoare si stralucire ai materialului se pot obtine efecte care imita materialele reale : metale, materiale plastice, cauciuc, pietre pretioase, etc. 4.4. Controlul pozitiei surselor de lumina. Sursa de lumina, asa cum a fost definita la punctul 4.1, este o sursa directionala n directia axei Oz (n sistemul de referinta universal). Pentru a schimba directia acestei surse se pot folosi doua metode: (a) Se modifica valorile coordonatelor din vectorul light_position transmis ca argument functiei glLightfv(); daca se pasteaza w = 0, atunci valorile x, y si z definesc directia sursei de lumina (n sistemul de referinta universal).

52

(b) Se pastreaza valorile implicite (0,0,1.0) din vectorul de pozitie light_position transmis ca argument functiei glLightfv() si se aplica transformarea dorita a directiei prin intermediul matricei MODELVIEW; binenteles, se salveaza stiva curenta si se reface dupa transformare. Ca exemplu, setati orientarea sursei de lumina ntr-o directie paralela cu planul xOz, care face un unghi de 45 grade cu axa Ox (si cu axa Oz) prin urmatoarele metode (si verificati echivalenta lor):
// Prima metoda: modificarea vectorului care da directia sursei de lumina light_position[0] = 1.41f; light_position[1] = 0.0f; light_position[2] = 1.41f; light_position[3] = 0.0f; glLightfv(GL_LIGHT0, GL_POSITION, light_position); // A doua metoda: introducerea transformarilor n matricea de transformare glPushMatrix(); light_position[0] = 0.0f; light_position[1] = 0.0f; light_position[2] = 1.0f; light_position[3] = 0.0f; glRotatef(45, 0.0, 1.0, 0.0); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glPopMatrix();

Cea de-a doua metoda de setare a orientarii surselor de lumina poate fi folosita pentru a obtine diferite comportari ale surselor de lumina. De exemplu, daca se seteaza pozitiei sursei (prin apelul functiei glLightfv()) nainte de transformarea de observare, atunci se obtine o sursa de lumina care se deplaseaza o data cu observatorul; daca se seteaza pozitia sursei dupa transformarea de modelare a obiectelor scenei, atunci sursa se deplaseza o data cu obiectele scenei. Se pot imagina diferite combinatii de transformari ale pozitiei surselor de lumina pentru a obtine anumite efecte de iluminare n scenele virtuale. Introduceti comenzi de meniu (sau n bara de dialog) care sa permita controlul pozitiei sursei de lumina: modificarea directiei sursei de lumina, deplasarea sursei o data cu observatorul, deplasarea sursei o data cu obiectele din scena, etc. 4.5. Normalele la suprafete si vrfuri. Pentru calculul reflexiei difuze si speculare este necesar sa fie definite normalele la suprafete sau n vrfuri. Se reaminteste formula de calcul a normalei la o suprafata data prin vrfurile v1(x1, y1, z1), v2, (x2, y2, z2), v3 (x3, y3, z3): N = ((y2 y1) (z3 z2) (y3 y2) (z2 z1)) i + ((x3 x2) (z2 z1) (x2 x1) (z3 z2)) j + ((x2 x1) (y3 y2) (x3 x2) (y2 y1)) k Normala ntr-un vrf este media (pe fiecare dintre cele 3 componente x, y, z) a normalelor suprafetelor incidente n vrful respectiv. n OpenGL normala care se foloseste pentru calculul reflexiei este normala curenta, care se seteaza prin apelul unei variante a functiei glNormal#() si se memoreaza ntr-o variabila de stare a bibliotecii. O parte din prototipurile functiilor glNormal#()sunt:
void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz); void glNormal3fv(const GLfloat *v);

Normala se poate specifica prin componentele nx, ny, nz, sau printr-un pointer la un vector care contine cele trei componente, de tipul cerut prin numele functiei glNormal#(). n exemplele precedente s-a putut observa iluminarea obiectului glutSolidTeapot() (sau alte obiecte GLUT) deoarece aceste functii calculeaza si seteaza corect normalele, dar, alte obiecte (cele ale caror modele au fost creat n lucrarile precedente: piramida, elipsoid, etc.) nu se redau corect cu iluminare. Deoarece nu se seteaza normalele la suprafete (sau la vrfuri), valoarea normalei curente

53

este nedeterminata si nu se pot calcula corect intensitatile componentelor de difuzie si speculara ale culorii. Componenta ambientala, care nu depinde de normala, se calculeaza corect. Pentru calculul iluminarii unui obiect definit printr-o multime de primitive date prin vrfurile lor, trebuie sa fie definite fie normalele la suprafete ( pentru umbrirea constanta) fie normalele n vrfuri (pentru umbrirea Gouraud). n mod obisnuit, fara precautii si testari ale starii OpenGL, nu se pot defini simultan ambele tipuri de normale pentru acelasi obiect. Normalele se specifica n acelasi sistem de referinta ca si vrfurile primitivelor geometrice, deci n sistemul de referinta de modelare. Acest mod de calcul permite ca normalele n vrfuri sa fie calculate o singura data, la modelare, si memorate ca parte a modelului obiectului n baza de date grafice. Asupra lor se aplica transformarea de modelare-vizualizare folosind valoarea matricei din vrful stivei de modelare-vizualizare, existenta n momentul apelului functiei glNormal#(). n felul acesta, normalele sunt transformate n sistemul de referinta de observare, unde se calculeaza intensitatile componentelor de reflexie n vrfuri. Pentru modelele simple, care contin numai fete paralele cu planele sistemului de referinta, normalele se pot deduce direct, fara calcule deosebite. De exemplu, pentru patratul desenat (RECTANGLE) n planul xOy, normala este (0,-1,0), dat fiind ca directia normalei este spre z negativ. Daca se schimba ordinea vrfurilor, normala va fi ndreptata spre z pozitiv, deci va fi (0,0,1).n mod asemanator se seteaza normalele pentru poligonul regulat modelat n lucrarile anterioare. Pentru cubul cu latura egala cu 2, se poate observa cu usurinta ca normala ntr-un vrf are componentele egale cu coordonatele vrfului. Deci, pentru setarea normalelor n vrfurile cubului, functia de redare se modifica astfel:
void DrawCube(){ // Modelul cu fete indexate for (int i=0;i<6;i++){ glBegin(GL_POLYGON); for (int j=0;j<4;j++){ int index = cubeIndex[i][j]; glNormal3f(cubeCoords[index][0],cubeCoords[index][1], cubeCoords[index][2]); glVertex3f(cubeCoords[index][0],cubeCoords[index][1], cubeCoords[index][2]); } glEnd(); } }

Calculul iluminarii necesita ca vectorul normalei (transmis prin argumentele functiei glNormal()) sa fie vectorul unitate, altfel rezultatele nu sunt corecte. Daca vectorul nu este unitate, se poate folosi validarea glEnable(GL_NORMALIZE), care impune normalizarea vectorului nainte de calculul iluminarii. Aceasta validare se poate introduce n functia de initializare. 4.6. Pentru celelalte modele create (piramida, elipsoid, etc.), adaugati structurile de date necesare memorarii materialului pentru fiecare suprafata si ai normalei n fiecare vrf, generati valorile normalelor n cursul creerii modelului si modificati functia de redare a obiectului astfel nct sa se transmita materialele (pentru fiecare suprafata) si normalele (pentru fiecare vrf) si sa se obtina imaginea cu ilumiare corecta a obiectelor. 4.7. Reprezentati pozitia sursei de lumina printr-un marcaj pe ecran. Introduceti functii de tratare a evenimentelor de mouse, astfel nct la apasarea si miscarea mouse-ului pe ecran sa se modifice corespunzator pozitia (directia) sursei de lumina. n proiectul Lab3d introduceti o comanda de meniu (sau n bara de dialog) care sa selecteze aplicarea miscarii mouse-ului obiectelor scenei sau sursei de lumina.

54

S-ar putea să vă placă și