Camera virtuală DirectX în direct3d

Atenție vă rog! Acest site nu este actualizat. Noua versiune: shatalov.su

    Lecții preliminare:
  1. Coordonați spațiile. Du-te.
  2. Transformarea spațiilor de coordonate. Du-te.
    Lecții suplimentare
  1. Mișcarea în spațiu și rotația în jurul unei linii drepte arbitrare. Du-te.

Astăzi vom examina mai îndeaproape dispozitivul camerei virtuale. Să începem cu imaginea.







Camera virtuală DirectX în direct3d

În figură, vedem spațiul de coordonate al camerei. Direcția ("vizualizarea") a camerei coincide întotdeauna cu direcția pozitivă a axei z, iar camera foto este la origine.

Spațiul intern al piramidei descris în figură este acea parte a lumii virtuale pe care utilizatorul o va vedea.

Observați cele trei avioane. Primul este situat la o distanță de 1 de-a lungul axei z. Acesta este planul apropiat. Ce este jucătorul înainte de a nu vedea niciodată. În acest caz, valoarea z este egală cu una, dar, în general, poate fi orice. În planul apropiat, este asociat un defect în afișarea graficii. Acest defect se manifestă în primul rând prin împușcături (datorită marii libertăți a camerei). Când te apropii prea mult de obiect, poți fi "înăuntru". Dintre cele mai recente jocuri, acest defect este deosebit de evidentă în Left 4 Dead: atunci când jucătorul a purtat în jos zombie mulțimea, apoi de foarte multe ori vă puteți uita în interiorul altor personaje.

Un plan situat la o distanță de 100 de unități de-a lungul axei z este numit departe. Din nou, valoarea poate fi arbitrară. Utilizatorul nu va vedea niciodată obiecte aflate dincolo de acest plan.

Șase avioane care leagă spațiul pe care îl văd utilizatorul sunt numite avioane de tăiere: stânga sus dreapta jos și mai departe.

Planul situat între proiecția apropiată și proiecția. În viitor, acest avion va fi localizat în z = 1, adică aceasta va coincide cu cea apropiată. Aici am separat planul de apropiere și de proiecție pentru a arăta că nu este același lucru. Planul de proiecție este destinat ultimei transformări a coordonatelor: transformarea din spațiul tridimensional al camerei în spațiul bidimensional.

Datorită planului de proiecție, utilizatorul va vedea lumea virtuală. De fapt, acest avion este ceea ce vede utilizatorul. Planul de proiecție este direct legat de concepte precum tampoanele principale / de fundal, fereastra programului și ecranul utilizatorului. Toate aceste concepte pot fi considerate ca o imagine rectangulară, care în memoria calculatorului este reprezentată de o serie de numere.

Transformarea coordonatelor dintr-o lume tridimensională într-un plan de proiecție este cea mai complexă dintre cele pe care le-am studiat în prezent.

Câmp de vedere / câmp vizual

În figura de mai sus, lățimea planului de proiecție (și, prin urmare, imaginea pe care utilizatorul o vede) este mai mare decât înălțimea. Lățimea și înălțimea planului de proiecție sunt specificate folosind unghiuri. Există nume diferite pentru aceste unghiuri: câmpul vizual sau zona de vizualizare. În engleză - câmpuri de vedere.

Camera virtuală DirectX în direct3d

Zonele de vizionare sunt definite de două unghiuri. Să le numim: fovx - zona de vizualizare orizontală, fovy - zona de vizualizare verticală. Detalii privind zonele de vizionare: de mai jos.

Z-tampon / tampon tampon / adâncime (z-tampon / tampon / tampon de adâncime)

Să ne uităm la imaginea care arată două triunghiuri: 25 și 50 de camere. Figura (a) arată locația triunghiurilor în spațiu (vedere de sus), iar în figura (b) puteți vedea imaginea finală:

Camera virtuală DirectX în direct3d

După cum probabil credeți, imaginea trebuie să fie extrasă de la cele mai îndepărtate elemente la cele mai apropiate. Soluția evidentă: calculați distanța de la origine (de la cameră) la fiecare obiect, apoi comparați. În grafica pe calculator se folosește un mecanism puțin mai avansat. Acest mecanism are mai multe nume: z-buffer, w-buffer, tampon de adâncime. Dimensiunea z-tamponului cu numărul de elemente este aceeași cu dimensiunea fundalului și a tampoanelor principale. Componenta z a obiectului cel mai apropiat de cameră este stocată în z-buffer. În acest exemplu, în cazul în care triunghiul albastru se suprapune cu triunghiul verde, coordonatele z de albastru vor fi introduse în tamponul de adâncime. Vom vorbi mai multe despre z-tampoane în mai multe detalii într-o lecție separată.

Proiectare ortografică / paralelă

Operația la care dimensionarea spațiului este redusă (a existat un spațiu tridimensional, a devenit un spațiu bidimensional) se numește proiecție. În primul rând, ne interesează o proiecție în perspectivă, dar ne vom familiariza cu proiecția paralelă (paralelă sau ortografică).

Camera virtuală DirectX în direct3d

Pentru a calcula proiecția paralelă, este suficient să renunțați la coordonatele suplimentare. Dacă avem un punct în spațiu [3 3 3], atunci când proiecția este paralelă cu planul z = 1, se proiectează la punctul [3 3 1].







Proiecție perspectivă pe planul de proiecție

În acest tip de proiecție, toate liniile converg la un punct. Așa este aranjată viziunea noastră. Și este cu ajutorul proiecție perspectivă că "aspectul" în toate jocurile este modelat.

Camera virtuală DirectX în direct3d

Comparați această figură cu un desen care prezintă coordonatele omogene din lecția anterioară. Pentru a comuta la bidimensional, primele două componente trebuie să fie împărțită în vectorii al treilea spațiu tridimensional: [x / z y / z z / z] = [x / z y / z 1].

După cum am scris mai sus, planul de proiecție poate fi localizat oriunde între apropiat și îndepărtat. Vom plasa întotdeauna planul de proiecție la z = 1, dar în această lecție vom examina alte opțiuni. Să ne uităm la imagine:

Camera virtuală DirectX în direct3d

Distanța față de planul de proiecție de la origine este notată cu d. Considerăm două cazuri: d = 1 și d = 5. Punct important: a treia componentă a tuturor vectorilor după proiecție ar trebui să fie egală cu d - toate punctele sunt situate în același plan z = d. Acest lucru se poate obține prin înmulțirea tuturor componentelor vectorului cu d: [xd / z yd / z zd / z]. Pentru d = 1, obținem: [x / z y / z 1], această formulă a fost folosită pentru a transforma coordonatele omogene.

Acum, dacă ne otodvinem planul de proiecție la punctul z = 5 (sootvtestvenno d = 5), obținem: [xd / z km / z zd / z] = [5x / z 5y / z 5]. Ultima formulă proiectează toți vectorii spațiului într-un plan, unde d = 5.

Avem o mică problemă aici. Formula anterioară funcționează cu vectori tridimensionali. Dar am convenit să folosim vectori tridimensionali. A patra componentă în acest caz poate fi pur și simplu eliminată. Dar nu vom face acest lucru, deoarece utilizarea sa oferă anumite capacități specifice, pe care le vom discuta.

Este necesar să se găsească divizorul comun al celei de-a treia și al patrulea componente, atunci când este împărțit în cea de-a treia componentă, valoarea lui d rămâne, iar cea de-a patra. Acest divizor este d / z. Acum, din vectorul obișnuit [x y z 1] trebuie să obținem un vector gata pentru proiecție (diviziune) [x y z z / d]. Aceasta se face folosind matricea de transformare (verificați rezultatul prin înmulțirea oricărui vector cu matricea dată):

Camera virtuală DirectX în direct3d

Ultima transformare nu este o proiecție. Aici aducem toți vectorii la forma de care avem nevoie. Vă reamintesc că vom plasa planul de proiecție în d = 1, astfel încât vectorii vor arăta astfel: [x y z z].

Matricea transformării perspectivei

Vom analiza matricea de transformare de perspectivă utilizată în DirectX:

Camera virtuală DirectX în direct3d

Acum știm pentru ce este elementul _34. De asemenea, știm că elementele _11 și _22 scară imaginea orizontal și vertical. Să vedem ce este ascuns în spatele numelor xScale și yScale.

Aceste variabile depind de zonele de vizionare, dintre care am vorbit mai sus. Prin mărirea sau micșorarea acestor colțuri, puteți scala (scala sau mări) imaginea - modificați dimensiunea și raportul de aspect al planului de proiecție. Mecanismul de zoom depinde de la distanță de zoom-ul camerelor / camerelor - principiul este foarte asemănător. Luați în considerare imaginea:

Camera virtuală DirectX în direct3d

Împărțim unghiul fov în două părți și luăm în considerare doar o jumătate. Ceea ce vedem aici: crescând unghiul fov / 2 (și, respectiv, unghiul fov), mărim unghiul de păcălitură și diminuăm cos. Aceasta duce la o creștere a planului de proiecție și, în consecință, la o scădere a obiectelor proiectate. Unghiul ideal pentru noi este fov / 2 = P / 4. Îmi amintesc că unghiul din radianele P / 4 este de 45 de grade. În acest caz, fov va fi egal cu 90 de grade. Ce este bun pentru noi unghiul de 45 grade? În acest caz, nu există scalare și cos (P / 4) / sin (P / 4) = 1.

Acum putem scala cu ușurință imaginea în verticală (orizontală) folosind sinus și cosinus de jumătate din câmpul vizual (funcția cotangentă în C ++ numit pat de copii):

În DirectX, este utilizată numai zona de vizualizare verticală (fovY), iar scalarea orizontală depinde de zona verticală de vizionare și de raportul de aspect.

Vă reamintesc că fereastra din programele noastre este de 500x500. Raportul de aspect: 1 la 1. Prin urmare, variabilele vor fi egale: xScale = 1, yScale = 1.

Raportul de aspect al monitorului / televizorului standard: 4: 3. Acest raport corespunde rezoluției ecranului: 640x480, 800x600, 1600x1200. Încă nu vom atinge modul ecran complet, dar putem schimba dimensiunea ferestrei programului. Puteți schimba dimensiunea ferestrei (în parametrii actuali), de exemplu, la 640X480. Dar toate obiectele nu se întind (pătraturile vor arăta drept dreptunghiuri), nu uitați să schimbați variabilele corespunzătoare în matricea de proiecție.

Aproape am uitat, forum pentru xScale în DirectX:

Raportul de aspect este setat simplu: 1/1, 4/3, 16/9 - acesta este de la standard.

Rămâne să aflăm scopul elementelor _33, _34 ale matricei de transformare perspectivă. zf este coordonata z din planul îndepărtat (de la f ar este departe), iar zn este coordonatul z al apropiatului (de la n ureche - aproape). Rețineți că elementul _43 = _33 * -zn.

Cel mai simplu mod de a înțelege exact ce fac aceste formule este prin exemple. Înmulțim vectorul standard [x y z w] cu matricea prezentată mai sus. Vă recomandăm să faceți acest lucru luând o foaie de hârtie și un creion (sper că vă amintiți cum să înmulțiți cele două matrice). Componentele vectorului au următoarea formă.

Să transformăm proiecția (împărțim toate elementele în componenta a 4-a, în același timp presupunem că d = 1 și w = 1):

Ca rezultat, am obținut un vector al formularului:

Acum, dacă setați valorile ZF și Zn specifice, apoi găsiți următoarea (pentru valori pozitive): în cazul în care vectorul este în planul apropiat, z-componenta după conversie va fi mai mică decât zero, în cazul în care vectorul este situat pe planul de departe, z-componenta va fi mai mare unitate.

Nu există nicio diferență în cazul în care acesta este situat în apropiere și planul de departe: zn = 1, zf = zn = 10 sau 10, și zf = 100 (sau orice altă valoare) - după transformarea zonei vizibile vor fi situate în intervalul de la zero la unu, inclusiv.

În acest scop, elementele sunt proiectate în elementele _33, _34 ale matricei de proiecție - pentru a proiecta distanța de la planul apropiat de cel din față în intervalul [0, 1]. Verificați acest lucru prin calcularea valorilor mai multor vectori pentru valorile specifice ale zn, zf (da, pe o bucată de hârtie.).

Arkanoid

Camera virtuală DirectX în direct3d

aparat foto
Camera virtuală DirectX în direct3d

celulele
Camera virtuală DirectX în direct3d

sprite
Camera virtuală DirectX în direct3d







Trimiteți-le prietenilor: