ゲームグラフィックス特論 第3回 講義ノート

1,039 views

Published on

座標変換に関して。まだ書きかけです。

Published in: Education
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,039
On SlideShare
0
From Embeds
0
Number of Embeds
69
Actions
Shares
0
Downloads
49
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

ゲームグラフィックス特論 第3回 講義ノート

  1. 1. 100 7 7.1 7.1.1 OpenGL × × × 6 ± OpenGL API ( 78) × × × ( CPU )
  2. 2. 101 GPU × ( 79) 78 79 80 部品 部品 配置 配置
  3. 3. 102 7.1.2 ( ) ( 80) 7.1.3 ( 81) 81 × 82 82 ローカル座標系 ローカル座標系 ワールド座標系 視点座標系 x z y x z y x z y x z y スクリーン
  4. 4. 103 7.1.4 × × (View Volume) 2 × (Canonical View Volume) ( 83) × 83 × × (Orthogonal Projection) (Perspective Projection) ( 19) × (View Frustum, ) 84 標準ビューボリューム 視野錐台 (View Frustum) 直交投影 (Orthographic Projection) 透視投影 (Perspective Projection) 1 -1 1 -1 1 -1 (Canonical View Volume) ビューボリューム (View Volume)
  5. 5. 104 7.2 7.2.1 6 (1) x a b (2) (3) (3) (4) 7.2.2 (4) x, y, z (5) x’, y’, z’ (3) ( ) (5) ( ) ( ) (x* , y* , z* ) (x, y, z, w) (6) 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 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 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 x⇤ = x w y⇤ = y w z⇤ = z w
  6. 6. 105 (x, y, z) (x, y, z, 1) w 0 (x, y, z) CG (x, y, z, 0) (x, y, z) (7) (8) (9) CG P0, P1 P0 = (x0, y0, z0, w0), P1 = (x1, y1, z1, w1) P0 P1 (10) w0 w1 0 w0w1 (11) (11) 0 P0 P1 0 (11) w0w1 (12) 0 B B @ x y z 1 1 C C A ) (x, y, z) 0 B B @ x y z 0 1 C C A ) (x, y, z) 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 ⌘ 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 NX i=1 Pi wi = NX i=1 0 B B @ xi/wi yi/wi zi/wi 1 1 C C A = 0 B B @ P xi/wiP yi/wiP zi/wi N 1 C C A ) ✓P xi N , P yi N , P zi N ◆
  7. 7. 106 7.3 7.3.1 (5) 0 1 v M v’ = Mv (15) (13) (14) (15) (16) v’ (x’, y’, z’, w’) (17) v’ M v x’ = (m0 m4 m8 m12) (x y z w)T ((17) ) (18) l OpenGL (16) 4 4 OpenGL GPU CPU GPU v = 0 B B @ x y z w 1 C C A v0 = 0 B B @ x0 y0 z0 w0 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 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 x0 = m0 x + m4 y + m8 z + m12 w y0 = m1 x + m5 y + m9 z + m13 w z0 = m2 x + m6 y + m10 z + m14 w w0 = m3 x + m7 y + m11 z + m15 w 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
  8. 8. 107 85 7.3.2 t = (tx, ty, tz) T(tx, ty, tz) (19) (x, y, z) (20) T(7, 8, 0) 86 86 0 (20) l m 行列の表記 配列の要素の格納順序 M = 0 B B @ m0 m4 m8 m12 m1 m5 m9 m13 m2 m6 m10 m14 m3 m7 m11 m15 1 C C A GLfloat(m[](=({ ((m0, m1, m2, m3, !!m4, m5, m6, m7, !!m8, m9, m10, m11, !!m12, m13, m14, m15 }; 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 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 T(7, 8, 0) x y O 7 8 x y O 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
  9. 9. 108 // (x, y, z) m GLfloat *loadTranslate(GLfloat x, GLfloat y, GLfloat z, GLfloat *m) { m[12] = x; m[13] = y; m[14] = z; m[ 1] = m[ 2] = m[ 3] = m[ 4] = m[ 6] = m[ 7] = m[ 8] = m[ 9] = m[11] = 0.0f; m[ 0] = m[ 5] = m[10] = m[15] = 1.0f; return m; } x, y, z m 16 (20) (15) m0 m5 m10 m15 1 m12 x m13 y m14 z m l 0 // m GLfloat *loadIdentity(GLfloat *m) { return loadTranslate(0.0f, 0.0f, 0.0f, m); } 7.3.3 s = (sx, sy, sz) S(sx, sy, sz) (21) 87 sx, = sy, = sz = a w 1/a 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 x y O S(2, 2, 1)
  10. 10. 109 (22) (23) l // (x, y, z) m GLfloat *loadScale(GLfloat x, GLfloat y, GLfloat z, GLfloat *m) { m[ 0] = x; m[ 5] = y; m[10] = z; m[ 1] = m[ 2] = m[ 3] = m[ 4] = m[ 6] = m[ 7] = m[ 8] = m[ 9] = m[11] = m[12] = m[13] = m[14] = 0.0f; m[15] = 1.0f; return m; } x, y, z x y z m 16 (23) (15) m0 x m5 y m10 z m15 1 m 7.3.4 88 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 ) (ax, ay, az) 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 ) (ax, ay, az) O x y 1s 1
  11. 11. 110 88 Y s X (24) (24) x, y, z (25) 7.3.5 l X 89 X (21) 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 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 Hyz(s) = 0 B B @ 1 0 0 0 0 1 s 0 0 0 1 0 0 0 0 1 1 C C A Hzx(s) = 0 B B @ 1 0 0 0 0 1 0 0 s 0 1 0 0 0 0 1 1 C C A Hyx(s) = 0 B B @ 1 0 0 0 s 1 0 0 0 0 1 0 0 0 0 1 1 C C A Hzy(s) = 0 B B @ 1 0 0 0 0 1 0 0 0 s 1 0 0 0 0 1 1 C C A Hxz(s) = 0 B B @ 1 0 s 0 0 1 0 0 0 0 1 0 0 0 0 1 1 C C A θ! Rx(✓) = 0 B B @ 1 0 0 0 0 cos ✓ sin ✓ 0 0 sin ✓ cos ✓ 0 0 0 0 1 1 C C A
  12. 12. 111 l Y 90 Y (22) l Z 91 Z (23) l (l, m, n) θ! 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
  13. 13. 112 92 (24) l (24) x, y, z a m // (x, y, z) a m GLfloat *loadRotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z, GLfloat *m) { const GLfloat d(sqrt(x * x + y * y + z * z)); if (d > 0.0f) { const GLfloat l(x / d), m(y / d), n(z / d); const GLfloat l2(l * l), m2(m * m), n2(n * n); const GLfloat lm(l * m), mn(m * n), nl(n * l); const GLfloat c(cos(a)), c1(1.0f – c), s(sin(a)); m[ 0] = (1.0f - l2) * c + l2; m[ 1] = lm * c1 + n * s; m[ 2] = nl * c1 - m * s; m[ 4] = lm * c1 - n * s; m[ 5] = (1.0f - m2) * c + m2; m[ 6] = mn * c1 + l * s; m[ 8] = nl * c1 + m * s; m[ 9] = mn * c1 - l * s; m[10] = (1.0f - n2) * c + n2; m[ 3] = m[ 7] = m[11] = m[12] = m[13] = m[14] = 0.0f; m[15] = 1.0f; } return m; } (l,m,n) θ! 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
  14. 14. 113 7.4 i’, j’, k’ p i, j, k p (x’, y’, z’) (x, y, z) p (30) (31) (x, y, z) (32) (i j k), (i’ j’ k’) (33) M (x’, y’, z’) (x, y, z) (34) M ( ) r, s, t (35) X Y Z x, y, z (36) r, s, t x, y, z M p = xi + yj + zk = x0 i0 + y0 j0 + z0 k0 i j k 0 @ x y z 1 A = i0 j0 k0 0 @ x0 y0 z0 1 A 0 @ x y z 1 A = i j k 1 i0 j0 k0 0 @ x0 y0 z0 1 A 0 @ x y z 1 A = i j k T i0 j0 k0 0 @ x0 y0 z0 1 A M = i j k T i0 j0 k0 = 0 @ i · i0 i · j0 i · k0 j · i0 j · j0 j · k0 k · i0 k · j0 k · k0 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
  15. 15. 114 (37) (38) 93 (39) M (40) 7.5 7.5.1 94 x 4 y 3 (41) 94 8 < : x = Mr y = Ms z = Mt x y z = M r s t x z y r s t M M M 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 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 T(4, 3, 0) T(4, 0, 0) T(0, 3, 0)
  16. 16. 115 (41) l OpenGL // m0 m1 m GLfloat *multiply(const GLfloat *m0, const GLfloat *m1, GLfloat *m) { for (int j = 0; j < 4; ++j) { for (int i = 0; i < 4; ++i) { const int ji(j * 4 + i); m[ji] = 0.0f; for (int k = 0; k < 4; ++k) m[ji] += m0[k * 4 + i] * m1[j * 4 + k]; } } return m; } // m0 m1 m GLfloat *multiply(const GLfloat *m0, const GLfloat *m1, GLfloat *m) { for (int ji = 0; ji < 16; ++ji) { const int i(ji & 3), j(ji & ~3); m[ji] = m0[i] * m1[j] + m0[4 + i] * m1[j + 1] + m0[8 + i] * m1[j + 2] + m0[12 + i] * m1[j + 3]; } return m; } 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)
  17. 17. 116 7.5.2 (42) M ! t (43) 7.5.3 7.3.5 M = T(p) Rz(θ) T(−p) 95 7.5.4 l M = T(t)R(l, m, n, ✓) = 0 B B @ r00 r10 r20 tx r01 r11 r21 ty r02 r12 r22 tz 0 0 0 1 1 C C A ¯R = 0 @ r00 r10 r20 r01 r11 r21 r02 r12 r22 1 A , t = 0 @ tx ty tz 1 A ) M = 0 @ ¯R t 0T 1 1 A p x y x y x y p T( p) θ" Rz(θ) T(p) M = T( p)Rz(θ)T(p) O O O
  18. 18. 117 96 M = T(p) S(s) T(−p) 97 7.5.5 l X Y Z X Y Z (x y z) (r s t) F sr ss st X Y Z S M = FSFT (44) O x y (移動) x y x y p T(-p) T(p) M = T( p)S (s)T(p) S(s) p x y O O O F = ✓ r s t 0 0 0 0 1 ◆
  19. 19. 118 (45) 98 7.5.6 99 7.6 7.6.1 X, Y, Z S = 0 B B @ sr 0 0 0 0 ss 0 0 0 0 st 0 0 0 0 1 1 C C A FT FS x ys r O s rO s rO x ys r O M = FTSF R(θ) R(θ) S(s) S(s) x y O x y O x y O x y O x y O x y O
  20. 20. 119 100 Z (roll, bank) X (pitch) Y (heading, yaw) r, p, h Ÿ r: roll, bank (Z ) Ÿ p: pitch (X ) Ÿ h: heading, yaw (Y ) E(h, p, r) (46) 7.6.2 p = / 2 sin p = 1, cos p = 0 (46) (47) heading pitchroll z x y E(h, p, r) = Ry(h)Rx(p)Rz(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 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
  21. 21. 120 (48) (h - r) r h p = / 2 r (Z ) h 7.6.3 M E(h, p, r) (49) m1 m5 r (50) m8 m10 h (51) p m9 (52) m1 = m5 = 0 cos p = 0 p = / 2 (50) (51) r h h = 0 m0 m14 h (53) 7.7 7.7.1 ( ) x y z x E(h, ⇡/2, r) = 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 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) m8 = sin h cos p m10 = cos h cos p ! h = atan2(m10, m8) m9 = sin p ! p = asin( m9) m0 = cos(h ⌥ r) m4 = sin(h ⌥ r) ! h = 0, r = atan2(m0, m4)
  22. 22. 121 y OpenGL ( 101) z 101 z z 102 7.7.2 l e = (ex, ey, ez) g = (gx, gy, gz) u = (ux, uy, uz) y (0, 1, 0) 103 x y z x y z O x y z -z O x y z O x y z u =(ux , uy, uz) g = (gx , gy, gz) 上方向の ベクトル 目標点の位置 e = (ex , ey, ez) 視点の位置
  23. 23. 122 l e = (ex, ey, ez) O = (0, 0, 0) Tv (54) l r, s, t e g – e u (r s t) 104 (r s t) z t = (tx, ty, tz) e − g x r = (rx, ry, rz) u t u × t y s = (sx, sy, sz) t r t × r (55) l (r s t) (40) (56) Rv Tv = 0 B B @ 1 0 0 ex 0 1 0 ey 0 0 1 ez 0 0 0 1 1 C C A O x y z t g e t = e − g r = u × t O x y z u t r s = t × r O x y z s t r t = e g = 0 @ ex gx ey gy ez gz 1 A = 0 @ tx ty tz 1 A r = u ⇥ t = 0 @ uytz uzty uztx uxtz uxty uytx 1 A = 0 @ rx ry rz 1 A s = t ⇥ r = 0 @ tyrz tzry tzrx txrz txry tyrx 1 A = 0 @ sx sy sz 1 A
  24. 24. 123 (56) s 0 r t 0 4 × 4 = 16 rv 3 × 3 l Tv Rv (57) 105 l // m GLfloat *loadLookat( GLfloat ex, GLfloat ey, GLfloat ez, // GLfloat gx, GLfloat gy, GLfloat gz, // GLfloat ux, GLfloat uy, GLfloat uz, // GLfloat *m) { // GLfloat tv[16]; loadTranslate(-ex, -ey, -ez, tv); // t = e - g const GLfloat tx(ex - gx); const GLfloat ty(ey - gy); const GLfloat tz(ez - gz); // r = u x t const GLfloat rx(uy * tz - uz * ty); const GLfloat ry(uz * tx - ux * tz); const GLfloat rz(ux * ty - uy * tx); Rv = 0 B B B B B B B B B @ rT |r| 0 sT |s| 0 tT |t| 0 0 0 0 1 1 C C C C C C C C C A = 0 B B B B B B B B B @ rx |r| ry |r| rz |r| 0 sx |s| sy |s| sz |s| 0 tx |t| ty |t| tz |t| 0 0 0 0 1 1 C C C C C C C C C A Mv = RvTv (0, 0, 1) (1, 0, 0) (0, 1, 0) O x y z z
  25. 25. 124 // s = t x r const GLfloat sx(ty * rz - tz * ry); const GLfloat sy(tz * rx - tx * rz); const GLfloat sz(tx * ry - ty * rx); // s const GLfloat s2(sx * sx + sy * sy + sz * sz); if (s2 == 0.0f) return m; // GLfloat rv[16]; // r const GLfloat r(sqrt(rx * rx + ry * ry + rz * rz)); rv[ 0] = rx / r; rv[ 4] = ry / r; rv[ 8] = rz / r; // s const GLfloat s(sqrt(s2)); rv[ 1] = sx / s; rv[ 5] = sy / s; rv[ 9] = sz / s; // t const GLfloat t(sqrt(tx * tx + ty * ty + tz * tz)); rv[ 2] = tx / t; rv[ 6] = ty / t; rv[10] = tz / t; // rv[ 3] = rv[ 7] = rv[11] = rv[12] = rv[13] = rv[14] = 0.0f; rv[15] = 1.0f; // return multiply(rv, tv, m); } 7.8 7.8.1 ( ) × ( ) 106 [-1, 1] (Canonical View Volume) xy
  26. 26. 125 106 7.8.2 l 2 (left, bottom) (right, top) (near, far) xy z ( ) near (xy ) far (View Volume) 107 (hither) (yon) z z −near −far x y z OO 11 11 11 −−11 −−11 −−11 前方面 (hither) 視体積 (view volume) 後方面 (yon) 視点 x y z −near −far leftleft rightright bottombottom toptop
  27. 27. 126 2 108 l ((right + left) / 2, (top + bottom) / 2, −(far + near) / 2) 109 (21) (58) far near Z (58) x z y x z y x z y OOOOO OOO 中心が原点になるよう平行移動 大きさを正規化 + 2 + 2 Mcentering = 0 B B B B B B B B @ 1 0 0 right + left 2 0 1 0 top + bottom 2 0 0 1 far + near 2 0 0 0 1 1 C C C C C C C C A
  28. 28. 127 l 2 right – left top – bottom –(far – near) 110 2 (21) (59) far near Z (59) l Mo Mcentering Mscaling (60) l m // m GLfloat *loadOrthogonal(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar, GLfloat *m) { const GLfloat dx(right - left); 1 1 1 122 22 Mscaling = 0 B B B B B B B @ 2 right left 0 0 0 0 2 top bottom 0 0 0 0 2 far near 0 0 0 0 1 1 C C C C C C C A Mo = MscalingMcentering = 0 B B B B B B B B @ 2 right left 0 0 right + left right left 0 2 top bottom 0 top + bottom top bottom 0 0 2 far near far + near far near 0 0 0 1 1 C C C C C C C C A
  29. 29. 128 const GLfloat dy(top - bottom); const GLfloat dz(zFar - zNear); if (dx != 0.0f && dy != 0.0f && dz != 0.0f) { m[ 0] = 2.0f / dx; m[ 5] = 2.0f / dy; m[10] = -2.0f / dz; m[12] = -(right + left) / dx; m[13] = -(top + bottom) / dy; m[14] = -(zFar + zNear) / dz; m[15] = 1.0f; m[ 1] = m[ 2] = m[ 3] = m[ 4] = m[ 6] = m[ 7] = m[ 8] = m[ 9] = m[11] = 0.0f; } return m; } 7.8.3 2 (left, bottom) (right, top) (near, far) ( ) (View Frustum) 111 (z ) 2 前方面 (hither) 後方面 (yon) 視点 x y z −near −far leftleft rightright bottombottom toptop 視錐台 (view frustum)
  30. 30. 129 112 l z –near ((right + left) / 2, (top + bottom) / 2) z = –1 ((right + left) / 2near, (top + bottom) / 2 near) 113 (61) l ( , z ) (x, y, z) –near (–near x / z, –near y / z) z l x z y x z y x z y OOOO OOO Z軸が中心を通るようにせん断変形 透視変換して平行移動と正規化 −−−− − 2 −1 2 Mshear = 0 B B B B B B @ 1 0 right + left 2 near 0 0 1 top + bottom 2 near 0 0 0 1 0 0 0 0 1 1 C C C C C C A
  31. 31. 130 114 (62) l Mp Mperspective Mshear Mscaling (63) l m // m GLfloat *loadFrustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar, GLfloat *m) { const GLfloat dx(right - left); const GLfloat dy(top - bottom); const GLfloat dz(zFar - zNear); if (dx != 0.0f && dy != 0.0f && dz != 0.0f) { m[ 0] = 2.0f * zNear / dx; m[ 5] = 2.0f * zNear / dy; m[ 8] = (right + left) / dx; m[ 9] = (top + bottom) / dy; near z− y −near z −farz y O yy 前方面 (hither) 後方面 (yon) 視錐台 (view frustum) Mperspective = 0 B B B @ near 0 0 0 0 near 0 0 0 0 far + near 2 far near 0 0 1 0 1 C C C A Mp = MscalingMperspectiveMshear = 0 B B B B B B B B B @ 2 near right left 0 right + left right left 0 0 2 near top bottom top + bottom top bottom 0 0 0 far + near far near 2 far near far near 0 0 1 0 1 C C C C C C C C C A
  32. 32. 131 m[10] = -(zFar + zNear) / dz; m[11] = -1.0f; m[14] = -2.0f * zFar * zNear / dz; m[ 1] = m[ 2] = m[ 3] = m[ 4] = m[ 6] = m[ 7] = m[12] = m[13] = m[15] = 0.0f; } return m; } 7.8.4 (z ) 115 xz A = (xa, za) B = (xb, zb) z = near C D 115 CD t : 1 – t P P AB Q = (xq, zq) (64) (64) (64) Q z zq A z za B z zb Q x xq z = 1 Q zq O x z t 1−t A = (xa, za) Q = (xq, zq) B = (xb, zb) C P Dnear 8 >>>>>>>< >>>>>>>: xq = xa za (1 t) + xb zb t 1 za (1 t) + 1 zb t zq = 1 1 za (1 t) + 1 zb t
  33. 33. 132 (z ) −far near (far − near) / 2 0 (59) Mscaling −2 / (far − near) [-1, 1] 116 (62) (65) (62) Mperspective (x, y, z) (66) (67) (66) (67) (x* , y* , z* ) (65) -farz 1 -1 O -near Oz -far -near far - near 2 far - near 2 - Oz far near -far-near far near z far near 2 ⇥ 2 far near x⇤ = near z x y⇤ = near z y z⇤ = far near z far + near 2 0 B B @ x0 y0 z0 w0 1 C C A = 0 B B B @ near 0 0 0 0 near 0 0 0 0 far + near 2 far near 0 0 1 0 1 C C C A 0 B B @ x y z 1 1 C C A x0 = near x y0 = near y z0 = far + near 2 z + far near w0 = z
  34. 34. 133 7.8.5 y (fovy) aspect ratio (68) f fovy 2 ( ) z = −near −bottom = top = near / f −left = right = aspect near / f (63) (69) 117 (68) (69) l m // m GLfloat *loadPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar, GLfloat *m) { const GLfloat dz(zFar - zNear); if (dz != 0.0f) { m[ 5] = 1.0f / tan(fovy * 0.5f); m[ 0] = m[5] / aspect; m[10] = -(zFar + zNear) / dz; 1 x y z −near −far fovy O y z O −near −far fovy −f −1 f = 1 tan ✓ fovy 2 ◆ = cot ✓ fovy 2 ◆ Mp = 0 B B B B B @ f aspect 0 0 0 0 f 0 0 0 0 far + near far near 2 far near far near 0 0 1 0 1 C C C C C A
  35. 35. 134 m[11] = -1.0f; m[14] = -2.0f * zFar * zNear / dz; m[ 1] = m[ 2] = m[ 3] = m[ 4] = m[ 6] = m[ 7] = m[ 8] = m[ 9] = m[12] = m[13] = m[15] = 0.0f; } return m; }

×