夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

ゼロから始めるUnityShader開発 第九章  座標変換と回転行列

本日はShader枠です。

昨日はUnityのシェーダーで頂点シェーダーをしようして回転を行うアニメーションを実装しました。

redhologerbera.hatenablog.com

シェーダーで回転を行うことはCPUで実行されるスクリプトのUpdate関数を使用しないため比較的軽量という特徴があります。

回転には座標変換が必要で昨日は回転行列を使用しました。

今回はこの回転行列についてもっと仕組みを見ていきます。

〇回転行列と回転を行う方法

今回はきちんと数学的な意味を理解しながら回転について理解していきます。

例えば原点に存在する3Dモデルのオブジェクトを鉛直軸(上下軸)に従って90度回転させることを考えます。

 3Dモデルの回転とはすなわち3Dモデルを構成している頂点の座標を一律に変換することに等しいです。

 ここで代表的な頂点を一つ抽出して鉛直軸から見る例として原点を太陽、頂点を地球というオブジェクトに置き換えてみると次の図のようになります。

 これを90度回転させる場合は直感的な単純な計算で求めることができます。

 

 しかし例えば現実の地球のように原点(太陽)に対して地球の位置を回転させ、さらに地球に対して回転する月の位置を回転させるという例を見ると単純な計算では実行できないことがわかります。

 

月を90度回転する際は地球の座標系を意識する必要がある

 正確に月を回転を行うためには座標系を太陽ではなく地球に変換して計算を行う必要があります。

 

 このような座標返還に使用される計算が回転行列です。

〇2次元の回転行列

 まず理解をしやすくするために3次元ではなく2次元での回転行列についてみていきます。

 回転行列はゆーくりっと空間についての回転の基本的な性質から導かれています。

 原点を中心に反時計回りに角度Θで回転させると新たな位置は次のようになります。

 \displaystyle 

 x =xsin(\theta) - ycos(\theta)
  \
 \displaystyle 

    y=xsin(\theta) +   ycos(\theta)
  \

これをもう少し説明すると直交座標系における点の位置を極座標系で表すと次のようになります。

 \displaystyle 
x = rcos(φ)
  \
 \displaystyle 

y= r sin(φ)

  \

極座標系では回転角と原点からの長さで表すことができます。

3次元の極座標(球座標)

つまり原点に対してその頂点の向き(ベクトル)とその大きさでその座標を表せるという閑雅になります。

ここで点を原点に対して角度Θだけ回転させる場合当然ですが新しい角度はφ+Θになります。

よって回転後の新しい座標は次のように計算できます。

 \displaystyle 


x = rcos(φ+Θ) = rcos(φ)cos(Θ) - rsin(φ)sin(Θ) = xcos(Θ) - ysin(Θ)

  \
 \displaystyle 
y=rsin(φ+Θ)= rsin(φ)cos(Θ) + rcos(φ)sin(Θ) = xsin(Θ)+ycos(Θ)

  \

ここでの変換は数学で習う三角関数の定理を使用しています。

よって最初に紹介した座標変換の式が求められました。

これを行列形式で表すことで次のような式が導き出せます。

 \displaystyle
R_z(\theta) = 
\begin{pmatrix}
\cos(\theta) & -\sin(\theta)  \\
\sin(\theta) & \cos(\theta) \\
\end{pmatrix}  \

これが回転行列です。

では最初の例に戻りますが、太陽を基準に地球が回転しており、その地球を基準に月が回転しているような場合の回転を見ていきます。

この場合まず太陽を基準とした地球の座標返還は先ほどの式で表されます。

次に地球を原点とした座標系を考えます。

地球を基準とした月の座標系は①太陽(原点)に対して地球座標の回転座標系に変換②地球に対して月の回転座標系に変換③これらを足し合わせる

というようにして月の座標を求めることができます。

 ここでは座標変換の例を太陽、地球、月を例といてみていきましたが、CGの世界ではこのような座標変換が頻繁に使用されます。

〇3次元の場合

わかりやすくするために2次元で説明していましたが同様に3次元の場合は次のような行列になります。

 \displaystyle
R_z(\theta) = 
\begin{pmatrix}
\cos(\theta) & -\sin(\theta) & 0 \\
\sin(\theta) & \cos(\theta) & 0 \\
0 & 0 & 1
\end{pmatrix}  \

以上が座標変換とそれに使用される回転行列です。