UE4でARKitをやった話

[Unreal Engine 4 (UE4) その2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/ue4_zwei)の14日目です。

UE4でARKitを使って、HandHeldARのテンプレートを動かす、以降のネタを日本語でやっている情報が少なかったので、その辺りをちょっといじってみた話を適当にまとめて書きます。

##はじめに
最初に言い訳するのもおかしいですが、
HandHeldARのテンプレートを動かす、以降の情報が全然ないうえに、
Macに不慣れ＆手元のMacの性能的にパッケージ化めっちゃ時間かかる&実機でしか確認できない、という3重苦なので、色々不十分感はありますので、間違ってるとかもっと情報あるとかあったら教えてもらえると助かります、という状態です。ということを書いておきます。

##検証バージョン等
UE4のエンジンバージョンは4.21.1です。
また、Xcodeのバージョンは10.0、iOSのバージョンは12で行っています(ハードはiPhone6S Plus)。
(※記事投稿時最新のエンジンバージョンは4.21.1ですが、実際に色々やっていた際のエンジンバージョンが4.20.3だったので、いくつかの情報やキャプチャがエンジンバージョンは4.20.3ベースのままかもしれません。)

##HandHeldARテンプレートを作成する
新規プロジェクトからブループリントタブの「HandheldAR」を選択して、プロジェクトを作成します。

![UE4_ARKit1.png](https://qiita-image-store.s3.amazonaws.com/0/214053/ea251fbc-bffc-612a-ec43-ceb2774a6fdd.png)
![UE4_ARKit2.png](https://qiita-image-store.s3.amazonaws.com/0/214053/46117b2c-2f79-1170-19f0-a76a7afc1d78.png)

あとはiOS用のデプロイ設定をプロジェクト設定から行い、まずテンプレートが実機で動かせる状態まで持っていきます。

ARKitのプロジェクトを実機で動かす具体的な手順については、ここでは記載しませんので、それについては以下のページ等を参考にすると良いかと思います(本記事ではテンプレートが実機で動いた後から、いじった話を書きます)。
[公式のiOSクイックスタート](http://api.unrealengine.com/JPN/Platforms/iOS/QuickStart/index.html)
[スライド](https://www.slideshare.net/EpicGamesJapan/ue4ar-ver-100)
[スライド](https://www.slideshare.net/T_Sumisaki/ue418arkit-ue4in3)
[ブログ](http://historia.co.jp/archives/8782/)
[ブログ](https://creator.game.cyberagent.co.jp/?p=4159)
[ブログ](http://jyuko49.hatenablog.com/entry/2018/07/07/180202)
ちなみに、もしこの辺りのプロビジョニングとかで詰まった場合は、最初からやり直すのをオススメします(私はこの辺り謎に詰まって、やり直したらいけたというパターンでした)。
[(某エピックなところの人も似たようなことを言っていますね。)](https://twitter.com/pafuhana1213/status/1067419112324788225)

##ARSessionCongigについて
![UE4_ARKit3.png](https://qiita-image-store.s3.amazonaws.com/0/214053/d359500a-d50b-6e70-c5f7-b38e8ed53fb6.png)
わりと重要な要素として、ARSessionConfigというものがありますが、詳細がよく判らないので、今判っている範囲で情報を書いておきます。
(テンプレートでプロジェクトを作成すると「HandheldARBP」フォルダに「D_ARSessionConfig」という名前で置いてあります。)
自分で作成する場合は、詳細なアセットを作成の「その他」→「データアセット」を選択し、「ARSessionConfig」を選択すると作成できます。
設定項目は以下の通りです。
#####World Alignment
[ここ](https://developer.apple.com/documentation/arkit/arsessionconfiguration/worldalignment/gravityandheading)に記載されているgravityとcameraの設定に対応しているっぽい

#####Session Type
ARモード時に適用されるトラッキング関連の設定みたいです

| 項目名 | 説明 |
|-----|-----|
| None | ARによる各種トラッキングは行わない設定 |
| Orientation | 自分のデバイスの位置のトラッキングのみを行う設定 |
| World | デフォルト値。検出している現実のオブジェクトのトラッキングも行う設定だと思います |
| Face | 顔に対してARのトラッキングを行うようの設定みたいです。iPhoneXとかでないとフルに機能を使えないっぽい |
| Image | ARマーカーのように、登録した画像を検出してトラッキングする機能があるので、それに該当するみたいです |
| Object Scanning | 現実空間のオブジェクトを検出するために、事前にスキャンの工程が必要なようで、そのスキャン用のセッション設定みたいです |

#####Holizontal Plane Direction
水平面の検出をするかどうか

#####Vertical Plane Direction
垂直面の検出をするかどうか

#####Enable Auto Focus
基本的には有効にしておいていいみたいです
ただ、有効な場合はマクロカメラとか小さいオブジェクトのトラッキングをする際にずれが出やすいらしい

#####Light Estimation Mode
光の推定モード
「None」以外に「Ambient Light Estimate」と「Directional Light Estimate」があるが、「Directional Light Estimate」はまだサポートしていないっぽい
「AmbientLighjtEstimate」になっていると後述の「ARBasicLightEstimate」を使った現実空間の光の推定ができる模様

#####Enable Automatic Camera Overlay
カメラのトラッキング(自デバイスのトラッキング)の状態をリセットするかどうか
たぶんセッションの開始時にリセットするかどうか

#####Enable Automatic Camera Tracking
オブジェクトのトラッキングの状態をリセット(削除)するかどうか
たぶんセッションの開始時にリセットするかどうか

#####Candidate Images
検出を行う画像オブジェクトを設定しておくみたいです

#####Max Num Simultaneous Images Tracked
画像のトラッキング数上限数
パフォーマンス的な意味合いで制限をかけられる模様

#####Environment Capture Probe Type
環境マッピング的なキャプチャ処理の設定、「None」以外に自動(「Automatic」)と手動(「Manual」)で作成する設定があります

#####World Map Data
AR的に認識する空間を、セッション開始時に作成するのではなく、今までのセッションで使用したデータを使う場合は、そのデータを設定するようです

#####Candidate Objects
検出を行う現実空間のオブジェクトの設定をしておくみたいです

##現実のライティングを反映させてみる

####ARKit2.0用のプロジェクト設定を行う
ARKit2.0の機能を使用することになるので、そのための設定が必要なようです。

プロジェクト設定を開き、「iOS」の「Rendering」にある「Metal Desktop-Forward Renderer」のチェックを有効にします。
「Max Metal Shader Standard To Target」は可能な限り最新にします。
そして設定を反映するため、エディタを再起動します。
(これを有効にすると、Metal2.1未満ではZ-Fightingの影響で一部マテリアルが正常に表示されないようです。Metal2.1はUE4.21から利用できます。)
![UE4_ARKit4.png](https://qiita-image-store.s3.amazonaws.com/0/214053/79981c5d-0007-dd7b-2bf1-e806bf83615e.png)

次はAR用のConfigを編集します。
テンプレート使用時に自動生成される「D_ARSessionConfig」を開きます。
「Environment Capture Probe Type」を「Automatic」にします。
![UE4_ARKit5.png](https://qiita-image-store.s3.amazonaws.com/0/214053/65c2ecbf-f55a-6a0b-d41f-00af6fde45f2.png)

####SkyLightとして現実の環境を反映する(環境マッピング的な)
(※これはエンジンバージョンが4.20.3の場合だと私の手元ではうまく動いていませんでした。)
AR用のSkyLightを作ります。
ブループリントを新規作成し、親クラスは「ARSkyLight」を選択します。
![UE4_ARKit7.png](https://qiita-image-store.s3.amazonaws.com/0/214053/391addd8-856f-9be5-69ed-271ee1104114.png)
![UE4_ARKit8.png](https://qiita-image-store.s3.amazonaws.com/0/214053/47af306c-e301-2762-2a7f-2a63d5a9232b.png)

ブループリントを作成したら、イベントグラフのBeginPlayノードに「GetAllTrackedEnvironmentCaptureProbes」ノードを呼び出し、SkyLightのキューブマップ用のテクスチャ情報等を取得します。
これで認識している環境キャプチャ情報が取ってこれるみたいです。
複数のデータの取得に対応していますが、ひとまず今回は動いているか確認したいレベルなので、配列の先頭の1つだけ取ってきます。
「SetEnvironmentCaptureProbe」ノードの引数「inCaptureProbe」に先頭のデータを渡します。
これで取得した情報を適用してくれるみたいです。
![UE4_ARKit9.png](https://qiita-image-store.s3.amazonaws.com/0/214053/3cdd0ec0-a9e0-6075-c486-25cd9a71e4dc.png)
(ただ実際はセッション開始後でないと「GetAllTrackedEnvironmentCaptureProbes」ノードで中身の入った配列は返ってこないので、画像のようにセッション開始後にも確認してくれる仕組みは必要です。)

あとは、レベルに置いてある「SkyLight」を作成した「ARSkyLight」に置き換えます。
これで環境マッピング的なことの反映もできるみたいです。
![UE4_ARKit10.png](https://qiita-image-store.s3.amazonaws.com/0/214053/54fc01ca-3a1e-6440-31cd-5811da04a966.png)

####現実の明るさと色味をDirectionalLightとして反映する
レベルブループリントを開いて、
「GetCurrentLightEstimate」ノードを出して、戻り値を「CastToARBasicLightEstimate」ノードにつなぎます。
そのままTickノードにつなぎ、キャストしたARBasicLightEstimateから「GetAmbientColor」、「GetAmbientColorTemperatureKelvin」、「GetAmbientIntensityLumens」ノードそれぞれを
レベルに配置されている「DirectinalLight」の「SetLightColor」、「SetTemperature」、「SetItensity」ノードにつなぎます。
(サンプルでもTickにCast入れてるのは落ち着きませんが、)これで実行時のライトの明るさや色合いの変化にリアルタイムに対応できます。
![UE4_ARKit6.png](https://qiita-image-store.s3.amazonaws.com/0/214053/422eb0dd-b7bf-6c48-97b0-e6bd09fe2ff6.png)

実機で動かすとこんな感じです。
<img width="414" alt="IMG_0019.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/214053/d3a71281-f578-b62e-bc23-7ef83964b8d6.png">

##さいごに
今回はライティングの部分しか記載はないですが、現実のライティングを反映できれば、CGにより実在感を与えられ、ARとしてのクオリティをあげられると思います。
他にも、画像の検出、現実空間のオブジェクトの検出、空間情報の保存等はUE4でできるみたいです(情報はほとんどありませんが)。

UE4×ARKit、まだまだ発展途上な感じではありますが、シンプルなAR以外にも、[こういったもの](https://www.makuake.com/project/dangla/)もありますし、ARKitも今後色々展開できると思っているので、少しでも情報が増えたらと思い、まとめてみました。
マシンパワーとMacの操作性等の影響で細々となりそうですが、今後も何か判ったら何かしら情報共有はすると思います。あと、ここの内容に間違い等あった場合は、随時修正しようと思います。

##情報源等
[公式のARの概要](http://api.unrealengine.com/JPN/Platforms/AR/HandheldAR/AROverview/index.html)
[環境光等の対応](https://medium.com/@joe.j.graf/ar-environment-probes-in-ue4-4-20-afda05bcc587)
[ARKit2.0の対応](https://medium.com/@joe.j.graf/arkit-2-0-support-in-ue4-4-20-47d1156d545f)

---
明日は15日目、@DaifukuOhnumaさんです。