この記事はWebGL Advent Calendar 2016の24日目の記事です。
たまたま空いてたのでWebGLの軽いネタを書こうかと。
pixi.jsのLive2Dプラグインを作ってたら、すでに作ってる人がいたので使ってみました。
中身のソース見てたら自分と同じく、オフスクリーンにLive2D描画しSpriteのテクスチャとしてました。
pixi.jsを使う事でお手軽に雪降るシーンが作れてクリスマスっぽくできましたっ!
pixi.js(WebGL)と組み合わせてクリスマスシーンできた! pic.twitter.com/e5jvZcz4dK
— naotaro (@naotaro0123) 2016年12月24日
開発環境
Live2D WebGL SDK2.1
Pixi.js v4.1.1
Pixi-live2dプラグイン
導入方法
Pixi-live2dはnpmにも公開されてるので、パチパチとnpmコマンドを打っていけば簡単に導入できます。
1)ターミナルを開いて、まずは作業フォルダを作ります
# npm initコマンドで怒られないように大文字は使わない
mkdir pixi_live2d
cd pixi_live2d
2)npmコマンドで必要なライブラリをインストール
pixi.jsはv4.2.1以上だと仕様が変わったようで、activeTexture切り替えエラーで描画できなかった...。
そのため、pixi.jsはver.4.1.1をインストールします
# initコマンド実行後に色々と聞かれるがEnter連打
npm init
# pixi.jsをインストール
npm install pixi.js@4.1.1
# pixi-live2dをインストール
npm install pixi-live2d
# webpackをインストール
npm install webpack
3)Live2D SDKからLive2d.min.jsをコピーしてくる
# libフォルダを作り、live2d.min.jsをおく
mkdir lib
4)Live2D SDKからLive2Dモデルをコピーしてくる
# assetsフォルダを作り、Live2Dモデルファイルをおく
mkdir assets
5)webpackでライブラリのjsをまとめる
# webpackの設定ファイルを作る
touch webpack.config.js
中身は以下の通りでwebpackコマンド実行後にbundle.jsが出力されます
module.exports = {
entry :{
lib: ['./lib/live2d.min.js',
'./node_modules/pixi.js/bin/pixi.min.js',
'./node_modules/pixi-live2d/dist/index.js',
]
},
output : {
filename : './lib/bundle.js'
}
};
# webpackコマンド実行し、bindle.jsを生成
webpack
6)index.htmlとindex.jsを作成し、以下のように記述する。
このあたりはpixi-live2dのサンプルとほぼ同じです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Live2D Core Library -->
<!--<script src="lib/live2d.min.js"></script>-->
<!--<script src="node_modules/pixi.js/bin/pixi.min.js"></script>-->
<!--<script src="node_modules/pixi-live2d/dist/index.js"></script>-->
<script src="lib/bundle.js"></script>
<title>pixi-live2d</title>
</head>
<body>
<div id="app"></div>
<!-- User Script -->
<script src="index.js"></script>
</body>
</html>
7)index.jsを作成し、以下のようにする
これもpixi-live2dのサンプルのほぼコピペ
// レンダラーの生成
const renderer = new PIXI.WebGLRenderer(800, 600);
document.getElementById('app').appendChild(renderer.view);
// ステージの生成
const stage = new PIXI.Container();
// Live2Dのモデル定義
const modelHaru = {
"type":"Live2D Model Setting",
"name":"haru",
"model":"assets/haru/haru_01.moc",
"textures":
[
"assets/haru/haru_01.1024/texture_00.png",
"assets/haru/haru_01.1024/texture_01.png",
"assets/haru/haru_01.1024/texture_02.png"
],
"physics":"assets/haru/haru.physics.json",
"pose":"assets/haru/haru.pose.json",
"expressions":
[
{"name":"f01","file":"assets/haru/expressions/f01.exp.json"},
{"name":"f02","file":"assets/haru/expressions/f02.exp.json"},
{"name":"f03","file":"assets/haru/expressions/f03.exp.json"},
{"name":"f04","file":"assets/haru/expressions/f04.exp.json"},
{"name":"f05","file":"assets/haru/expressions/f05.exp.json"},
{"name":"f06","file":"assets/haru/expressions/f06.exp.json"},
{"name":"f07","file":"assets/haru/expressions/f07.exp.json"},
{"name":"f08","file":"assets/haru/expressions/f08.exp.json"}
],
"layout":
{
"center_x": 0,
"y": 1.2,
"width": 2.9
},
"hit_areas":
[
{"name":"head", "id":"D_REF.HEAD"},
{"name":"body", "id":"D_REF.BODY"}
],
"motions":
{
"idle":
[
{"file":"assets/haru/motions/idle_00.mtn" ,"fade_in":2000, "fade_out":2000},
{"file":"assets/haru/motions/idle_01.mtn" ,"fade_in":2000, "fade_out":2000},
{"file":"assets/haru/motions/idle_02.mtn" ,"fade_in":2000, "fade_out":2000}
],
"tap_body":
[
{ "file":"assets/haru/motions/tapBody_00.mtn" , "sound":"assets/haru/sounds/tapBody_00.mp3"},
{ "file":"assets/haru/motions/tapBody_01.mtn" , "sound":"assets/haru/sounds/tapBody_01.mp3"},
{ "file":"assets/haru/motions/tapBody_02.mtn" , "sound":"assets/haru/sounds/tapBody_02.mp3"}
],
"pinch_in":
[
{ "file":"assets/haru/motions/pinchIn_00.mtn", "sound":"assets/haru/sounds/pinchIn_00.mp3" }
],
"pinch_out":
[
{ "file":"assets/haru/motions/pinchOut_00.mtn", "sound":"assets/haru/sounds/pinchOut_00.mp3" }
],
"shake":
[
{ "file":"assets/haru/motions/shake_00.mtn", "sound":"assets/haru/sounds/shake_00.mp3","fade_in":500 }
],
"flick_head":
[
{ "file":"assets/haru/motions/flickHead_00.mtn", "sound":"assets/haru/sounds/flickHead_00.mp3" }
]
}
};
// Live2DのSpriteを生成
const live2dSprite = new PIXI.Live2DSprite(modelHaru, {
debugLog: false,
randomMotion: false,
eyeBlink: false,
});
stage.addChild(live2dSprite);
// 位置調整
live2dSprite.x = -105;
// live2dSprite.y = -150;
// スケール
live2dSprite.adjustScale(0,0,0.7);
// 移動
live2dSprite.adjustTranslate(0.4, 0);
// ランダムモーション
live2dSprite.startRandomMotion('idle');
// マウス操作
live2dSprite.on('mousemove', (evt) => {
const point = evt.data.global;
live2dSprite.setViewPoint(point.x, point.y);
});
function animate() {
requestAnimationFrame(animate);
renderer.render(stage);
}
animate();
8)実行結果
これでpixi.js上にLive2Dが描画できました!
詳しいAPIの使い方はpixi-live2d APIを見ると良いです。
目パチやリップシンクなどtrue/falseを渡すだけでON/OFFできるようですね。
ソースコード
以下のサイトを参考に雪を降らせたソースもgithubにアップしておきました。
・pixi.jsを使って雪を降らせてみた。
・github - Live2D-Pixijs-Test
pixi.jsは、stageごとにブラーフィルタかけられるのは便利ですね。
これで簡単にインタラクティブなサイトが作れそうな気がします!
では、よいクリスマスをお過ごしください!