Tutti Lab

元シリコンバレー在住のおっさん技術者、モバイルVRアプリ開発に挑戦中

Vuforia for UnityのExtended Tracking機能を利用してGoogle Cardboardでポジショントラッキング

はじめに

Google CardboardやGear VRなど、スマホを利用したいわゆる「モバイルVR」は、Oculus Rift/HTC Vive等と比較し、値段が安くお手軽にVR体験を楽しむことができます。一方で、Oculus Rift/HTC Viveには搭載されているハンドデバイス(Oculus RiftのOculus Touchはこの2016/12に出荷予定)や、ポジショントラッキング等、VRの没入感を生み出すための重要な機能が、モバイルVRには搭載されておりません。
モバイルVRでは、立体視+ヘッドトラッキング(顔=デバイスの向きをトラッキング)により、顔の向きとCG空間内の視線方向を一致させることで、あたかも自分が向いている方向のCGを立体視しているような錯覚を生み出し、これが没入感を生み出します。この「立体視+ヘッドトラッキング」だけでも、相当の没入感であり、私も最初にGoogle Cardboard(Oculus Rift DK1も)を見たときには相当な感動を覚えました。しかし、ポジショントラッキングやハンドデバイスが実装されているVR、特にHTC Viveのルームスケールなんかを体験してしまうと、「立体視+ヘッドトラッキング」だけでは物足りなさを感じるようになってしまいます。
ポジショントラッキングとは、その名の通り、ユーザの位置をトラッキングする機能です。ヘッドトラッキングでは顔の向きだけ任意の方向に向けることができましたが、例えば立ち上がったり・しゃがんだり・肩を左右に振っても、ユーザの視点位置は変化しません。しかし、ポジショントラッキング搭載のものであれば、例えば向こうから飛んでくるボールを避けるゲーム、なんてものも実現することができます。
Oculus Rift (DK2/CV1)では、ユーザの正面の専用のカメラを設置し、このカメラがOculus Rift本体の位置を捉えることでポジショントラッキングを実現しています。HTC Viveは、Oculus Riftと逆の方法、部屋の2角に赤外線を発光するベースステーションを設置し、ヘッドセットやハンドデバイスに内蔵のカメラで赤外線を受光することでトラッキングをしているようです。これにより、ルームスケールと呼ばれる「CG空間を歩き回る体験」や、まるで自分の手がCG空間に現れたかのような秀悦な操作感が実現されています。
f:id:tuti107:20161127153421p:plain
しかし、これらポジショントラッキングやハンドデバイスには高度が技術が必要となり、廉価版であるモバイルVRでの実現はコスト的に困難です。Vico VRのように、ポジショントラッキングや手足による入力に対応している(らしい、コンシュマー版は未出荷)ものもありますが、それなりのお値段のようです。
今回は、有名なARエンジンである「Vuforia」を利用して、簡易なポジショントラッキングを実現してみます。

Daydream Technical Preview

はじめに、前回説明した、Daydream technical previewのUnityを起動し、適当なプロジェクトを作成してください。
おそらく通常のUnity + Google VR SDK for Unityの組み合わせでの開発も可能かと思いますが、AndroidManifestがVuforia/Google VR SDKで競合するなど、いろいろと面倒な問題が発生するため、今回は割愛します。

Vuforiaのライセンスキー登録

Vuforiaを利用したアプリを開発する際、以下の手順でライセンスキーの登録が必要となります(下記の手順の場合は無料です)。

  1. Vuforiaにログインの後、こちらより、Add License Keyボタンを押下する。
  2. Project TypeよりDevelopmentを選択、Project Detailは、App Nameには適当な名前、DeviceはMobileを選択し、Nextボタンを押下する。
  3. "By clicking "Confirm" below, ..."をチェックし、Confirmボタンを押下する。
  4. License Managerに表示されるアプリ一覧より、2でApp Nameとして入力したものを選択する。
  5. License Keyが表示されるので、これをコピーする。
  6. Unityに戻り、ARCameraのインスペクタを開く。Vuforia BehaviorコンポーネントのApp License Keyにペーストする。

Targetの登録

次に、認識対象となるイメージの登録を、以下の手順で行います。

  1. Target Managerで、Add Databaseボタンを押下する。
  2. Create Databaseポップアップにて、Nameには適当なデータベース名を、TypeはDeviceを選択し、Createボタンを押下する。
  3. Target Managerのデータベース一覧に2で追加したデータベースが追加されるので、これを選択する。
  4. Add Targetボタンを押下する。
  5. Add Targetポップアップにて、TypeはSingle Image、Fileには適当なイメージファイル、widthには実世界(プリントアウトしたイメージ)のサイズ(単位はメートル)、Nameには適当な名前を入力し、Addボタンを押下する。
  6. Download Databaseボタンを押下し、Download Databaseポップアップにて、Unity Editorを選択し、Downloadボタンを押下して、データベース(unitypackage形式)をダウンロードする。
  7. ダウンロードしたパッケージをインポートする。すると、Assets/StreamingAssets/QCARに、データベースが読み込まれる。
  8. ARCAmeraオブジェクトのDatabaseLoadBehaviorコンポーネントに、Load データベース名 Databaseというチェックが現れるので、これをチェックする。また、これをチェックすると現れる「Activate」もチェックする。

f:id:tuti107:20161127200849p:plain

VuforiaがTargetを認識した時の処理

  1. Assets/Vuforia/Prefabs/ImageTargetをシーンに追加する
  2. ImageTargetオブジェクトのImageTargetBehaviorコンポーネントについて、インスペクタにて、TypeはPredefined、Databaseはデータベース名、Image Targetはターゲットの名前を選択する。また、Enable Extended Trackingにチェックを入れる。
  3. f:id:tuti107:20161127201605p:plain
  4. ImageTargetオブジェクト配下に適当なオブジェクト(以下の図の場合はCube)を適当なサイズで配置する。なお、Extended Trackingの効果をわかりやすくするために、縦方向に長くしています。
  5. f:id:tuti107:20161127202058p:plain
  6. 認識用のイメージを印刷する。サイズはAdd Targetにて設定した横幅とする。

フロントカメラ搭載のノートPCやMacをご利用の方は、エディタ上にて実行し、印刷したターゲットのイメージにカメラを向けると、上記のCubeが撮影イメージ上に表示されます。また、Extended Trackingをチェックすると、カメラからターゲットのイメージが外れてしまってもCubeが適切な位置に表示され続けます。つまり、一度でもターゲットのイメージを認識すると、その後はターゲットのイメージの周囲の情報をリアルタイムに認識することで、ターゲットのイメージがカメラ内に無くてもまるでターゲットのイメージがカメラ内に捉えられているかのごとく振舞います(当然、周囲に動くものがある場合はダメなようです)。
www.youtube.com

Google Cardboardとのインテグレーション

  1. ARCamera配下のCameraをDisableする。また、ARCameraオブジェクトのVideoBackgroundManagerコンポーネントのEnable video backgroundチェックを外す。これらは、スマホで撮影したカメラプレビューを背景映像として表示するためのものですが、ポジショントラッキングの用途には不要なためです。
  2. ImageTarget配下のCube(もしくは上記で追加した何らかの3Dオブジェクト)をDisableする。こちらもポジショントラッキングには不要なためです。
  3. シーンのルートにEmptyObject(名前をPlayerとする)を配置、そこにCameraをぶら下げる。このCameraのTagはMainCameraとする。
  4. 以下のPositionTracker.csを作成し、Playerにコンポーネントとして設定する。
  5. using UnityEngine;
    using System.Collections;
    
    public class PositionTracker : MonoBehaviour {
      public GameObject arCamera;
    	
      void Update () {
        var p = arCamera.transform.position;
        gameObject.transform.position = new Vector3 (p.x, p.z, -p.y);
      }
    }
    

  6. Cameraの前に適当な3Dオブジェクト(Cubeなど)をシーンに配置する。

  7. Assets/Plugins/Android/AndroidManifest.xmlのandroid:minSdkVersionを"16"に変更する。
  8. 前回説明した手順にて、Virtual Reality Supportedをチェック、SDKをCardboardとして、Android向けにビルドする

品質は微妙

アプリ起動前に、ターゲットイメージを印刷した紙を(多少ごちゃごちゃした)壁・棚などに貼り付け、この紙の方を向いて端末を起動してください。
f:id:tuti107:20161127220737p:plain

紙に近づけばCubeが大きく、左右に動いたりしゃがんだりすればCubeはそれぞれの方向に動きます。ちゃんとシーンを構成すれば一応ポジショントラッキングのあるVR、な感じになります。以下は、Editorで実行し、前後上下左右にMacを動かした際のものです。
f:id:tuti107:20161128211500g:plain

ただ、品質があまりよくありません。静止していてもプルプル動くし、時々変な方向に飛んでしまうし。。シンプルにARCameraの座標を使うのでは無く、ちょっと一工夫が必要のようです。
また、私のAndroid端末(Galaxy S6)でGoogle Cardboard使用中にデバイスのカメラを利用するためには、Google Cardboardに切れ込みを入れる必要がありました。。
f:id:tuti107:20161127220810j:plain