はりうすブログ (のすけのメモ)

湘南にある小さな会社 代表 ”のすけ”のブログです

babylon.jsで3D表現の初めの一歩

f:id:hollywis:20200619121440p:plain

こんにちは

どうしても3Dでゲームっぽい物をWeb上で作りたくて、ここ数ヶ月Three.jsを勉強していたのですが、、

どうやらゲームを作るにはbabylon.jsの方が良さそうです。

なぜ、Three.jsではダメなのか?

それは純粋な3D表現ツールだからです。

  • キャラクターが簡単には歩いたりはしない
  • 地面もただの平面オブジェクト
  • 重力は自前でプログラミング

などなど。


何ていうか・・・・全て自作が前提なのです。

Unityであるように、重力を付与するモジュールとか無いです。

誰かが作ってるかもしれないけれど、公式では無いです。

これがとても辛いです。(あったら御免なさい。教えていただきたいです)



ぽぽん!とゲーム作りたい!


じゃあUnityやりなさいよ!!


という話なのですが、どうやらWeb上では動作が遅いらしく家庭用ゲーム機とかPCやスマホにインストールする形式じゃ無いと辛いらしいです(未検証)


あとは、JSで動かしたいんだ!!既存のWebサービスにシームレスに組み込みたいんだ!という話です。


そこで検討したのが、babylon.js(バビロンジェイエス)名前が、人類の愚かさの象徴であるバベルの塔を作り出したバビロンということで、全然いけてないのがとても気になるのですが。。。

f:id:hollywis:20200619113925j:plain
バベルの塔

果たして、これは目的の物なのか、、


頑張って検証していきます。


www.babylonjs.com


f:id:hollywis:20200619114011p:plain

執筆時点の最新版は4.1です。

Microsoftのエンジニアが作った物らしく、フリーで使えますし、定期的にアップデートもされており、良さげです。

Microsoftと言えばマインクラフト!!

きっとマインクラフトみたいな物も、簡単に作れるんじゃないかと予想していますw

f:id:hollywis:20200619114348j:plain


ただ、babylon.jsにも、一つも問題が。。。。


それは、、、


babylonには日本語のドキュメントが一切ない!! 書籍もない!!


ということです。

Three.jsには素晴らしい書籍がありました。


初めてのThree.js 第2版 ―WebGLのためのJavaScript 3Dライブラリ

初めてのThree.js 第2版 ―WebGLのためのJavaScript 3Dライブラリ

  • 作者:Jos Dirksen
  • 発売日: 2016/07/23
  • メディア: 単行本(ソフトカバー)


ですが、babylon.jsにはありません。

なので、このブログで説明しつつ、頑張って使っていきたいと思います。




それでは使っていきましょう。

なお、Three.jsがある程度使える方を前提に買いていきます!

もし、分からない場合は、コチラのThree.jsの書籍を買って、基本的なWebにおける3D表現のお作法を学んだ方がいいかもしれません。

初めてのThree.js 第2版 ―WebGLのためのJavaScript 3Dライブラリ

初めてのThree.js 第2版 ―WebGLのためのJavaScript 3Dライブラリ

  • 作者:Jos Dirksen
  • 発売日: 2016/07/23
  • メディア: 単行本(ソフトカバー)

まず球体を置いてみる

コード全容

まずは、コード全容です

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">

    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>Babylon Template</title>

        <style>
            html, body {
                overflow: hidden;
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
            }

            #renderCanvas {
                width: 100%;
                height: 100%;
                touch-action: none;
            }
        </style>

        <script src="https://preview.babylonjs.com/babylon.js"></script>
        <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
        <script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
    </head>

   <body>

    <canvas id="renderCanvas" touch-action="none"></canvas> <!-- touch-action="none" for best results from PEP -->

    <script>
        var canvas = document.getElementById("renderCanvas"); // Get the canvas element
        var engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

        /******* Add the create scene function ******/
        var createScene = function () {

            // Create the scene space
            var scene = new BABYLON.Scene(engine);

            // Add a camera to the scene and attach it to the canvas
            var camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new BABYLON.Vector3(0,0,5), scene);
            camera.attachControl(canvas, true);

            // Add lights to the scene
            var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), scene);
            var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(0, 1, -1), scene);

            // Add and manipulate meshes in the scene
            var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter:2}, scene);

            return scene;
        };
        /******* End of the create scene function ******/

        var scene = createScene(); //Call the createScene function

        // Register a render loop to repeatedly render the scene
        engine.runRenderLoop(function () {
                scene.render();
        });

        // Watch for browser/canvas resize events
        window.addEventListener("resize", function () {
                engine.resize();
        });
    </script>

   </body>

</html>

解説

まず、この部分

<canvas id="renderCanvas" touch-action="none"></canvas>

これはcanvasタグをidを付けて置いているだけです。


<style>
            html, body {
                overflow: hidden;
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
            }

            #renderCanvas {
                width: 100%;
                height: 100%;
                touch-action: none;
            }
        </style>

スタイルシートで全画面表示しています。

<script src="https://preview.babylonjs.com/babylon.js"></script>
        <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
        <script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>

babylon.jsと、babylonjs.loaders.min.jsの本体とローダの読み込み。

そして、スマホでタップを取り扱いたい場合はpep.jsも読み込んであげます。

        var canvas = document.getElementById("renderCanvas"); // Get the canvas element
        var engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

キャンバス要素をID指定で取得して、それをバビロン3Dエンジンに紐付けます!

この3Dエンジンにいろいろ、要素を追加していくことになります。


/******* Add the create scene function ******/
        var createScene = function () {

            // Create the scene space
            var scene = new BABYLON.Scene(engine);

            // Add a camera to the scene and attach it to the canvas
            var camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new BABYLON.Vector3(0,0,5), scene);
            camera.attachControl(canvas, true);

            // Add lights to the scene
            var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), scene);
            var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(0, 1, -1), scene);

            // Add and manipulate meshes in the scene
            var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter:2}, scene);

            return scene;
        };
        /******* End of the create scene function ******/

        var scene = createScene(); //Call the createScene function

3D表現では、シーンという概念を扱います。

一つの画面表現をシーンとして扱うのですね。

で、

var scene = new BABYLON.Scene(engine);

でシーンを新しく作ります。もちろんバビロン3Dエンジンを使います。

// Add a camera to the scene and attach it to the canvas
            var camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new BABYLON.Vector3(0,0,5), scene);
            camera.attachControl(canvas, true);

次に、カメラの追加です。

今回は、「ArcRotateCamera」です。球形に回転するカメラですね。

場所はVector3型でz軸に5個進んだところに配置です。(手前に5歩って感じでしょうか)

そのほかにも、いろいろカメラがあるっぽいですが。それは別の記事で

// Add lights to the scene
            var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), scene);
            var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(0, 1, -1), scene);

ライトの追加です。2個追加してますね。

一つは、「HemisphericLight」ヘミソフィックライト(環境光)ですね。
場所はVector3型でx軸(左)に1, y軸(上)に1, z軸に0の場所に配置です。

もう一つは「PointLight」スポットライトみたいなやつでしょうか。
場所はVector3型で上奥に設置してますね。

// Add and manipulate meshes in the scene
            var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter:2}, scene);

球体(sphere)のプリミティブの配置です。

 var scene = createScene(); //Call the createScene function

でこの関数を実行していると。

        // Register a render loop to repeatedly render the scene
        engine.runRenderLoop(function () {
                scene.render();
        });

で、このエンジンを使ってレンダリングするわけですが

それをループさせてシーンの描画を繰り返します。

そうすることでアニメーションとか、カメラの位置変更が常に反映されるようになります。

        // Watch for browser/canvas resize events
        window.addEventListener("resize", function () {
                engine.resize();
        });

おまけで、ウィンドウサイズのリサイズ対応ですね。

Three.jsなら自前で各所をbabylonならengine.resize();で一撃です。便利

整理

  1. まずライブラリを読み込む
  2. HTMLにcanvasを作っておく
  3. 3Dエンジンを起動!
  4. canvasと3Dエンジンを紐付け
  5. シーン作成!!
  6. シーンには「カメラ」と「ライト」と「物体」をVector3型で設置!!
  7. ループ処理を設置
  8. リサイズ対応も書いとく

この順番を覚えておきましょう!

Three.jsよりちょっとだけシンプルかな。

感想

いけそう!

Three.jsを学んだあとなら、babylon.jsは簡単そうな気がする

どんどんブログにあげていこうと思います



追記:Three.jsでもPointerLockカメラというのがあって

それを使えばマイクラフト的な視点のカメラはできるっぽい。

https://threejs.org/examples/#misc_controls_pointerlock


あとは、Physijsというライブラリを使うと物理演算を導入することができるっぽい!!

この辺りも検証したい

hollywis.hatenablog.com