FBX SDK(Python)でunityちゃんを解析し、WebGLでアニメーションする！(WebGL編)

# FBX SDK(Python)でunityちゃんを解析し、WebGLでアニメーションする！(WebGL編)

本記事は、[FBX SDK(Python)でunityちゃんを解析し、WebGLでアニメーションする！](https://qiita.com/kota017a/items/dd0fab59c06ca72dd3f6)の記事の、WebGLでスキンメッシュアニメーションを実装する記事になります  

## [WebGL 開発支援サイト webgl.org](https://wgld.org/)を読んで、「ポリゴンのレンダリング」「テクスチャマッピング」「アルファブレンド」のやり方を理解する  

正直な話、[WebGL 開発支援サイト webgl.org](https://wgld.org/)を読んでいれば、前回の[FBX SDK(Python)を使って、unityちゃんのfbxを解析する](https://qiita.com/kota017a/items/1cdc347dec9800ae66bd)の情報だけで、スキンメッシュアニメーションを実装できるようになっているかと思います  

最終目的である「unityちゃんのfbxファイルを、Python版のFBX SDKを用いて解析し、WebGLにおいてスキンメッシュアニメーションを再生する」において、fbxファイルから必要な情報を抽出できるようになった時点で、これ以降に躓くようなポイントはほぼないでしょう...  

なので、まずは[WebGL 開発支援サイト webgl.org](https://wgld.org/)を学んで、「ポリゴンのレンダリング」「テクスチャのマッピング」「アルファブレンド」が出来るようになってください  

そこまで理解できれば、unityちゃんのモデルをWebGLで表示できるはずです  

### 注意点: unityちゃんの「cheek」のメッシュは最後に描画する

[WebGL 開発支援サイト webgl.org](https://wgld.org/)を読んでも解決しないと思われる問題があります  

「cheek」のメッシュがこんな感じの見た目になっちゃう問題です...
![チークのメッシュが真っ黒](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398708/7237287f-02cb-e5cc-d224-fbe40826d55e.png)

結論いうと、「cheek」のメッシュを最後に描画するようにすれば解決します
理由は良く分かりません...
(Z値が同一なので、描画順によってαブレンドがうまくいっていないとか？)  

## スキンメッシュアニメーションを実装する

スキンメッシュアニメーションに関しても、[「〇×(まるぺけ)つくろーどっとコム」さんの「FBX習得編」その9 ボーンの情報を取得する](http://marupeke296.com/FBX_No9_Bone.html)に書いてある通りにすれば実装できるので、ほぼ説明することはありません...
「ボーンの初期姿勢の逆行列」「ボーンのフレーム時姿勢」は既に取得できているので、これを掛け合わせた「ボーン行列」を毎フレーム計算すればいいだけです  

注意点...というほどではないですが、[WebGL 開発支援サイト webgl.org minMatrix.jsと座標変換行列](https://wgld.org/d/webgl/w013.html)で解説されている通り、WebGL(OpenGL)では、「列オーダー」になっているので掛け合わせる順序が逆になることには気を付けましょう  

ボーン行列の計算のサンプルコード(イメージ)

```javascript
var boneMatrix = [];// 計算後のボーン行列

for(var boneIndex; boneIndex < boneMatrix.length; boneIndex++>){
    var inverseInitMatrix; // 初期姿勢の逆行列
    var frameInfo;// フレーム時の姿勢行列

    // 書ける順番が逆順になっている
    m.multiply(frameInfo, inverseInitMatrix, boneMatrixs[boneIndex]);
}
```

このようにして計算したボーン行列をuniform変数としてシェーダに渡せば、スキンメッシュアニメーションが再生できます  

難しい話は特にないと思いますが、私の最終的な頂点シェーダのコードを載せておきますので、分からなくなってしまったら、この頂点シェーダを実行できるようにattribute変数やuniform変数をbind出来るように試行錯誤してみるとよいかもしれません    
<details><summary>頂点シェーダのサンプルコード</summary><div>

```html
<script id="vs" type="x-shader/x-vertex">
    // unityChanメッシュの最大値が 108なので、それが収まるような値にしておく
    const int boneMatrixNum = 128;

    attribute   vec3 position;// 頂点
    attribute   vec2 textureCoord;// uv座標
    attribute   vec4 weight;// ウェイト
    attribute   vec4 boneIndex;// ボーンインデックス
    uniform     mat4 mvpMatrix;// mvp行列
    uniform     mat4 boneMatrix[boneMatrixNum];// ボーン行列
    varying     vec2 vTextureCoord;

    void main(void){
        vTextureCoord = textureCoord;

        mat4 skinMeshMatrix = (boneMatrix[int(boneIndex[0])] * weight[0]) + (boneMatrix[int(boneIndex[1])] * weight[1]) + (boneMatrix[int(boneIndex[2])] * weight[2]) + (boneMatrix[int(boneIndex[3])] * weight[3]);
        vec4 pos = skinMeshMatrix * vec4(position, 1.0);
        gl_Position = mvpMatrix * pos;
    }
</script>
```
</div></details>

## まとめ

以上、FBX SDK 2017(Python版)を使って、unitychan.fbxから抽出した情報を用いて、WebGLでスキンメッシュアニメーションを再生する方法について説明しました  

説明した...と言いつつ、ほとんど[WebGL 開発支援サイト webgl.org](https://wgld.org/)を読んでもらうように勧めただけですが...  

これで、unityちゃんをWebGLでアニメーションさせられるようになりました！
![アニメーションする動画](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398708/72a13a7b-713e-891a-f410-be9f76fa41e8.gif)

## 備考

本記事の内容を実際に私が作成した際のソースコードを一応GitHub公開していますので、必要であれば、ご確認ください  
[ソースコード](https://github.com/kota017a/WebGLTraining_FBXSkinMeshAnimationProject)