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

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

babylon.js ステップ7 ライティング

f:id:hollywis:20200620154902j:plain


babylon.js ステップ7 ライティングです。

3D表現はライティングが無いと始まりません。

ライディングの無い空間はただの暗黒です。

暗黒の空間に一条の光として、ライトを設置します。

ライトと言っても、太陽のような環境光もあります。

いきましょう!

ライトの種類

4種類のライトあります

  1. ポイントライト(Point Light)
  2. 指向性ライト(Directional Light)
  3. スポットライト(Spot LIghe)
  4. 半球ライト(HemiLight)

ポイントライト/点光源(Point Light)

ポイントライトは、ワールドスペース内の一意のポイント(点)にから発光されるライトです。

光はこのポイントからあらゆる方向に放出されます。

ポイントライトの分かりやすい例は、裸電球です。

ちょっと上(y軸を多め)に置くとメッシュ全体を照らせます。

var light = new BABYLON.PointLight("pointLight", new BABYLON.Vector3(1, 10, 1), scene);


例はこちら
https://www.babylonjs-playground.com/#20OAV9

指向性ライト/平行光源(Directional Light)

指向性ライト/平行光源は、方向によって定義される特殊な光です。

光は、指定された方向のあらゆる場所から放出され、無限の範囲を持ちます。

指向性ライトの例としては、太陽からの十分に遠い惑星があったとして

その惑星に対して、並行な光が降り注ぐと思うのですが、そんな感じです。

下方向に光を当てると、オブジェクトの上部が明るくなります。

var light = new BABYLON.DirectionalLight("DirectionalLight", new BABYLON.Vector3(0, -1, 0), scene);

例はこちら
https://www.babylonjs-playground.com/#20OAV9#1

スポットライト(Spot LIghe)

スポットライトは、単一の点から一方向に円錐状に放出されます。

方向、角度、および指数を設定出来ます。

値は、位置、照らす方向で光の円錐を定義します。

照射角は、ラジアンで、スポットライトの円錐ビームのサイズ(照明のフィールド)を定義し、

指数は、距離(距離)に伴う光の減衰の速度を定義します。

// new BABYLON.SpotLight(名前, 位置, 照らす方向, 照射角, 光の減衰, scene);
var light = new BABYLON.SpotLight("spotLight", new BABYLON.Vector3(0, 30, -10), new BABYLON.Vector3(0, -1, 0), Math.PI / 3, 2, scene);

例はこちら
https://www.babylonjs-playground.com/#20OAV9#3

半球ライト(HemiLight)

半球ライトは、環境光をシミュレートします。

半球の光は、通常は上空に向かう方向によって定義されます。

ただし、次に説明する色の設定をすることで、より完全な効果が得られる。

var light = new BABYLON.HemisphericLight("HemiLight", new BABYLON.Vector3(0, 1, 0), scene);

例はこちら
https://www.babylonjs-playground.com/#20OAV9#5

色の設定

色に影響を与えるライトには、3つのプロパティがあります。

  • 拡散反射光(diffuse )・・・ベースの反射光 4種類のライトすべてに適用
  • 鏡面反射光(specular)・・・ハイライト 4種類のライトすべてに適用
  • 地面光(groundColor)・・・地面からの反射光。半球ライトにのみ適用


地面光(groundColor)の例はこちら

地面からの反射光が緑だと想定して、gtoundColorが適用されています

https://www.babylonjs-playground.com/#20OAV9#6

ライトのオン、オフ、または調光

これでオフ

light.setEnabled(false);

これでオン

light.setEnabled(true);

intensityを設定することで調光できる

light0.intensity = 0.5;
light1.intensity = 2.4;

ポイントライトとスポットライトの場合、rangeプロパティを使用してライトが到達する距離を設定できます

light.range = 100;

ライティングへのテクスチャの適用

テクスチャへ拡散色を定義するとよい(拡散はオブジェクトに基本色を与えます)。

拡散色の例としては、大聖堂内部の光の効果をシミュレートする場合、ステンドグラスを通過する様々な光は色がついて地面に投影されます。

これは、プロジェクターからの光やなどの光の効果にも当てはまります。

これを再現するためには、SpotLightを用いて、projectionTextureプロパティを適用します。

f:id:hollywis:20200620154802p:plain

var spotLight = new BABYLON.SpotLight("spot02", new BABYLON.Vector3(30, 40, 30),
        new BABYLON.Vector3(-1, -2, -1), 1.1, 16, scene);
spotLight.projectionTexture = new BABYLON.Texture("textures/stainedGlass.png", scene);

まとめ

ライトには4つの種類がありました。

ポイントライト(Point Light)、指向性ライト(Directional Light)、スポットライト(Spot LIghe)、半球ライト(HemiLight)

さらには、ライトの反射光に色の設定する方法とテクスチャを適用する方法も説明しました。

次回はアニメーション!!
hollywis.hatenablog.com

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っぽい一人称視点を得られます。

それぞれの入力方法のデフォルト設定は次の通り

  1. キーボード・・・上下左右キー
  1. マウス・・・視点を回転
  1. タッチ操作・・・上下左右にスワイプ
  1. ゲームパッド・・・デバイス次第

コード

// 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);

操作例はこちら:
https://www.babylonjs-playground.com/#SRZRWV

アーク回転カメラ(Arc Rotate Camera)

このカメラは常に所定のターゲット位置を指し、ターゲットを回転の中心としてそのターゲットを中心に回転できます
カーソルとマウス、またはタッチイベントで制御できます。

このカメラは、その目標位置を周回するカメラ、またはより想像力で地球を周回するスパイ衛星と考えてください。ターゲット(地球)に対するその位置は、アルファ(ラジアン)縦回転、ベータ(ラジアン)緯度回転、および ターゲット位置からの距離の半径の3つのパラメーターで設定できます。

f:id:hollywis:20200620014150j:plain

コード

// 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);

操作例:
https://www.babylonjs-playground.com/#SRZRWV#1

フォローカメラ(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にはあり

ユニバーサルカメラとアーク回転カメラが2大カメラです。

さらに、拡張としてバーチャルジョイスティックを画面上に表示させるなど、十分な操作方法が提供されています

次回はライトの設定です

babylon.js ステップ5 マテリアル

マテリアルを使用すると、メッシュを色とテクスチャで覆うことができます。

なお、メッシュを表示するには光が必要です。

拡散マテリアル(Diffuse)と鏡面マテリアル(Specular)では、光源を作成する必要があります。

いきましょう!

f:id:hollywis:20200619152808p:plain

まずは、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で透明度を変えられる

テクスチャ

メッシュに対して、画像を張れる.

f:id:hollywis:20200619152557p:plain

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;

ワイヤーフレーム

マテリアルに対して、ワイヤーフレーム表示

f:id:hollywis:20200619153209p:plain

myMaterial.wireframe = true;

まとめ

メッシュに対して、設定できるマテリアルについて紹介しました。

色マテリアルの場合は、まず光Lightをシーンに設定した上で

それぞれ、拡散光、鏡面反射、自身の発光、環境光を設定出来ました。

また、画像テクスチャを貼ることも出来ます。

そして、ワイヤフレーム表示もマテリアルで行いました。

次はカメラです。

hollywis.hatenablog.com

babylon.js ステップ4 位置、回転、スケーリング

babylon.js やってみようシリーズのステップ4

位置、回転、スケーリングのお話です

位置の話

babylon.jsには2つの座標系があります

  • ワールド座標系
  • ローカル座標系

ワールド座標系

ワールド座標系の原点は変わりません。

通常、メッシュが作成されると、その中心はワールド軸の原点に配置されます。

移動しても、ワールド座標系はそのワールドの中心(原点)を元に判断されます

ローカル座標系

ローカル軸はメッシュの場所によって動きます。

でもローカル軸の原点は、ワールド座標における位置に関係なく、常にメッシュの作成された中心にあります。

初期状態

ワールド座標とローカル座標は一致しますが

メッシュが動くとズレることになります。

f:id:hollywis:20200619144019j:plain

配置

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;

です。

f:id:hollywis:20200619144327j:plain

赤が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軸を中心に回転させたらこんな感じです。

f:id:hollywis:20200619145855j:plain

まとめ

メッシュに対して、position, rotation, scalingを設定することで

それぞれ、位置、回転、大きさを制御できることがわかりました

次回はマテリアルです

hollywis.hatenablog.com

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型で繋いでいきます

f:id:hollywis:20200619142450p:plain


Babylon.js Playground

螺旋

f:id:hollywis:20200619142758p:plain

 //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個を螺旋状に繋いでグルグルな物も作れます

まとめ

線です。

簡単です。螺旋を描くには座標計算にオイラー角が必要なので、その辺りは難しいですが

線自体は簡単ですね。

hollywis.hatenablog.com

babylon.js ステップ2 いろいろなプリミティブを表示

早速いきます

BABYLON.MeshBuilderを使っていろいろ作っていきます

Three.jsならジオメトリを作って、マテリアルを設定してメッシュを作るのですが、babylonは一行です。

球体

f:id:hollywis:20200619140955p:plain

  // 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好きなサイズに出来ます

Babylon.js Playground

f:id:hollywis:20200619141013p:plain

    // 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奥行きを設定出来ます

https://www.babylonjs-playground.com/#K6M44R

Plane平面

f:id:hollywis:20200619141024p:plain

       // Add and manipulate meshes in the scene
    var plane = BABYLON.MeshBuilder.CreatePlane("plane", {height:2, width: 1}, scene);

箱の奥行きないバージョンですね


www.babylonjs-playground.com

地面Ground

Three.jsには無いプリミティブ

f:id:hollywis:20200619141230p:plain

    // 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個ですね

Babylon.js Playground

まとめ

プリミティブには球体、箱、平面、そして地面がありました。

どれも1行でシーンに追加出来て、Three.jsよりシンプルです。

Three.jsには無かった、地面Groundが気になる所です

次回は、その他の数学的な形状です

hollywis.hatenablog.com

Three.jsに物理法則を導入できるPhysijs を入れてみたいけど、、

前回の記事で、Three.jsはゲームに使えない的なことを言ってしまったのですが。。


実は、物理法則を簡単にいれる方法があったっぽい。

それが、外部ライブラリPhysijsだ!!


特徴はこうだ!

  • オブジェクトが重力の影響を受け、お互いに衝突するようになる
  • シーン内の物体の摩擦係数と反発係数を触れる!
  • Physijs がサポートしているさまざまな形状がある
  • 単純な形状を組み合わせた合成形状もある
  • ハイトフィールドを使用した複雑な形状もできる
  • オブジェクトの動きの制限する点制約、ヒンジ制約、スライダー制約、コーンツイスト制

約、自由度制約

  • 左右の音量がカメラの位置に基づいて決定される音源

何と盛り沢山な!!



いこう

と思ったらいろいろメンテされてないらしい

qiita.com

ふむふむ。3年くらいメンテされてないとな、、、

Three.jsは結構頻繁にバージョンアップするので、これは厳しいのかなぁ


f:id:hollywis:20200619133908p:plain

比較的に新しいのはOimo.js(お芋ドットジェイエス)。お芋かぁ...


とりあえず、次回!