Macierze w grafice 3D

Download Report

Transcript Macierze w grafice 3D

Jacek Matulewski
Instytut Fizyki, UMK
WWW: http://www.fizyka.umk.pl/~jacek
E-mail: [email protected]
Macierze w grafice 3D
Nowoczesny OpenGL
Toruńska Letnia Szkoła Matematyki i Informatyki
25-29 sierpnia 2014
Motywacja
•
•
•
•
nowoczesny OpenGL (3.*, 4.0)
WebGL (HTML 5)
OpenGL ES 2.0
analogicznie w DirectX 10, 11 (ale XNA Math)
Zmiany w nowoczesnym OpenGL (m.in.):
• obowiązkowanie buforowanie (werteksów)
• shadery, w tym nowe
• algebra macierzy (GLM)
• macierze w grafice 3D
• Profile, zamieszanie z tworzeniem kontekstu
Macierze OpenGL
• macierz model-widok
macierz świata (modelu)
glTranslate, glScale, glRotate
macierz widoku
gluLookAt
• macierz rzutowania
glFrustum, glOrtho, gluPerspective
Funkcje usunięte z profilu rdzennego
GLM, własna implementacja
Trivia
• Współrzędne jednorodne:
𝑜𝑥𝑥
𝑜𝑦𝑥
𝑜𝑧𝑥
0
𝑜𝑥𝑦
𝑜𝑦𝑦
𝑜𝑧𝑦
0
𝑜𝑥𝑧
𝑜𝑦𝑧
𝑜𝑧𝑧
0
𝑜𝑥𝑥𝑜𝑥𝑥𝑥
+0 𝑜+𝑥𝑦𝑜𝑦𝑥𝑦
+0 𝑜+𝑥𝑧𝑜𝑧𝑥𝑧
+0 𝑡+𝑥 𝑡𝑥
𝑡𝑥
𝑥0 𝑡𝑥
0𝑥
0𝑦
0𝑧
𝑥0
𝑡𝑦𝑦0 +𝑦0 𝑡𝑦 =𝑜𝑦𝑥𝑜𝑥𝑦𝑥
+0 𝑜+𝑦𝑦𝑜𝑦𝑦𝑦
+0 𝑜+𝑦𝑧𝑜𝑧𝑦𝑧
+0 𝑡+𝑦 𝑡𝑦
0𝑥
0𝑦
0𝑧
=
𝑡𝑧𝑧 0 𝑧0 𝑡𝑧
𝑜𝑧𝑥𝑜𝑥𝑧𝑥
+0 𝑜+𝑧𝑦𝑜𝑦𝑧𝑦
+0 𝑜+𝑧𝑧𝑜𝑧𝑧𝑧
+0 𝑡+𝑧 𝑡𝑧
0𝑥
0𝑦
0𝑧
1
1
1
• Dzielenie perspektywiczne:
𝑥
𝑦
𝑧
𝑤
𝑥/𝑤
𝑦/𝑤
𝑧/𝑤
Sami piszemy shadery,
które „konsumują” macierze!
• Macierze w grafice 3D:
𝑴=
𝑚𝑥𝑥
𝑚𝑦𝑥
𝑚𝑧𝑥
𝑚𝑤𝑥
𝑚𝑥𝑦
𝑚𝑦𝑦
𝑚𝑧𝑦
𝑚𝑤𝑦
𝑚𝑥𝑧
𝑚𝑦𝑧
𝑚𝑧𝑧
𝑚𝑤𝑧
𝑚𝑥𝑤
𝑚𝑦𝑤
𝑚𝑧𝑤
𝑚𝑤𝑤
=
𝑚[0]
𝑚[1]
𝑚[2]
𝑚[3]
𝑚[4] 𝑚[8] 𝑚[12]
𝑚[5] 𝑚[9] 𝑚[13]
𝑚[6] 𝑚[10] 𝑚[14]
𝑚[7] 𝑚[11] 𝑚[15]
Trivia
• Potok renderowania
• GLSL: mat3, mat4 + funkcje i operatory
(w pewnym stopniu można przenieść ciężar obliczeń na karty graficzne)
• CUDA i inne
Macierz rzutowania
Macierz rzutowania
• Macierz rzutowania OpenGL nie jest
macierzą rzutowania na płaszczyznę!
• Macierz rzutowania OpenGL nie zmniejsza
wymiaru zrzutowanego wektora
• Perspektywa w grafice 3D: x, y ~ 1/z (nie 1/r)
(dzięki temu proste przechodzą w proste)
• Macierz rzutowania perspektywicznego
OpenGL nie wprowadza perspektywy!
• Dzielenie perspektywiczne (transf. nieliniowa)
Macierz rzutowania równoległego
• Rzutowanie izometryczne (równoległe):
bez perspektywy tzn. dalsze obiekty po
zrzutowaniu nie są mniejsze
• Zmiana we wszystkich współrzędnych (x, y, z)
jest liniowa (LERP): prostokątny obszar
widzenia przechodzi w sześcian (NDC)
• Podział perspektywiczny
nic device
nie wnosi
NDC (ang. normalized
coordinates)
(ukł. wsp.
przycinania
= NDC)
normalizacja
= zakres
współrzędnych to [-1,1]
• Zmiana kierunku osi OZ
(w OpenGL i XNA/MG, ale nie w Direct3D)
Macierz rzutowania równoległego
LERP:
𝑙, 𝑟 →
−1,1
położenie𝑥: na
ekranie
𝑥𝑐 =
2
𝑟+𝑙
𝑥𝑒 −
𝑟−𝑙
𝑟−𝑙
𝑦𝑐 =
2
𝑡+𝑏
𝑦𝑒 −
𝑡−𝑏
𝑡−𝑏
𝑥𝑐 = 𝑎𝑥 𝑥𝑒 + 𝑏𝑥
𝑦𝑐 = 𝑎𝑦 𝑦𝑒 + 𝑏𝑦
𝑦: 𝑏, 𝑡 → −1,1
𝑧𝑐 = 𝑎𝑧 𝑧𝑒 + 𝑏𝑧
𝑧: −𝑛, −𝑓 → −1,1
głębia
𝑧𝑐 = −
2
𝑓+𝑛
𝑧𝑒 −
𝑓−𝑛
𝑓−𝑛
Macierz rzutowania równoległego
We współrzędnych jednorodnych:
2
𝑟+𝑙
𝑥𝑁𝐷𝐶 = 𝑥𝑐 =
𝑥 −
𝑤
𝑟−𝑙 𝑒 𝑟−𝑙 𝑒
2
𝑡+𝑏
𝑦𝑁𝐷𝐶 = 𝑦𝑐 =
𝑦 −
𝑤
𝑡−𝑏 𝑒 𝑡−𝑏 𝑒
𝑦𝑁𝐷𝐶
2
𝑡+𝑏
= 𝑦𝑐 =
𝑦 −
𝑤
𝑡−𝑏 𝑒 𝑡−𝑏 𝑒
𝑤𝑐 = 𝑤𝑒 = 1
2
𝑟−𝑙
𝑶=
0
0
0
2
𝑡−𝑏
0
0
0
0
0
−
2
𝑓−𝑛
0
𝑟+𝑙
−
𝑟−𝑙
𝑡+𝑏
−
𝑡−𝑏
𝑓+𝑛
−
𝑓−𝑛
1
Wolny wyraz „załatwia” współrzędna skalowania
Macierz rzutowania równoległego
Przypadek symetryczny:
r = –l = w/2
2
𝑤
𝑶=
t = –b = h/2
0
0
0
0
2
ℎ
0
0
2
−
𝑓−𝑛
0
𝑓+𝑛
−
𝑓−𝑛
1
0
0
0
0
Typowe wartości w i h:
w = 2 (l = –1, r = 1)
h = 2 (t = 1, b = –1)
n = 0, f = 1
𝑶=
1
0
0
0
0 0
1 0
0 −2
0 0
0
0
−1
1
Macierz rzutowania perspektyw.
• Rzutowanie perspektywiczne: rozmiar
obiektów zależy od głębi, a nie od odległości
• Transformacja perspektywiczna
nie jest liniowa (głębokość z w mianowniku)
• Kluczowa rola podziału perspektywicznego
Macierz rzutowania perspektyw.
Z podobieństwa trójkątów OPeRe i OPpRp:
𝑥𝑝
𝑥𝑒
=
𝑧𝑒 −𝑛
𝑦𝑝
𝑦𝑒
=
𝑧𝑒 −𝑛
𝑥𝑒
𝑥𝑝 = −𝑛
𝑧𝑒
𝑦𝑒
𝑦𝑝 = −𝑛
𝑧𝑒
istota perspektywy
Macierz rzutowania perspektyw.
• Perspektywa + przeskalowanie
(we wsp. x i y, jak w rzutowaniu równoległym)
𝑥𝑁𝐷𝐶 =
2
𝑥𝑒
𝑟+𝑙
1 2𝑛
𝑟+𝑙
−𝑛
−
=−
𝑥𝑒 +
𝑧
𝑟−𝑙
𝑧𝑒
𝑟−𝑙
𝑧𝑒 𝑟 − 𝑙
𝑟−𝑙 𝑒
𝑦𝑁𝐷𝐶 =
2
𝑦𝑒
𝑡+𝑏
1 2𝑛
𝑡+𝑏
−𝑛
−
=−
𝑥𝑒 +
𝑧
𝑡−𝑏
𝑧𝑒
𝑡−𝑏
𝑧𝑒 𝑡 − 𝑏
𝑡−𝑏 𝑒
Przekształcenie nieliniowe!
część liniowa (macierz)
tu użyjemy podziału perspektywicznego
Macierz rzutowania perspektyw.
• Transformacja do wsp. przycinania i NDC
2𝑛
𝑟+𝑙
𝑥𝑐 =
𝑥𝑒 +
𝑧
𝑟−𝑙
𝑟−𝑙 𝑒
𝑥𝑁𝐷𝐶 =
𝑥𝑐
𝑥𝑐
=
𝑤𝑐 −𝑧𝑒
2𝑛
𝑡+𝑏
𝑦𝑐 =
𝑥𝑒 +
𝑧
𝑡−𝑏
𝑡−𝑏 𝑒
𝑦𝑁𝐷𝐶 =
𝑦𝑐
𝑦𝑐
=
𝑤𝑐 −𝑧𝑒
𝑧𝑐 = 𝑎𝑧 𝑧𝑒 + 𝑏𝑧
nie może zależeć od x i y
𝑧𝑁𝐷𝐶
𝑧𝑐
𝑧𝑐
=
=
𝑤𝑐 −𝑧𝑒
𝑤𝑐 = −𝑧𝑒
• Transformacja głębi
𝑧𝑁𝐷𝐶 = −
1
𝑎 𝑧 + 𝑏𝑧
𝑧𝑒 𝑧 𝑒
𝑧: −𝑛, −𝑓 → −1,1
𝑧𝑁𝐷𝐶
1
𝑓+𝑛
2𝑛𝑓
=−
−
𝑧 −
𝑧𝑒
𝑓−𝑛 𝑒 𝑓−𝑛
Macierz rzutowania perspektyw.
1
zNDC
0.5
0
-0.5
-1
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
ze
• Transformacja głębi
𝑧𝑁𝐷𝐶 = −
1
𝑎 𝑧 + 𝑏𝑧
𝑧𝑒 𝑧 𝑒
𝑧: −𝑛, −𝑓 → −1,1
𝑧𝑁𝐷𝐶
1
𝑓+𝑛
2𝑛𝑓
=−
−
𝑧 −
𝑧𝑒
𝑓−𝑛 𝑒 𝑓−𝑛
Macierz rzutowania perspektyw.
• Macierz „rzutowania” perspektywicznego
(bez podziału nie daje perspektywy!)
2𝑛
𝑟−𝑙
𝑷=
0
0
2𝑛
𝑡−𝑏
0
0
0
0
𝑟+𝑙
𝑟−𝑙
𝑡+𝑏
𝑡−𝑏
𝑓+𝑛
−
𝑓−𝑛
−1
0
0
2𝑛𝑓
−
𝑓−𝑛
0
Macierz rzutowania perspektyw.
• Wersja symetryczna:
2𝑛
𝑤
𝑷=
0
0
0
0
2𝑛
ℎ
0
0
𝑓+𝑛
−
𝑓−𝑛
−1
2𝑛𝑓
−
𝑓−𝑛
0
0
0
0
0
Pole widzenia w pionie (FOVY):
𝜑
ℎ = 2𝑛 tg
2
Proporcja ekranu (aspect ratio):
𝑎 = 𝑤/ℎ
• Dla w = 2, h = 2, n = 1:
1 0
0 1
𝑷=
0 0
0 0
0
0
0
0
𝑓+1
2𝑓
−
−
𝑓−1
𝑓−1
−1
0
Pomijam problem transformacji
do układu współrzędnych viewportu
Macierz świata
Macierz świata
Translacje (!)
𝑥
𝑦
𝑻
=
𝑧
𝑤
1
0
0
0
0
1
0
0
0
0
1
0
∆𝑥
∆𝑦
∆𝑧
1
𝑥
𝑦
=
𝑧
𝑤
𝑥 + ∆𝑥 · 𝑤
𝑦 + ∆𝑦 · 𝑤
𝑧 + ∆𝑧 · 𝑤
𝑤
Skalowania i obroty
𝑥
𝑦
𝑺
=
𝑧
𝑤
𝑠𝑥
0
0
0
Pochylenia
0
𝑠𝑦
0
0
0
0
𝑠𝑧
0
0
0
0
1
𝑥
𝑠𝑥 𝑥
𝑦
𝑠 𝑦
= 𝑦
𝑧
𝑠𝑧 𝑧
𝑤
𝑤
Macierz świata – macierze obrotu
Obroty 2D (wokół osi OZ, OX i OY):
𝑹𝑧 =
cos(𝛾)
sin(𝛾)
0
0
−sin(𝛾)
cos(𝛾)
0
0
0
0
1
0
0
0
0
1
𝑹𝑥 =
1
0
0
0
0
cos(𝛼)
sin(𝛼)
0
𝑹𝑦 =
cos(𝛽)
0
−sin(𝛽)
0
0
−sin(𝛼)
cos(𝛼)
0
0
0
0
1
0 sin(𝛽)
1
0
0 cos(𝛽)
0
0
0
0
0
1
Kąty Cardana (yaw, pitch, roll):
𝑹𝑥 𝑹𝑦 𝑹𝑧
Kąty Eulera (fizyka, powt. oś OZ):
𝑹𝑧 𝑹𝑥 𝑹𝑧
Macierz świata – macierze obrotu
Obrót wokół dowolnej osi:
𝑹𝑢 =
cos 𝜃 + (1 − cos 𝜃 ) 𝑢𝑥2
(1 − cos 𝜃 ) 𝑢𝑥 𝑢𝑦 + sin 𝜃 𝑢𝑧
(1 − cos 𝜃 ) 𝑢𝑧 𝑢𝑥 − sin 𝜃 𝑢𝑦
(1 − cos 𝜃 ) 𝑢𝑥 𝑢𝑦 − sin 𝜃 𝑢𝑧
cos 𝜃 + (1 − cos 𝜃 ) 𝑢𝑦2
(1 − cos 𝜃 ) 𝑢𝑦 𝑢𝑧 + sin 𝜃 𝑢𝑥
(1 − cos 𝜃 ) 𝑢𝑧 𝑢𝑥 + sin 𝜃 𝑢𝑦
(1 − cos 𝜃 ) 𝑢𝑦 𝑢𝑧 − sin 𝜃 𝑢𝑥
cos 𝜃 + (1 − cos 𝜃 ) 𝑢𝑧2
Macierze obrotu
to macierze ortonormalne
• wiersze i kolumny to wersory
(układów współrzędnych)
• wiersze są ortogonalne
• kolumny są ortogonalne
Macierz świata – macierze obrotu
Własności macierzy ortonormalnych:
• odwrotność = transpozycja 𝑹−1 = 𝑹𝑇
• zachowują rozmiary obiektów
• równoważne z kwaternionami jednostkowymi
• za pomocą macierzy obrotu można zapisać
równania ruchu brył sztywnych
(obrotów brył w ich układzie własnym)
Macierz widoku
Macierz widoku
Macierz odpowiadająca funkcji gluLookAt
Złożenie przekształceń
• przesunięcia (pierwsze)
• obrotu
𝑽=𝑹𝑻
Macierz obrotu wyznaczają
wersory układu wsp. kamery
Macierz widoku
Macierz odpowiadająca funkcji gluLookAt
Dane wejściowe (arg. funkcji):
• położenie kamery E
• położenie centrum C
• Wektor polaryzacji 𝑈
Należy obliczyć wersory
układu współrzędnych kamery
Macierz widoku
Macierz odpowiadająca funkcji gluLookAt
Konstrukcja:
1.
2.
3.
4.
5.
Oblicz wektor 𝐹 = 𝐶 − 𝐸.
Zapisz znormalizowaną wartość tego
wektora 𝐹′ = 𝐹 𝐹 .
Oblicz wektor 𝑅 prostopadły do wektorów
𝐹′ i 𝑈 korzystając z iloczynu wektorowego
𝑅 = 𝐹′ × 𝑈 (zwrot wyniku wyznacza
reguła śruby prawoskrętnej).
Znormalizuj wektor 𝑅.
Oblicz wektor 𝑈′ = 𝑅 × 𝐹′ prostopadły
do wektorów 𝑅 i 𝐹′ (wektor 𝑈′ będzie
jednostkowy, bo oba czynniki są jednostkowe,
a jednocześnie prostopadłe do siebie).
Macierz widoku
Macierz odpowiadająca funkcji gluLookAt
macierz obrotu
𝑹=
𝑅𝑥
𝑈𝑥′
−𝐹𝑥′
0
𝑅𝑦
𝑈𝑦′
−𝐹𝑦′
0
𝑅𝑧
𝑈𝑧′
−𝐹𝑧′
0
0
0
0
1
macierz translacji
𝑻=
1
0
0
0
0
1
0
0
0 −𝐸𝑥
0 −𝐸𝑦
1 −𝐸𝑧
0
1
ostateczna macierz widoku
𝑅𝑥𝑥
𝑅𝑦𝑦
𝑅𝑧𝑧 0
𝑅
𝑅
𝑅
−𝑅 ∘ 1𝐸 0
′
′
′
𝑈
𝑈
𝑈
0 ∘0𝐸 1
′
′
′
𝑥
𝑦
𝑧
𝑈
𝑈
𝑈
−𝑈′
𝑽
=
𝑹𝑻
=
𝑥
𝑦
𝑧
𝑽 = 𝑹𝑻 = −𝐹 ′ −𝐹 ′ −𝐹 ′ 0
0 0
𝑥′
𝑦′
𝑧′
−𝐹𝑥 −𝐹𝑦 −𝐹𝑧
𝐹′ ∘ 𝐸0 0
0
0
0
1
0
0
0
1
0
0
1
0
−𝐸𝑥
−𝐸𝑦
−𝐸𝑧
1
Macierze OpenGL
Podsumowanie
• wzory używane w tradycyjnym OpenGL
oraz XNA Math, GLM i innych
• macierz rzutowania izometrycznego
(równoległego) i perspektywicznego
• macierze przekształceń
• konstrukcja macierzy widoku
Książka
Wykład zawiera lokowanie produktu
Artykuł w „Programiście” 5/2014
Wykład zawiera lokowanie produktu
Kontakt
E-mail: [email protected]
WWW: http://www.fizyka.umk.pl/~jacek