This is an old revision of the document!


Laboratorul 05

Spatiul Obiect

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

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.

 World Space

Spatiul de Vizualizare

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.

 World Space and View Space

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);

 World Space and View Space

Vectorul cameraUP 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:

„The engines don’t move the ship at all. The ship stays where it is and the engines move the universe around it.”
- Futurama

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.

Exemplu: Daca vrem sa ne uitam pe axa OX(lume) din pozitia (3, 5, 7) codul corespunzator pentru functia glm::lookAt este:

glm::lookAt(glm::vec3(3, 5, 7), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0));

Spatiul de Proiectie

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 intru-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.

Matricea de Proiectie

Trecerea din spatiul de vizualizare in spatiul de proiectie se face tot utilizand o 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.

Proiectia Ortografica

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.

 Ortographic Projection

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.

 Ortographic Matrix

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

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.

 Perspective View

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.

 Perspective Matrix

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.

 Normalized Device Coordinate Space

Volum de vizualizare perspectiva (stanga) si rezultatul obtinut (dreapta) in urma aplicarii transformarii de proiectie asupra geometriei din scena

Spatiul Coordonatelor de Dispozitiv Normalizate (NDC)

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.

 Normalized Device Coordinate Space

Exemplu rezultat al proiectiei in coordonate dispozitiv normalizate (NDC). Proiectie ortografica (stanga), perspectiva (dreapta)

 Normalized Device Coordinate Space

Exemplu vizualizare spatiu NDC din directia camerei (stanga) si proiectia corespunzatoare pentru un anumit viewport (dreapta)

Aplicarea Transformarilor de Modelare, Vizualizare si Proiectie

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

In cadrul laboratorului trebuie doar sa calculam aceste matrici si sa le trimitem ca parametru functiei de randare RenderMesh. Inmultirile respective sunt executate pe placa video in cadrul programului vertex shader ce va fi introdus incepand cu laboratorul urmator.

Transformari de Camera

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.

First-person Camera

Camera de tipul First-person presupune faptul ca scena 3D este vizualizata din perspectiva ochilor unui observator, adesea uman. Constrangerile de implementare sunt urmatoarele:

Translatia camerei First-person

  • translatiile fata/spate se calculeaza utilizand vectorul forward (directia de vizualizare sau proiectia acestuia in planul orizontal XOZ)
  • translatiile sus/jos se calculeaza utilizand vectorul local Up sau cel mai adesea directia OY globala (glm::vec3(0, 1, 0))
  • translatiile dreapta/stanga se calculeaza folosind vectorul local right (ce se poate obtine si prin operatia de cross product intre vectorii forward si up), sau folosind proiectia acestuia pe planul orizontal XOZ
posCamera = posCamera + glm::normalize(direction) * distance;

Rotatia camerei First-person

  • rotatiile se fac pastrand observatorul pe loc si modificand directia in care priveste acesta
  • pentru rotatia stanga/dreapta, vectorii forward respectiv right se pot calcula prin aplicarea transformarii de rotatie in jului axei OY globale. Se poate roti si in jurul axei OY locale (vectorul up), insa in in general nu prea are aplicabilitate practica
  • vectorul up se poate recalcula folosind cross product intre right si forward
forward = RotateWorldOY(angle) * forward;
right = RotateWorldOY(angle) * right;
up = glm::cross(right, forward);
  • rotatia sus/jos se poate face rotind vectorii forward respectiv up in jurul vectorului axei OX adica vectorul right (right ramane constant)
forward = RotateLocalOX(angle) * forward;
up = glm::cross(right, forward);

Matricile de rotatie necesare se pot calcula folosind functia glm::rotate

glm::mat4 = glm::rotate(glm::mat4 model, float angle, glm::vec3 rotationAxis);
  • primul parametru reprezinta o matrice de modelare asupra careia aplicam transformarea specificata. Atunci cand nu avem o transformare precedenta se porneste de la matricea identitate glm::mat4(1.0f)
  • rotationAxis este axa fata de care rotim. In cazul nostru pentru rotatia fata de OX este vectorul right, pentru rotatia fata de OZ este vectorul forward, sau glm::vec3(0, 1, 0) pentru rotatia fata de OY global
  • intrucat vectorii utilizati sunt 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);
  • Daca vrem sa rotim vectorul “forward” in jurul axei OY globale atunci facem astfel:
// 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);

Dupa ce ati facut calculele de rotatie aveti grija sa pastrati vectorii normalizati

glm::vec3 vector = ...
glm::vec3 rezultat = glm::normalize(vector);

Third-person Camera

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

Rotatia Camerei Third-person

  • se translateaza observatorul pe directia de vizualizare in punctul de interes (target)
  • se aplica rotatia de tip First-person specifica
  • se traslateaza observatorul inapoi pe noua directie de vizualizare cu aceasi distanta

In laborator aveti variabila distanceToTarget care retine distanta pana la punctul fata de care rotim

Translatia Camerei Third-person

Pozitia camerei depinde de pozitia punctului de interes. Astfel, miscarea punctului de interes va determina si translatia camerei in mod corespunzator.

Cerinte laborator

  1. Sa se implementeze camera de tip First Person (fisierul LabCamera.h)
  2. Sa se implementeze camera de tip Third Person (fisierul LabCamera.h)
  3. Sa se completeze functiile de translatie a camerei din Laborator5::OnInputUpdate()
  4. Sa se completeze functiile de rotatie a camerei din Laborator5::OnMouseMove()
  5. Sa se deseneze inca 2 obiecte in scena 3D avand rotatia/scalarea/translatia diferite
    • Aveti grija sa setati matricea de modelare de fiecare data inainte de desenare
    • Utilizati glm::translate(), glm::rotate() si glm::scale() pentru a construi o matrice de modelare pentru fiecare obiect.
  6. Schimbare proiectie perspectiva/ortografica
    • tasta O face trecerea in proiectie ortografica
    • tasta P face trecerea in proiectie perspectiva
  7. Sa se modifice FoV-ul camerei in cazul proiectiei persepective
    • folositi 2 taste pentru a modifica pozitiv si negativ FoV-ul
    • se va folosi OnInputUpdate()
  8. Sa se modifice latimea si/sau inaltimea ferestrei de proiectie in cazul proiectiei ortografice
    • se va folosi OnInputUpdate()
egc/laboratoare/05.1508967230.txt.gz · Last modified: 2017/10/26 00:33 by florin_eugen.iancu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0