ステンシルバッファ(マスク処理)にシェーダー適用して、部分的にモザイクさせてみました。
Live2D WebGL版と合わせるとこんな感じにできます♪
(エロゲー用の素材を持っていないので公式サンプルでテスト)
・Live2Dで部分モザイクデモ
上記デモページでは、モーション切替とモザイク箇所の切替ができます。
モザイクは一部の描画オブジェクトごとにかけられるように実装しています。
そのため、描画オブジェクトが動くとモザイク部分も動きますっ!
WebGLの技術としては、以下のものを使いました。
1)モザイクシェーダー
2)ステンシルバッファ
3)フレームバッファ
4)Live2DのWebGL描画
開発環境
・Live2D WebGL SDK 2.0.04_1
・SDKのSimpleプロジェクトをカスタム
モザイクシェーダー部分の実装
モザイクシェーダーは以下の記事を参考にさせていただきました。
・Qita - GLSLでモザイク処理
GLSLでたった4行でモザイクが実現できるのは驚きですねっ!
これをテクスチャに実装するとこんな感じです。
・WebGL-モザイク・・・モザイク適用したコード
ステンシルバッファ部分の実装
ステンシルバッファは、マスク用のテクスチャを描画し、その上に2枚目のテクスチャを描画する方法で実装しました。
マスク用のテクスチャは目の部分だけ描画してるので、目の部分だけくり抜くマスクができます。
テクスチャ描画だけでなく、三角形などの描画でもマスク用に使えてワイプエフェクトなどもできます。
テクスチャ2枚使って実装するとこんな感じです。
・WebGL-ステンシルバッファ・・・ステンシルバッファのコード
フレームバッファ部分の実装
テクスチャ1枚をフレームバッファで実装するとこんな感じです。
・WebGL-オフスクリーン・・・フレームバッファのコード
フレームバッファは描画結果を加工するために4枚使いました。
まず、Live2Dライブラリの中でステンシルもオフになっているので、フレームバッファを使わないと何もできません。
フレームバッファ1枚目:Live2D描画用
フレームバッファ2枚目:ステンシルバッファ用
フレームバッファ3枚目:モザイクシェーダー用
フレームバッファ4枚目:ステンシルとモザイク合成用
ステンシルにシェーダー適用し合成の実装
ステンシルバッファにシェーダーを適用し、テクスチャ画像と合成してみました。
カラー反転シェーダーで実装するとこんな感じになります。
・WebgL-ステンシルとポストエフェクト・・・ステンシルとエフェクト合成のコード
Live2D WebGLで実装してみる
実はLive2D SDKでは、描画オブジェクトの頂点情報が取れます。
取得できた頂点を繋いでマスク用の図形を描画しました。
・Live2D Manual - 頂点インデックスの取得
// 描画オブジェクトIDからインデックス取得
var drawIndex = live2DModel.getDrawDataIndex("描画オブジェクトID");
// 頂点位置を取得
var points = live2DModel.getTransformedPoints(drawIndex);
本当は頂点インデックスも取りたかったけど、JavaScriptではlive2dModel.getIndexArray()が見えない...orz
そのため、インデックスバッファを使わないで描画しています。
ちなみにUnityでは頂点インデックスが取れたので、JSではこの関数は存在するが暗号化されているのか取れないようです。
(Unityではこちらのコードで取れます → Qita - Live2DモデルファイルからパラメータID取得)
また、頂点情報がCanvas座標で返ってくるのでWebGL用の座標に正規化しています。
var w = live2DModel.getCanvasWidth();
var h = live2DModel.getCanvasHeight();
var p = w / h; // ModelerのCanvas縦横サイズが違うもの対応
var vertex_cnt = 0;
// 初期化
for (var j = 0; j < points.length; j+=2) {
// Canvasの解像度位置で返されるので、WebGL用に-1.0〜1.0の値に正規化
that.object_pro.object_pos[vertex_cnt] = ((points[j] * 2.0 - w) / w) * p;
that.object_pro.object_pos[vertex_cnt+1] = ((points[j + 1] * 2.0 - h) / h);
that.object_pro.object_pos[vertex_cnt+2] = 0.0;
vertex_cnt+=3;
}
頂点情報以外の部分は、前回書いたWebGLで円形ワイプエフェクトしてみたとほぼ一緒です。
これでLive2D&WebGLでエロゲが作れる事が証明できましたっ!
Live2Dでのソースコード
githubにソースをアップしたので、モデルとLive2DライブラリをDLすれば使えます。
Live2D-Mozaiku