Tokyo HoloLensミートアップvol.26での登壇資料になります
HoloLens2のWebARで軽率にImmersalによる位置合わせを行うにー兄さん(@ninisan_drumath)Tokyo HoloLensミートアップ vol.26
View Slide
自己紹介- にー兄さん(@ninisan_drumath)- 筑波大学 情報科学類(coins18)- 3DCGが好きUnityやWebGLで遊ぶのが好き- Vオタク2
スライド資料・作業ログなど公開しています👍スライドのスクショ📸SNS共有OKです(お願いします)3
Agenda4- やりたいことについて- WebAR + Immersal- おわりに
やりたいことについて5
やりたいことBabylon.jsのWebARモードでImmersalによる空間の位置合わせをHoloLens2の(Chromium-based)Edgeでやってみたいやってみたくない......?6
位置合わせ(Localization)- 現実空間とマップ座標の整合性をとる- ワールドの座標原点はARアプリ開始位置によって変わってくる- 世界座標にコンテンツを固定できる- Immersalの他、Azure Spatial AnchorsやVuforia Area TargetなどのVPSを使う- 他人と体験を共有できるようになるマップ原点ワールド原点(初期位置)とても遠いところにある地球の中心(世界座標系の原点 )7
Immersal- AR Cloud開発で使われるサービス- VPSを提供- つまり位置合わせができる- 連続写真(RBG)を使ってマップを作成点群/メッシュも作成できる- Unity(Android/iOS)で使えるSDKがある- REST APIによってサーバーサイド位置合わせも可能- スマホさえあれば手軽に利用できてうれしいimmersal公式ドキュメントより 8
WebAR + Immersal9
開発環境など- Babylon.js- WebGLライブラリ- WebXR対応が簡単- MicrosoftがWebXRするのに押していてイイ感じ- Microsoft Mesh対応も待ちどおしい- Vite- Webフロントエンドのビルドシステム- 複雑な設定が要らず、融通が利くイメージ- ノーバンドルで開発時は爆速ビルド- loaderの設定なしでTypeScriptやPostCSSを導入できる- プロジェクトテンプレートが利用できる- 今回はvanilla-tsで作る10
HoloLens2を使ったWebXRについて- 5月のOSアップデート21H1- EdgeでイマーシブWebXRがサポート(嬉しい)- Hand Trackingなども使える(嬉しい)- (詳しくはWebXR Tech Tokyo#6で少し話したり)11
(注意)ローカル開発環境でデバッグするために- WebXR APIを使いたい- LANでもhttps接続が必須- 方法は何でもよい- opensslコマンドでオレオレ証明書作成- Viteの場合vite.config.jsに設定を追記const config = defineConfig({server: {https: {key: fs.readFileSync("./key.pem"),cert: fs.readFileSync("./cert.pem"),},},});openssl req -newkey rsa:2048 -new -nodes-x509 -days 3650 -keyout key.pem -outcert.pem12
Babylon.jsでWebARを使うconst xr = await scene.createDefaultXRExperienceAsync({uiOptions: {sessionMode: "immersive-ar",referenceSpaceType: "unbounded",},});13
準備:Immersalで部屋のスキャン- 部屋の写真を複数枚撮る(下のマップは162枚使った)- 一つ前に撮った写真と半分くらい被るようにずらして撮影- マップデータおよびply/glbが生成14
処理の流れカメラ画像取得鯖サイド位置合わせマップの座標変換15ImmersalREST API
カメラ画像の取得- WebクライアントからHoloLensの背面カメラストリームを取得- 通常のWebCamアクセスと同じやり方で取得可能- QC Back Camera(1270x720)にアクセスできるっぽいconst videoElement =document.getElementById("video");const videoCanvas =document.getElementById("videoCapture")const width = 1270;const height = 720;navigator.mediaDevices.getUserMedia({audio: false,video: true,}).then((stream) => {videoElement.srcObject = stream;videoElement.autoplay = true;videoCanvas.width = width;videoCanvas.height = height;});button.onPointerDownObservable.add(() => {videoCanvas.getContext("2d")!.drawImage(videoElement, 0, 0, width, height);const imageURL = videoCanvas.toDataURL();}); 16
Immersal REST API- Immersalの機能をサーバサイドで使うためのもの- マップ作成、位置合わせ、アカウントやマップの管理など- SDKがないプラットフォームでもImmersalを使うことができる- 現状だとHoloLensやWebにはSDKがない- C#やPythonのサンプルコードがドキュメントに- 参考:https://immersal.gitbook.io/sdk/cloud-service/rest-api17
Server-side Localization:リクエスト- REST APIを用いて位置合わせを行う- postリクエストで次のデータを送信- base64エンコードされた画像データ- カメラの焦点距離(focal length)- カメラの光学中心(principal offset)- トークン- マップID配列- 焦点距離と光学中心はWebAPIから取得できなさそう→別途調査&直打ち- 画像1枚で姿勢推定できるのはすごい......interface ImmersalLocalizeRequest {token: string,fx: number;fy: number;ox: number;oy: number;b64: string;mapIds: SDKMapId[];}18
Server-side Localization:レスポンス- 次のデータを受信データ- エラーの有無- 位置合わせの成功/失敗- カメラの位置ベクトル- カメラの回転行列- 計算時間- マップID- 送信データに誤りがあればエラー内容だけが返ってくる- エラーはないけど位置合わせが失敗、みたいなケースもあり- データはマップ原点との相対姿勢19
座標変換 Immersalマップ座標系のカメラの姿勢カメラ座標系のマップの姿勢ワールド座標系のマップの姿勢20レスポンスから変換行列を作成逆変換を計算リクエスト時のカメラの姿勢を適用MapPhysicalWorld
demo21
おわりに22
まとめ・感想- ImmersalでWebARから位置合わせを行うことができた- Web固有の問題でちょっとやりにくいところもある- 実装方法などは要検討- HoloLens+WebARに光あれ- WebAR+ARCloudはちょっと期待している- インスタントかつプレゼンスの高い表現の可能性を追求したい- ちょっととがった技術スタックでの検証は面白い23
参考資料作業ログ:https://zenn.dev/drumath2237/scraps/cc4fa2315477f9Babylon.js+HoloLensの発表資料:https://speakerdeck.com/drumath2237/edge-on-hololens2deqing-lu-niwebxrsurutokigalai-taImmersal REST API Doc:https://immersal.gitbook.io/sdk/cloud-service/rest-apiImmersal勉強会:https://hololab.connpass.com/event/210907/Babylon.js WebXR:https://doc.babylonjs.com/divingDeeper/webXR/introToWebXRHoloLens MediaFrameReader を使ったメディア フレームの処理:https://docs.microsoft.com/ja-jp/windows/uwp/audio-video-camera/process-media-frames-with-mediaframereader24