LoginSignup
34
32

More than 5 years have passed since last update.

WebGLでエロゲー風に部分モザイクしてみた

Last updated at Posted at 2015-09-13

ステンシルバッファ(マスク処理)にシェーダー適用して、部分的にモザイクさせてみました。
Live2D WebGL版と合わせるとこんな感じにできます♪
(エロゲー用の素材を持っていないので公式サンプルでテスト)
001.gif
・Live2Dで部分モザイクデモ

上記デモページでは、モーション切替とモザイク箇所の切替ができます。
モザイクは一部の描画オブジェクトごとにかけられるように実装しています。
そのため、描画オブジェクトが動くとモザイク部分も動きますっ!
002.png

WebGLの技術としては、以下のものを使いました。
1)モザイクシェーダー
2)ステンシルバッファ
3)フレームバッファ
4)Live2DのWebGL描画

開発環境

・Live2D WebGL SDK 2.0.04_1
・SDKのSimpleプロジェクトをカスタム

モザイクシェーダー部分の実装

モザイクシェーダーは以下の記事を参考にさせていただきました。
・Qita - GLSLでモザイク処理

GLSLでたった4行でモザイクが実現できるのは驚きですねっ!
これをテクスチャに実装するとこんな感じです。
003.png
・WebGL-モザイク・・・モザイク適用したコード

ステンシルバッファ部分の実装

ステンシルバッファは、マスク用のテクスチャを描画し、その上に2枚目のテクスチャを描画する方法で実装しました。
マスク用のテクスチャは目の部分だけ描画してるので、目の部分だけくり抜くマスクができます。
テクスチャ描画だけでなく、三角形などの描画でもマスク用に使えてワイプエフェクトなどもできます。

テクスチャ2枚使って実装するとこんな感じです。
004.png
・WebGL-ステンシルバッファ・・・ステンシルバッファのコード

フレームバッファ部分の実装

テクスチャ1枚をフレームバッファで実装するとこんな感じです。
・WebGL-オフスクリーン・・・フレームバッファのコード

フレームバッファは描画結果を加工するために4枚使いました。
まず、Live2Dライブラリの中でステンシルもオフになっているので、フレームバッファを使わないと何もできません。

 フレームバッファ1枚目:Live2D描画用
 フレームバッファ2枚目:ステンシルバッファ用
 フレームバッファ3枚目:モザイクシェーダー用
 フレームバッファ4枚目:ステンシルとモザイク合成用

ステンシルにシェーダー適用し合成の実装

ステンシルバッファにシェーダーを適用し、テクスチャ画像と合成してみました。
カラー反転シェーダーで実装するとこんな感じになります。
005.png
・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

34
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
32