ARインスタレーション『Ameblo EX』の技術

このブログは[CyberAgent Developers Advent Calendar 2016](http://www.adventar.org/calendars/1620)の7日目です。

<img src="https://qiita-image-store.s3.amazonaws.com/0/42051/22392636-364d-0400-aaf0-f47367e8edc0.jpeg" width="90%" alt="Ameblo EX">

# はじめに
株式会社VR Agentの稲村（[@arumani](https://twitter.com/arumani)）です。本エントリでは、11月20日に開催された『[dotFes 2016 渋谷](http://www.dotfes.jp/2016shibuya/)』というイベントに出展したARインスタレーション作品『Ameblo EX』の技術について、概要や苦労した点、考えた事などを書きます。

# dotFesとは
『[dotFes](http://www.dotfes.jp/)』は主にデザイナー/クリエイター向けのイベントで、トークセッション＋ワークショップ＋展示（インスタレーション）がまる1日行われます。展示エリアは私達の作品のような実験的なものもあれば、数年前からバージョンアップを重ねて現在ではゲームセンターにも置かれている[本格的なゲーム](http://www.gekitsuioh.jp/)まである混沌とした空間になります。

# 『Ameblo EX』概要
今回制作した作品はキャッチコピーの*「アメブロはここまで進化する！？デジタル表現を用いた新しいブログ投稿体験」*[^1]をコンセプトとする**スマホを使ったARアプリ**です。
<img src="https://qiita-image-store.s3.amazonaws.com/0/42051/92a2413f-3aad-d9b1-21d2-3f06241c6f53.png" width="80%">

スマホVR用HMD（ヘッドマウントディスプレイ）[^2]を用いているため傍から見るとVRなのですが、実際にはゴーグル内でその場のリアルタイムな景色が見えており、そこにCGが重なるというARになっています。「場所に紐付いた思い出をブログ投稿しよう」という趣旨で、アプリの流れは以下のようになっています。

1. ゴーグルをかぶり、机上のロゴを眺めるとスタート 
2. 架空の場所（街/島/森）を選択 
3. 机の上にその場所のミニチュアが出現し、それぞれの場所に応じたブログのお題が表示される（島であれば「無人島に持って行きたいもの3つ」）
4. お題に答える形で、音声入力でブログを入力
5. 入力が終わると、そのブログエントリを象徴する1文字[^3]が巨大な3Dオブジェクト[^4]として目の前に出現し、ミニチュアの上に落下する
6. 最後に、ミニチュア上に散らばる過去投稿されたブログエントリ達（の巨大な文字）を眺めて表示される本文を読んだり、ミニチュアに顔を近づけてどアップで景色を見たりなどしたら終了

  ARなのにHMDを用いているのが特徴になっていますが、そうした理由はひとことで言うと**「[HoloLens](https://www.microsoft.com/microsoft-hololens/ja-jp)のような体験をスマホで再現」したかった**ためです。具体的には、

- 一般的なスマホARは平面で表示される → VR用HMDを使って立体視する事で実在感と迫力を出す
- 一般的なスマホVRだとポジショントラッキング（頭の移動検知）ができない → AR技術でポジトラを実現する

という**スマホARとVRの良いとこ取り**を狙いました。

もちろんHoloLensの精度や解像感には遥か及びませんし色々な条件つきでの体験ではありますが、世間的にこのような組み合わせの事例があまり無い事もあってか、幸い体験して頂いた方達に面白がって頂く事ができました。  

一方でスマホ/PCに関わらずHMDを用いた場合の大きな欠点として、**周りの人から見ると何をやっているか全く分からない**という課題があります。これはdotFesのようにその場にいる人達に興味を持ってもらう事が大事なイベント展示の場合、「自分も体験してみたい」と思って頂ける可能性が低くなるため致命的な問題となってしまいます。PCのVRだとよくゴーグル内の映像を横のディスプレイにも表示したり、最近だとその進化版的なものとして[体験している人をVR空間に合成して表示](https://youtu.be/x5TZNxKvSg4)するといった解決策が採られています。ただ今回はスマホという事もあり負荷とネットワーク環境的にそういった解決策の実現が難しかったため、かわりの手段として、体験中のAR環境を俯瞰した映像を展示ブース内のプロジェクターでも投影しました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/42051/2898d8b1-8ebd-e3e1-7292-ed60d0ab61cb.png" width="80%">

 今年超大ヒットとなった[ポケモンGO](http://www.pokemongo.jp/)の影響やApple社CEOがARへの注目を[公言している](http://www.moguravr.com/apple-ceo-ar/)事などから、ARは今年急速に注目が高まってきています。制作チームで今回の展示コンセプトである「アメブロの進化」を考える中で、そのような背景から**「将来的には皆がAR/VR兼用のメガネ型もしくはコンタクト型のデバイスを着ける時代が来るだろう」「1つの方向性としてブログはよりライフログに近くカジュアルなものになっていくのではないか」**という思いを持ち、結果としてAmeblo EXはARを中心に据える事が決まりました。  
次の節ではこのARの概要について少しだけ説明します。

# ARについて
『AR(Augmented Reality)』は一般的に**『拡張現実』**と訳されます。概念の詳細や学問的な定義は書籍[^AR書籍例]や各種Web情報をあたって頂ければと思いますが、ざっくり**「現実の環境や知覚に対して情報を追加する技術（もしくは追加したもの）」**と捉えて良いと思います。ARの事例は世界中に数多く存在し、例えばポケモンGOは[現実の景色にポケモンが追加されて見えます](http://app.famitsu.com/20160728_785913/)し 、[広場に恐竜達が出現する](http://markezine.jp/article/detail/14643)ナショナルジオグラフィックの大規模なキャンペーンや、最近の身近なものだと[カップ麺の上にキャラクターが現れる](http://www.rao.jp/majikoi8/)ラ王のキャンペーンなど、特にプロモーション目的の事例が多くあります。
※事例や最近の動向などは[このスライド](http://www.slideshare.net/ekame/ar-vr-mr-20150830)がまとまっていて参考になりました。

 これらを見ても分かる通りARにおける『現実』は**現状ほとんどが視覚的なもの**なので、一般的なARのイメージは「目の前の光景に人工の絵や文字がうまいこと重なって見えるもの」だと思います。しかしこの**「うまいこと重ねて見せる」技術**や**それとインタラクションする技術**は、違和感の無い現実に近いレベルで実現しようとするとかなり難易度が高いため、丸ごと人工環境に置き換えるVRと比べて今のところハードもソフトも発展途上感が強いものになっています。先日HoloLensを体験しましたが、よく言われる通りAR部分の視野角がかなり狭く感じました、今回の制作で利用したARミドルウェアのVuforia（詳しくは後述）も動かしてみると期待する精度が出ないケースが多々ありました。 とは言え[Microsoft社のプロモーション動画](https://youtu.be/aThCr0PsyuA)は大きな夢と実用性を兼ね備えた未来を感じますし、詳細はまだ不明なものの[Magic Leap](https://www.magicleap.com/)は非常に楽しみであり、中長期で見るとAR市場の方がVR市場よりもだいぶ大きいものになるという[予測](http://jp.techcrunch.com/2015/04/08/20150406augmented-and-virtual-reality-to-hit-150-billion-by-2020/)は、レベル感の差はあれど業界の共通認識になっているようです。

さて、ここからAmeblo EXの技術についての本編です。

# 『Ameblo EX』のシステム全体と利用技術
<img src="https://qiita-image-store.s3.amazonaws.com/0/42051/def9a31b-588f-62f5-cbaa-937a265524bd.png" width="100%" alt="Ameblo EXシステム全体図">

## それぞれの役割
### アプリ本体（iPhone 7 Plus＋VR HMD）
主に以下の機能を実装しています。それぞれのポイントや苦労した点は次項にて。

- 背面カメラを使ったビデオシースルー（画面を通じて周囲の現実世界を見る方式）
- VR HDM＋2眼レンダリングによる立体視
- Vuforiaを使ったAR処理（マーカー画像認識と、それによるポジショントラッキング）
- Unityによるエリア / エフェクト / UIレンダリング
- iOSのSpeech Frameworkを用いた音声認識
- FlyingText3D（Unityアセット）を使った巨大3D文字レンダリング
- サーバAPIを用いたブログ情報永続化
- Photon Chatを通じた文字情報/位置情報リアルタイム同期

### Webカメラ＋ノートPC＋プロジェクター
HMDのみだと周りから見ても内容が全く分からない問題の解決策として、展示ブースの俯瞰映像にAR映像（CG）を重ねたものをスクリーンに投影しました。またそれだけだと若干地味な見た目だったので、派手目のエフェクト、浮遊物の演出を追加しました。

### ブログ保存/取得用API
音声入力されたブログ内容の永続化と、体験開始時にその一覧を端末から取得するためのAPIを実装しています。 [GCE(Google Compute Engine)](https://cloud.google.com/compute/)上で、[Spring Boot](https://projects.spring.io/spring-boot/)の組み込みJetty+H2DBで作りました。
※このエントリ書いていて、まだインスタンスを動かしたままである事を思い出しました…

### Photon Chat
マルチプレイのプラットフォームです。音声入力中のブログ文面を全端末＋プロジェクター用PCで同期するのに用いました。 要件的にシビアなリアルタイム性は不要で、やり取りする内容がテキスト情報＋α程度だったため、[Photon Realtime](https://www.photonengine.com/ja/realtime)よりもシンプルに使える[Photon Chat](https://www.photonengine.com/ja/chat)にしました。

# 利用技術個別のポイント、苦労した部分
## 背面カメラによるビデオシースルー＋VR HDM＋2眼レンダリングによる立体視
スマホの背面カメラによるビデオシースルー（画面を通して外の世界を見る方式）とVR HDMを組み合わせた場合、通常のスマホARのように端末を手に持って画面を見る場合と比べて下記のような課題が顕著になります。  

### 課題(1) 解像度 
画面を視野全体に大きく拡大して見るので、どうしても映像が粗く見えてしまいます。更に今回は[2眼レンダリング](https://www.google.co.jp/search?q=2%E7%9C%BC%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0&tbm=isch)（画面を左右に分割して、左目用画面と右目用画面を作る）なので、片目あたりの画面が半分＝解像度が半分です。ARで重ねるCG部分はピクセル単位でクッキリ描かれるのでそれでも綺麗に見えますが、カメラ映像部分はたとえiPhone 7 Plusという**現状スマホ最高レベルのカメラと画面でも、クリアとは言えない解像度感**になってしまいします。

###   課題(2) フレームレート
 解像度以上に問題なのが[フレームレート](https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AC%E3%83%BC%E3%83%88)（画面を更新する頻度）です。通常のスマホゲームでは最近の端末だとだいたい60fps（1秒間に60回更新）になっていますが、今回の方式の場合ざっくり以下のような重いプロセスになるためフレームレートがかなり低くなります（CPU/GPUのスペックに加えて、カメラ自体の性能も影響します）。

1. カメラ映像入力
2. 画像認識処理（AR用の処理）
3. Unityの3D空間上に映像展開
4. CG部分の描画処理
5. 2眼レンダリング＝おおよそ2画面分の処理量

**VR HDMで視野全体に表示されている映像のフレームレートが低い場合、単に「カクカクしてる」と感じるレベルではなく、リアルに酔ってしまう**ため厳しい問題となります。VR開発における実践的な指針として評価の高い[Oculus Riftのベストプラクティス(PDF)](http://static.oculus.com/documentation/pdfs/ja-jp/intro-vr/latest/bp.pdf)をはじめ、VR酔い対策の話では必ずと言って良いほどこのフレームレートに言及されるほどです。今回のAmeblo EXのフレームレートはiPhone 7 Plusであっても正直なところ長時間体験するには厳しいレベルなのですが、イベント展示で一人当たりの体験時間は2〜3分程度なので言及しつつであれば[^酔い注意]許容できると判断しました。  

### 課題(3) オートフォーカス
 現実の光景を肉眼で直接見る場合、見る距離に応じた焦点の調整を目で行います。しかしビデオシースルーの場合、カメラのフォーカス（焦点）を距離に応じて変えないと、例えば近くにフォーカスがあった状態で固定された映像の場合遠くの景色はどう頑張ってもぼやっとしか見えない（そもそも画面にぼやっと表示されているのでどうにもならない）事になります。スマホのカメラは今回の使い方をする場合オートフォーカス任せになりますが、**目で見ている場所（実際の視線）とオートフォーカスの基準になる場所が常に完全には一致しません**。その結果、「近くを見回しているのに突然遠くにフォーカスが合ってしまって見ているものがいきなりぼやける」「フォーカスがすぐに決まらず映像がぼやけたりクリアになったりを繰り返す」といった事が起きてしまいます。

これもまた酔いや不快感につながるため極力回避したいのですが、フォーカスを制御する手段が見つけられず対応できませんでした。そのためコンテンツ設計での対策として、体験のメインとなる部分は周囲を見回さなくても進められるよう、目の前の（展示ブースの）机の上周辺で完結できるものとしました。  

### 課題(4) 体験場所の明るさ
 周囲が暗かったり極端に明るかったりすると、「フォーカスがなかなか合わない」「画質が粗くなる」「色が飛ぶ」といった問題が起きます（みなさんもスマホなどで撮影する時にこういった問題に当たった事があるのではと思います）。今回のdotFes展示場所は窓からの光を遮断して室内光のみだったため、天候や時間で明るさが変化する事はないものの、場所がDeNAさんの総合受付のホールなので**本番当日まで会場のライティングの状態が確認できませんでした**。結果としてはiPhone 7 Plusの素晴らしいカメラ性能に助けられてライト無しでも十分機能しましたが、暗かった場合に備えてライトを幾つか用意して備えました。
![事前に会議室を暗くして試した時の様子](https://qiita-image-store.s3.amazonaws.com/0/42051/2de53422-f64d-1b2a-e6d3-4d6ffc8061dd.jpeg)
※事前に社内の会議室を暗くして試した時の様子

###   課題(5) 処理負荷 
フレームレートのところでも書きましたが、2眼レンダリング≒2画面分の処理量となるうえ、VR HMDレンズの屈折に合わせた画像の歪み処理（画像全体が樽型になっている所以）を行うので、映像入力やAR処理が無かったとしてもそこだけでも相当な処理負荷になります。これは後述する電池消費量問題の大きな要因の1つになっています。

## AR処理（Vuforia利用）
### Vuforiaについて
[Vuforia](https://www.vuforia.com/)はAR開発に用いるミドルウェアとして、少なくとも一般の開発者向けに提供されているものとしては世界中で最も広く使われています。マーカー処理をはじめとするよくあるARの基本的な機能は当然備えているので、「あそこで見たARのあれをやりたい」みたいな場合はVuforiaでほぼ実現できるのではないかと思います。Unityインテグレーションもunitypackageとして提供されており、最近Asset Storeにも入りました。無料ですぐに開発アカウントも作れるので、**導入は非常に簡単**です。
 有力な競合ミドルウェアとして[Kudan](https://www.kudan.eu/)があり、こちらも最近[資金調達](http://jp.techcrunch.com/2016/07/05/kudan-raises-200m-yen/)したり[博報堂と提携](http://thebridge.jp/2016/10/kudan-partners-with-hakuhodo)するなど勢いがあります。技術的にも**Vuforiaに対して[幾つかの優位性を明言している](https://www.kudan.eu/kudan-news/comparison-kudan-vuforia/)**ので試したかったのですが、今回は制作期間の関係で既に経験があり比較的情報が多いVuforiaを選択しました。

### Vuforiaでの処理(1) [Image Target](https://library.vuforia.com/articles/Training/Image-Target-Guide)を使ったマーカー画像認識処理
いわゆるAR処理として最もメジャーな、「予め指定した画像を見つけて、その位置や大きさ、回転を取得する」という処理です。今回は展示ブース中央の机の上に置いた『Ameblo EX』ロゴ画像をマーカーとし、UnityのHierarchyではそのImage Targetの下に全ての表示オブジェクトをぶら下げる形にしました。更に[ Extended Tracking](https://library.vuforia.com/articles/Training/Extended-Tracking)を有効にする事で、一度マーカーを認識したあとはある程度周りを見回してマーカーが視界から外れても空間上の位置が維持されるようにしています。

例えばTownエリア（今回用意した3エリアのうちの1つの名称）を見たあとに横を向いても、視界の隅の机上にビル群が見えていたりします。これが無いとマーカーが視界から外れた瞬間に全てのCGオブジェクトがパッと消えてしまい、「マーカーを使っています」感満載になってしまいます。もちろん少しでもARを知っている人が見れば一瞬で「これはああやってるんだな」というのは分かる訳ですが、**Ameblo EXでは机の上のマーカー全体を、認識後にエリアの風景で覆って隠している事もあって、体験していると結構マーカーの存在を忘れる**ようで、机上にエリアが出現してるように感じてもらえているようでした。

### Vuforiaでの処理(2) [Digital Eyeware Behaviour](https://library.vuforia.com/articles/Training/Vuforia-for-Digital-Eyewear)を使ったビデオシースルー＋2眼レンダリング
背面カメラからの映像をUnityに取り込み、画面を左右に分割してそれぞれに表示する部分です。Vuforiaの2眼対応は融通があまり効かずUI系の実装が面倒だったので、制作途中でその部分だけ[Google VR](https://developers.google.com/vr/)に切り替えようと試みたのですが、それを説明しているはずのVuforia公式手順では上手く表示されず（しかもUnity Editorと実機でおかしい内容も違う）、どちらも少しソースを追っていくと途端にクローズド部分に当たってしまうため諦めました。今後**Kudan+Google VRを試してうまくいったら、個人的にはそれだけでもKudanに切り替える価値があるかも…**と思うくらいこのVuforiaの2眼処理には振り回されました。

### マーカーを机上の1つに絞った理由
上記の通りARで使うマーカーは机上のロゴ1つですが、当初はこの他に各HMDにもマーカーをつけて相互に位置をトラッキングしようと考えていました。それによって体験中に他の体験者の方を見た際に位置が正確に把握でき、そこに情報や演出を表示するためです。しかし以下の理由で最終的にこのHMDのマーカーは諦めました。 

- **フォーカスが外れる事による位置揺れ問題** 
先に述べたオートフォーカス問題とまた若干異なる問題です。他の人のHMD付加マーカーを読もうとする場合、カメラの焦点をそちらに合わせる必要があります。でないとVuforiaがマーカーとして判定する事ができないためです。一方で、**一度認識してトラッキング中のマーカーでも、カメラのフォーカスが変わってそのマーカーが映像上若干ぼやけた場合、取得する座標が不安定に揺れまくる**事がわかりました。つまり顔を上げて他のHMDのマーカーを読み取ろうとそちらに向いた際にフォーカスが変わると、机上マーカーの位置情報を元に表示しているエリアオブジェエクトや巨大文字オブジェクトが、ガクガクと震えてしまうという事です。これは見た目上致命的です。簡易的なスタビライズ処理を入れてみましたが、本当に視線を動かした場合の追従性とのバランスが悪く、最終的に諦める理由の1つなりました。

- **マーカーの大きさと形状** 
Vuforiaのマーカー処理は、いったん認識してトラッキングが始まるとその後ある程度離れて小さくなったり角度が結構厳しくなっても頑張ってくれます。ただし**最初に認識させる時は、それなりの大きさと正面に近い角度でカメラに映す必要**があります。机上のロゴはちょうど眼下にあり大きさも十分なので問題ありませんが、各HMDにマーカーをつけて認識させる場合、見た目上だいぶインパクトのある大きさでマーカーとなる絵なり物体なりをつける必要があります。しかも他の人が向きを変えた場合にも対応するためには、風船のように浮かせる、何箇所かにとりつけるといった、大勢に体験してもらうという運用に逆行する対応が必要になってしまいます。実際試してみましたが、実用的なレベルで認識させるためには位置や大きさ、姿勢の実験などかなりの調整が必要と感じ、後述の通り別の手段でも目的は達成できるため諦めました。

- **複数マーカーの同時認識による負荷** 
これはちゃんと数字を計測していないので程度問題ではあるかもしれませんが、マーカーを同時に複数認識させる場合、1つだけの場合（1つ見つけたらそこで探すのをやめる、トラッキング中は他のマーカーを探さない）と比べて計算量が増えます。しかも後述しますが今回の展示は電池消費と熱がシビアな問題なので、より軽量な手段で避けられるものはできるだけ避けたいと考えました。特に**画像認識処理はアプリの起動中ほとんどの時間動き続けている**ので、そこの負荷が電池消費の支配的なパラメータではないかと考えています。

- **→マーカー1つで実現する代替案** 
上記の問題と懸念の結果、複数マーカーの同時認識はやめ、かわりに**机上マーカーのAR処理から得た自分のUnity3D空間上の位置をブログ文面と共にリアルタイムに共有する**事にしました。
机上マーカーは位置も向きも固定されているので、机の周りに配置された各HMDの認識する空間上のカメラ座標は位置関係的にお互い矛盾が無いものになるため、単純な位置情報の共有だけで相互の表示が可能です。文面の共有は毎秒1回程度の同期なので、他のHMDを自力で認識するのに比べてリアルタイム性はやや下がりますが、座標情報を追加する処理コストや実装コストは小さく、他のHMDの座標が一瞬ずれていても体験の本質への影響は少ないと判断しました。

### Windshield UIを一部諦めた理由
Windshield UIというのは、[コクピットの窓にUIが投影されたイメージ](https://www.google.co.jp/search?q=windshield+ui&tbm=isch)の、外の景色の動きとは関係なく自分の位置と回転を元に展開されるUIです。とは言え完全に頭部の回転にと一致してUIを動かしてしまうと、視線が検知できずタップもできない現状のVR HMDではボタンなどを選択する手段が無くなってしまうため（横に見えているボタンを押そうとしても、横を向くとボタンが更に横に行ってしまう）、それもそれで問題です。
やりたかったのは、**頭の回転と緩く連動しつつARマーカーの認識状態とは無関係に安定して表示／インタラクションできるUI**です。 しかしVuforiaの2眼対応処理がこれに向かないようでしたので（細かい話は省略しますが、カメラとマーカ位置の安定、注視UIのフォーカス、端末のジャイロの値を使った回転、を綺麗に成り立たせる事が少なくとも検証期間中にはできませんでした）、結局3D空間上にUIを配置し、そのUIが常にプレイヤーの方を向くようにしました。

## Unityによるエリア / エフェクト / UIレンダリング
（ここは担当してくれたKさんに完全にお任せだったので割愛します）

## iOSのSpeech Frameworkを用いた音声認識
音声認識は、iOS 10で実装された[Speech Framework](https://developer.apple.com/reference/speech)を利用しています。もともとシンプルなAPIなところ、Unityアセット『[Mobile Speech Recognizer](https://www.assetstore.unity3d.com/jp/#!/content/73036)』によって更に楽に使えました。認識精度/変換精度も良好なのでそこは良いのですが、今回の利用用途としては以下の懸念点がありました。

- 端末ごと、アプリごとに1日の利用回数制限がある  
[公式ドキュメント](https://developer.apple.com/reference/speech)に以下の制限が明記されています。

> Because speech recognition is a network-based service, limits are enforced so that the service can remain freely available to all apps. Individual devices may be limited in the number of recognitions that can be performed per day and an individual app may be throttled globally, based on the number of requests it makes per day. 

しかし**具体的に何回なのかが分からず**、制限の意図からして問い合わせても明確な答えがすぐに得られるとは思えなかったため、富豪的ではありますが端末を多めに用意するという単純なリスクヘッジを行いました。アプリ毎の総回数については、1日のイベントで最大限回転したとしても、通常の公開アプリで想定されるような回数には達しないだろうからおそらく大丈夫だろう、と**腹を括りました**[^本当は]。結果的には1日展示した中で3回程度、その制限に引っかかった可能性のあるエラーが起きましたが、アプリを再起動したら正常動作に戻ったため大きな問題にはなりませんでした。事前に時間をかけて確認する余裕が全く無かったため、秘かにかなりドキドキしていました。

- 音声認識がクラウド側で処理されるため、認識処理中は継続的に通信が発生する  
オフラインモードは提供されておらず、リアルタイムに変換を行いたいため、**継続的な通信が必須**になっています。Speechの最大入力時間が1分間で、バッファを見て体験中は45秒以内としてはいるものの、電池消費や発熱の懸念がある中でこちらでも頻繁に通信が発生する事には懸念がありました。
実は音声認識入力を試す前に、「HMDに入れた端末とは別にもう1台端末を持ってフリック入力で文章を入力する」という案を試したのですが[^フリック入力テスト]、フレームレートの低さと解像度の問題が相まって、**手元の端末の映像を凝視して数十秒文字を入力するというのが結構目の疲れや酔い的に厳しい**と分かりました。そのため極力音声認識で文章を入力したく、iOSで日本語で実用的な速度と精度かつ低コストとなると現状このSpeech一択と思われるため、結局利用するに至りました。

### 周りの音を拾い過ぎ問題
VR HMDに端末を入れただけの状態だと、（HMDの横に隙間が空いてはいますが）ちゃんと声を拾えないケースがあります。体験されるかた全員に大声で話してもらう訳にもいかないので、ピンマイク[^ピンマイク]をつける事にしました。
しかし冒頭に書いた通り展示会場は混沌とした感じで色んな人の声や音が鳴っており、結果としてはマイクが音を拾い過ぎて、**文章中に謎の単語やフレーズが紛れ込む**という事が頻発してしまいました。かといってマイクを外すとまともに拾えないので、マイクをつける位置を工夫して改善するくらいしか対応ができずに終わる事となりました。
これは今後何かの形で対応したいと考えていますが、すぐに思いつくのは（音声入力にこだわる場合は）指向性マイクにする、口の周りを覆う何かを作る、ソフトウェア的に閾値を設定できるよう頑張る、展示場所をホールではなく個別の部屋にしてもらう、という高コストもしくは茨の道っぽい対策しか思いついていません。

## 巨大3D文字レンダリング
文字をポリゴンで作ってPhysicsが簡単に使えるようにしたいという事で探した結果、Unityアセット『[FlyingText3D](https://www.assetstore.unity3d.com/jp/#!/content/3627)』を利用しました。これは柔軟な設定とシンプルな使い方が出来るので、ほぼ当初の要件を満たしてくれて有り難かったです。このアセットの使い方は別のQiita記事として以前書きました。 [Unityで文字の3Dモデルを作る（FlyingText3Dアセット編） - Qiita](http://qiita.com/arumani/items/fc7211287678deb75277)

## サーバAPIを用いたブログ情報永続化
[UnityWebRequest](https://docs.unity3d.com/ja/current/Manual/UnityWebRequest.html)でAPIサーバに対してGET/POSTしているだけです。
サーバ側は前述の通りSpring Bootでごく短時間で作る事ができました。こちらも特筆すべき話は無いので省略します。

## Photon Chatを通じたリアルタイムな文字情報＋位置情報連携
標準にUnity統合が用意されており簡単に始められる[Photon Chat](https://doc.photonengine.com/ja-jp/chat/current/getting-started/chat-intro)を使い、体験している方それぞれが音声入力している内容や、見ているブログの文面をリアルタイムに共有しました。
使い方としては単純で、固定IDで単一のルームを作った上で、そこにチャットの発言として入力中の文面＋Unity上の自分のカメラ座標（＝体験者の頭の位置）を投げました。[Photon Realtime](https://www.photonengine.com/ja-JP/realtime/)は今回の要件にtoo muchで価格もChatより高かったためこちらを選択しました。後述する通信環境問題を除いては、Photon Chatそのものは何の問題も無く使えて助かりました。

## Webカメラ＋PC＋プロジェクター
このエントリの冒頭近くの写真を見て頂いただけで伝わるかどうか自信が無いのですが、以下のような仕組みでプロジェクター投影を行いました。

- Webカメラ[^Webカメラ]をスクリーンの最上部に取り付けて、展示ブースを斜めに見下ろす形で映す。この位置にしたのは以下の理由がありました。
  - 机の上にCGでエリアが乗っている様子を通りがかりの人に見せるのが最大の目的なので、机全体を映す
  - 机の周りも映して、録画映像ではなくその場をリアルタイムに映しているのがわかるようにする
  - 展示ブース全体が暗い中で投影のみ明るいので、カメラの前を人が通りがかって陰になる事でブース全体が暗くなったり明るくなったりするのを避ける

- Unityで[WebCamTexture](https://docs.unity3d.com/jp/current/ScriptReference/WebCamTexture.html)を使ってWebカメラの映像を取り込み、写っている机の上に、座標固定（決め打ち）でCGのエリアを定期的に切り替えて出す。
固定にした理由としては、マーカーもカメラに写り込んでいるのでARで出す事もできたのですが、決め打ちで出すのに比べると表示が安定しなかったため、このプロジェクターに関してはAR処理そのものを入れず、人間が目で大きさや角度を合わせて表示しました。当然ながらカメラも机も展示中は一切動かさない前提だからこそ成り立つ手法でした。

- ノートPCからもブログ取得APIにアクセスし、そのエリアに直前までに入力されたブログの文字をバラバラと落とす。VR HMDの体験と違ってこのプロジェクターの映像では本文を読む事ができないので、謎のひらがなや漢字が散らばっているだけなのですが、見た目のインパクトがあるので多めに落としました。

- それでも見た目が地味（うっかりすると監視カメラの映像のように見えなくもなかった）なので、画面全体に演出でパーティクルやオブジェクトを飛ばして、より多くの人に興味を持ってもらえるよう努めた。

# アプリ全体の技術的課題
かなり長くなっていますが、上記の技術個別の話の中で何度か出てきた、全体に関わる課題について。

## 電池消費量
『Ameblo EX』は、以下の処理が重なる事でかなり電池消費が激しいアプリになっています。

- ビデオシースルー
- AR処理（画像認識）
- 2眼レンダリング
- 3Dのレンダリングと物理演算（これはUnity上普通の話ではあります）
- 音声認識（継続的なサーバ通信）
- サーバを経由した端末間のリアルタイム同期（継続的なサーバ通信）

はじめAndroid（Galaxy S6）で動かしてみたところ、みるみる内に電池が無くなっていきました。その後の検証の結果、バッテリーの持ち、画面が綺麗で大きい、処理速度が速い、を兼ね備えたiPhone 7 Plusに統一しました。
それでも**フル充電の状態から休み無しに使い続けると2,3時間程度しか持たない**と分かり、展示時間は7時間ほどあるため、音声認識の回数制限回避を兼ねてローテーションさせる事にしました。

## 発熱
上記の通り電池消費が激しい＝発熱します。しかも**VR HMDに入れるため通常よりも放熱ができない状態**なので、発熱し放題みたいな状況です。
こちらはローテーションで回避できるレベルかどうかも怪しいと考えていたのですが、ビデオシースルーのために背面の一部が開いて事も寄与したためか、確かに熱くはなるものの、クロック数強制ダウン／暴走／電源断などが起きるところまではいかないようだ、という事が分かりました。

なお電池消費と発熱問題のオチとしては、**本番当日は幸か不幸か常時行列という事態にはならず**、特にトークセッションが開催されている時間帯はまず全台稼働はしないという状態でした[^うちだけでは]。そのため、そういう時間帯はHMDを開けて端末もスリープさせてこまめに充電する事で、最終的にはギリギリでローテーションせずに持った状態で展示時間終了を迎えました。

## 当日の通信環境
**これが本当に最大の障害で、死ぬかと思いました**。人が集まるイベントなのである程度悪化するとは予想していましたが、以下のように本当にギリギリセーフな状況でした。

- 会場のヒカリエで提供されている**公衆WiFiは最初から全く通信できなかった**
- こんな事もあろうかと持って行った2台のポケットWiFiは、**どちらもイベント開始直後からみるみる遅くなっていき**、20分くらいした段階で実質的に数百KBを超える通信はできないレベルになった。
- 困ってイベント運営の方々に相談した結果、隣の会場で行われているワークショップのWiFiに相乗りさせて頂ける事になったが、**そちらも速度が非常に低下しており利用がほぼできなかった**（一応画面上のアンテナは立っていましたが、隣の部屋なのでというのもあったかも）
- ますます困って相談した結果、主催のDeNA社の方から個人のXiのWiFiを提供して頂き、**それだけが唯一快調に通信する事ができ**て、ギリギリセーフだった

展示慣れしている方には、そういう展示でネット接続を前提にするとか怖すぎて出来ないと言われました…。
次からは全てオフライン or 有線前提にしたいと思います。

# おわりに（感想など）
## 立体視AR（AR＋VR HMD）の魅力について
実装や運用上苦労した部分はあったものの、やってみての感想としては、立体視ARは通常のスマホAR（端末を構えて画面を見るAR）と比べて魅力が2〜3倍になると感じました。ただし現状の解像度とフレームレート、AR部分の座標の安定性だと、目の負担と酔いやすさも10倍くらいになっています。

 立体視と言っても背面カメラのビデオシースルーによる現実の光景は視差[^視差とは]が無いので、正確に言うと立体視できるのはUnityで重ねたCG部分だけなのですが、その**CG部分が立体視に引き摺られてその他の現実部分も立体のように錯覚する**と感じました。そもそも体験直前まで現実に見ていた光景である事なども影響しているかもしれません。

ともあれHDMを用いることで通常のスマホARの「覗き窓」感が無くなり、拡張された情報を眼前まで近づけたり大きなオブジェクトを見上げたりできるので、今後のVR用HMD普及と相まって事例が色々増えてくるかもしれないと思っています。惜しむらくは、先日Googleが販売開始した[Daydream](https://vr.google.com/daydream/headset/)のゴーグルに**背面カメラ用の穴が無い**ことでしょうか。**[初代Cardboardには穴があった](https://vr.google.com/cardboard/images/join-the-fold_2x.jpg)**のに…。

## VR好きエンジニアの方はARもいかがでしょう
 このクソ長くて文字ばかりのエントリを読んで頂いているエンジニアの方の中には、VRに興味がある、もしくは既にVRで何か作られているという方が結構な割合でいらっしゃるのではと思います。そういった方で「ARは今のところ特に…」という方がいらっしゃったら、これを機に是非そちらも触ってみてはいかがでしょうか。
私自身まさにそのパターンで、某案件と今回でARでのモノづくりをした結果、VRとはまた違った大きな魅力を感じるようになりました。ARとVRはハードソフト共に今後融合が進むと思われるので、触れておいて損は無いと思います。ちょうど今月[GoogleのAR関連技術Tango](https://get.google.com/tango/)の初実機[Phab2 Pro](http://shopap.lenovo.com/jp/tango/)が日本でも販売開始された事ですし[^phab2pro]。

## 株式会社VR Agentについて
本当に最後に、私が所属している株式会社VR Agentについてちょっとだけ紹介させて下さい。
<img src="https://www.cyberagent.co.jp/files/topics/12976_ext_05_0.png?b3bd2de468d79065dd1f29c0a9742486" width="50%">

[今月1日（2016年12月1日）に設立された](https://www.cyberagent.co.jp/newsinfo/info/detail/id=12976)ばかりの、VR事業を行うサイバーエージェント子会社です。VR/ARを用いたイベントやアミューズメントコンテンツ、VR関連サービスの制作、開発、運営を行っていきますので、皆様よろしくお願いいたします。

まだHPやメールアドレスも出来ていないようなホヤホヤ状態なので、もしお話やご質問などがありましたら、[@arumani](https://twitter.com/arumani)か、inamura_so あっと cyberagent.co.jp まで是非ご連絡下さい。


それでは、お読み頂き本当に有難うございました！

---

[^1]: かなりフワッとしているのは理由があり、このコピーを提出した時点では企画が具体的に固まっていなかったので、どう作っても間違いにならない文言を選ばざるを得ませんでした:-)
[^2]: HMDは背面カメラ部分が開けられるという条件で選んだ結果、価格も安かった[VOX 3DVR ゴーグル](http://amzn.asia/ftjWuss)にしました
[^3]: 実際には冒頭の1文字固定ですが、コンセプトとしてそのように説明していました
[^4]: 制作中は「[コエカタマリン](https://www.google.co.jp/search?q=コエカタマリン&tbm=isch)」と呼んでいました
[^AR書籍例]: [AR(拡張現実)技術の基礎・発展・実践 (設計技術シリーズ) ](http://amzn.asia/0VH5vE1)はタイトル通り各種の実現技術やその長所短所、今後の課題などが網羅されていて、個人的にとても勉強になっています
[^phab2pro]: 先日注文しました。早ければ今週届くので（少なくとも直販サイトにはそう書いてありました）、楽しみにしています
[^酔い注意]: 基本的に体験者にマンツーマンで説明スタッフがついていたので、説明の際に酔い注意についても言及するようにしました。
[^本当は]: 一応回避策も考えたのですが、思いついたものが若干グレーで別のリスクになるため結局実行しませんでした。
[^フリック入力テスト]: その時にiOS/Androidの漢字変換まわりを調査してまとめたのが [UnityのInput Field日本語入力挙動まとめ（iOS / Android） - Qiita](http://qiita.com/arumani/items/cdc02a1eef60cc815fd3) です。
[^ピンマイク]: ピンマイクは[AGPtEK Z02 新型 ミニクリップマイク マイクロフォン](http://amzn.asia/bDGVnQo)にしました。
[^Webカメラ]: 視野角と明るさから、[ロジクール c930e](http://www.logicool.co.jp/ja-jp/product/c930e-webcam)にしました。
[^うちだけでは]: 私達のブースに限った話ではなく、わりと展示全体がそんな感じでした。たぶん…
[^視差とは]: 右目と左目で見えるものの微妙な違い