ゲームグラフィックス特論
第3回 変換 (1)
変換行列
同次座標による座標変換
2
内積
3
v1 =
0
B
B
@
x1
y1
z1
w1
1
C
C
A , v2 =
0
B
B
@
x2
y2
z2
w2
1
C
C
A
v1 · v2 = x1 y1 z1 w1
0
B
B
@
x2
y2
z2
w2
1
C
C
A...
アフィン変換
• 線形変換と平行移動の組み合わせ
x0
= ax + b
x0
= axxx + ayxy + bx
y0
= axyx + ayyy + by
x0
= axxx + ayxy + azxz + bx
y0
= axyx + ...
x0
= axxx + ayxy + azxz + bx
y0
= axyx + ayyy + azyz + by
z0
= axzx + ayzy + azzz + bz
0
@
x0
y0
z0
1
A =
0
@
axx ayx azx
...
アフィン変換の同次座標による表現
6
0
B
B
@
x0
y0
z0
1
1
C
C
A =
0
B
B
@
axx ayx azx bx
axy ayy azy by
axz ayz azz bz
0 0 0 1
1
C
C
A
0
B
B...
v =
0
B
B
@
x
y
z
w
1
C
C
A
= x y z w
T
同次座標
7
0
B
B
@
x
y
z
w
1
C
C
A
⇣ x
w
,
y
w
,
z
w
⌘
(x, y, z)
(x, y, z)
0
B
B
@
x
y...
同次座標の性質
• 同次座標にスカラーをかけても実座標は変わらない
8
a
0
B
B
@
x
y
z
w
1
C
C
A =
0
B
B
@
ax
ay
az
aw
1
C
C
A
⇣ ax
aw
,
ay
aw
,
az
aw
⌘
=
⇣ ...
同次座標の性質
• 同次座標の差は「通分」してから求める
9
P1
w1
P0
w0
=
0
B
B
@
x1/w1
y1/w1
z1/w1
1
1
C
C
A
0
B
B
@
x0/w0
y0/w0
z0/w0
1
1
C
C
A =
0
B...
変換
10
v0
=
0
B
B
@
x0
y0
z0
w0
1
C
C
A v =
0
B
B
@
x
y
z
w
1
C
C
A
M =
0
B
B
@
m0 m4 m8 m12
m1 m5 m9 m13
m2 m6 m10 m14
m3 ...
平行移動
T 7,8,0( )
x
y
7
8
x
y
11
T(t) = T(tx, ty, tz) =
0
B
B
@
1 0 0 tx
0 1 0 ty
0 0 1 tz
0 0 0 1
1
C
C
A
O O
位置と方向の平行移動
位置 方向
移動する 変化なし
12
0
B
B
@
1 0 0 tx
0 1 0 ty
0 0 1 tz
0 0 0 1
1
C
C
A
0
B
B
@
x
y
z
1
1
C
C
A =
0
B
B
@
x + tx
...
0
B
B
@
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1/a
1
C
C
A
0
B
B
@
x
y
z
1
1
C
C
A =
0
B
B
@
x
y
z
1/a
1
C
C
A
0
B
B
@
a 0 0 0
0 a ...
せん断
( )
⎟
⎟
⎟
⎟
⎟
⎠
⎞
⎜
⎜
⎜
⎜
⎜
⎝
⎛
=
1000
0100
0010
001 s
sxzH ( )
⎟
⎟
⎟
⎟
⎟
⎠
⎞
⎜
⎜
⎜
⎜
⎜
⎝
⎛
=
1000
0100
010
0001
s
syz...
座標軸中心の回転
15
Rx(✓) =
0
B
B
@
1 0 0 0
0 cos ✓ sin ✓ 0
0 sin ✓ cos ✓ 0
0 0 0 1
1
C
C
A
Ry(✓) =
0
B
B
@
cos ✓ 0 sin ✓ 0
0 1 0 ...
任意軸周りの回転
(l,m,n)
θ
16
R(l, m, n, ✓)
=
0
B
B
@
l2
+ (1 l2
) cos ✓ lm(1 cos ✓) n sin ✓ ln(1 cos ✓) + m sin ✓ 0
lm(1 cos ✓) +...
直交座標系の変換
• (i, j, k), (i’, j’, k’): 直交座標系
• p: 点の位置
17
k
´
i
´
j´
i
j
k
p
p = xi + yj + zk = x0
i0
+ y0
j0
+ z0
k0
0
@
x0
...
直交座標系の変換
x
z
y
r
s
t
M
M
M
M =
0
@
rx sx tx
ry sy ty
rz sz tz
1
A
1
=
0
@
rx sx tx
ry sy ty
rz sz tz
1
A
T
=
0
@
rx ry rz
...
あるベクトルを別のベクトルに一致させる回
転 (1)
v
u
n
n =
u× v
u× v
( )
( )
( ) ⎟
⎟
⎠
⎞
⎜
⎜
⎝
⎛
××
××
×
×
=
=
vuu
vuu
vu
vu
u
lnuMu
p n
n
p
p
l...
変換の合成
変換行列の積
20
変換の合成
21
• 変換の合成は行列の積で表す
T(4, 3, 0)
T(4, 0, 0)
T(0, 3, 0)
T(0, 3, 0)T(4, 0, 0) =
0
B
B
@
1 0 0 0
0 1 0 3
0 0 1 0
0 0 0 1
1...
M = T t( )R θ( ) =
r00 r10 r20 tx
r01 r11 r21 ty
r02 r12 r22 tz
0 0 0 1
!
"
#
#
##
$
%
&
&
&&
剛体変換
• 立体の移動と回転
• 一般的に立体の形状に...
任意の点を中心にした回転
p
x
y
x
y
x
y
p
T(−p)
θ
Rz(θ) T(p)
M = T(−p)Rz(θ)T(p)
23
O O O
任意の点を基準にした拡大縮小
x
y
x
y
p
T(-p) T(p)
M = T(−p)S (s)T(p)
S(s)
p
x
y
24
O O O
特定方向への拡大縮小
拡大縮小する軸の方向
(x y z) 軸方向の拡大縮小
(x y z) 軸の空間から (r s t) 軸の空間への回転
(r s t) 軸の空間 → (x y z) 軸の空間への回転
(x y z) 軸方向の拡大縮小
(x...
変換の連結
• 行列の演算は非可換
• 連結した変換の結果は行列の順序に依存する
R(θ)
R(θ)
S(s)
S(s)
26
オイラー変換
27
heading
pitchroll
z x
y
h: heading (yaw)
p: pitch
r: roll (bank)
E(h, p, r) = Ry(h)Rx(p)Rz(r)
オイラー変換
28
E(h, p, r)
=
0
B
B
@
cos h 0 sin h 0
0 1 0 0
sin h 0 cos h 0
0 0 0 1
1
C
C
A
0
B
B
@
1 0 0 0
0 cos p sin p 0
0 s...
ジンバルロック
• これは (r − h) の単一の角度に依存する1軸中心の回転
• したがって自由度が一つ減る
29
=
0
B
B
@
cos(h r) sin(h r) 0 0
0 0 1 0
sin(h r) cos(h r) 0 0
...
回転変換行列からオイラー角を算出
30
M =
0
B
B
@
m0 m4 m8 m12
m1 m5 m9 m13
m2 m6 m10 m14
m3 m7 m11 m15
1
C
C
A = E(h, p, r)
m1 = cos p sin ...
法線ベクトルの変換
面との直交性の維持
31
変換と法線ベクトル
• ベクトルも変換行列によって変換できる
• 面の頂点に適用した座標変換の行列をそのままその面の法
線ベクトルに適用しても正しく変換できない場合がある
M: x 軸方向に
0.5 倍スケーリ
ングする行列
間違い 正解
x
...
法線ベクトルの正しい変換
• M: 形状の変換に用いる行列
• G: この形状の法線ベクトルの変換に用いる行列
MG =
( )Madj :Mの随伴行列
( )( )T
MG adj=
33
随伴行列 (adjoint)
M =
m00 m10 m20
m01 m11 m21
m02 m12 m22
!
"
#
#
##
$
%
&
&
&&
d00
M
=
m11 m21
m12 m22
d10
M
=
m01 m21
m02 m...
逆行列
逆変換を行う
35
逆行列の計算
• クラメールの公式
• 3×3までの行列なら簡単
• ガウスの消去法など
• 数値計算的手法
• 一般に計算コストが高い
• できるだけ「楽に」逆行列を求めたい
( )M
M
M adj
11
=−
36
逆行列の求め方
• 平行移動
• 拡大縮小
• 回転
• せん断
37
T 1
(t) = T( t) =
0
B
B
@
1 0 0 tx
0 1 0 ty
0 0 1 tz
0 0 0 1
1
C
C
A
S 1
(s) = S
✓
1
s...
逆行列の求め方
• 剛体変換
38
M = T t( )R θ( )⇒ M−1
= R−1
θ( )T−1
t( )= R −θ( )T −t( )= RT
θ( )T −t( )
R =
r00 r10 r20
r01 r11 r21
r02...
逆行列の求め方
• オイラー変換
39
E−1
h, p,r( )= ET
h, p,r( )
= Ry h( )Rx p( )Rz r( )( )
T
= Rz
T
r( )Rx
T
p( )Ry
T
h( )
E h, p,r( )= Ry...
OpenGL の変換行列
GLSL における座標変換
40
OpenGL の変換行列の要素の順序
この講義での行列表記
M =
m0 m4 m8 m12
m1 m5 m9 m13
m2 m6 m10 m14
m3 m7 m11 m15
!
"
#
#
#
#
#
$
%
&
&
&
&
&
C/C++ ...
課題
• y 軸中心に r ラジアン回
転したあと,y 方向に d
平行移動する変換行列
を右の配列変数 m に設
定しなさい.関数 sin() /
cos() は使って構わない.
• この配列変数は
OpenGL で使用するも
のとする.
G...
行列をシェーダプログラムで使う
• uniform 変数
• 描画単位 (glDrawArrays(), glDrawElements() 等) で不変な値をもつ
• 変換行列,光源位置,視点位置,材質情報等
• 各シェーダステージから共通して...
uniform 変数に行列を設定する
• シェーダプログラムの作成(loadShader() を使う場合)
• GLuint program = createProgram( … );
• この後に uniform 変数 mc のインデックスを...
ビュー変換
視点の位置や視線の方向を変更する
45
ビュー変換 (視野変換)
ビュー変換前
O x
y
z
ビュー変換後
O x
y
z
−z
46
視点の移動
O x
y
z
u = (ux, uy, uz)
t = (tx, ty, tz)
e = (ex, ey, ez)
O x
y
z
u
t − e
Tv =
1 0 0 −ex
0 1 0 −ey
0 0 1 −ez
0 0 0 ...
視線の回転
O x
y
z
u
t − e
O x
y
z
(0, 0, 1)
(1, 0, 0)
(0, 1, 0)
Rv =
!x T
0
!y T
0
!z T
0
0 0 0 1
"
#
$
$
$
$
$
%
&
'
'
'
'
'
...
回転の変換行列
Rv =
!x T
0
!y T
0
!z T
0
0 0 0 1
"
#
$
$
$
$
$
%
&
'
'
'
'
'
=
!xx !xy !xz 0
!yx !yy !yz 0
!zx !zy !zz 0
0 0 0 1
...
ビュー変換行列
Mv = RvTv =
!xx !xy !xz 0
!yx !yy !yz 0
!zx !zy !zz 0
0 0 0 1
"
#
$
$
$
$
$
%
&
'
'
'
'
'
1 0 0 (ex
0 1 0 (ey
0 0 ...
投影変換
直交投影と透視投影
51
標準ビューボリューム
x
y
z
O
1
1
1
−1
−1
−1
• −1≦ x ≦1, −1≦ y ≦1,
−1≦ z ≦1 の立方体の
空間
• この空間からはみ出た
ものはクリッピングされ
る
• この空間のxy平面への
直交投影像がビ...
直交投影
xz
y
left
right
top
bottom
-near
-far
xz
y
x
z
y
x
z
y
53
中心に平行移動
O x
y
left right
top
bottom
1 0 0 −
right +left
2
0 1 0 −
top+ bottom
2
0 0 1
far + near
2
0 0 0 1
"
#
$
$
$
$
$
$...
スケーリングして大きさを正規化
x
y
Oleft right
top
bottom
1
-1
-1 1
top-bottom
right-left
2
2
2
right −left
0 0 0
0
2
top− bottom
0 0
0 0...
直交投影変換行列
!
!
!
!
!
!
!
!
"
#
$
$
$
$
$
$
$
$
%
&
−
+
−
−
−
−
+
−
−
−
+
−
−
=
!
!
!
!
!
!
!
"
#
$
$
$
$
$
$
$
%
&
+
+
−
+
−...
透視投影
xz
y
left
right
top
bottom
-near
-far
(hither)
(yon)
xz
y
xz
y
x
z
y
57
せん断
1 0
right +left
2near
0
0 1
top+ bottom
2near
0
0 0 1 0
0 0 0 1
!
"
#
#
#
#
#
#
##
$
%
&
&
&
&
&
&
&&
58
O
z
−near
−fa...
透視変換
O
−near
−farz z
y
y
near
z y−
(view frustum)
(hither) (yon)
x*
= −
near
z
x
y*
= −
naer
z
y
z*
= −
far + near
2
−
far...
透視変換
!x
!y
!z
!w
"
#
$
$
$
$
%
&
'
'
'
'
=
near 0 0 0
0 near 0 0
0 0
far + near
2
farnear
0 0 −1 0
"
#
$
$
$
$
$$
%
&
'
'
...
透視深度
−near
−farz −near −far
near
far
O z O
−1
1
61
視錐台による透視投影変換行列
Mp =
2
right −left
0 0 0
0
2
top− bottom
0 0
0 0
−2
far − near
0
0 0 0 1
"
#
$
$
$
$
$
$
$
$
$
%
&
'
'
'
'
...
画角をもとにした透視投影変換行列
f =
1
tan
fovy
2
!
"
#
$
%
&
= cot
fovy
2
!
"
#
$
%
&
Mp =
f
aspect
0 0 0
0 f 0 0
0 0 −
far + near
far − ...
各変換行列の使い方
Mm : モデリング変換行列(パーツごとの拡大・縮小,回転,平行移動等)
Mv
Mp: ビュー変換行列 : 投影変換行列
Pl Nl: ローカル座標系の座標値 : ローカル座標系の法線ベクトル
Mc = MpMvMm Pc ...
宿題
• 次の変換行列を求めて引数の配列変数
m に格納する関数を作成してください.
• 透視投影変換行列を求める関数 perspective()
• ビュー変換行列を求める関数 lookat()
• 関数の仕様はひな形プログラムを参照のこと
...
結果
このような画像が表示さ
れれば,多分,正解です.
66
Upcoming SlideShare
Loading in …5
×

ゲームグラフィックス特論 第3回

2,638 views

Published on

同次座標,座標変換,モデル変換,ビュー変換,投影変換,透視深度

Published in: Education
1 Comment
6 Likes
Statistics
Notes
No Downloads
Views
Total views
2,638
On SlideShare
0
From Embeds
0
Number of Embeds
91
Actions
Shares
0
Downloads
105
Comments
1
Likes
6
Embeds 0
No embeds

No notes for slide

ゲームグラフィックス特論 第3回

  1. 1. ゲームグラフィックス特論 第3回 変換 (1)
  2. 2. 変換行列 同次座標による座標変換 2
  3. 3. 内積 3 v1 = 0 B B @ x1 y1 z1 w1 1 C C A , v2 = 0 B B @ x2 y2 z2 w2 1 C C A v1 · v2 = x1 y1 z1 w1 0 B B @ x2 y2 z2 w2 1 C C A = x1x2 + y1y2 + z1z2 + w1w2
  4. 4. アフィン変換 • 線形変換と平行移動の組み合わせ x0 = ax + b x0 = axxx + ayxy + bx y0 = axyx + ayyy + by x0 = axxx + ayxy + azxz + bx y0 = axyx + ayyy + azyz + by z0 = axzx + ayzy + azzz + bz 4
  5. 5. x0 = axxx + ayxy + azxz + bx y0 = axyx + ayyy + azyz + by z0 = axzx + ayzy + azzz + bz 0 @ x0 y0 z0 1 A = 0 @ axx ayx azx axy ayy azy axz ayz azz 1 A 0 @ x y z 1 A + 0 @ bx by bz 1 A アフィン変換の行列表現 5
  6. 6. アフィン変換の同次座標による表現 6 0 B B @ x0 y0 z0 1 1 C C A = 0 B B @ axx ayx azx bx axy ayy azy by axz ayz azz bz 0 0 0 1 1 C C A 0 B B @ x y z 1 1 C C A x0 = axxx + ayxy + azxz + bx y0 = axyx + ayyy + azyz + by z0 = axzx + ayzy + azzz + bz
  7. 7. v = 0 B B @ x y z w 1 C C A = x y z w T 同次座標 7 0 B B @ x y z w 1 C C A ⇣ x w , y w , z w ⌘ (x, y, z) (x, y, z) 0 B B @ x y z 1 1 C C A 0 B B @ x y z 0 1 C C A の位置 の方向
  8. 8. 同次座標の性質 • 同次座標にスカラーをかけても実座標は変わらない 8 a 0 B B @ x y z w 1 C C A = 0 B B @ ax ay az aw 1 C C A ⇣ ax aw , ay aw , az aw ⌘ = ⇣ x w , y w , z w ⌘
  9. 9. 同次座標の性質 • 同次座標の差は「通分」してから求める 9 P1 w1 P0 w0 = 0 B B @ x1/w1 y1/w1 z1/w1 1 1 C C A 0 B B @ x0/w0 y0/w0 z0/w0 1 1 C C A = 0 B B @ x1/w1 x0/w0 y1/w1 y0/w0 z1/w1 z0/w0 0 1 C C A w0P1 w1P0 = 0 B B @ w0x1 w0y1 w0z1 w0w1 1 C C A 0 B B @ w1x0 w1y0 w1z0 w1w0 1 C C A = 0 B B @ w0x1 w1x0 w0y1 w1y0 w0z1 w1z0 0 1 C C A
  10. 10. 変換 10 v0 = 0 B B @ x0 y0 z0 w0 1 C C A v = 0 B B @ x y z w 1 C C A M = 0 B B @ m0 m4 m8 m12 m1 m5 m9 m13 m2 m6 m10 m14 m3 m7 m11 m15 1 C C A v0 = Mv 0 B B @ x0 y0 z0 w0 1 C C A = 0 B B @ m0 m4 m8 m12 m1 m5 m9 m13 m2 m6 m10 m14 m3 m7 m11 m15 1 C C A 0 B B @ x y z w 1 C C A
  11. 11. 平行移動 T 7,8,0( ) x y 7 8 x y 11 T(t) = T(tx, ty, tz) = 0 B B @ 1 0 0 tx 0 1 0 ty 0 0 1 tz 0 0 0 1 1 C C A O O
  12. 12. 位置と方向の平行移動 位置 方向 移動する 変化なし 12 0 B B @ 1 0 0 tx 0 1 0 ty 0 0 1 tz 0 0 0 1 1 C C A 0 B B @ x y z 1 1 C C A = 0 B B @ x + tx y + ty z + tz 1 1 C C A 0 B B @ 1 0 0 tx 0 1 0 ty 0 0 1 tz 0 0 0 1 1 C C A 0 B B @ x y z 0 1 C C A = 0 B B @ x y z 0 1 C C A
  13. 13. 0 B B @ 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1/a 1 C C A 0 B B @ x y z 1 1 C C A = 0 B B @ x y z 1/a 1 C C A 0 B B @ a 0 0 0 0 a 0 0 0 0 a 0 0 0 0 1 1 C C A 0 B B @ x y z 1 1 C C A = 0 B B @ ax ay az 1 1 C C A 拡大縮小 x y 13 S(s) = S(sx, sy, sz) = 0 B B @ sx 0 0 0 0 sy 0 0 0 0 sz 0 0 0 0 1 1 C C A (ax, ay, az) O
  14. 14. せん断 ( ) ⎟ ⎟ ⎟ ⎟ ⎟ ⎠ ⎞ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎛ = 1000 0100 0010 001 s sxzH ( ) ⎟ ⎟ ⎟ ⎟ ⎟ ⎠ ⎞ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎛ = 1000 0100 010 0001 s syzH x y 1s 1 ( ) ⎟ ⎟ ⎟ ⎟ ⎟ ⎠ ⎞ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎛ = 1000 0100 001 0001 s syxH ( ) ⎟ ⎟ ⎟ ⎟ ⎟ ⎠ ⎞ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎛ = 1000 010 0010 0001 s szxH ( ) ⎟ ⎟ ⎟ ⎟ ⎟ ⎠ ⎞ ⎜ ⎜ ⎜ ⎜ ⎜ ⎝ ⎛ = 1000 010 0010 0001 s szyH y: せん断変形の基準となる座標軸 x: 変更される座標軸 Hxz(t) Hyz(s) 14 Hxy(s) = 0 B B @ 1 s 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1 C C A O
  15. 15. 座標軸中心の回転 15 Rx(✓) = 0 B B @ 1 0 0 0 0 cos ✓ sin ✓ 0 0 sin ✓ cos ✓ 0 0 0 0 1 1 C C A Ry(✓) = 0 B B @ cos ✓ 0 sin ✓ 0 0 1 0 0 sin ✓ 0 cos ✓ 0 0 0 0 1 1 C C A Rz(✓) = 0 B B @ cos ✓ sin ✓ 0 0 sin ✓ cos ✓ 0 0 0 0 1 0 0 0 0 1 1 C C A
  16. 16. 任意軸周りの回転 (l,m,n) θ 16 R(l, m, n, ✓) = 0 B B @ l2 + (1 l2 ) cos ✓ lm(1 cos ✓) n sin ✓ ln(1 cos ✓) + m sin ✓ 0 lm(1 cos ✓) + n sin ✓ m2 + (1 m2 ) cos ✓ mn(1 cos ✓) l sin ✓ 0 ln(1 cos ✓) m sin ✓ mn(1 cos ✓) + l sin ✓ n2 + (1 n2 ) cos ✓ 0 0 0 0 1 1 C C A
  17. 17. 直交座標系の変換 • (i, j, k), (i’, j’, k’): 直交座標系 • p: 点の位置 17 k ´ i ´ j´ i j k p p = xi + yj + zk = x0 i0 + y0 j0 + z0 k0 0 @ x0 y0 z0 1 A = MT 0 @ x y z 1 A= 0 @ i · i0 j · i0 k · i0 i · j0 j · j0 k · j0 i · k0 j · k0 k · k0 1 A 0 @ x y z 1 A 0 @ x y z 1 A = M 0 @ x0 y0 z0 1 A = i j k T i0 j0 k0 0 @ x0 y0 z0 1 A = 0 @ i · i0 i · j0 i · k0 j · i0 j · j0 j · k0 k · i0 k · j0 k · k0 1 A 0 @ x0 y0 z0 1 A
  18. 18. 直交座標系の変換 x z y r s t M M M M = 0 @ rx sx tx ry sy ty rz sz tz 1 A 1 = 0 @ rx sx tx ry sy ty rz sz tz 1 A T = 0 @ rx ry rz sx sy sz tx ty tz 1 A = 0 @ rT sT tT 1 A r = 0 @ rx ry rz 1 A s = 0 @ sx sy sz 1 A t = 0 @ tx ty tz 1 A x = 0 @ 1 0 0 1 A y = 0 @ 0 1 0 1 A z = 0 @ 0 0 1 1 A 8 < : x = Mr y = Ms z = Mt x y z = M r s t 0 @ 1 0 0 0 1 0 0 0 1 1 A = M 0 @ rx sx tx ry sy ty rz sz tz 1 A
  19. 19. あるベクトルを別のベクトルに一致させる回 転 (1) v u n n = u× v u× v ( ) ( ) ( ) ⎟ ⎟ ⎠ ⎞ ⎜ ⎜ ⎝ ⎛ ×× ×× × × = = vuu vuu vu vu u lnuMu p n n p p l = u×n u×n = u× u× v( ) u× u× v( ) m = v × n v × n = v × u× v( ) v × u× v( ) ( ) ( ) ( ) ⎟ ⎟ ⎠ ⎞ ⎜ ⎜ ⎝ ⎛ ×× ×× × × = = vuv vuv vu vu v mnvMv T uvuv MMMMM == −1 u v 19
  20. 20. 変換の合成 変換行列の積 20
  21. 21. 変換の合成 21 • 変換の合成は行列の積で表す T(4, 3, 0) T(4, 0, 0) T(0, 3, 0) T(0, 3, 0)T(4, 0, 0) = 0 B B @ 1 0 0 0 0 1 0 3 0 0 1 0 0 0 0 1 1 C C A 0 B B @ 1 0 0 4 0 1 0 0 0 0 1 0 0 0 0 1 1 C C A = 0 B B @ 1 0 0 4 0 1 0 3 0 0 1 0 0 0 0 1 1 C C A = T(4, 3, 0)
  22. 22. M = T t( )R θ( ) = r00 r10 r20 tx r01 r11 r21 ty r02 r12 r22 tz 0 0 0 1 ! " # # ## $ % & & && 剛体変換 • 立体の移動と回転 • 一般的に立体の形状に影響を与えない(=剛体) R = r0, r1, r2,( )= r,0 T r,1 T r,2 T ! " # # # # $ % & & & & ⎟⎟ ⎠ ⎞ ⎜⎜ ⎝ ⎛ =⇒ 1T 0 tR M 22
  23. 23. 任意の点を中心にした回転 p x y x y x y p T(−p) θ Rz(θ) T(p) M = T(−p)Rz(θ)T(p) 23 O O O
  24. 24. 任意の点を基準にした拡大縮小 x y x y p T(-p) T(p) M = T(−p)S (s)T(p) S(s) p x y 24 O O O
  25. 25. 特定方向への拡大縮小 拡大縮小する軸の方向 (x y z) 軸方向の拡大縮小 (x y z) 軸の空間から (r s t) 軸の空間への回転 (r s t) 軸の空間 → (x y z) 軸の空間への回転 (x y z) 軸方向の拡大縮小 (x y z) 軸の空間 → (x y z) 軸の空間への回転 FT FS 25 F = ✓ r s t 0 0 0 0 1 ◆ r s t x ys r O s rO s rO x ys r O S M = FSFT
  26. 26. 変換の連結 • 行列の演算は非可換 • 連結した変換の結果は行列の順序に依存する R(θ) R(θ) S(s) S(s) 26
  27. 27. オイラー変換 27 heading pitchroll z x y h: heading (yaw) p: pitch r: roll (bank) E(h, p, r) = Ry(h)Rx(p)Rz(r)
  28. 28. オイラー変換 28 E(h, p, r) = 0 B B @ cos h 0 sin h 0 0 1 0 0 sin h 0 cos h 0 0 0 0 1 1 C C A 0 B B @ 1 0 0 0 0 cos p sin p 0 0 sin p cos p 0 0 0 0 1 1 C C A 0 B B @ cos r sin r 0 0 sin r cos r 0 0 0 0 1 0 0 0 0 1 1 C C A = 0 B B @ sin h sin p sin r + cos h cos r sin h sin p cos r cos h sin r sin h cos p 0 cos p sin r cos p cos r sin p 0 cos h sin p sin r sin h cos r cos h sin p cos r + sin h sin r cos h cos p 0 0 0 0 1 1 C C A
  29. 29. ジンバルロック • これは (r − h) の単一の角度に依存する1軸中心の回転 • したがって自由度が一つ減る 29 = 0 B B @ cos(h r) sin(h r) 0 0 0 0 1 0 sin(h r) cos(h r) 0 0 0 0 0 1 1 C C A E(h, ⇡/2, r) = 0 B B @ sin h sin r + cos h cos r sin h cos r cos h sin r 0 0 0 0 1 0 cos h sin r sin h cos r cos h cos r + sin h sin r 0 0 0 0 0 1 1 C C A p ! ⇡/2
  30. 30. 回転変換行列からオイラー角を算出 30 M = 0 B B @ m0 m4 m8 m12 m1 m5 m9 m13 m2 m6 m10 m14 m3 m7 m11 m15 1 C C A = E(h, p, r) m1 = cos p sin r m5 = cos p cos r ! r = atan2(m5, m1) m9 = sin p ! p = asin( m9) m8 = sin h cos p m10 = cos h cos p ! h = atan2(m10, m8) もし m1 = m5 = 0 ) cos p = 0 ! p = ±⇡/2 m0 = cos(h ⌥ r) m4 = sin(h ⌥ r) ! h = 0 r = atan2(m0, m4)
  31. 31. 法線ベクトルの変換 面との直交性の維持 31
  32. 32. 変換と法線ベクトル • ベクトルも変換行列によって変換できる • 面の頂点に適用した座標変換の行列をそのままその面の法 線ベクトルに適用しても正しく変換できない場合がある M: x 軸方向に 0.5 倍スケーリ ングする行列 間違い 正解 x y N MN x y GN x y 32
  33. 33. 法線ベクトルの正しい変換 • M: 形状の変換に用いる行列 • G: この形状の法線ベクトルの変換に用いる行列 MG = ( )Madj :Mの随伴行列 ( )( )T MG adj= 33
  34. 34. 随伴行列 (adjoint) M = m00 m10 m20 m01 m11 m21 m02 m12 m22 ! " # # ## $ % & & && d00 M = m11 m21 m12 m22 d10 M = m01 m21 m02 m22 adj M( )= d00 M −d01 M d02 M −d10 M d11 M −d12 M d20 M −d21 M d22 M " # $ $ $ $ % & ' ' ' ' 余因子 ちなみに ( )M M M adj 11 =− したがって ( )T1− = MG でも可 34
  35. 35. 逆行列 逆変換を行う 35
  36. 36. 逆行列の計算 • クラメールの公式 • 3×3までの行列なら簡単 • ガウスの消去法など • 数値計算的手法 • 一般に計算コストが高い • できるだけ「楽に」逆行列を求めたい ( )M M M adj 11 =− 36
  37. 37. 逆行列の求め方 • 平行移動 • 拡大縮小 • 回転 • せん断 37 T 1 (t) = T( t) = 0 B B @ 1 0 0 tx 0 1 0 ty 0 0 1 tz 0 0 0 1 1 C C A S 1 (s) = S ✓ 1 sx , 1 sy , 1 sz ◆ = 0 B B @ 1 sx 0 0 0 0 1 sy 0 0 0 0 1 sz 0 0 0 0 1 1 C C A R 1 (✓) = R( ✓) = RT (✓) H 1 ij (s) = Hij( s)
  38. 38. 逆行列の求め方 • 剛体変換 38 M = T t( )R θ( )⇒ M−1 = R−1 θ( )T−1 t( )= R −θ( )T −t( )= RT θ( )T −t( ) R = r00 r10 r20 r01 r11 r21 r02 r12 r22 ! " # # ## $ % & & && = r0, r1, r2,( )= r,0 T r,1 T r,2 T ! " # # # # $ % & & & & M = R t 0T 1 ! " # # $ % & & ⇒ M−1 = r,0 0 r,1 0 r,2 0 −RT t 1 ! " # # $ % & &
  39. 39. 逆行列の求め方 • オイラー変換 39 E−1 h, p,r( )= ET h, p,r( ) = Ry h( )Rx p( )Rz r( )( ) T = Rz T r( )Rx T p( )Ry T h( ) E h, p,r( )= Ry h( )Rx p( )Rz r( )
  40. 40. OpenGL の変換行列 GLSL における座標変換 40
  41. 41. OpenGL の変換行列の要素の順序 この講義での行列表記 M = m0 m4 m8 m12 m1 m5 m9 m13 m2 m6 m10 m14 m3 m7 m11 m15 ! " # # # # # $ % & & & & & C/C++ 言語の配列の格納順序 GLfloat m[] = { m[ 0], m[ 1], m[ 2], m[ 3], m[ 4], m[ 5], m[ 6], m[ 7], m[ 8], m[ 9], m[10], m[11], m[12], m[13], m[14], m[15], }; 41
  42. 42. 課題 • y 軸中心に r ラジアン回 転したあと,y 方向に d 平行移動する変換行列 を右の配列変数 m に設 定しなさい.関数 sin() / cos() は使って構わない. • この配列変数は OpenGL で使用するも のとする. GLfloat m[16]; m[0] = … ; m[1] = … ; … m[15] = … ; 42
  43. 43. 行列をシェーダプログラムで使う • uniform 変数 • 描画単位 (glDrawArrays(), glDrawElements() 等) で不変な値をもつ • 変換行列,光源位置,視点位置,材質情報等 • 各シェーダステージから共通して参照される • CPU 側のプログラムで値を設定する • シェーダプログラムからは読み出しのみ #version 150 core in vec4 pv; uniform mat4 mc; void main(void) { gl_Position = mc * pv; } バーテックスシェーダ uniform uniform 変数の宣言 mat4 実数 (float) 4×4 要素の行列 データ型 mc mat4 型のユーザ定義 uniform 変数 43
  44. 44. uniform 変数に行列を設定する • シェーダプログラムの作成(loadShader() を使う場合) • GLuint program = createProgram( … ); • この後に uniform 変数 mc のインデックスを求める • GLint mcLoc = glGetUniformLocation(program, "mc"); • uniform 変数はシェーダのハードウェアの「レジスタ」に割り当てられる • glGetUniformLocation() は uniform 変数に割り当てられたレジスタの「イン デックス」を求める • 描画時に使用するシェーダプログラムの選択 • glUseProgram(program); • その後に uniform 変数に値を設定する • glUniformMatrix4fv(mcLoc, count, transpose, mc); • count: 設定する配列変数の数(行列の数が1個なら1), transpose: m を転 置するなら GL_TRUE, しないなら GL_FALSE 44
  45. 45. ビュー変換 視点の位置や視線の方向を変更する 45
  46. 46. ビュー変換 (視野変換) ビュー変換前 O x y z ビュー変換後 O x y z −z 46
  47. 47. 視点の移動 O x y z u = (ux, uy, uz) t = (tx, ty, tz) e = (ex, ey, ez) O x y z u t − e Tv = 1 0 0 −ex 0 1 0 −ey 0 0 1 −ez 0 0 0 1 " # $ $ $ $ $ % & ' ' ' ' ' 47
  48. 48. 視線の回転 O x y z u t − e O x y z (0, 0, 1) (1, 0, 0) (0, 1, 0) Rv = !x T 0 !y T 0 !z T 0 0 0 0 1 " # $ $ $ $ $ % & ' ' ' ' ' 48
  49. 49. 回転の変換行列 Rv = !x T 0 !y T 0 !z T 0 0 0 0 1 " # $ $ $ $ $ % & ' ' ' ' ' = !xx !xy !xz 0 !yx !yy !yz 0 !zx !zy !zz 0 0 0 0 1 " # $ $ $ $ $ % & ' ' ' ' ' !z T = !zx !zy !zz( )= ex (tx ey (ty ez (tz( ) ex (tx( ) 2 + ey (ty( ) 2 + ez (tz( ) 2 !x T = !xx !xy !xz( )= uy !zz (uz !zy uz !zx (ux !zz ux !zy (uy !zx( ) uy !zz (uz !zy( ) 2 + uz !zx (ux !zz( ) 2 + ux !zy (uy !zx( ) 2 !y T = !yx !yy !yz( )= !zy !xz ( !zz !xy !zz !xx ( !zx !xz !zx !xy ( !zy !xx( ) 49
  50. 50. ビュー変換行列 Mv = RvTv = !xx !xy !xz 0 !yx !yy !yz 0 !zx !zy !zz 0 0 0 0 1 " # $ $ $ $ $ % & ' ' ' ' ' 1 0 0 (ex 0 1 0 (ey 0 0 1 (ez 0 0 0 1 " # $ $ $ $ % & ' ' ' ' = !xx !xy !xz (ex !xx (ey !xy (ez !xz !yx !yy !yz (ex !yx (ey !yy (ez !yz !zx !zy !zz (ex !zx (ey !zy (ez !zz 0 0 0 1 " # $ $ $ $ $ % & ' ' ' ' ' 50
  51. 51. 投影変換 直交投影と透視投影 51
  52. 52. 標準ビューボリューム x y z O 1 1 1 −1 −1 −1 • −1≦ x ≦1, −1≦ y ≦1, −1≦ z ≦1 の立方体の 空間 • この空間からはみ出た ものはクリッピングされ る • この空間のxy平面への 直交投影像がビュー ポートに表示される • この空間の座標系はク リッピング座標系 52
  53. 53. 直交投影 xz y left right top bottom -near -far xz y x z y x z y 53
  54. 54. 中心に平行移動 O x y left right top bottom 1 0 0 − right +left 2 0 1 0 − top+ bottom 2 0 0 1 far + near 2 0 0 0 1 " # $ $ $ $ $ $ $ $ % & ' ' ' ' ' ' ' ' 54
  55. 55. スケーリングして大きさを正規化 x y Oleft right top bottom 1 -1 -1 1 top-bottom right-left 2 2 2 right −left 0 0 0 0 2 top− bottom 0 0 0 0 −2 far − near 0 0 0 0 1 " # $ $ $ $ $ $ $ $ $ % & ' ' ' ' ' ' ' ' ' 55
  56. 56. 直交投影変換行列 ! ! ! ! ! ! ! ! " # $ $ $ $ $ $ $ $ % & − + − − − − + − − − + − − = ! ! ! ! ! ! ! " # $ $ $ $ $ $ $ % & + + − + − ! ! ! ! ! ! ! ! " # $ $ $ $ $ $ $ $ % & − − − − = 1000 2 00 0 2 0 00 2 1000 2 100 2 010 2 001 1000 0 2 00 00 2 0 000 2 nearfar nearfar nearfar bottomtop bottomtop bottomtop leftright leftright leftright nearfar bottomtop leftright nearfar bottomtop leftright oM 56
  57. 57. 透視投影 xz y left right top bottom -near -far (hither) (yon) xz y xz y x z y 57
  58. 58. せん断 1 0 right +left 2near 0 0 1 top+ bottom 2near 0 0 0 1 0 0 0 0 1 ! " # # # # # # ## $ % & & & & & & && 58 O z −near −far left right x right+left 2 1 right+left 2 near (view frustum)
  59. 59. 透視変換 O −near −farz z y y near z y− (view frustum) (hither) (yon) x* = − near z x y* = − naer z y z* = − far + near 2 − farnear z 59
  60. 60. 透視変換 !x !y !z !w " # $ $ $ $ % & ' ' ' ' = near 0 0 0 0 near 0 0 0 0 far + near 2 farnear 0 0 −1 0 " # $ $ $ $ $$ % & ' ' ' ' '' x y z 1 " # $ $ $ $ % & ' ' ' ' !x = near x !y = near y !z = far + near 2 z + farnear !w = −z x* = − near z x y* = − naer z y z* = − far + near 2 − farnear z 60 求め方は 後述
  61. 61. 透視深度 −near −farz −near −far near far O z O −1 1 61
  62. 62. 視錐台による透視投影変換行列 Mp = 2 right −left 0 0 0 0 2 top− bottom 0 0 0 0 −2 far − near 0 0 0 0 1 " # $ $ $ $ $ $ $ $ $ % & ' ' ' ' ' ' ' ' ' near 0 0 0 0 near 0 0 0 0 far + near 2 farnear 0 0 −1 0 " # $ $ $ $ $$ % & ' ' ' ' '' 1 0 right +left 2near 0 0 1 top+ bottom 2near 0 0 0 1 0 0 0 0 1 " # $ $ $ $ $ $ $$ % & ' ' ' ' ' ' '' = 2near right −left 0 right +left right −left 0 0 2near top− bottom top+ bottom top− bottom 0 0 0 − far + near far − near − 2 farnear far − near 0 0 −1 0 " # $ $ $ $ $ $ $ $ $ % & ' ' ' ' ' ' ' ' ' 62
  63. 63. 画角をもとにした透視投影変換行列 f = 1 tan fovy 2 ! " # $ % & = cot fovy 2 ! " # $ % & Mp = f aspect 0 0 0 0 f 0 0 0 0 − far + near far − near − 2 farnear far − near 0 0 −1 0 ! " # # # # # # ## $ % & & & & & & && fovy x y z -far -near 63
  64. 64. 各変換行列の使い方 Mm : モデリング変換行列(パーツごとの拡大・縮小,回転,平行移動等) Mv Mp: ビュー変換行列 : 投影変換行列 Pl Nl: ローカル座標系の座標値 : ローカル座標系の法線ベクトル Mc = MpMvMm Pc = McPl Pw = MmPl G = adj Mm( )( ) T Nw = GNl (要正規化) 64
  65. 65. 宿題 • 次の変換行列を求めて引数の配列変数 m に格納する関数を作成してください. • 透視投影変換行列を求める関数 perspective() • ビュー変換行列を求める関数 lookat() • 関数の仕様はひな形プログラムを参照のこと • https://github.com/tokoik/ggsample03 • 透視投影変換行列とビュー変換行列の積 をシェーダプログラムの uniform 変数 mc に格納してください. • バーテックスシェーダにおいて,頂点座標 に uniform 変数 mc をかけてください. • main.cpp と simple.vert をメールに添付 してください. • 送り先 tokoi@sys.wakayama-u.ac.jp 第2回の宿題の図形に対 してビュー変換と透視投 影変換を行ったものを描 いてください 65
  66. 66. 結果 このような画像が表示さ れれば,多分,正解です. 66

×