📖

Babylon.js を一から学習して自分の部屋の中を作る

2023/09/24に公開

今回はBabylon.jsについてお話しします。
Babylon.jsを知ったきっかけ、Babylon.jsとは、どうやって学習したのか、自分の成果物の順にお話ししていきます。

Babylon.jsを知ったきっかけ

Babylon.jsを知ったきっかけは、connpassで見つけた以下のイベントです。

https://babylonjs.connpass.com/event/276698/

元々WebGLに興味があるのでそのイベントに参加して、登壇者のLT発表を試聴したり、
実際にBabylon.jsを触ってみてすごく面白いと実感してこの日から学習し始めました。

Babylon.jsとは

Babylon.jsはMicrosoft社が開発したJavaScriptのWebGLのライブラリです。
有名なThreeJSと同じWebGLですね。
Babylon.jsはWeb上3Dゲーム開発で主に利用されているようです。

https://www.babylonjs.com/

Babylon.jsメリットデメリット

BabylonJSのメリット・デメリットについてです。

メリット

ライブエディタがある。

Babylon.jsでは以下のライブエディタがあります。
Three.jsでは以下のようなライブエディタがないので、動作確認する場合はブラウザキャッシュをしてフロント確認する必要があります。位置や色調整する場合はすごく時間がかかってしまいます。
Babylon.jsではライブエディタがあるのでブラウザキャッシュをする必要もないので便利です。

https://playground.babylonjs.com/

ファイルをモジュール化できる。

Babylon.jsではモジュール化するができます。
エディタで作成したものを「babylon format」あるいは「GLB format」を保存して、モジュール化したファイルを利用してリファクタリングすることができます。

エディタで作成したものを以下の手順で保存することができます。
まずは「Inspector」(インスペクタ)をクリックをします。

その中の「Tools」をクリックし、エクスポートすることができます。
出力形式は「babylon format」 と 「GLB format」のどちらか選べます。

すると左のようにxxx.babylonで保存され、以下のようにインポートすることができます。
このようにインポートができればコードが整理しやすくなります。

安定性がある

3つ目のメリットは安定性があるところです。
今まで利用したThree.jsと比較して感じたことは2点あります。

・パフォーマンス性が良く、表示するスピードが早い

Babylon.jsはThree.jsと比較してパフォーマンス性が良く、表示するスピードが早いと感じているところです。
自分のポートフォリオサイトはThree.jsで利用してメインビジュアルを表示してるのですが、表示速度が遅く改善方法にすごく悩みました。

・ パージョンアップされても、大きな不具合を発生することがない。

これが、Babylon.jsはThree.jsと比較して大きく感じたところです。
今まで利用したThree.jsはバージョンアップすると以前利用したプラグインが使えなくなり、フロントが正常に表示されなく なったという事象が発生したことが何回かありました。

デメリット

ThreeJsと比べると認知度が高くない

Babylon.jsはThree.jsと比べると認知度が高くないところです。
GitHub成果物を見てみるとBabylon.jsはThree.jsと比べると少ないことがわかります。
Babylon.jsのドキュメントは英語版しかなく、それが原因で認知度が低いなのではないかと考えられます。

Babylon.jsをどうやって学んだのか?

先ほどBabylon.jsのドキュメントには英語版しかないと言いましたが、
ちょまどさん(@chomado) が、公式ドキュメントから日本語版に和訳していただいたzennで投稿していたものがあり自分はそこから学習していました。
ものすごくわかりすく書いていただいているので本当に助かりました!
そちらで学習した後、公式ドキュメントでいろんなサンプルを見て学習しました。

https://zenn.dev/chomado/books/babylonjs-tutorial-ja

https://zenn.dev/chomado

自分の部屋の中を作成する。

ある程度学習したので、自分の部屋の中を作成しました。
以下のサンプルを参考にして実装しました。

ドキュメント・Playground

https://doc.babylonjs.com/features/featuresDeepDive/animation/sequenceAnimations

https://playground.babylonjs.com/#2L26P1#8

上記のサンプルのようにカメラ・ドアがアニメーション実装されています。
これは、「BABYLON.Animation」というメソッドと「beginDirectAnimation」という関数を利用して、自分自身が移動してるかのように見えます。
「BABYLON.Animation」というメソッドと「beginDirectAnimation」については公式ドキュメントから日本語版に翻訳してお話ししていきます。

基本的なアニメーション

まず、beginDirectAnimation関数を解説する前に、Babylon.jsのアニメーション実行のロジックについて解説していきます。

まず、基本的なスライドのコードはいかになります。
https://doc.babylonjs.com/features/featuresDeepDive/animation/animation_design


const frameRate = 1000;
const xSlide = new BABYLON.Animation("xSlide", "position.x", frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

const keyFrames = []; 

keyFrames.push({
    frame: 0,
    value: 2
});

keyFrames.push({
    frame: frameRate,
    value: -2
});

keyFrames.push({
    frame: 2 * frameRate,
    value: 2
});

xSlide.setKeys(keyFrames);

box.animations.push(xSlide);

scene.beginAnimation(box, 0, 2 * frameRate, true);

上記は、ボックス型のジオメトリを生成して、x位置を利用して2秒間左右ループしてアニメーション実行してるコードになります。

まずは、BABYLON.Animationメソッドを利用して、ジオメトリをx位置をスライドしてアニメーションするために以下のようにセットしていきます。

const frameRate = 1000;
const xSlide = new BABYLON.Animation("xSlide", "position.x", frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

次に、1秒ごとにアニメーションを実行させるために「フレーム (数値) と値」のキーフレームを用意して、JavaScriptオブジェクトの配列に設定します。
以下はx位置を2と設定して1秒後はx位置を-2・2秒後はx位置を2に設定して、BABYLON.Animationメソッドにそのキーフレームを引数として渡します。

const keyFrames = [];

keyFrames.push({
    frame: 0,
    value: 2,
});

keyFrames.push({
    frame: frameRate,
    value: -2,
});

keyFrames.push({
    frame: 2 * frameRate,
    value: 2,
});

xSlide.setKeys(keyFrames);

ボックスジオメトリにそのアニメーション「xSlide」の引数を渡してボックスをアニメーションさせる準備ができました。

box.animations.push(xSlide);

あとは描画するために以下のようにシーンを追加してアニメーション実行します。

scene.beginAnimation(box, 0, 2 * frameRate, true);

出力結果は以下のURLになります。
https://playground.babylonjs.com/#7V0Y1I

beginDirectAnimation関数

上記のように実行すればアニメーション実行できますが一つのジオメトリに関して同時に複数のアニメーションをすることができません。
同時に複数のアニメーションを実行させるには、beginDirectAnimationを利用していきます。
例えば、boxジオメトリにy軸回転(yRot)・x位置移動(xSlide)を同時アニメーション実行する場合は以下のように設定します。


//Position Animation
var xSlide = new BABYLON.Animation("xSlide", "position.x", frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
    
var keyFramesP = []; 

keyFramesP.push({
      frame: 0,
      value: 2
});

・・・省略

xSlide.setKeys(keyFramesP);

//Rotation Animation
var yRot = new BABYLON.Animation("yRot", "rotation.y", frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

var keyFramesR = []; 

keyFramesR.push({
      frame: 0,
      value: 0
});

  ・・・省略

yRot.setKeys(keyFramesR);

scene.beginDirectAnimation(box, [yRot, xSlide], 0, 2 * frameRate, true);
    

上記は、yRot, xSlideのアニメーションを用意してbeginDirectAnimation関数内に複数の引数を渡して、シーン作成するコードです。

その実行結果はこれになります。
https://playground.babylonjs.com/#9WUJN#16

部屋のアニメーションを作る

サンプルを参考にして自分の部屋の中のアニメーションを2週間かけて作成します。
完成したものは以下になります。

https://babylonjs-tau.vercel.app/myroom/

左にシーン作成した描画、右がメニューになります。
例えば、トイレをクリックしたら入口付近からアニメーションを開始して、トイレに移動します。

いろんなジオメトリを作成したり自分で写真を撮ってテクスチャを貼ったり、
設定したジオメトリをx・y・z位置を移動したり、x・y・zを回転したりするなど色々と調整して実行しました。

GitHubを貼っておりますのでもし興味がありましたら見てください!

https://github.com/uemura5683/babylonjs/tree/main/myroom

感想

今年初めてBabylon.Jsを触ってみて本当に面白かったです!
是非、この機会にBabylon.jsを触ってみてください!

年内か来年ごろに自分のポートフォリオサイトにBabylon.Jsを利用して何かを作成していこうと考えています!

参考サイト

https://zenn.dev/chomado/books/babylonjs-tutorial-ja

https://doc.babylonjs.com/features/featuresDeepDive/animation/animation_design

https://doc.babylonjs.com/features/featuresDeepDive/animation/combineAnimations

https://doc.babylonjs.com/features/featuresDeepDive/animation/sequenceAnimations

Discussion