">
FlatIsleロゴ

Flat Isle 日誌

Blenderのオブジェクトを表示する

2022-08-29

前回はBABYLON.jsの基本的な使用方法までを説明しました。
今回はBlenderで作成した3DオブジェクトをglTF形式で出力し、BABYLON.jsで表示(ロード)してみます。

Blenderによる3Dオブジェクトの作成

まずはBlenderで簡単な3Dオブジェクトを作成します。
テクスチャやアニメーションを設定し、最後にglTF形式で出力します。

3Dオブジェクトの作成

メッシュは何でも良かったのですが、せっかくなのでBlenderの看板娘スザンヌさんにしました。
そのままでは素っ気ないので、木目の画像テクスチャを貼り、縦軸を中心に回転するアニメーションを付けています。

BlenderとBABYLONでは高さを表す軸が異なります。
Blenderでは高さはZ軸、BABYLONでは高さはY軸で表しますが、Blender上では特に意識しなくても大丈夫です。(後述のエクスポート機能が自動変換してくれます)

3Dオブジェクトのエクスポート

作成した3DオブジェクトをglTFバイナリ形式ファイルとしてエクスポートします。
メニューバーの[ファイル]-[エクスポート]-[glTF 2.0 (.glb/gltf)] を選びます。
表示された画面の右側にある「フォーマット」項目で「glTFバイナリ (.glb)」を選択します。
画面中央で保存先を選択し、画面下側にある入力欄にファイル名を入力、その右側にある「glTF 2.0をエクスポート」ボタンをクリックするとglbファイルとして保存されます。
なお今回使用したglbファイルはこちらからダウンロードできます。

glTF形式にはファイルの出力形式が2種類あり、画像データ等を内包するかで異なります。
3Dオブジェクトを複数のファイルで保存する場合、テクスチャ等の共通する項目を外部ファイルとして保存できるgltfファイルの方が容量を節約できる場合があります。

  • glbファイル
    出力されるファイルが1つになる
  • gltfファイル
    出力されるファイルが複数(gltf、bin、テクスチャ画像)に分かれる

Blenderにアドオンを導入すれば、babylonファイル形式で出力する事も出来ます。
アドオンのサポート範囲はBlender 2.93まで(2022年7月現在)となっていますが、Blender 3.0でも動作しました。
ただしメタボール等、メッシュ以外はエクスポート出来ない様です。
エクスポートした「.babylon」ファイルは、以下と同様にSceneLoaderで表示できます。

BABYLONによる表示

BABYLON.jsでglbファイルを読み込み、表示してみます。基本的な使用方法は前回を参照してください。

初期設定

以下のスクリプトをロードしておきます。

<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>

オブジェクトのロード

外部ファイルの読み込みには SceneLoader を使います。
glbファイルに複数のメッシュが含まれていても対応できるように記述しています。
下記の例では上記「モンキー」(スザンヌさん)に対して、縮尺を変更してスリムに見せています。

BABYLON.SceneLoader.ImportMeshAsync("", "./", "blender_to_babylon_blog.glb", scene) 
.then((result) => {
	for(let i = 1; i < result.meshes.length; i++){
		switch(result.meshes[i].name){
			case 'モンキー':
				result.meshes[i].scaling    = new BABYLON.Vector3(0.5, 1, 0.5);
				break;
			default: //Not working
		}
	}
});

実行結果は下記の様になります。

おサル感が増していますね😅。
ソースコードは以下のようになります。(glbファイルは同じフォルダ内に保存して下さい。)

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta  http-equiv="Content-Type" content="text/html" charset="utf-8"/>
	<title>Babylon Test</title>
	<script src="https://cdn.babylonjs.com/babylon.js"></script>
	<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
	<style>
		html, body {
			overflow: hidden;
			width: 100%;
			height: 100%;
			margin: 0;
			padding: 0;
		}
		#renderCanvas {
			width: 100%;
			height: 100%;
			touch-action: none;
		}
	</style>
</head>
<body>
	<canvas id="renderCanvas"></canvas>
<script>
	let canvas, engine, scene;
	canvas = document.getElementById("renderCanvas");
	engine = new BABYLON.Engine(canvas, true);
	scene  = new BABYLON.Scene(engine);
	scene.gravity           = new BABYLON.Vector3(0, -0.98, 0);
	scene.collisionsEnabled = true;

	var camera = new BABYLON.UniversalCamera ("Camera", new BABYLON.Vector3(0,  1.2, 5), scene);
	var lightD = new BABYLON.DirectionalLight("LightD", new BABYLON.Vector3(0,    0, 0), scene);
	var lightH = new BABYLON.HemisphericLight("LightH", new BABYLON.Vector3(0, 1000, 0), scene);
	lightD.intensity = 0.8;
	lightH.intensity = 0.6;
	var oGnd   = BABYLON.MeshBuilder.CreateGround("Ground", {width: 100, height:100});
	
	camera.ellipsoid        = new BABYLON.Vector3(0.25, 0.8, 0.25);
	camera.checkCollisions  = true;
	camera.applyGravity     = true;
	camera.speed            = 0.3;
	camera.attachControl(canvas, true);
	camera.rotation.y       = Math.PI;
	oGnd.checkCollisions    = true;

	BABYLON.SceneLoader.ImportMeshAsync("", "./", "blender_to_babylon_blog.glb", scene)
	.then((result) => {
		for(let i = 1; i < result.meshes.length; i++){
			switch(result.meshes[i].name){
				case 'モンキー':
					result.meshes[i].scaling    = new BABYLON.Vector3(0.5, 1, 0.5);
					break;
				default: //Not working
			}
		}
	});
	
	window.addEventListener("resize", function(){engine.resize();});
	engine.runRenderLoop(function(){scene.render();});
</script>
</body>
</html>

次回はXRカメラ(VRやAR等)を進めていきます。
それまでにVRで表示したい3Dモデルを作成しておくのもよいですね。