読者です 読者をやめる 読者になる 読者になる

Tutti Lab

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

Oculus Touchをつかってみる

Oculus Touch

Oculus Touchが出荷され、約一月が経ちました。Oculus StoreにはOculus Touch対応コンテンツが多数並び、Oculus Touchの凄さを体験できるわけですが、一方で開発向きとなるとまだ情報が足りない状況のようです。
今回は、Oculus Touchの練習用に作成したコンテンツを取り上げ、開発のポイントを挙げていきたいと思います。
youtu.be
コンテンツは、今年大流行したアレを、Oculus Touchで体験する、というものです。

情報収取

Oculus Touchの技術情報については、以下が必読です。

準備

Oculus Touchにて「手やアバターを表示し、なにかをつかむコンテンツを作る」ためには、以下のインストールが必要です(詳細は上記情報収集をご参照)

  • Oculus Utilities for Unity 5(こちらからダウンロード可能)
  • Oculus Avatar SDK(同じくこちらからダウンロード可能)
  • Avater Grab Sample(こちらからダウンロード可能)、なおUnity 5.5でのみ動作(Unity 5.4ではクラッシュ)とのこと
  • その後適当なプロジェクトを作成し、上記ダウンロードしたパッケージ(OculusUtilities.unitypackage, OvrAvatar.unityPackage, AvatarGrabSample.unitypackage)をそれぞれインポートします

サンプル実行

Assets/Samples/Content/AvaterWithGrab をダブルクリックして、シーンをロードします。あとは、PlayerSettings→Other SettingsのVirtual Reality Supportedをチェックし、実行してみます。
f:id:tuti107:20161231102951p:plain
つかむ・離す・投げる、一通りのことができます。

つかめるものを追加

まずは、サンプルで「つかめるもの」がどのようになっているかを見てみます。
f:id:tuti107:20161231103341p:plain
ポイントは、Grabbableというスクリプトです。これはAvater Grab Sampleに含まれるスクリプトで、これを追加したオブジェクト(かつ、Collider, Rigidbodyも追加する必要あり)がつかめるようになります。
つかんだ時、離した時の振る舞いは、Grabbable#GrabBegin()、Grabbable#GrabEnd()メソッドにそれぞれ記述します。これらメソッドはvirtualメソッドですので、Grabbableクラスの子クラスを作ってこれらメソッドをオーバーライドすれば、任意のつかむ・離す際の処理を作成することができます。

Oculus Touchのバイブレーション

OVRHapticsClipを使用します。AudioClipを引数としてOVRHapticsClipを作成することで、そのAudioClipの音量に基づいた振動を作成できます。
作成したOVRHapticsClipを引数としてOVRHaptics.RightChannel.Mix()(=右側コントローラ、左側の場合はOVRHaptics.LeftChannel.Mix())を呼び出すことで、Oculus Touchが振動します。なお、振動させるためのメソッドにはMix()以外に幾つかあり、それぞれ挙動が異なります(詳細は情報収集で挙げたサイトを御覧ください)。
以下は、スタティックメソッドSE.PlaySE()を呼び出すと、効果音鳴動+振動するサンプルです。

using UnityEngine;

public class SE : MonoBehaviour {

  public AudioSource audioSource;
  public OVRHapticsClip hapticClip;

  private static SE thisObj;

  void Start () {
    thisObj = this;
    hapticClip = new OVRHapticsClip(audioSource.clip);
  }
	
  public static void PlaySE() {
    if (thisObj != null) {
      thisObj.audioSource.Play();
      OVRHaptics.RightChannel.Mix(thisObj.hapticClip);
      OVRHaptics.LeftChannel.Mix(thisObj.hapticClip);
    }
  }
}

No Oculus Rift App ID has been provided

エディタで実行すると、問題なく実行できますが、上記のエラーがでます。Oculusサイトにて、アプリを登録してIDを取得することで、本エラーを回避できるようです(私がつくったコンテンツをエディタ上で実行する上では特に問題がなかったため、試していません)。詳細は、上記「情報収集」で挙げたサイトを御覧ください。

PP◯Pっぽい素材

終わりに

Oculus Touchは本当にすごいです。CG空間に触る、というユーザ体験は先行していたHTC Viveをも超えるものでは、と個人的には思います。

VR Trip around the world

MSI VR JAM Oculus CV1 VR Game

私が開発したVRゲーム「VR Trip around the world」が、幸運にもVRゲームコンテストMSI VR JAMのファイナリストに残りました。

プレーヤーは、指定された場所で写真を撮影すべく広大なVRの世界を飛び回ります。VR世界の移動、となると最も懸念の課題が「VR酔い」です。本作では、遠くへ移動する際「巨人」になって世界を見渡し、次に行く場所を探します。「巨人」になって世界を見渡し、怪しそうな場所を探して、「元の姿」に戻り、細かな場所を探索する、という新たなVRにおける移動手段についても提案しています。
www.youtube.com

本アプリはOculus CV1専用であり、こちらから無料でダウンロードできます。
ぜひプレイいただき、気に入って頂けた方は、こちらより投票を頂けると幸いです(2016年12月28日迄)。

Vuforia for Unityを使って(擬似)ハンドトラッキング

Google VR SDK Google Cardboard Vuforia ハンドトラッキング hand-tracking

前回、Viforia for Unityの機能を活用し、Google Cardboardでポジショントラッキングを実現する方法について記載しました。同様に、Vuforia for Unityを使うことで(擬似)ハンドトラッキングも可能です。
Vuforiaでは直接「手」を認識することはできません。しかし、手にマーカーを貼り付ける、マーカーを貼り付けたふだを持つなど、マーカ認識を通じて手の位置を認識する、ということは比較的容易に実現できます。
先日とあるVRイベント向けに開発した「Santa Claus Job Simulator」というサンタのお仕事を体験するアプリにて、この擬似ハンドトラッキングを実装してみましたので、本実装技術についてご紹介したいと思います。
www.youtube.com

ARCameraの設定

Google CardboardにてVuforia for Unityを利用した(マーカ認識による)ハンドトラッキングをする際のポイントは「VRのヘッドトラッキングを考慮した上で、Vuforiaで認識した「手」を「手の位置」に表示すること」です。
Vuforia for Unityはデフォルトでは「はじめに発見した認識対象の座標を固定し、認識対象との位置関係に応じてCameraの位置を変える」という設定になっています。VuforiaがImage Targetに指定された認識対象を発見した際、Image Targetの座標・回転が変化するのではなく、ARCamera(Main Cameraを子として含む)の座標・回転を変化させることで、相対的にImage Targetが動いているように見せます。
VRでなければ、特段問題は生じませんが、VR(Player SettingsにてVirtual Reality SupportedがON)の場合、ヘッドトラッキングによりデバイスの回転によりMain Cameraを回転させます。このため、上記のデフォルト設定では、ヘッドトラッキングの回転設定とVuforiaの回転設定が競合してしまい、ちょっと都合が悪いです。

そこで、

  • ARCameraのVuforia BehaviorコンポーネントのWorld Center Modeをデフォルトの「FIRST TARGET」から「CAMERA」に変更します。これで、認識対象物が発見された際の固定される座標はMain Cameraとなり、代わりにImage Targetの座標が変わります。
  • また、もう一点、Image TargetはMain Cameraの子とします。これは上記の通り、認識対象の位置はMain Cameraが固定であることを前提としていますから、ヘッドトラッキングによるMain Cameraの回転変化に関わらず、Image TargetからはMain Cemeraが固定に見えるようにするためです。

f:id:tuti107:20161221234833p:plain

また、Image Targetと「手」の位置関係にも工夫が必要です。Santa Claus Job Simulatorでは、マーカ付きの看板を手に持ってもらい、そのマーカを認識することで手を表示するようにしています。
f:id:tuti107:20161221233051p:plain

このためImage Target認識時に表示される手の位置・回転は、看板に貼り付けられたマーカからの相対位置・回転を設定する必要があります。
f:id:tuti107:20161221233148p:plain

高速化が不可欠

Vuforiaをハンドトラッキングに活用する上でもう一つ重要な点は、可能な限り処理の高速化を図ることです。
VR表示しながら、同時にマーカ認識するという処理は、モバイル端末にとって非常にヘビーなものとなります。
このため、Edit->Project Settings->Qualityにて処理をFastestとして描画・表示負荷を下げる等、できるだけ処理を軽くし、Vuforiaの認識処理にリソースを回してあげる必要があります。
描画負荷が高い場合等、Vuforiaの認識処理のための余裕がない場合、認識の品質は明らかに低下し、すぐに認識対象を見失ってしまいます。こうなると心地よりハンドトラッキングとは程遠くなってしまいます。

最後に

今回は、Google Cardboard向けに(擬似)ハンドトラッキング処理を実装した当方が開発したゲームを例に、Vuforiaによる(擬似)ハンドトラッキングを実装する方法について説明をしました。
モバイル向けにはVuforiaを活用したハンドトラッキング・ポジショントラッキングをどんどん活用したい、と思っていますが、最新のモバイルVRヘッドセットであるDaydream ViewではVuforiaが使えません。Google Cardboardのようにスマホカメラの位置に穴を開けるわけにはいきませんので。。
何らか他の方法を検討する必要があるな、と考えております。

UNIBOOK7で、ThetaSによる360度立体視映像配信について書かせていただきました

360度立体視 THETA Unity

知人に紹介いただいたことがきっかけで、UNIBOOK7の「第8章 ThetaSを使った360度立体視映像配信」を書かせていただきました。
f:id:tuti107:20161221221355j:plain
半年ほど前、ThetaSを2台使った360度立体視の撮影・配信についてブログにかきましたが、その当時は、私の知識不足&当時作成していたアプリの要求仕様に合わない、ということから中途半端となっていた、撮影と配信、そして配信映像を視聴するためのモバイルアプリの作り方について記載しております。
本書には、その他多数の著名クリエイターが執筆した読み応えのある内容満載です。購入いただけると幸いです!

www.unity-bu.com

Oculus Touch + Daydream View

Daydream Oculus Touch

Oculus TouchとDaydream View、それにPixelが一気に届きました。週末はいじり倒します!
f:id:tuti107:20161208224808j:plain

Vuforiaの認識精度を上げるには

vuforia Cardboard ポジショントラッキング positional tracking

はじめに

前回、Vuforia for UnityのExtended Tracking機能を利用してGoogle Cardboardでポジショントラッキングということで記事を書いたところ、ブログ始めて以来の反響、非常に驚きました。モバイルVRでもポジショントラッキングをやりたい、というニーズは高いのかもしれません。
前回の記事では、結局十分な精度を実現できず、自分が動かなくても、プルプルとポジションが動いてしまう状態のままで公開をしましたが、その後、精度を上げる方法について調べましたので、これをご紹介しようと思います。

理想的なイメージとは?

Vuforiaは、イメージの特徴点を比較することで、イメージを認識します。特徴点の詳細については割愛しますが、Vuforiaの場合、この特徴点は「イメージを白黒化した上で、尖った部分
(三角形や長方形の角のような箇所)」に多く現れるようです(詳細はこちら)。
理想的なイメージは、
- コントラストがはっきりしている。コントラストが低いと「尖り」が分かりづらくなるため
- ごちゃごちゃしている。シンプルだと特徴点が少なくなってしまう
- 規則性がない。詳細は分かりませんが、特徴点を比較する上で、規則的な配列の特徴点は、認識率を悪化させるのだと思われます
もの、となります。

f:id:tuti107:20161201161146j:plain f:id:tuti107:20161201161155j:plain

前回は、Vuforiaがサンプルとして提供している「stones」というイメージを利用しており、上記の条件は満たしております。

印刷品質・サイズ

次に疑われるのは、印刷したイメージの印刷品質・サイズです(詳細はこちら)。
印刷したイメージのサイズがあまりにも小さすぎると、カメラより入力した画像から十分な特徴点を抽出できず、認識を失敗したり・精度が不安定となります。サイズについては、端末ー印刷物間の距離(m)<印刷物のイメージの幅✖️10以下、とするのが良いようです。前回私は幅30cmでイメージを印刷したので、距離は3m以内、ということになります。私はせいぜい2m程度の距離で試したため、印刷サイズの問題ではないようです。
印刷品質については、「コントラストはっきり」「テカらない」、かつ「印刷物に折り目などがない」ものである必要があります。
私は前回、ペラッペラの再生紙に、印刷品質「普通」で印刷したため、コントラストが低く、紙がよれてしまい一部部屋の光をかなり反射している、という最悪の状況になっていました。
そこで、ためしにイメージをディスプレイに表示し、試してみたところ、品質はかなり安定しました。早速こちらの紙を注文しました!

終わりに

前回品質が低かった理由は、単に印刷物が粗末だったためでした。ディスプレイ表示によるポジショントラッキングは、ゲーム等の開発に十分耐えうる品質(Oculus RiftやHTC Viveと比べればかなり低いですが)です。
ちなみに、名刺サイズの用紙に認識用イメージをプリントし、手の甲に貼り付ければ、簡易ハンドトラッキング(ハンドポジショントラッキングというのが正確)も可能な旨、確認しました。これらを駆使すれば、モバイルVRでも、Oculus RiftやHTC Viveの様な没入感のあるアプリを開発することもできそうですね。

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

Android Cardboard モバイルVR Vuforia ポジショントラッキング positional tracking

はじめに

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