株式会社グローバルゲート公式ブログ

Babylon.js Ver.7を使ってMMDモデルとモーションを読み込み初音ミクさんを踊らせる

こんにちは、株式会社グローバルゲートのモーリーです。  
 
10月に開催されるマジカルミライのチケットに当選しました!!!!! 
 
 
 
ということで(?)、今回はBabylon.jsを用いてMMDモデルを読み込み、踊らせてみようと思います。 

Babylon.jsとは

Babylon.jsはMicrosoft製のJavascriptライブラリで、3Dモデルを高品質に描画することができ、マウスやキーボードによって画面内の物体を操作することも可能です。
他の同種のライブラリに比べると採用例は多くないものの、3DCG表現のほか、ゲームやVR(Meta QuestやApple Vision Proなど)向けコンテンツでの採用例があります。 
 
2024年4月にVersion 7がリリースされ、なぜかMMDの読み込みが公式にサポートされました。 

Microsoftのプロダクトのページに初音ミクさんがいるのがシュールすぎる

MMDとは

MMDは「Miku Miku Dance」の略で、元来は3Dキャラクターのモデルと体の動き、カメラのモーションを定義してアニメーションを作成するソフトウェアの名前です。 
その名の通りボーカロイド楽曲のMVを簡単に作るために開発されました。 
 
現在ではツールの名称というより3Dキャラクターを音楽にあわせて踊らせる動画のジャンルを指すことが多くなっています。

初音ミクはもちろん

伝説のアイドルとか

ウマ娘とか

Babylon.jsでMMDモデルを読み込んで踊らせるまで

Babylon.js Ver.7 ではMMDで使用する形式のキャラクター・モーション・カメラ・音楽データを読み込み表示することができるようになりました。 
 
モデルやモーションの作成からはじめるのは難易度が高すぎるため、作成者の皆様に感謝しつつ配布されているMMDデータを利用して動かしてみようと思います。

使用する楽曲はもちろん「バビロン」しかないでしょう!

お借りしたデータ類 
モデル:Sour式初音ミク 
モーション: FlyingSpirits-P様
カメラ: 泯默様
音楽: トーマ様「バビロン」

HTML 

まずは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は 
 
・キャラクターのモデル 
・キャラクターのモーション 
・カメラのモーション 
・音源 

 
で構成されています(背景となる「ステージ」やエフェクトデータもありますが、今回は一旦省略) 
 
これを順番に読み込んでいきます。 

モデルデータの読み込み

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サイトでよく使われています) 
 
これからも様々な表現を模索していきたいと思います。

【関連記事】

ご相談・お問い合わせ

当社サービスについてのお問い合わせは下記までご連絡下さい。

お電話でのお問い合わせ

06-6121-7581 / 03-6415-8161