QuestやHoloLens 2対応! Babylon.js x WebXRハンズオン (2023年版)

11.5K Views

February 11, 23

スライド概要

profile-image

可視化技術や人間計測/空間計測技術を活用した問題解決に関する研究開発。 ARコンテンツ作成勉強会(AR_Fukuoka)を主催。

シェア

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

Babylon.js x WebXRハンズオン for HoloLens 2 / Meta Quest

2.

もろもろのダウンロード https://github.com/TakashiYoshinaga/AR-Fukuoka/ raw/main/Babylonjs_20230211/Sample.zip

3.

⾃⼰紹介 ⽒名︓吉永崇 (Takashi Yoshinaga) 仕事︓AR/VR応⽤に関するR&D。主に医療⽀援 ウェアラブル・モーションキャプチャ技術開発 Volumetric Video遠隔コミュニケーション コミュニティ︓ARコンテンツ作成勉強会を主催

4.

ARコンテンツ作成勉強会(略称:AR Fukuoka)の概要 [形式] AR/VRコンテンツの作り⽅や関連技術を主にハンズオン形式で体験。 [規模] 参加⼈数はコロナ前は約5~10名/回、現在は約10~20名/回。 [参加条件] AR/VRの開発に興味があれば初⼼者⼤歓迎。専⾨知識は不要。

5.

Twitterと勉強会ページで情報を発信しています @AR_Fukuoka Googleで「AR勉強会」で検索

6.

ハッシュタグ #AR_Fukuoka + #エンジニアカフェ #DoMCN #XR信州 現地会場

7.

本題に⼊ります

8.

本⽇のゴール https://youtu.be/iok646xGtd0 Babylon.jsの基本的な使い⽅とMRTKによるインタラクションの活⽤について紹介

9.

テンプレートの複製 https://glitch.com/~babylon-template GET STARTED

10.

テンプレートの複製 Remix Your Own

11.

テンプレートの確認 index.htmlをクリックし、コードが表⽰されることを確認 index.html

12.

テンプレートの確認 index.htmlをクリックし、コードが表⽰されることを確認 エディタ Preview

13.

テンプレートの確認 index.htmlをクリックし、コードが表⽰されることを確認 エディタ Preview

14.

補⾜︓Previewが表⽰されない場合 PREVIEW

15.

補⾜︓Previewが表⽰されない場合 Open preview pane

16.

ハンズオンの⼿順 PCのWebブラウザ 3D空間の作成 HoloLens/Quest XRモード MRTKによるインタラクション 手のオブジェクト表示

17.

テンプレートの確認 Lesson01

18.

テンプレートの確認 ライブラリの読み込み 描画やインタラクション の記述(今⽇のメイン) 描画領域のレイアウト

19.

テンプレートの確認 描画領域のレイアウト

20.
[beta]
HTMLの記述の解説
<!--描画する領域-->
<canvas id="renderCanvas" style="width: 100%; height: 100%;"></canvas>

idはjavascriptからアクセスする際に使⽤

ウィンドウ内、めいっぱいのサイズでcanvasを貼り付け

21.

テンプレートの確認 ライブラリの読み込み

22.

テンプレートの確認 描画やインタラクション の記述(今⽇のメイン)

23.

ハンズオンの⼿順 PCのWebブラウザ 3D空間の作成 HoloLens/Quest XRモード MRTKによるインタラクション 手のオブジェクト表示

24.

変数の宣⾔ ここに変数を追加 //ページの読み込み終了後に各種初期化を⾏う window.onload = function() { } //3D空間の初期化 function createScene() { } //WebXRの初期化 async function initializeXR(){ } //表⽰オブジェクトの初期化 function addObjects(){ }

25.

変数の宣⾔ let canvas; //canvas要素 (描画領域) ← 「どこに」描画するか let engine; //Babylon.jsによる描画機能 ← 「何を使って」描画するか let scene; //仮想3D空間 ← 「何を」描画するか //ページの読み込み終了後に各種初期化を⾏う window.onload = function() { } //3D空間の初期化 function createScene() { } //WebXRの初期化 async function initializeXR(){ } Lesson02

26.

Babylon.jsを⽤いた描画機能の初期化 let canvas; //canvas要素 (描画領域) let engine; //Babylon.jsによる描画機能 let scene; //仮想3D空間 //ページの読み込み終了後に各種初期化を⾏う window.onload = function() { //描画領域(canvas要素)をHTMLから取得 canvas = document.getElementById("renderCanvas"); //Babylon.jsを使って描画する準備 (引数︓描画先,アンチエイリアス) engine = new BABYLON.Engine(canvas, true); //カメラやライトの設定を⾏ったscene(3D空間)を取得 scene= createScene(); } //3D空間の初期化 function createScene() { } Lesson03

27.

シーン(3D空間)の初期化 let canvas; //canvas要素 (描画領域) let engine; //Babylon.jsによる描画機能 let scene; //仮想3D空間 //ページの読み込み終了後に各種初期化を⾏う window.onload = function() { //描画領域(canvas要素)を取得 canvas = document.getElementById("renderCanvas"); //Babylon.jsを使って描画する準備 (引数︓描画先,アンチエイリアス) engine = new BABYLON.Engine(canvas, true); //カメラやライトの設定を⾏ったscene(3D空間)を作成 createScene(); } //3D空間の初期化 function createScene() { } シーンの初期化処理を記述(次⾴) Lesson04

28.
[beta]
シーン(3D空間)の初期化
function createScene() {
//3D空間を作成
scene = new BABYLON.Scene(engine);
//背景⾊を設定
scene.clearColor = new BABYLON.Color3.Black();
//Lightを設定 (引数︓名前,反射の⽅向,追加先)
let light = new BABYLON.HemisphericLight("light",
new BABYLON.Vector3(1, 1, -0.5) ,scene);
//カメラを作成 [詳細]
let camera = new BABYLON.ArcRotateCamera(
"camera",
//名前
-Math.PI/2, Math.PI/2, 3, //alpha,beta,距離
new BABYLON.Vector3(0, 0, 0)); //注視点
//マウスやキーボードによるカメラ操作を可能にする
camera.attachControl(canvas, true);
}

Lesson05

29.

実際に描画しよう //ページの読み込み終了後に各種初期化を⾏う window.onload = function() { //描画領域(canvas要素)を取得 canvas = document.getElementById("renderCanvas"); //Babylon.jsで描画する準備 (引数︓描画先,アンチエイリアス) engine = new BABYLON.Engine(canvas, true); //カメラやライトの設定を⾏ったscene(3D空間)を作成 createScene(); //毎フレーム描画を更新 engine.runRenderLoop(function () { if (scene && scene.activeCamera) { scene.render(); //描画︕ } }); } Lesson06

30.

確認 Previewの背景が指定した⾊(=⿊)になる

31.

オブジェクトを描画 //ページの読み込み終了後に各種初期化を⾏う window.onload = function() { //描画領域(canvas要素)を取得 canvas = document.getElementById("renderCanvas"); //Babylon.jsで描画する準備 (引数︓描画先,アンチエイリアス) engine = new BABYLON.Engine(canvas, true); //カメラやライトの設定を⾏ったscene(3D空間)を作成 createScene(); //描画オブジェクトの作成 addObjects(); //毎フレーム描画を更新 engine.runRenderLoop(function () { if (scene && scene.activeCamera) { scene.render(); } }); Lesson07 }

32.

オブジェクトを描画 次はここを編集

33.
[beta]
オブジェクトを描画
function addObjects(){

}

//地⾯を作成 (原点の位置確認⽤。後で削除してOK)
let ground = BABYLON.MeshBuilder.CreateGround(
"ground", {width: 1, height: 1});
//箱状のオブジェクト作成 (30cm)
let box = BABYLON.MeshBuilder.CreateBox(
"box", {width: 0.3, height: 0.3, depth: 0.3});
box.position.x = 0.0;
box.position.y = 1; //地⾯(ground)から1mの⾼さ
//マテリアルを作成
let boxMaterial = new BABYLON.StandardMaterial("material");
//箱の⾊を設定 (今回はランダムに変化)、そのあとboxに適⽤
boxMaterial.diffuseColor = BABYLON.Color3.Random();
box.material = boxMaterial;
//8⾯体を作成
let octa = BABYLON.MeshBuilder.CreatePolyhedron("octa", {type:1,size: 0.15});
octa.position.x=0.5;
octa.position.y=1;
Lesson08

34.

確認 マウス操作で視点を変更することで追加した、地⾯に相当する板を観察できる 初期視点 左クリック+ドラッグで回転 スクロールで前後移動 右クリック+ドラッグで 上下左右移動

35.
[beta]
オブジェクトを描画
function addObjects(){

}

//地⾯を作成 (原点の位置確認⽤。後で削除してOK)
let ground = BABYLON.MeshBuilder.CreateGround(
"ground", {width: 1, height: 1});
//箱状のオブジェクト作成 (30cm)
let box = BABYLON.MeshBuilder.CreateBox(
"box", {width: 0.3, height: 0.3, depth: 0.3});
box.position.x = 0.0;
box.position.y = 1; //地⾯(ground)から1mの⾼さ
//マテリアルを作成
let boxMaterial = new BABYLON.StandardMaterial("material");
//箱の⾊を設定 (今回はランダムに変化)、そのあとboxに適⽤
boxMaterial.diffuseColor = BABYLON.Color3.Random();
box.material = boxMaterial;
//8⾯体を作成
let octa = BABYLON.MeshBuilder.CreatePolyhedron("octa", {type:1,size: 0.15});
octa.position.x=0.5;
octa.position.y=1;
Lesson09

36.

確認 箱が追加される

37.
[beta]
オブジェクトを描画
function addObjects(){

}

//地⾯を作成 (原点の位置確認⽤。後で削除してOK)
let ground = BABYLON.MeshBuilder.CreateGround(
"ground", {width: 1, height: 1});
//箱状のオブジェクト作成 (30cm)
let box = BABYLON.MeshBuilder.CreateBox(
"box", {width: 0.3, height: 0.3, depth: 0.3});
box.position.x = 0.0;
box.position.y = 1; //地⾯(ground)から1mの⾼さ
//マテリアルを作成
let boxMaterial = new BABYLON.StandardMaterial("material");
//箱の⾊を設定 (今回はランダムに変化)、そのあとboxに適⽤
boxMaterial.diffuseColor = BABYLON.Color3.Random();
box.material = boxMaterial;
//8⾯体を作成 [詳細]
let octa = BABYLON.MeshBuilder.CreatePolyhedron("octa", {type:1,size: 0.15});
octa.position.x=0.5;
octa.position.y=1;
Lesson10

38.

確認 箱と⼋⾯体が表⽰される

39.

ハンズオンの⼿順 PCのWebブラウザ 3D空間の作成 HoloLens/Quest XRモード MRTKによるインタラクション 手のオブジェクト表示

40.

QuestやHoloLens2で体験可能にしよう window.onload = function() { /*スペースの都合上、省略*/ //描画オブジェクトの作成 addObjects(); //XRモードの初期化 initializeXR(); //毎フレーム描画を更新 engine.runRenderLoop(function () { if (scene && scene.activeCamera) { scene.render(); } }); } //WebXRの初期化 async function initializeXR(){ let xr = await scene.createDefaultXRExperienceAsync({ /*オプション*/ }); } Lesson11

41.

実機での体験前にURLを変更 Settingsをクリック

42.

実機での体験前にURLを変更 Edit project details ここを分かりやすく変更 最後にSave

43.

URLを確認 をクリック Copy Link

44.

URLを確認 テキストエディタなどに貼り付けてURLを確認 https://⾃⾝でつけた名前.glitch.me/

45.

動作確認 HoloLens2 URLを⼊⼒ ゴーグルボタン Quest URLを⼊⼒ ゴーグルボタン WebブラウザのアドレスバーにコンテンツのURLを⼊⼒後、ゴーグルボタンをタップ/クリック

46.

動作確認

47.

終了⽅法 HoloLens2 ホームボタン Quest 閉じるボタン ⼿⾸タップ(HoloLens2)やOculusボタン(Quest)からウィンドウを表⽰してコンテンツを終了

48.

ハンズオンの⼿順 PCのWebブラウザ 3D空間の作成 HoloLens/Quest XRモード MRTKによるインタラクション 手のオブジェクト表示

49.
[beta]
オブジェクトを操作
function addObjects(){
/*スペースの都合上、省略*/
//箱の⾊をランダムに設定
let boxMaterial = new BABYLON.StandardMaterial("material");
boxMaterial.diffuseColor = BABYLON.Color3.Random();
box.material = boxMaterial;
//8⾯体を作成
let octa = BABYLON.MeshBuilder.CreatePolyhedron("octa", {type:1,size: 0.15});
octa.position.x=0.5;
octa.position.y=1;
//boxに⼿で掴んで移動できる属性を追加
let dragBehavior = new BABYLON.SixDofDragBehavior();
dragBehavior.allowMultiPointer = false;
dragBehavior.rotateWithMotionController = false;
box.addBehavior(dragBehavior);
}

Lesson12

50.

PCで動作確認(マウス操作) DragBehaviorを適⽤した オブジェクトのみ操作可能

51.

実機で動作確認 再読み込み 再読み込み 必ず再読み込みボタンをクリック

52.

実機で動作確認 Questユーザーは現時点ではハンドトラッキングでの⼿の表⽰がおかしい (あとで修正)

53.

ハンズオンの⼿順 PCのWebブラウザ 3D空間の作成 HoloLens/Quest XRモード MRTKによるインタラクション 手のオブジェクト表示

54.
[beta]
⼿のオブジェクト表⽰ (For Quest)
//WebXRの初期化
async function initializeXR() {
let xr = await scene.createDefaultXRExperienceAsync({});
//XRモード利⽤可能か不可かを確認
if (!xr.baseExperience) { }
else {
//利⽤可能な場合はハンドトラッキングをオンにする
xr.baseExperience.featuresManager.enableFeature(
BABYLON.WebXRFeatureName.HAND_TRACKING,
"latest",
{xrInput: xr.input}
);
}
}

Lesson13

55.

実機で動作確認

56.

基本⼿順は以上︕

57.

Next Step 3Dモデルを利⽤しよう

58.

3Dモデルも表⽰可能(GLB, OBJなど)

59.

3Dモデルファイルの読み込み準備 ライブラリの読み込み Babylon.jsが提供するオブジェクト 読み込み機能を利⽤できるようにする

60.
[beta]
3Dモデルファイルの読み込み準備
<!--babylon.jsの読み込み-->
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
<!--実際の処理の実装-->
<script type="text/javascript">
let canvas; //canvas要素 (描画領域)
let engine; //Babylon.jsによる描画機能
let scene; //仮想3D空間
//ページの読み込み終了後に各種初期化を⾏う
window.onload = function () {
//描画領域(canvas要素)をHTMLから取得
canvas = document.getElementById("renderCanvas");
//Babylon.jsを使ってcanvasに描画する準備 (引数︓描画先,アンチエイリアス)
engine = new BABYLON.Engine(canvas, true);
/*以下省略*/

Lesson14

61.

3Dモデルのアップロード Assets

62.

3Dモデルのアップロード ブラウザ内にドラッグ&ドロップ figure.glb

63.

3Dモデルのアップロード index.htmlに戻る

64.
[beta]
3Dモデルファイルの読み込み
function addObjects(){
/*スペースの都合上、省略*/
let boxMaterial = new BABYLON.StandardMaterial("material");
boxMaterial.diffuseColor = BABYLON.Color3.Random();
box.material = boxMaterial;
//8⾯体を作成
let octa = BABYLON.MeshBuilder.CreatePolyhedron("octa", {type:1,size: 0.15});
octa.position.x=0.5;
octa.position.y=1;
//boxに⼿で掴んで移動できる属性を追加
let dragBehavior = new BABYLON.SixDofDragBehavior();
dragBehavior.allowMultiPointer=false;
dragBehavior.rotateWithMotionController=false;
box.addBehavior(dragBehavior);
}

オブジェクトを読み込むコードを追加(次⾴)

65.

3Dモデルファイルの読み込み function addObjects(){ /*スペースの都合上、省略*/ dragBehavior.rotateWithMotionController=false; box.addBehavior(dragBehavior); //SceneLoaderを使って3Dモデルを読み込む BABYLON.SceneLoader.LoadAssetContainer( "3DモデルのURL", //3Dモデルが置かれたフォルダ or 3DモデルのURL "", //3Dモデルのファイル名。上記でモデルのURLを指定した場合は空でOK scene, //オブジェクトを追加する先のScene function (container) { //Babylon.jsでは0番⽬のメッシュはただのroot。1番⽬にモデルの実体。 [詳細] let glbMesh = container.meshes[1]; //scene(3D空間)にオブジェクトを追加 scene.addMesh(glbMesh); } ); } Lesson15

66.

3Dモデルファイルの読み込み function addObjects(){ /*スペースの都合上、省略*/ dragBehavior.rotateWithMotionController=false; box.addBehavior(dragBehavior); //SceneLoaderを使って3Dモデルを読み込む BABYLON.SceneLoader.LoadAssetContainer( "3DモデルのURL", //3Dモデルが置かれたフォルダ or 3DモデルのURL "", //3Dモデルのファイル名。上記でモデルのURLを指定した場合は空でOK scene, //オブジェクトを追加する先のScene function (container) { //Babylon.jsでは0番⽬のメッシュはただのroot。1番⽬にモデルの実体。 let glbMesh = container.meshes[1]; //scene(3D空間)にオブジェクトを追加 scene.addMesh(glbMesh); } ); } Lesson15

67.

オブジェクトのURL Assets

68.

オブジェクトのURL figure.glbをクリック

69.

オブジェクトのURL Copy URL

70.

オブジェクトのURL 閉じる

71.

オブジェクトのURL index.htmlに戻る

72.

3Dモデルファイルの読み込み function addObjects(){ /*スペースの都合上、省略*/ dragBehavior.rotateWithMotionController=false; box.addBehavior(dragBehavior); //SceneLoaderを使って3Dモデルを読み込む BABYLON.SceneLoader.LoadAssetContainer( "3DモデルのURL", //3Dモデルが置かれたフォルダ or 3DモデルのURL "", //3Dモデルのファイル名。上記でモデルのURLを指定した場合は空でOK "と scene, //オブジェクトを追加する先のScene function (container) { "の間にURLをペースト //Babylon.jsでは0番⽬のメッシュはただのroot。1番⽬にモデルの実体。 let glbMesh = container.meshes[1]; //scene(3D空間)にオブジェクトを追加 scene.addMesh(glbMesh); } ); }

73.

確認 すごく⼩さい

74.

3Dモデルの調整 //SceneLoaderを使って3Dモデルを読み込む BABYLON.SceneLoader.LoadAssetContainer( "3DモデルのURL", //3Dモデルが置かれたフォルダ or 3DモデルのURL "", //3Dモデルのファイル名。上記でモデルのURLを指定した場合は空でOK scene, //オブジェクトを追加する先のScene function (container) { //Babylon.jsでは0番⽬のメッシュはただのroot。1番⽬にモデルの実体。 let glbMesh = container.meshes[1]; //スケールを10倍 glbMesh.scaling=new BABYLON.Vector3(10,10,10); //scene(3D空間)にオブジェクトを追加 scene.addMesh(glbMesh); } ); Lesson16

75.

3Dモデルの調整 //SceneLoaderを使って3Dモデルを読み込む BABYLON.SceneLoader.LoadAssetContainer( "3DモデルのURL", //3Dモデルが置かれたフォルダ or 3DモデルのURL "", //3Dモデルのファイル名。上記でモデルのURLを指定した場合は空でOK scene, //オブジェクトを追加する先のScene function (container) { //Babylon.jsでは0番⽬のメッシュはただのroot。1番⽬にモデルの実体。 let glbMesh = container.meshes[1]; //スケールを10倍 glbMesh.scaling=new BABYLON.Vector3(10,10,10); //Y軸(=鉛直⽅向の軸)を中⼼に180度(=πラジアン)回転 glbMesh.rotation =new BABYLON.Vector3(0, Math.PI, 0); //scene(3D空間)にオブジェクトを追加 scene.addMesh(glbMesh); } ); Lesson17

76.

マニピュレーション追加 //SceneLoaderを使って3Dモデルを読み込む BABYLON.SceneLoader.LoadAssetContainer( "3DモデルのURL", "", scene, function (container) { //Babylon.jsでは0番⽬のメッシュはただのroot。1番⽬にモデルの実体。 let glbMesh = container.meshes[1]; //スケールを10倍 glbMesh.scaling=new BABYLON.Vector3(10,10,10); //Y軸(=鉛直⽅向の軸)を中⼼に180度(=πラジアン)回転 glbMesh.rotation =new BABYLON.Vector3(0, Math.PI, 0); //読み込んだオブジェクト⽤にマニピュレーションの挙動を作成 let dragBehavior2 = new BABYLON.SixDofDragBehavior(); dragBehavior2.allowMultiPointer=false; dragBehavior2.rotateWithMotionController=false; glbMesh.addBehavior(dragBehavior2); //scene(3D空間)にオブジェクトを追加 scene.addMesh(glbMesh); } ); Lesson18

77.

実機で動作確認

78.

参考 Camera https://doc.babylonjs.com/divingDeeper/cameras/camera_introduction WebXR Experience Helper https://doc.babylonjs.com/divingDeeper/webXR/webXRExperienceHelpers#webxr-defaultexperience-helper MRTK https://doc.babylonjs.com/divingDeeper/gui/mrtk SixDofDragBehaviour https://doc.babylonjs.com/typedoc/classes/BABYLON.SixDofDragBehavior Hand Tracking https://doc.babylonjs.com/divingDeeper/webXR/WebXRSelectedFeatures#hand-tracking SceneLoader https://doc.babylonjs.com/typedoc/classes/BABYLON.SceneLoader ARモード(Questパススルー対応) https://doc.babylonjs.com/features/featuresDeepDive/webXR/webXRARFeatures#features

79.

今⽇の完成品 GitHubでも公開しています https://github.com/TakashiYoshinaga/babylonjs-webxr