Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

【Unity道場スペシャル 2017博多】クォータニオン完全マスター

10,652 views

Published on

2017/6/3に開催されたUnity道場 博多スペシャルの講演スライドです。
講師:安原 祐二(ユニティ・テクノロジーズ・ジャパン合同会社)
講演動画:https://youtu.be/uKWLPU8gfIY

知ってはいるけれどピンとこない、知ってはいるけれどピンとこない、そんなクォータニオンについて基本となる概念からたっぷりと、丁寧に説明していきます。行列についても解説しますので、これからシェーダプログラミングに取り組もうとするエンジニアにも役に立つ内容です。数学に苦手意識のある人も、この機会にマスターしてしまいましょう!

こんな人におすすめ
・プログラマ全般および数学に興味のある人

受講者が得られる知見
・クォータニオンの意味
・行列とクォータニオンの関係
・数学的な背景

Unityのイベント資料はこちらから:
https://www.slideshare.net/UnityTechnologiesJapan/clipboards

Published in: Technology
  • Be the first to comment

【Unity道場スペシャル 2017博多】クォータニオン完全マスター

  1. 1. クォータニオン完全マスター ユニティ・テクノロジーズ・ジャパン合同会社 安原 祐二
  2. 2. Unity スクリプトリファレンスより抜粋
  3. 3. 座標変換 CG オイラー角 複素数 クォータニオン 本セッションの旅程
  4. 4. 座標変換
  5. 5. CGの きほん たくさんの点を動かす! © Unity Technologies Japan/UCL
  6. 6. P(1, 2) x y 二次元座標
  7. 7. P’(-2, 1) x y P(1, 2)
  8. 8. P(1, 2) P’(-2, 1) ある変換で点を移動 変換 ある変換=なんらかのルール
  9. 9. 同じ変換でたくさんの点を移動 Q(2, 0) Q’(0, 2) 変換 P(1, 2) P’(-2, 1) 変換 R(1, 1) R’(-1, 1) 変換
  10. 10. こういう式にしてみよう x’ = ax + by y’ = cx + dy P’(x’, y’) = [変換]P(x, y)
  11. 11. x’ = ax + by y’ = cx + dy x’ = 1x + 0y y’ = 0x + 1y a=1 b=0 c=0 d=1 なら x’ = x y’ = y 変化しない変換 色々できそう!
  12. 12. 色々できそう! x’ = ax + by y’ = cx + dy x’ = 1x + 0y y’ = 0x + 1y a=1 b=0 c=0 d=1 なら x’ = x y’ = y 変化しない変換 x’ = 0x + 1y y’ = 1x + 0y a=0 b=1 c=1 d=0 なら x’ = y y’ = x xy入れ替え変換
  13. 13. abcdをまとめてしまおう x’ = ax + by y’ = cx + dy a b c d( ) これを行列と呼ぶ!
  14. 14. 変換を行列Mとして P(1, 2) P’(-2, 1) 変換 P’=MP P’(x’, y’) = [変換]P(x, y)
  15. 15. a b c d( )P’= P 変換を行列Mとして P(1, 2) P’(-2, 1) 変換 P’=MP P’(x’, y’) = [変換]P(x, y)
  16. 16. ( 行列に点ベクトルを掛ける a b c d( )= a b c d( ) 1 2)=)(-2 1 x’ = ax + by y’ = cx + dy -2 = a1 + b2 1 = c1 + d2 例えば )(x’ y’ (x y)
  17. 17. -2 = a1 + b2 1 = c1 + d2 行列に点ベクトルを掛ける
  18. 18. -2 = a1 + b2 1 = c1 + d2 1 2( )a b c d( ) 1 =)(-2 1 2 1 2 + +
  19. 19. 三次元では3x3行列になる x’ = ax + by + cz y’ = dx + ey + fz a b c d e f g h i( ) z’ = gx + hy + iz 概念は同じなので 以降も二次元で続けます
  20. 20. いろいろな行列 2 0 0 2( ) 2倍に拡大 スケーリング行列 cosθ -sinθ sinθ cosθ( )θ回転する 回転行列
  21. 21. デモ
  22. 22. x y あれ? 移動は? 行列の値をどう工夫しても移動はできない!
  23. 23. x’ = ax + by y’ = cx + dy x’ = ax + by + s y’ = cx + dy + t 移動するために式を変更 これで(s,t)で移動できる 追加!
  24. 24. 移動を実現するために行列を拡張 a b s c d t( ) a b c d( ) a b s c d t 0 0 1 ( ) 何かと都合がいいので 3x3 にする x’ = ax + by + s y’ = cx + dy + t 行と列の数が同じ 正方行列と呼ぶ
  25. 25. デモ
  26. 26. 三次元でも同様にして移動を実現 つまり三次元では4x4行列を使う a b c s d e f t g h i u 0 0 0 1 )( x’ y’ z’ 1 ( )= x y z 1 ( )
  27. 27. a b s c d t 0 0 1 ( ) 二次元用3x3行列の 各部分の役割 回転 移動
  28. 28. a b c s d e f t g h i u 0 0 0 1 )( 回転 移動 三次元用4x4行列の 各部分の役割
  29. 29. 回転 移動 三次元用4x4行列の 各部分の役割 transform.rotation transform.position Quaternion クォータニオン で作る Vector3 ベクトル で作る a b c s d e f t g h i u 0 0 0 1 )(
  30. 30. 異なる変換をいくつも重ねる これを点ごとに計算するのはたいへん… P’=(○(○(○(○P))))
  31. 31. いくつも変換する場合は事前に計算しておける 点ごとにMを掛ければ済む P’=MP P’=○○○○P P’=(○(○(○(○P)))) M=○○○○ を 事前に計算して…
  32. 32. 座標変換 CG オイラー角 複素数 クォータニオン
  33. 33. CGに応用する行列
  34. 34. 3つの変換行列 • モデル行列 • ビュー行列 • プロジェクション行列
  35. 35. すべての変換前 モデリングした物体の座標 データにはこの座標が 格納されている
  36. 36. この変換が モデル行列 Transformで 移動・回転
  37. 37. シーンにはカメラがある カメラ Transformで 移動・回転 z
  38. 38. カメラが原点・ゼロ回転 になるように変換 この変換が ビュー行列 空間全体をモニタの位置に合わせる! z
  39. 39. 画角や near, far を処理 w に z を格納など… この変換が プロジェクション行列
  40. 40. Unity組み込みシェーダ UnityShaderVariables.cginc より抜粋 M:モデル V:ビュー P:プロジェクション
  41. 41. モニタに映すための 透視変換 この変換は 行列ではなく奥行きで割る 遠くのものを小さく!
  42. 42. 透視変換のようす
  43. 43. 座標変換 CG オイラー角 複素数 クォータニオン
  44. 44. オイラー角方式
  45. 45. 二次元の回転はシンプル 回転軸はひとつ cosθ -sinθ sinθ cosθ( )θ回転の 回転行列
  46. 46. 三次元では3軸の 回転量をそれぞれ記述 あらゆる姿勢を表現可能 これがオイラー角方式 x y z 直感的!
  47. 47. Unity の Inspector の Rotation は… 表示に関しては オイラー角方式
  48. 48. P’=YXZP X X軸まわりの回転行列 Y Y軸まわりの回転行列 Z Z軸まわりの回転行列 オイラー角方式の回転には順番がある Unityは ZYXの順番
  49. 49. プログラム例: オイラー角で作った回転を代入 transform.rotation = Quaternion.Euler(x, y, z); ① ② ③ 変換を3回重ねている
  50. 50. 座標変換 CG オイラー角 複素数 クォータニオン
  51. 51. 複素数と複素平面
  52. 52. クォータニオンは 複素数の拡張
  53. 53. 問題
  54. 54. は虚数単位
  55. 55. 虚数の定義 虚数単位
  56. 56. 複素数 :実部 :虚部
  57. 57. 2 1 普通の平面 P(1, 2) x y
  58. 58. 実軸 虚軸 1+2i 1 2 複素平面
  59. 59. 実軸 虚軸 半径1の円周上の点を 考える 単位円と呼ぶ
  60. 60. 実軸 虚軸 1+0i つまり 1
  61. 61. 実軸 虚軸 -1+0i つまり -1 1
  62. 62. 実軸 虚軸 0+i つまり i -1 1
  63. 63. 実軸 虚軸 0-i つまり -i -1 1 i
  64. 64. 実軸 虚軸 -1 1 i -i
  65. 65. 実軸 虚軸 -1 1 i -i 45°
  66. 66. 実軸 虚軸 cos45°-1 1 i -i 45° sin45°
  67. 67. 実軸 虚軸 cos45°+isin45° -1 1 i -i 45° cos45° sin45° 0.7+0.7iぐらい
  68. 68. 実軸 虚軸 cosθ+isinθ -1 1 i -i θ cosθ sinθ
  69. 69. 重大な事実 単位円上の点は回転だった
  70. 70. 実軸 虚軸 -1 1 i -i ゼロ回転
  71. 71. 実軸 虚軸 -1 1 i -i 180°回転
  72. 72. 実軸 虚軸 90°回転 -1 1 i -i
  73. 73. 実軸 虚軸 270°回転 -1 1 i -i
  74. 74. 実軸 虚軸 -90°回転 -1 1 i -i 270°と-90°は 同じ意味 もしくは
  75. 75. もっと重大な事実 点と点を掛けると回転する
  76. 76. 虚数の性質
  77. 77. 実軸 虚軸 i -1 1 i -i i は90°回転
  78. 78. 実軸 虚軸 i -1 1 i -i i は i をさらに 90°回転 2 つまり i = -12
  79. 79. 実軸 虚軸 -1 1 i -i -1 -1をさらに 180°回転 つまり (-1) = 12
  80. 80. 実軸 虚軸 0.7+0.7i -1 1 i -i
  81. 81. 実軸 虚軸 0.98i -1 1 i -i 0.7+0.7i
  82. 82. θ 実軸 虚軸 cosθ+isinθ -1 1 i -i (cosθ+isinθ) 2 回転角を足す と 複素数を掛ける は 同じ意味! cos2θ+isin2θ = 2θ
  83. 83. ところで… この方程式を解いてみよう
  84. 84. 実軸 虚軸 -1 1 i -i
  85. 85. 実軸 虚軸 -1 1 i -i から正三角形! 120°
  86. 86. 座標変換 CG オイラー角 複素数 クォータニオン
  87. 87. クォータニオン
  88. 88. 考案者はハミルトン (William Rowan Hamilton 1805-1865) 「複素平面の三次元版は 作れないものか…」
  89. 89. 虚軸を3つにすればうまくいく! i が虚数単位 クォータニオン複素数 i, j, kが虚数単位 i =-12 i =-12 j =-12 k =-12 ij=k jk=i ki=j ji=-k kj=-i ik=-j 驚愕のアイデア!
  90. 90. クォータニオンは複素数の三次元版 a+ib a+ib+jc+kd クォータニオン複素数 複素数の要素はふたつ クォータニオンの要素は4つ
  91. 91. クォータニオン要素を x, y, z, w とする ix+jy+kz+w (x, y, z, w) 実部虚部
  92. 92. 複素平面の回転軸は 固定だった
  93. 93. 立体の場合 (x, y, z) ix+jy+kz+w (x, y, z, w) 実部虚部 回転軸が 虚部のベクトル
  94. 94. 複素数の回転と クォータニオンの回転 cosθ+isinθ 複素数 cosー+nsinー 2 2 θ θ n=inx+jny+knz n(nx, ny, nz)は回転軸のベクトル クォータニオン
  95. 95. 重大な事実 あらゆる回転は ひとつの軸回転で表現できる そしてクォータニオンは 軸回転を表現する
  96. 96. クォータニオンなら 一発で決まる! あらゆる回転は ひとつの軸回転で表現できる
  97. 97. クォータニオンのテクニック
  98. 98. 便利なテクニック Slerp (Spherical Linear Interpolation):球面線形補間 transform.rotation = Quaternion.Slerp(transform.rotation, target_rotation, 0.1f); 現在の値 目標の値 適当な率
  99. 99. 凝ったテクニック バネトルク 目標との差分に比例したトルクをかける
  100. 100. 基本戦略: 目標への差分を求めて、トルクに変換する
  101. 101. 差分クォータニオンの求めかた 差分=目標の値×現在の値 -1
  102. 102. 実演 バネトルク実装例
  103. 103. 4要素の符号を反転しても 同じ回転になる (x, y, z, w) (-x, -y, -z, -w)
  104. 104. 実は回転の方向が異なる (x, y, z, w) (-x, -y, -z, -w)
  105. 105. バネトルクを完成させる テクニック wが負のときに反転すると 短い方の回転になる (x, y, z, w) (-x, -y, -z, -w)
  106. 106. 修正済みコード 追加
  107. 107. var rot = Quaternion.LookRotation(diff); 第二引数に Vector.up が省略されている var up = transform.TransformVector(Vector3.up); var rot = Quaternion.LookRotation(diff, up); 自分の姿勢から up ベクトルを作る 水平を維持しないテクニック
  108. 108. 修正済みコードその2 追加
  109. 109. デモ
  110. 110. このあと学習を続けるなら… • トルクや物理を詳しく知りたい→Unity道場札幌講演をぜひ! https://www.youtube.com/watch?v=FqjM9oujyNE&feature=youtu.be • クォータニオンの応用例を知りたい→Unite2017Tokyoをぜひ! https://www.youtube.com/watch?v=6EtTI5xC524 27分あたりから • なんで と、 になるのか気になる→ ブログ「クォータニ オンで回転を表現する定義にθ/2が使用される理由」をぜひ! http://qiita.com/yuji_yasuhara/items/a5b7c489e1d521adbd72 θ 2 cosー+nsinー 2 θ 2 θ ー
  111. 111. 参考:Inverse自前実装 虚部を反転するだけで逆クォータニオン
  112. 112. 実軸 虚軸 -1 1 i -i マメ知識 逆変換は 虚部の符号を反転 共役複素数と呼ぶ
  113. 113. おしまい

×