babylon.js ステップ6 カメラ
babylon.jsにはよく使われる2つのカメラがあります。
一つは1人称視点のユニバーサルカメラ(the Universal Camera)、
もう一つはアークカメラ(Arc Rotate Camera)です。
まずカメラのコントロールを可能にしましょう
camera.attachControl(canvas, true);
ユニバーサルカメラ Universal Camera
ユニバーサルカメラはキーボード、タッチ、ゲームパッドに対応したカメラです。
これはFreeCamera,Touch Camera, Gamepad Cameraの上位互換です。
ユニバーサルカメラを使うとFPSっぽい一人称視点を得られます。
それぞれの入力方法のデフォルト設定は次の通り
- キーボード・・・上下左右キー
- マウス・・・視点を回転
- タッチ操作・・・上下左右にスワイプ
コード
// Parameters : name, position, scene var camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene); // Targets the camera to a particular position. In this case the scene origin camera.setTarget(BABYLON.Vector3.Zero()); // Attach the camera to the canvas camera.attachControl(canvas, true);
アーク回転カメラ(Arc Rotate Camera)
このカメラは常に所定のターゲット位置を指し、ターゲットを回転の中心としてそのターゲットを中心に回転できます
カーソルとマウス、またはタッチイベントで制御できます。
このカメラは、その目標位置を周回するカメラ、またはより想像力で地球を周回するスパイ衛星と考えてください。ターゲット(地球)に対するその位置は、アルファ(ラジアン)縦回転、ベータ(ラジアン)緯度回転、および ターゲット位置からの距離の半径の3つのパラメーターで設定できます。
コード
// Parameters: alpha, beta, radius, target position, scene var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene); // Positions the camera overwriting alpha, beta, radius camera.setPosition(new BABYLON.Vector3(0, 0, 20)); // This attaches the camera to the canvas camera.attachControl(canvas, true);
フォローカメラ(FollowCamera)
実際に触ってもらった方が早いため例を見てください。
ターゲットとなるメッシュを追随するように設定出来ます
操作例:
https://www.babylonjs-playground.com/#SRZRWV#6
コード
// Parameters: name, position, scene var camera = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 10, -10), scene); // The goal distance of camera from target camera.radius = 30; // The goal height of camera above local origin (centre) of target camera.heightOffset = 10; // The goal rotation of camera around local origin (centre) of target in x y plane camera.rotationOffset = 0; // Acceleration of camera in moving from current to goal position camera.cameraAcceleration = 0.005 // The speed at which acceleration is halted camera.maxCameraSpeed = 10 // This attaches the camera to the canvas camera.attachControl(canvas, true); // NOTE:: SET CAMERA TARGET AFTER THE TARGET'S CREATION AND NOTE CHANGE FROM BABYLONJS V 2.5 // targetMesh created here. camera.target = targetMesh; // version 2.4 and earlier camera.lockedTarget = targetMesh; //version 2.5 onwards
その他のカメラ
デバイス回転カメラ(Device Orientation Camera)
・・・デバイスの方向を取得して反映する
例はこちら
https://www.babylonjs-playground.com/#SRZRWV#3
バーチャルジョイスティックカメラ(Virtual Joysticks Camera)
画面上にジョイスティックを表示する
例はこちら
www.youtube.com
WebVR Free Camera
Use the WebVR Camera - Babylon.js Documentation
飛行カメラ(FlyCamera)
WSADキーで動きます
// Parameters: name, position, scene var camera = new BABYLON.FlyCamera("FlyCamera", new BABYLON.Vector3(0, 5, -10), scene); // Airplane like rotation, with faster roll correction and banked-turns. // Default is 100. A higher number means slower correction. camera.rollCorrect = 10; // Default is false. camera.bankedTurn = true; // Defaults to 90° in radians in how far banking will roll the camera. camera.bankedTurnLimit = Math.PI / 2; // How much of the Yawing (turning) will affect the Rolling (banked-turn.) // Less than 1 will reduce the Rolling, and more than 1 will increase it. camera.bankedTurnMultiplier = 1; // This attaches the camera to the canvas camera.attachControl(canvas, true);
babylon.js ステップ5 マテリアル
マテリアルを使用すると、メッシュを色とテクスチャで覆うことができます。
なお、メッシュを表示するには光が必要です。
拡散マテリアル(Diffuse)と鏡面マテリアル(Specular)では、光源を作成する必要があります。
いきましょう!
色
まずは、StandardMaterialでいきます。
var myMaterial = new BABYLON.StandardMaterial("myMaterial", scene); myMaterial.diffuseColor = new BABYLON.Color3(1, 0, 1); myMaterial.specularColor = new BABYLON.Color3(0.5, 0.6, 0.87); myMaterial.emissiveColor = new BABYLON.Color3(1, 1, 1); myMaterial.ambientColor = new BABYLON.Color3(0.23, 0.98, 0.53); mesh.material = myMaterial;
BABYLON.Color3はそれぞれ、赤、緑、青を0~1の間で設定します。0がなし、1が一番強い状態です。
- diffuseColorは拡散色(光に対して反射する基本の色)
- specularColorは鏡面反射(ハイライト的な反射)
- emissiveColorは影の色(そのメッシュ自身がその色で反射する)
- ambientColor 環境光の反射。シーンのアンビエントカラーが設定されている場合にのみ適用される
そして、定義してマテリアルは、mesh.materialでマテリアルを設定していきます
myMaterial.alpha = 0.5;
aplhaで透明度を変えられる
テクスチャ
メッシュに対して、画像を張れる.
var myMaterial = new BABYLON.StandardMaterial("myMaterial", scene); myMaterial.diffuseTexture = new BABYLON.Texture("PATH TO IMAGE", scene); myMaterial.specularTexture = new BABYLON.Texture("PATH TO IMAGE", scene); myMaterial.emissiveTexture = new BABYLON.Texture("PATH TO IMAGE", scene); myMaterial.ambientTexture = new BABYLON.Texture("PATH TO IMAGE", scene); mesh.material = myMaterial;
まとめ
メッシュに対して、設定できるマテリアルについて紹介しました。
色マテリアルの場合は、まず光Lightをシーンに設定した上で
それぞれ、拡散光、鏡面反射、自身の発光、環境光を設定出来ました。
また、画像テクスチャを貼ることも出来ます。
そして、ワイヤフレーム表示もマテリアルで行いました。
次はカメラです。
babylon.js ステップ4 位置、回転、スケーリング
babylon.js やってみようシリーズのステップ4
位置、回転、スケーリングのお話です
位置の話
babylon.jsには2つの座標系があります
- ワールド座標系
- ローカル座標系
ワールド座標系
ワールド座標系の原点は変わりません。
通常、メッシュが作成されると、その中心はワールド軸の原点に配置されます。
移動しても、ワールド座標系はそのワールドの中心(原点)を元に判断されます
ローカル座標系
ローカル軸はメッシュの場所によって動きます。
でもローカル軸の原点は、ワールド座標における位置に関係なく、常にメッシュの作成された中心にあります。
初期状態
ワールド座標とローカル座標は一致しますが
メッシュが動くとズレることになります。
配置
mesh(メッシュ)に対して positionで位置を設定出来ます
mesh.position = new BABYLON.Vector3(2, 3, 4);
例えばワールド軸にしたがって、2,3,4の位置に配置します
この意味は
obj.position.x = 2; obj.position.y = 3; obj.position.z = 4;
です。
赤がX軸、緑の線がY軸、青がZ軸
回転
meshに対して rotationで回転させることが出来ます
mesh.rotation = new BABYLON.Vector3(alpha, beta, gamma);
回転もVector3型でメッシュに設定します。
alpha、beta、およびgammaはラジアンで設定します。
mesh.rotation.x = alpha; //rotation around x axis mesh.rotation.y = beta; //rotation around y axis mesh.rotation.z = gamma; //rotation around z axis
これも同じ意味になります。
また、addRotationを使ってmesh(メッシュ)を連鎖的に回転させることも出来ます
mesh.addRotation(Math.PI/2, 0, 0).addRotation(0, Math.PI/2, 0).addRotation(0, 0, Math.PI/2);
スケーリング
meshに対して scalingで大きさを設定出来ます
mesh.scaling = new BABYLON.Vector3(scale_x, scale_y, scale_z);
または、個別に
mesh.scaling.y = 5;
とか出来ます。
y軸に対してスケーリングした物を、z軸を中心に回転させたらこんな感じです。
まとめ
メッシュに対して、position, rotation, scalingを設定することで
それぞれ、位置、回転、大きさを制御できることがわかりました
次回はマテリアルです
babylon.js ステップ3 線Lineを使ったいろいろな形状を表示
いろいろな形状シリーズです。
いきましょう!
線
//Array of points to construct lines var myPoints = [ new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 1, 1), new BABYLON.Vector3(0, 1, 0) ]; //Create lines var lines = BABYLON.MeshBuilder.CreateLines("lines", {points: myPoints}, scene);
BABYLON.Vector3型で繋いでいきます
螺旋
//Array of points to construct a spiral with lines var myPoints = []; var deltaTheta = 0.1; var deltaY = 0.005; var radius = 1; var theta = 0; var Y = 0; for (var i = 0; i<400; i++) { myPoints.push(new BABYLON.Vector3(radius * Math.cos(theta), Y, radius * Math.sin(theta))); theta += deltaTheta; Y += deltaY } //Create lines var lines = BABYLON.MeshBuilder.CreateLines("lines", {points: myPoints}, scene);
線400個を螺旋状に繋いでグルグルな物も作れます
babylon.js ステップ2 いろいろなプリミティブを表示
早速いきます
BABYLON.MeshBuilderを使っていろいろ作っていきます
Three.jsならジオメトリを作って、マテリアルを設定してメッシュを作るのですが、babylonは一行です。
球体
// Add and manipulate meshes in the scene var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameterX: 1, diameterY: 0.75, diameterZ: 0.25}, scene);
diameterとは直径のことです。x,y,x好きなサイズに出来ます
箱
// Add and manipulate meshes in the scene var box = BABYLON.MeshBuilder.CreateBox("box", {height: 1, width: 0.75, depth: 0.25}, scene);
height高さ, width横幅, depth奥行きを設定出来ます
Plane平面
// Add and manipulate meshes in the scene var plane = BABYLON.MeshBuilder.CreatePlane("plane", {height:2, width: 1}, scene);
箱の奥行きないバージョンですね
地面Ground
Three.jsには無いプリミティブ
// Add and manipulate meshes in the scene var ground = BABYLON.MeshBuilder.CreateGround("ground", {height: 1.5, width: 2.5, subdivisions: 4}, scene);
subdivisionsとはsquare(正方形)の数です。これは4個ですね
まとめ
プリミティブには球体、箱、平面、そして地面がありました。
どれも1行でシーンに追加出来て、Three.jsよりシンプルです。
Three.jsには無かった、地面Groundが気になる所です
次回は、その他の数学的な形状です
Three.jsに物理法則を導入できるPhysijs を入れてみたいけど、、
前回の記事で、Three.jsはゲームに使えない的なことを言ってしまったのですが。。
実は、物理法則を簡単にいれる方法があったっぽい。
それが、外部ライブラリPhysijsだ!!
特徴はこうだ!
- オブジェクトが重力の影響を受け、お互いに衝突するようになる
- シーン内の物体の摩擦係数と反発係数を触れる!
- Physijs がサポートしているさまざまな形状がある
- 単純な形状を組み合わせた合成形状もある
- ハイトフィールドを使用した複雑な形状もできる
- オブジェクトの動きの制限する点制約、ヒンジ制約、スライダー制約、コーンツイスト制
約、自由度制約
- 左右の音量がカメラの位置に基づいて決定される音源
何と盛り沢山な!!
いこう
babylon.jsで3D表現の初めの一歩
こんにちは
どうしても3Dでゲームっぽい物をWeb上で作りたくて、ここ数ヶ月Three.jsを勉強していたのですが、、
どうやらゲームを作るにはbabylon.jsの方が良さそうです。
なぜ、Three.jsではダメなのか?
それは純粋な3D表現ツールだからです。
- キャラクターが簡単には歩いたりはしない
- 地面もただの平面オブジェクト
- 重力は自前でプログラミング
などなど。
何ていうか・・・・全て自作が前提なのです。
Unityであるように、重力を付与するモジュールとか無いです。
誰かが作ってるかもしれないけれど、公式では無いです。
これがとても辛いです。(あったら御免なさい。教えていただきたいです)
ぽぽん!とゲーム作りたい!
じゃあUnityやりなさいよ!!
という話なのですが、どうやらWeb上では動作が遅いらしく家庭用ゲーム機とかPCやスマホにインストールする形式じゃ無いと辛いらしいです(未検証)
あとは、JSで動かしたいんだ!!既存のWebサービスにシームレスに組み込みたいんだ!という話です。
そこで検討したのが、babylon.js(バビロンジェイエス)名前が、人類の愚かさの象徴であるバベルの塔を作り出したバビロンということで、全然いけてないのがとても気になるのですが。。。
果たして、これは目的の物なのか、、
頑張って検証していきます。
執筆時点の最新版は4.1です。
Microsoftのエンジニアが作った物らしく、フリーで使えますし、定期的にアップデートもされており、良さげです。
Microsoftと言えばマインクラフト!!
きっとマインクラフトみたいな物も、簡単に作れるんじゃないかと予想していますw
ただ、babylon.jsにも、一つも問題が。。。。
それは、、、
babylonには日本語のドキュメントが一切ない!! 書籍もない!!
ということです。
Three.jsには素晴らしい書籍がありました。
初めての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ライブラリ
- 作者: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();で一撃です。便利
整理
- まずライブラリを読み込む
- HTMLにcanvasを作っておく
- 3Dエンジンを起動!
- canvasと3Dエンジンを紐付け
- シーン作成!!
- シーンには「カメラ」と「ライト」と「物体」をVector3型で設置!!
- ループ処理を設置
- リサイズ対応も書いとく
この順番を覚えておきましょう!
Three.jsよりちょっとだけシンプルかな。
感想
いけそう!
Three.jsを学んだあとなら、babylon.jsは簡単そうな気がする
どんどんブログにあげていこうと思います
追記:Three.jsでもPointerLockカメラというのがあって
それを使えばマイクラフト的な視点のカメラはできるっぽい。
https://threejs.org/examples/#misc_controls_pointerlock
あとは、Physijsというライブラリを使うと物理演算を導入することができるっぽい!!
この辺りも検証したい