VulkanをサポートしたOculus QuestでVisual Effect Graphを使う

# はじめに

Unity2019.3になってOculus QuestでVulkanがサポートされました。
更にURP 7.2.0からXR周りが改善されたりXR Interaction Toolkitだけでクロスプラットフォームにカメラリグやコントローラーを扱えるようになっています。

- [Vulkan Support for Oculus Quest in Unity (Experimental)](https://developer.oculus.com/blog/vulkan-support-for-oculus-quest-in-unity-experimental/)
- [2019.3 Release - XR Updates](https://forum.unity.com/threads/2019-3-release-xr-updates.821637/)
- [XR Interaction Toolkit Preview Package is here](https://blogs.unity3d.com/2019/12/17/xr-interaction-toolkit-preview-package-is-here/)
- [XR Interaction Toolkit Preview Release](https://forum.unity.com/threads/xr-interaction-toolkit-preview-release.795684/)

そこでUnityとPackage Managerの機能だけで外部アセットを使わずにOculus QuestでVisual Effect Graphを使ってみます。

# できあがったもの

- スクリーンショットと動画
    
    [![screenshot](http://img.youtube.com/vi/C_DgvLJiuP8/0.jpg)](http://www.youtube.com/watch?v=C_DgvLJiuP8)
- ソース
    - https://github.com/shiena/QuestVulkan
- ビルドしたapk
    - https://github.com/shiena/QuestVulkan/releases/tag/1.0.0

# 開発環境

- Unity2019.3.1f1
    - Android Build Support
    - Android SDK & NDK Tools
    - OpenJDK
- Oculus Quest v13以上

Unityインストール時にAndroid Build Supportを展開してAndroid SDK & NDK ToolsとOpenJDKもチェックします。
![0.unity2019.3install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/63f87954-986d-3027-7a63-a9eb9348e2c1.png)


# 手順概要

1. 新規プロジェクト作成
1. Oculus Quest向けにProject Settingsを変更
1. Package Managerから必要なパッケージを追加
1. VisualEffectGraph Additionsをインポート
1. シーン構築
1. ビルドと実行
1. クオリティ調整

## 新規プロジェクト作成

UnityHubで新規作成してUniversal Template Projectから作成します。
![1.10.new-project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/532b7d83-6f3b-09b2-e865-46fd4bbbbde7.png)


## Oculus Quest向けにProject Settingsを変更

1. Androidプラットフォームに変更
    - メニューの`ファイル > ビルド設定`を開き、プラットフォームからAndroidを選択して`Switch Platformボタン`を押します。
    
    <img width="473" alt="2.10.switch-platform2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/63ef7736-cccf-8322-da62-40b5c50e3c01.png">
1. Oculus Quest向けにProject Settingsを変更
    1. Build Settingsの`プレイヤー設定ボタン`を押してProject Settingsを開きます。
    1. Player > Androidアイコン > その他の設定を開きます。
        - Graphics APIsをVulkanのみに変更
        - 最低APIレベルを4.4から6.0に変更

        <img width="583" alt="2.30.player-settings-after2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/f4ba7fe9-7f33-2d00-c3c7-dba3906d8607.png">
    1. XR Plugin Managementを開きます。
        1. Install XR Plugin Managementボタン、Oculus XR PluginのInstallボタンの順に押します。
        1. AndroidアイコンのPlugin ProvidersにOculus Loadersを追加します。

        <img width="461" alt="2.50.xr-settings-all2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/c34340a5-f052-6088-bf30-f5530172fc69.png">
    1. Oculusを開きます。
        - 作成ボタンを押してOculus Quest用の設定を作ります。

        <img width="461" alt="2.80.oculus-all2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/b18d34d2-f86f-aa92-29cc-ca8d55493a49.png">


## Package Managerから必要なパッケージを追加

1. メニューの`ウインドウ > Package Manager`を開き、`Advanced`から`Show preview packages`をチェックしてプレビューバージョンを見えるようにします。
1. プロジェクト内をすべてのパッケージに変更して以下のパッケージをインストールします。
    - XR Integration Toolkit
    - Visual Effect Graphの**7.2以上**
    - Universal RPの**7.2以上**
    - Android Logcat
    
    ![3.10.package-manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/b1a408f1-bc9b-4d2e-0243-86e22ecaa4f4.png)


## VisualEffectGraph Additionsをインポート

1. Package ManagerのVisual Effect GraphからVisualEffectGraph Additionsの`Import into Projectボタン`を押します。
    
     <img width="526" alt="4.10.import-vfx-additions2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/1f56e527-1063-4e36-4831-16da567c9889.png">
1. `Assets/Samples/Visual Effect Graph/7.2.1/VisualEffectGraph Additions/VFX/`にアセットが作られますがそのままでは動かないのでメニューの`編集 > Visual Effects > Rebuild All Visual Effect Graphs`から再コンパイルします。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/491a4eac-3f7b-4012-00f1-5ffadfb485af.png)

## シーン構築

1. メニューの`ゲームオブジェクト > XR > Room-Scale XR Rig`を選択するとMain CameraがVR用のXR Rigに変換されます。
    
    <img width="377" alt="5.10.xr-rig2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/e66e0f0b-ec54-b03f-909a-8511f8bd39cb.png">
    元のカメラに合わせる場合は以下のTransformになります。
    ![5.20.xr-rig-transform.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/b478fc13-329a-1ca7-2e99-3bc92bf05c0e.png)

1. Main Cameraのnear clipがデフォルトの0.3では遠いので0.01に変更します。
1. `Assets/Samples/Visual Effect Graph/7.2.1/VisualEffectGraph Additions/Prefabs/`にあるVFXのプレハブをヒエラルキーに追加します。
    
    <img width="679" alt="5.30.vfx-prefab2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/2f8285ac-2f68-1902-d614-bdbbac2163f7.png">
1. 追加したVFXをカメラから見やすい位置に調整します。

## ビルドと実行

1. メニューの`ファイル > ビルド設定`を開きます。
1. デバイスを実行しますからOculus Questを選択します。
1. ビルドして実行ボタンを押します。
1. アプリを起動してメニューの`ウインドウ > 分析 > Android Logcat`を開くとVulkanが使われているのが分かります。
    
    ![androidlog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/9bcc93d0-193d-ebd1-8d5e-480bdc6a7d95.png)

## クオリティ調整

このままでもVisual Effect Graphは動きますがBloomが弱いのでPCと比べると貧弱です。以下の設定を行うとBloomの違いが分かります。
ただしHDRとPostProcessingはOculusの開発者ブログでパフォーマンス低下させると指摘されているようにFPSが更に下がってしまいます。

- [Getting Started with Unity’s Lightweight Render Pipeline (LWRP)](https://developer.oculus.com/blog/getting-started-with-unitys-lightweight-render-pipeline-lwrp/)

- クオリティ調整後のスクリーンショットと動画
    - [![screenshot](http://img.youtube.com/vi/-TtlK6eY22I/0.jpg)](http://www.youtube.com/watch?v=-TtlK6eY22I)
- ビルドしたapk
    - https://github.com/shiena/QuestVulkan/releases/tag/1.1.0

1. `Assets/Settings/UniversalRP-MediumQuality.assets`を`Assets/Settings/UniversalRP-OculusQuest.assets`に複製して以下の項目を変更します。
    - HDRを有効にする
    - Anti Aliasing (MSAA)を`4x`にする
    - Grading Modeを`High Dynamic Range`にする
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/aae3aae2-135c-c837-6cfe-9309d9211bcf.png)
1. `Player Settings > 品質`にOculusQuestを追加して以下の項目を変更します。
    - AndroidのDefaultに設定する
    - Renderingに`UniversalRP-OculusQuest`を設定する
    - それ以外は`Medium`と同じ
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/27d338ad-711d-2c2e-a6fc-060fc4c1fb95.png)
1. `Player Settings > グラフィックス`のスクリプタブルレンダーパイプライン設定に`UniversalRP-OculusQuest`を設定します。
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/7c9701b9-87fb-165e-6ab5-be1eba58823e.png)


## その他

- カメラのPost Processingを有効にしてStereo Rendering ModeをMultiviewにすると右目の位置がおかしくなります。
- Post Processingが重いのでFPSは40～60くらいしか出ません。Post Processingを無効にすると70FPSくらい出ます。
- Visual Effect GraphをRebuildするとOpenGLES3でもVulkanと同様に表示できました。<details><summary>設定ミスの場合</summary>~~OpenGLES3だとVisual Effect Graphのエフェクトが謎のレーザーになってしまいました。~~
    [![screenshot](http://img.youtube.com/vi/uB0pnrfENEc/0.jpg)](http://www.youtube.com/watch?v=uB0pnrfENEc)
</details>