RPGツクールMVでLive2Dを再生してみる


最初はspine を試す予定だったのですがもう再生できたみたいですね。
そこで似てるLive2Dを試してみました。
結論言うとバグありますが表示するところまでできました(アニメもします


(gif convertしたら小さい…

Live2D SDK Cubism

Live2dのwebGL版が公開されてたので組み込み簡単かなぁと思ってました。
ところがLive2Dのmocとmtnバイナリファイルのファイルフォーマットは公開されていません。
そのうえ一番重要なwebGLを使っての描画部分が圧縮されて隠蔽されてました。
ユーザーに関数詳細を意識させないという点はよいと思うのですが
実際にwebGLライブラリに組み込む場合は既存の描画系とバッティングするのは目に見えています。
unity版も見ましたが、エンジン標準の描画系から外れて非常に扱いづらい印象を受けました。
とはいえ一般ユーザや小規模事業者であれば無料なのは非常に大きなメリット。
一手間かかるもののゲームのクオリティは格段に上がることでしょう。

pixi.js v2に組み込み

ひとまずpixi.js v2のexample1-BasicsでLive2dサンプルのSimpleを動かすところから始めました。
表示はすんなりできましたがLive2DModel.draw内部でwebgl contextが書き換えられているようです。
pixi.jsはwebgl context が書き換えられてることに気付けないので表示がおかしくなるようです。
アプローチとしてはdraw 直前にpixi.js側はflushしたうえでgl contextの内容を保持してdrawのあと復帰しなくてはいけません。

gl contextの内容を保持・戻すの箇所が分からなかったので
ダミーのshader持ったPIXI.Spriteを描画して、pixi.jsにwebGL context変えてと知らせるような方法にしました(左上の黒いのがRGBSplitFilterシェーダーのやつです

RPGツクールMVに組み込み

https://dl.dropboxusercontent.com/u/7527575/qiita/Live2DTest.zip
一番上のyoutube 版のプロジェクトzipにしておきました。
pluginは登録順に気をつけないと依存関係のエラーでます(一個にまとめるべきなんでしょう
live2d.min.jsの.min.jsが拡張子と誤認されるので適当にリネームしてやります。

rpg_scene.js
Scene_Title.prototype.create = function() {
    Scene_Base.prototype.create.call(this);
    this.createBackground();
    this.createForeground();
    this.createlive2d();// 新規追加
    this.createWindowLayer();
    this.createCommandWindow();
};

Scene_Title.prototype.createlive2d = function(){
    this.live2DMgr = new LAppLive2DManager();
    this.live2DMgr.reloadFlg = true;
    this.live2DMgr.count++;

    var model = this.live2DMgr.createModel();
    model.load( Graphics._renderer.gl, LAppDefine.MODEL_HARU);
    this.addChild(model);
};

pixi.jsはScene への登録順が描画順となるのでそれっぽい箇所に挿入してやります。
エディタから実行するとなぜかエラーになりLive2Dキャラが表示されません。
index.html直接再生だと正常です(brackets からもOK
原因は分かりません。

rpg_scene.js
Scene_Title.prototype.terminate = function() {
    Scene_Base.prototype.terminate.call(this);
    SceneManager.snapForBackground();

    this.live2DMgr.releaseAll(Graphics._renderer.gl);
    Graphics._renderer.shaderManager.setShader(Graphics._renderer.shaderManager.complexPrimitiveShader);
    Graphics._renderer.gl.disable(Graphics._renderer.gl.CULL_FACE);
};

Live2Dは自前でGL texture を確保しているため、自前で解放する必要があります。
シーンを抜ける前にlive2DMgr.releaseAllしてやります。
(Pixi.jsのtextureを継承して管理してもよかったかも

setShaderは、pixi.jsにshaderが変わったことを知らせるためにわざと呼んでいます。
設定するshaderは絶対使われないダミーシェーダーにすべきですが、今回は内蔵のcomplexPrimitiveShaderでお茶を濁してます。

Live2D内部でカリングが有効になってることがあるため
gl.disable(Graphics._renderer.gl.CULL_FACE)を呼んで無効化しておきます。

その他注意点

Live2Dはtexture を作成する時に
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); //imageを上下反転
を呼んでいます。
ピクセルストレージモードの設定らしいのですが、これ以降webGLがtextureを上下反転してよみこんでしまいます。
なのでtexture作成し終わったら設定を元に戻します(PIXI.js側で反転設定使う可能性もあるので注意、普通は使わないけど
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);

ひとまずRPGツクールMVでLive2Dは再生可能と分かりました。
Live2Dの全機能を使うにはまだまだやることがありそうです。
やる気のあるwebGL使いは色々教えて下さい;