WebGL Lib 2019/04/24
進捗
## ボーンスキニング
実行⇒[ボーンスキニングのテスト](index.html)
* CPUサイドのロジックを実装したのでそのテスト。BDEF4。
* スキニングに対応したシェーダがまだなので上記のテストは WebGL ではなく Canvas2D (内部的には3Dデータ)
* このままシェーダを書こうかと思ったけれど、データの入力が面倒になってきたので、次はモデルデータの読み込みか。
## その他
* Canvas 要素周りのユーティリティに徐々に着手していく
* 固定サイズ, レスポンシブ, 全画面を切り替えられるように
* デバッグ用の情報をオーバーレイ表示できるように。
* 以前 2D でテストしていたカーブに沿った変形は、
3D に持ち込むと回転が消えてしまうことに気づき一旦お蔵入り。
## メモ
各ジョイント(ボーン)は、
ジョイント座標からモデル座標に変換する <span role="math">B</span> (bind matrix) と、
各ジョイントの局所変換行列 <span role="math">L</span> を持つ。
各ジョイントの変換行列 <span role="math">J</span> (joint matrix) は、
根から対象ジョイントまでの添え字を 0 から i としたとき、 次のように求められる。
~~~math
J = B_0 L_0 B^{-1}_0 \cdots B_i L_i B^{-1}_i
~~~
シェーダでは、1..4個程度の joint matrix に、ウェイト<span role="math">w_i</span>を掛けたものをスキニング行列 <span role="math">S</span> とする。
~~~math
S = w_0 J_0 + w_1 J_1 + w_2 J_2 + w_3 J_3
~~~
基本的には、ウェイトの合計は 1。
~~~math
\sum_i w_i = 1
~~~
モデル変換行列を <span role="math">M</span>,
ビュー変換行列を <span role="math">V</span>,
プロジェクション行列を <span role="math">P</span>,
入力頂点座標を <code role="math">\bm{p}_{\tt model}</code>,
入力頂点法線を <code role="math">\bm{n}_{\tt model}</code>,
とすると、バーテックスシェーダで行うべきことは、以下相当。
~~~math
\begin{aligned}
S & = w_0 J_0 + w_1 J_1 + w_2 J_2 + w_3 J_3 \\
M' & = M \times S \\
\bm{p}_{\tt world} & = M' \times \bm{p}_{\tt model} \\
N &= M'_{44} \in \Reals^{3 \times 3}\\
\bm{n}_{\tt world} & = (N^{-1})^T \times \bm{n}_{\tt model} \\
\bm{p}_{\tt project} & = P \times V \times \bm{p}_{\tt world} \\
\end{aligned}
~~~
拡大縮小を使う場合、skin matrix はそのまま法線に適用できないので逆転置行列が要る。
3x3 なら軽めに求められるので、動的に計算してしまってよいような気がする。
法線用の joint matrix を別途受け渡すのはコストが高そう。
### メモのメモ
インライン数式を書くときは span じゃなくて code じゃないと、showdown の変換と衝突するようだ...。