株式会社グローバルゲート公式ブログ
こんにちは、株式会社グローバルゲートのモーリーです。
10月に開催されるマジカルミライのチケットに当選しました!!!!!
ということで(?)、今回はBabylon.jsを用いてMMDモデルを読み込み、踊らせてみようと思います。
Babylon.jsはMicrosoft製のJavascriptライブラリで、3Dモデルを高品質に描画することができ、マウスやキーボードによって画面内の物体を操作することも可能です。
他の同種のライブラリに比べると採用例は多くないものの、3DCG表現のほか、ゲームやVR(Meta QuestやApple Vision Proなど)向けコンテンツでの採用例があります。
2024年4月にVersion 7がリリースされ、なぜかMMDの読み込みが公式にサポートされました。
Microsoftのプロダクトのページに初音ミクさんがいるのがシュールすぎる
MMDは「Miku Miku Dance」の略で、元来は3Dキャラクターのモデルと体の動き、カメラのモーションを定義してアニメーションを作成するソフトウェアの名前です。
その名の通りボーカロイド楽曲のMVを簡単に作るために開発されました。
現在ではツールの名称というより3Dキャラクターを音楽にあわせて踊らせる動画のジャンルを指すことが多くなっています。
初音ミクはもちろん
伝説のアイドルとか
ウマ娘とか
Babylon.js Ver.7 ではMMDで使用する形式のキャラクター・モーション・カメラ・音楽データを読み込み表示することができるようになりました。
モデルやモーションの作成からはじめるのは難易度が高すぎるため、作成者の皆様に感謝しつつ配布されているMMDデータを利用して動かしてみようと思います。
使用する楽曲はもちろん「バビロン」しかないでしょう!
お借りしたデータ類
モデル:Sour式初音ミク
モーション: FlyingSpirits-P様
カメラ: 泯默様
音楽: トーマ様「バビロン」
まずはBabylon.js本体と関連ファイルを通常のJavascriptファイルと同じように読み込みます。
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/havok/HavokPhysics_umd.js"></script>
<script src="https://www.unpkg.com/babylon-mmd/umd/babylon.mmd.min.js"></script>
<script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
babylon.js・・・本体
HavokPhysics_umd.js・・・物理計算を行うライブラリ
babylon.mmd.min.js・・・MMDの読み込み用プラグイン
pep.js・・・タッチスクリーンでの動作を安定させるライブラリ
Babylon.jsはWebGLという技術を使い3Dを描画しますが、WebGLはHTML上ではcanvasという要素の中に描画されるため、HTML上ではcanvasタグを書いておきます。
<canvas id="renderCanvas" touch-action="none"></canvas>
そしてJavascript(外部.jsファイルにしてもHTMLに直接書いても)を書いていきます。
Babylonの初期化と実行だけを定義したものが以下の記述です。
createSchene関数の中でカメラやライトの設置、物体の生成などを行います。
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);
const createScene = async function () {
const scene = new BABYLON.Scene(engine);
//ここにいろいろ書いていく
return scene;
};
(async function () {
const scene = await createScene();
engine.runRenderLoop(async function () {
scene.render();
});
window.addEventListener("resize", function () {
engine.resize();
});
})()
3DCGを構成するために欠かせない要素はカメラ・ライト・物体の3つです。
まずはカメラを配置しましょう。
Babylon.jsではマウスやキーボード操作で自由に動かせるカメラや物体を自動で追い続けるオートフォーカスのようなカメラなどがありますが、ひとまず位置と視点も固定したベーシックなカメラであるTargetCameraを配置してみます。
const camera = new BABYLON.TargetCamera('TargetCamera', new BABYLON.Vector3(0, 0.5, -4), scene)
camera.lockedTarget = new BABYLON.Vector3(0, 0.5, 0)
明かりがないと何も見えませんのでライトを設置します。
シーン全体を明るくするHemisphericLightというライトを設置してみます。
const hemisphericLight = new BABYLON.HemisphericLight("HemisphericLight", new BABYLON.Vector3(0, 10, -10), scene);
HemisphericLightはCGの世界では環境光、一般的には地明かりと呼ばれ、方向性のない均一な光を放ちます。
Babylon.jsではこのHemisphericLightは影を作りません。
最後に物体を置いてみましょう。
初音ミクさんは一旦置いといてまずは単純な球体を置いてみます。
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {});
これで画面を見てみると、球体が表示されました。
実際の表示はこちら
ざっくりとBabylon.jsの仕組みを理解したところで、それでは本題のMMDモデルの読み込みをやっていきたいと思います。
MMDは
・キャラクターのモデル
・キャラクターのモーション
・カメラのモーション
・音源
で構成されています(背景となる「ステージ」やエフェクトデータもありますが、今回は一旦省略)
これを順番に読み込んでいきます。
MMDのモデルデータは.pmxというファイルと付随する画像データなどになっています。
今回はSour式初音ミクVer.1.02 をダウンロードし、assets/pmx(フォルダ名は任意)の中に置きました。
そしてこのpmxファイルをBABYLON.SceneLoader.ImportMeshAsyncという関数で読み込みます。
const mmdMesh = await BABYLON.SceneLoader.ImportMeshAsync(undefined, pmxModel, undefined, scene).then((result) => result.meshes[0]);
実はこの関数だけでMMDモデルを読み込み、原点に配置することができています。
実際に画面を表示させてみると直立したミクさんが表示されます。
実際の表示はこちら
モーションは.vmdという拡張子のファイルです(カメラモーションも同じ拡張子なので注意)
今回はFlyingSpirits様配布のモーションをダウンロードし、assets/vmd/の中に置きました。
モーションは以下のようにloadAsyncという関数で読み込み、読み込み済みのモデルとaddAnimationという関数で紐づけます。
const vmdLoader = new BABYLONMMD.VmdLoader(scene);
const modelMotion = await vmdLoader.loadAsync("model_motion", vmdModel);
const mmdRuntime = new BABYLONMMD.MmdRuntime();
mmdRuntime.register(scene);
const mmdModel = mmdRuntime.createMmdModel(mmdMesh);
mmdModel.addAnimation(modelMotion);
mmdModel.setAnimation("model_motion");
StreamAudioPlayer というクラスで音楽プレイヤーを定義し、そのクラスに対してsourceという属性で音楽ファイルを指定します。
mp3, .ogg, .wav, .m4a, .mp4が対応していますが、mp3かwavが無難だと思います。
const audioPlayer = new BABYLONMMD.StreamAudioPlayer(scene);
audioPlayer.source = wavModel;
はじめに位置と視点を固定したカメラの設置を試しましたが、MMD用のカメラは違う記述が必要になります。
通常のカメラのための記述はコメントアウトし、MMD用にBABYLONMMD.MmdCameraという関数でカメラ定義を行います。
//通常のカメラ
// const camera = new BABYLON.TargetCamera('TargetCamera', new BABYLON.Vector3(0, 10, -40), scene)
// camera.lockedTarget = new BABYLON.Vector3(0, 10, 0)
//MMDのカメラモーション
const camera = new BABYLONMMD.MmdCamera("mmdCamera", new BABYLON.Vector3(0, 10, 0), scene);
そしてそのカメラとカメラモーションを関連付けます。
mmdRuntime.setCamera(camera);
const cameraMotion = await vmdLoader.loadAsync("camera_motion", camModel);
camera.addAnimation(cameraMotion);
camera.setAnimation("camera_motion");
最後にPlayAnimationという関数を実行すればアニメーションが再生されます。
mmdRuntime.playAnimation();
完成品はこちら!
(音量注意&通信量注意!)
初回読み込み時はミュートになっている可能性があります。下段の音量ボタンをクリックしてミュートを解除してお楽しみください。
無事ミクさんをブラウザ上で踊らせることに成功しました。
ですが今回のモーションと音楽データの合計は約80MBにもなり、レンダリングのクオリティもYoutubeで見るMMDと比べると粗さが目立ちます。
単に動画を見せたいのであればmp4で動画ファイルを用意したりYoutubeにアップロードして見せるほうが安定します。
VRチャットや3DのブラウザゲームなどでMMDの資産を有効活用するとか3Dモデル配布時のプレビュー用途など…果たしてどのような使い道があるのか、MMDerの発想に期待しましょう。
ということで、今回はBabylon.jsを使ってMMDモデルとモーション、音楽データを読み込み、踊らせるまでをやってみました。
ブラウザ上でミクさんが歌って踊ってくれるのは最高です。
Babylon.js自体はMMDに限らない汎用的な3D表現のためのライブラリですので、Webサイトの表現として取り入れるのも面白いかもしれません(実際にThree.jsという同種のライブラリは3D表現を取り入れたWebサイトでよく使われています)
これからも様々な表現を模索していきたいと思います。
【関連記事】
カテゴリー
月別アーカイブ
ブログ内検索
執筆メンバーについて
モーリー
Webデザイナー。
当サイトのデザインと管理も担当しています。
ナミー
Webディレクター。
本社制作部の紅一点。お客様に寄り添った提案を心かげています。
タカ
サーバーエンジニア。
Webサイトにとってサーバーは命、ネットワークは血液です。Webサイトの安定稼働のために日夜注力しています。
たっくん
ITアドバイザー
Webサイトの活用方法からオフィスのネットワーク整備まで、多角的にITの活用方法をご案内させていただきます。
ノーさん
制作部ディレクター。
業種を問わず多くのお客様を担当させていただきました。Webサイトのお悩み、活用方法などぜひご相談ください。
カン
制作部デザイナー。
制作部最年少の若手ですが、だからこそ生まれるアイデア・発想にご期待ください。
当社サービスについてのお問い合わせは下記までご連絡下さい。
06-6121-7581 / 03-6415-8161