Trojrozmerná projekcia

**Trojrozmerná projekcia** alebo **3D projekcia** je matematická transformácia požívaná na zobrazenie trojdimenzionálneho sveta na dvojdimenzionálnu plochu, napríklad obrazovku. Tento proces sa v počítačovej terminológií nazýva aj renderovanie. 

Nasledujúci algoritmus bol používaný už na skorších počítačoch na simulovanie alebo renderovanie videohier. Avšak tento algoritmus je používaný s malými zmenami dodnes.

## Dáta nevyhnutné pre projekciu
Dáta o objektoch na vyrenderovanie sú väčšinou uložené ako zoznam bodov, poprepájané do trojuholníkov, alebo polygónov. Každý bod je reprezentovaný troma súradnicami : X,Y,Z ktoré majú počiatok v základnom bode objektu ktorému patria. Každý objekt má viacero trojuholníkov. Objekt má tiež svoje súradnice X,Y,Z a slúžia na uľahčený pohyb všetkých trojuholníkov ktoré obsahuje. Okrem toho môže obsahovať aj rotáciu, napríklad alfa, beta a gama. Tieto údaje slúžia na určenie lokácie a rotácie vo svete.

Nakoniec je tu kamera (pozorovateľ), ktorá je niekde umiestnená vo svete a zobrazuje svet z tohto bodu. Jeden svet môže obsahovať aj viac kamier a prepínať medzi nimi.

Všetky tieto dáta sú uložené v desatinných číslach a potom prevádzané na celé, aby ich bolo možné vykresliť na obrazovku, Treba poznamenať, že programy, ktoré pracujú len s celými číslami sú rýchlejšie.

## Krok 1: Transformácia sveta
Prvým krokom je presúvanie (po anglicky: *Translation*) bodov vo svete. Všetky body sa uložia v tvare:

\begin{bmatrix}
X\\
Y\\
Z\\
1 
\end{bmatrix}
 — Bod 
Tá jednotka na konci je dôležitá. Potom sa na ňu aplikujú matice rotácií (po anglicky: *Rotation*) po všetkých osiach:

\begin{bmatrix}
1 & 0 & 0 & x \\
0 & 1 & 0 & y \\
0 & 0 & 1 & z \\
0 & 0 & 0 & 1 
\end{bmatrix}
  — Presúvanie bodu 

:
\begin{bmatrix}
1 & 0 & 0 & 0 \\
0 & \cos \alpha & -\sin \alpha & 0 \\
0 & \sin \alpha & \cos \alpha & 0 \\
0 & 0 & 0 & 1 
\end{bmatrix}
  — Rotácia po *x*-ovej osi

:
\begin{bmatrix}
\cos \beta & 0 & -\sin \beta & 0 \\
0 & 1 & 0 & 0 \\
\sin \beta & 0 & \cos \beta & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
  — Rotácia po *y*-ovej osi

:
\begin{bmatrix}
\cos \gamma & -\sin \gamma & 0 & 0 \\
\sin \gamma & \cos \gamma & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
  — Rotácia po *z*-ovej osi

Tieto štyri matice sú dokopy vynásobené a vzniká tak *matica transformácie sveta*. Touto maticou je potom vynásobený bod a vzniká jeho nová pozícia.

Násobenie matíc nepracuje na rovnakom princípe ako normálne násobenie, záleží tu na poradí a to zľava doprava. Takže si treba premyslieť toto poradie. Treba to najskôr zrotovať a až potom objekt presunúť. Keby sa to urobilo opačne, tak by sme objekt neotočili okolo svojho stredu, ale okolo bodu, ktorý bol stredom pred jeho posunutím. To spôsobí rotáciu podobnú obežnej dráhy a nie rotáciu okolo svojej osi.

Transformácia sveta = Presun × Rotácia

Aby bola transformácia kompletná, je potrebné mať možnosť zväčšovania a zmenšovania, po anglicky: *Scale*. Táto matica sa pridá k predošlým štyrom.

:
\begin{bmatrix}
s_x & 0 & 0 & 0 \\
0 & s_y & 0 & 0 \\
0 & 0 & s_z & 0 \\
0 & 0 & 0 & 1 
\end{bmatrix}
  — kde *s<sub>x</sub>*, *s<sub>y</sub>*, and *s<sub>z</sub>* sú činitele naťahovania. 

Keďže je väčšinou výhodnejšie najskôr objekt scalenúť (pretože pôvodné súradnice sú krajšie ako tie zrotované) Tak sa táto matica uprednostňuje.

Transfomácia sveta = Presun × Rotácia × Scaleovanie

:
\begin{bmatrix}
s_x\cos \gamma \cos \beta & -s_y\sin \gamma \cos \beta & s_z\sin \beta & x \\
s_x\cos \gamma \sin \beta \sin \alpha + s_x\sin \gamma \cos \alpha & s_y\cos \gamma \cos \alpha - s_y\sin \gamma \sin \beta \sin \alpha & -s_z\cos \beta \sin \alpha & y \\
s_x\sin \gamma \sin \alpha - s_x\cos \gamma \sin \beta \cos \alpha & s_y\sin \gamma \sin \beta \cos \alpha + s_y\sin \alpha \cos \gamma & s_z\cos \beta \cos \alpha & z \\
0 & 0 & 0 & 1
\end{bmatrix}
  — Konečný výsledok: × *x* × *y* × *z* × Scaleovanie.

## Krok 2: Transformácia kamery
Tento krok je podobný prvému, len na miesto sveta hýbeme kamerou a používame súradnice kamery. Keďže hýbeme kamerou a treba to aplikovať na svet, tak pohneme svetom v opačnom smere a v opačnom poradí. (Treba poznamenať : (A×B)-1=B-1×A-1.) Výsledná matica transformuje koordináty sveta tak, aby to vyzeralo, že sa kamera pohla.

Kamera sa zvyčajne na začiatku pozerá do *z*-ovej osi, *x*-ová os je do ľava a *y*-ová smerom hore.

:
\begin{bmatrix}
1 & 0 & 0 & -x \\
0 & 1 & 0 & -y \\
0 & 0 & 1 & -z \\
0 & 0 & 0 & 1 
\end{bmatrix}
 —  (inverzný presun je presun v opačnom smere).

:
\begin{bmatrix}
1 & 0 & 0 & 0 \\
0 & \cos \alpha & \sin \alpha & 0 \\
0 & -\sin \alpha & \cos \alpha & 0 \\
0 & 0 & 0 & 1 
\end{bmatrix}
  — inverzná rotácia po *x*-ovej osi (Inverzná rotácia je rovnako veľká rotácia do opačnej strany. Netreba zabudnúť že : sin(−x) = −sin(*x*), a cos(−*x*) = cos(*x*)).

:
\begin{bmatrix}
\cos \beta & 0 & -\sin \beta & 0 \\
0 & 1 & 0 & 0 \\
\sin \beta & 0 & \cos \beta & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
  — inverzná rotácia po *y*-ovej osi.

:
\begin{bmatrix}
\cos \gamma & \sin \gamma & 0 & 0 \\
-\sin \gamma & \cos \gamma & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
  —  inverzná rotácia po *z*-ovej osi.

Tieto matice môžu byť spolu vynásobené a vznikne tak transformácia kamery, tým že sme pohli svetom.

:Transformácia kamery = inverzná rotácia × inverzná tranformácia

:Tranformácia dokopy = tranformácia kamery × transformácia sveta.

## Krok 3: Transformácia perspektívy
Doteraz boli koordináty zobrazené izometrickou projekciou, alebo niečím podobným, ale na realistické renderovanie potrebuje ešte jeden krok, ktorý výsledok priblíži tomu, čo ľudské oko naozaj vidí. Volá sa to priestorové skreslenie (po anglicky: perspective distortion). Rozhodne len tento posledný krok je schopný ukázať pozovateľovi, že ako ďaleko ten objekt vlastne je.

Priestorové skreslenie môže byť generované použitím tejto 4×4 matice:

:
\begin{bmatrix}
\cot\mu & 0 & 0 & 0 \\
0 & \cot\nu & 0 & 0 \\
0 & 0 & \frac{B+F}{B-F} & \frac{-2BF}{B-F} \\
0 & 0 & 1 & 0
\end{bmatrix}


kde μ (čítaj *ní*) je uhol medzi základným bodom kamery a jej pravej strany (šírka perspektívy). Obdobne je ν (čítaj *mí*) uhol medzi základným bodom kamery a hornej časti, výška perspektívy. Projekcia by mala vyzerať realisticky, keď sa pozeráš jedným okom. Tvoje oko je umiestnené na normálovom vektore obrazovky (pozeráš sa na obrazovku kolmo) a pretína stred obrazovky. *μ* and *ν* sú fyzicky zmerané hodnoty podľa ľudského oka. Na typických obrazovkách je cot μ okolo 11/3 krát väčšie cot ν, a cot μ by malo byť od 1 do 5, v závislosti na tom, že ako ďaleko od obrazovky si.

*F* je kladné číslo reprezentujúce vzdialenosť od predku (z anglického *front*) zobrazovania (povrch oka) až k bodu kamery. *B* je naopak maximálna vzdialenosť, kde oko/kamera dovidí. Pri predstavovaní si tejto situácie, je dobré si zobrať jeden bod (počiatok vykreslovania) a vo vzdialenostiach *F* a *B* si nakresliť dve roviny. Priestor medzi týmito rovinami reprezentuje časť svetu, ktorý sa bude vykresľovať. 

Keď chceme vzkresliť objekty akokoľvek vzdialené (čo nie je odporúčané), je možné si za *B* zvoliť nekonečno a v tomto prípade to bude: 
(*B*&nbsp;+&nbsp;*F*)/(*B*&nbsp;−&nbsp;*F*) = 1 a −2*BF*/(*B*&nbsp;−&nbsp;*F*) = −2*F*.

Nakoniec nám vyjde:

:\begin{bmatrix}
x' \\
y' \\
z' \\
\omega' \\
\end{bmatrix}=\begin{bmatrix}{\rm Perspective\ transform}\end{bmatrix} \times \begin{bmatrix}{\rm Camera\ transform}\end{bmatrix} \times \begin{bmatrix}{\rm World\ transform}\end{bmatrix} \times \begin{bmatrix}
x \\
y \\
z \\
1 \\
\end{bmatrix}.


Keď chceme zobraziť výsledný bod na ploche, tak najskôr vynásobíme výsledný bod tak, aby na štvrtom mieste (tam kde je teraz \omega) bola jednotka. To ovplyvní všetky súradnice. *x* a *y* budú už súradnice bodíka. Pre *x* -1 je ľavý okraj obrazovky a 1 pravý okraj. Podobne pre *y* -1 je spodok obrazovky a 1 horná časť obrazovky. *z* reprezentuje vzdialenosť bodu od počiatku vykresľovania, pričom body *z* &lt; *F* a *z* &gt; *B* sú mimo vykresľovacieho priestoru a nebudú vykreslené, podobne ako *x* a *y* keď sú mimo interval &lt; -1 , 1 &gt; nebudú vykreslené. Z trojuholníkov, ktoré budú mať mimo len jeden bod sa spravia dva trojuholníky, ktoré budú reprezentovať časť trojuholníka, ktorý ešte bude vnútri. Obdobne sa to spraví pre dva body, keď sú mimo vykresľovacej časti, len vtedy stačí urobiť trojuholník.

Kategória:Lineárna algebra