This is an old revision of the document!
Spatiul obiect mai este denumit si SPATIUL COORDONATELOR LOCALE
Pentru a putea lucra mai eficient si a reutiliza obiectele 3D definite, in general fiecare obiect este definit intr-un sistem de coordonate propriu. Obiectele simple sau procedurale pot fi definite direct din cod insa majoritatea obiectelor utilizate in aplicatiile 3D sunt specificate in cadrul unui program de modelare gen 3D Studio Max, Maya, Blender, etc. Definind independent fiecare obiect 3D, putem sa ii aplicam o serie de transformari de rotatie, scalare si translatie pentru a reda obiectul in scena 3D. Un obiect incarcat poate fi afisat de mai multe ori prin utilizarea unor matrici de modelare, cate una pentru fiecare instanta a obiectului initial, ce mentin transformarile 3D aplicate acestor instante.
In general, fiecare obiect 3D este definit cu centrul (sau centrul bazei ca in poza de mai jos) in originea propriului sau sistem de coordonate, deoarece in acest fel pot fi aplicate mai usor transformarile de modelare. Astfel, rotatia si scalarea fata de centrul propriu sunt efectuate intotdeauna fata de origine.
Spatiul lume sau SPATIUL COORDONATELOR GLOBALE este reprezentat prin intermediul matricii de modelare, aceeasi despre care s-a vorbit sus. Matricea se obtine printr-o serie de rotatii, scalari si translatii. Prin multiplicarea fiecarui varf al unui obiect (mesh 3D) cu aceasta matrice, obiectul va fi mutat din spatiul local in spatiul lume, adica se face trecerea de la coordonate locale la coordonate globale.
Folosind matrici de modelare diferite putem amplasa un obiect in scena de mai multe ori, in locatii diferite, cu rotatie si scalare diferta daca este necesar. Un exemplu este prezentat in scena din dreapta.
Spatiul de vizualizare sau SPATIUL CAMEREI este reprezentat de matricea de vizualizare.
Matricea de modelare pozitioneaza obiectele in scena, in spatiul lume. Dar o scena poate fi vizualizata din mai multe puncte de vedere. Pentru aceasta exista transformarea de vizualizare. Daca intr-o scena avem mai multe obiecte, fiecare obiect are o matrice de modelare diferita (care l-a mutat din spatiul obiect in spatiul lume), insa toate obiectele au aceeasi matrice de vizualizare. Transformarea de vizualizare este definita pentru intreaga scena.
In spatiul lume camera poate sa fie considerata ca un obiect avand cele 3 axe locale OX, OY, OZ (vezi poza). Matricea de vizualizare se poate calcula folosind functia glm::lookAt
.
glm::mat4 View = glm::lookAt(glm::vec3 posCameraLume, glm::vec3 directieVizualizare, glm::vec3 cameraUP);
Ox,Oy,Oz sunt axele sistemului de coordonate al lumii (spatiul scenei 3D). Punctul O nu este marcat in imagine. O’x’,O’y’,O’z’ sunt axele sistemului de coord. al observatorului (spatiul de vizualizare). Punctul O’ nu este marcat in imagine (este inauntrul aparatului).
Vectorul forward este directia in care observatorul priveste, si este de asemenea normala la planul de vizualizare (planul fiind baza volumului de vizualizare, ce seamana cu o piramida si este marcat cu contur portocaliu). Vectorul right este directia dreapta din punctul de vedere al observatorului. Vectorul ¬up este directia sus din punctul de vedere al observatorului.
In imagine, observatorul este un pic inclinat, in mod intentionat, in jos, fata de propriul sistem de axe. Cand observatorul este perfect aliniat cu axele, right coincide cu +x’, up coincide cu +y’, iar forward coincide cu -z’. In imagine, se poate vedea ca up nu coincide cu +y’, iar forward nu coincide cu -z’.
Vectorul “up” se proiecteaza in planul de vizualizare, cu directia de proiectie paralela cu normala la planul de vizualizare. Proiectia acestuia da directia axei verticale a planului de vizualizare.
In spatiul lume camera poate fi considerata un simplu obiect 3D asupra caruia aplicam transformarile de rotatie si translatie. Daca in spatiul lume, camera poate fi pozitionata oriunde si poate avea orice orientare, in spatiul de vizualizare (spatiul observator) camera este intotdeauna pozitionata in (0,0,0), si priveste in directia OZ negativa.
Matricea de vizualizare contine transformari de rotatie si translatie, la fel ca si matricea de modelare. De aceea, daca tinem scena pe loc si mutam camera, sau daca tinem camera pe loc si rotim/translatam scena, obtinem acelasi efect:
Totusi, cele doua matrici au scopuri diferite. Una este folosita pentru pozitionarea obiectelor in scena, iar cealalta pentru vizualizarea intregii scene din punctul de vedere al camerei.
glm::lookAt(glm::vec3(3, 5, 7), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0));
Dupa aplicarea transformarii de vizualizare, in spatiul de vizualizare camera se afla in origine si priveste inspre –OZ. Pentru a putea vizualiza pe ecran aceasta informatie este necesar sa se faca proiectia spatiului vizualizat de camera intr-un spatiu 2D. Cum spatiul vizibil al camerei poate fi de diferite feluri, cel mai adesea trunchi de piramida (proiectie perspectiva) sau paralelipiped (proiectie ortografica) in OpenGL este necesara trecerea intr-un spatiu final numit spatiu de Proiectie ce reprezinta un cub centrat in origine cu dimensiunea 2, deci coordonatele X, Y, Z intre +1 si -1.
Din spatiul de proiectie este foarte usor matematic sa obtinem proiectia finala 2D pe viewport fiind nevoie doar sa mapam informatia din cubul [-1,1] scalata corespunzator pe viewport-ul definit de aplicatie.
Trecerea din spatiul de vizualizare in spatiul de proiectie se face tot utilizand o matrice, denumita matrice de proiectie, calculata in functie de tipul de proiectie definit. Biblioteca GLM ofera functii de calcul pentru cele mai utilizate 2 metode de proiecte in aplicatiile 3D, anume: proiectia perspectiva si ortografica
Datele (varfurile din spatiul de vizualizare) sunt inmultite cu matricea de proiectie pentru a se obtine pozitiile corespunzatoare din spatiul de proiectie.
In proiectia ortografica observatorul este plasat la infinit. Distanta pana la geometrie nu influenteaza proiectia si deci nu se poate determina vizibil din proiectie. Proiectia ortografica pastreaza paralelismul liniilor din scena.
Proiectia ortografica este definita de latimea si inaltimea ferestrei de vizualizare cat si a distantei de vizualizare dintre planul din apropiere si planul din departare. In afara acestui volum obiectele nu vor mai fi vazute pe ecran.
Matricea de proiectie poate fi calculata utilizand functia glm::ortho
unde punctele left, right, bottom, top sunt relative fata de centrul ferestrei (0, 0) si definesc inaltimea si latimea ferestrei de proiectie
glm::mat4 Projection = glm::ortho(float left, float right, float bottom, float top, float zNear, float zFar);
Proiectia perspectiva este reprezentata de un trunchi de piramida (frustum) definit prin cele 2 planuri, cel din apropiere si cel din departare, cat si de deschiderea unghiurilor de vizualizare pe cele 2 axe, OX si OY. In proiectia perspectiva distanta pana la un punct din volumul de vizualizare influenteaza proiectia.
Matricea de proiectie in acest caz poate fi calculata cu ajutorul funectiei glm::perspective
ce primeste ca si parametri deschiderea unghiului de vizualizare pe orizontala (Field of View - FoV), raportul dintre latimea ai inaltimea ferestrei de vizualizare (aspect ratio), cat si distanta pana la cele 2 planuri zFar si zNear.
In cazul proiectiei perspectiva, dupa inmutirea coordonatelor din spatiul view, componenta w a fiecarui vertex este diferita, ceea ce inseamna ca spatiul de proiecte nu e acelasi pentru fiecare varf. Pentru a aduce toti vectorii in acelasi spatiu se imparte fiecare componenta a vectorului rezultat cu componenta w. Aceasta operatie este realizata automat de placa video, in cadrul unei aplicatii fiind nevoie doar de inmultirea cu matricea de proiectie.
Volum de vizualizare perspectiva (stanga) si rezultatul obtinut (dreapta) in urma aplicarii transformarii de proiectie asupra geometriei din scena
Dupa aplicarea transformarilor de Modelare, Vizualizare si Proiectie iar apoi divizarea cu W a vectorilor, se obtine spatiul de coordonate normalizate (NDC) reprezentat de un CUB centrat in origine (0, 0, 0) cu latura 2. Informatia din acest cub se poate proiecta foarte usor pe orice suprafata 2D de desenare definita de utilizator.
Exemplu rezultat al proiectiei in coordonate dispozitiv normalizate (NDC). Proiectie ortografica (stanga), perspectiva (dreapta)
Exemplu vizualizare spatiu NDC din directia camerei (stanga) si proiectia corespunzatoare pentru un anumit viewport (dreapta)
Aplicarea trasformarilor de Modelare, Vizualizare si Proiectie se face prin inmultirea fiecarui varf al geometriei din scena cu cele 3 matrici calculate.
pos_vertex = Projection * View * Model * pos_vertex
RenderMesh
. Inmultirile respective sunt executate pe placa video in cadrul programului vertex shader ce va fi introdus incepand cu laboratorul urmator.
Implementarea unei camere in cadrul unei aplicatii 3D depinde de cerintele aplicatiei. In practica cele mai utilizate tipuri de implementari de camera sunt: First person si Third person.
Camera de tipul First-person presupune faptul ca scena 3D este vizualizata din perspectiva ochilor unui observator, adesea uman. Constrangerile de implementare sunt urmatoarele:
glm::vec3(0, 1, 0)
)posCamera = posCamera + glm::normalize(direction) * distance;
forward = RotateWorldOY(angle) * forward; right = RotateWorldOY(angle) * right; up = glm::cross(right, forward);
forward = RotateLocalOX(angle) * forward; up = glm::cross(right, forward);
glm::rotate
glm::mat4 = glm::rotate(glm::mat4 model, float angle, glm::vec3 rotationAxis);
glm::mat4(1.0f)
glm::vec3(0, 1, 0)
pentru rotatia fata de OY global glm::vec3
cand facem inmultirea va trebui sa construim un vector de 4 componente ca sa putem inmulti cu matricea de 4×4. Puteti construi vectorul astfel: glm::vec3 forward = ... glm::vec4 newVec = glm::vec4(forward, 1.0);
// get the rotate vec4 vector glm::vec4 newVector = glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0, 1, 0)) * glm::vec4(forward, 1); // extract the vec3 vector and then normalize it forward = glm::normalize(glm::vec3(newVector);
glm::vec3 vector = ... glm::vec3 rezultat = glm::normalize(vector);
In cazul camerei de tip Third-person observatorul se muta in jurul unui obiect de interes, ce reprezinta intotdeauna centrul atentiei. Deci rotatiile se fac intr-un mod diferit
Pozitia camerei depinde de pozitia punctului de interes. Astfel, miscarea punctului de interes va determina si translatia camerei in mod corespunzator.
Laborator5::OnInputUpdate()
Laborator5::OnMouseMove()
glm::translate()
, glm::rotate()
si glm::scale()
pentru a construi o matrice de modelare pentru fiecare obiect.OnInputUpdate()
OnInputUpdate()