MetaQuest3 で DepthAPI を利用した オクルージョン の設定

# はじめに
MetaQuest3 での DepthAPI を使ったオクルージョンのテストしたので、その方法をまとめます

https://qiita.com/kanakanho/items/b0c68bb1b81c9e95624d

上記の記事からの連続した実装になっているので、初期設定はこちらの記事を参考にしてください。

# DepthAPI の環境構築
DepthAPI の 利用には MetaQuest3 と v60 以上のMeta の SDK が必要になります

## 要件（Metaのリファレンスは誤っているので修正）
- Unity 2022.3.1fまたはUnity 2023.2
- V60 Meta XRオールインワンSDK以降
- [Scene Support (シーンのサポート)]が[Required (必須)]に設定されていること(空間データアクセス許可をリクエストするため)
- グラフィックスAPIが[Vulkan]に設定されていること
- レンダリングモードが[Multiview (マルチビュー)]に設定されていること

:::note warn
警告
リファレンスでは以下のように記載されています
*com.unity.xr.oculusパッケージをサポートするDepth API。Unityパッケージマネージャの[Add package by name (パッケージを追加(名前を指定))]で名前としてcom.unity.xr.oculus、バージョンとして4.2.0-exp-env-depth.2を指定*

ですが、現在設定の必要はありません
:::

## DepthAPIの有効化
MetaQuest と PC が接続した状態で以下のコードを実行する
```
adb shell setprop debug.oculus.experimentalEnabled 1
```

## `OculusProjectConfig` の設定
`Scene Support` → `Required`
`Passthough Support` → `Required`
<img width="738" alt="image.png (10.0 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/d5f49096-09d3-47df-b8e6-f50628226814.png">



## DepthAPI の説明
こちらが DepthAPI のレポジトリになります

https://github.com/oculus-samples/Unity-DepthAPI

DepthAPI は カメラから深度情報を取得して、端末から壁面や床面など現実の遮るオブジェクトまでの距離を測定する機能を提供します
今回はこの API を利用して オクルージョン を設定します

:::note info
オクルージョンとは？
AR を利用する中で表示する対象の前に遮るものが横切ったときに、奥にあるオブジェクトを部分的に表示しないようにする機能を指す言葉です
:::


`Getting started with samples` を参照して サンプルコードをダウンロードしてテストしてみるのをお勧めします

サンプルコードでは DepthAPI のパッケージをローカルから読みんでいますが、これ以降の実装では Github を利用して読み込んでいます

## DepthAPI パッケージの導入
Github の README に書かれている URL をコピーしてパッケージマネージャーから追加します 

### 1. パッケージマネージャーを開く
### 2. `Add Package from git URL`を選択
<img width="256" alt="image.png (8.1 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/3b044a00-5428-425e-84bf-f3d82a6c6eaa.png">

### 3. [こちらのURL](https://github.com/oculus-samples/Unity-DepthAPI#2importing-depth-api-package)  から git のURLをコピー

https://github.com/oculus-samples/Unity-DepthAPI#2importing-depth-api-package

記事編集時のURLはこちらです
```
https://github.com/oculus-samples/Unity-DepthAPI.git?path=/Packages/com.meta.xr.depthapi
```

### 4. DepthAPI が Project に追加されているのを確認する
<img width="187.5" alt="image.png (12.5 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/99e4df39-6fd9-435a-963b-3a10c2439670.png">

# DepthAPI を使ったオクルージョンの設定
## Material の作成
### 1. Assets の中に新しく `Materials` フォルダを作成
### 2. フォルダの中で新しい `Material` を作成
<img width="435" alt="image.png (25.7 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/0441384b-96c7-4dd5-af14-e96326f16743.png">

### 3. `DepthDemo`と名前をつける
<img width="546.75" alt="image.png (51.4 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/3deca898-fb85-4c76-879e-1db1bff8e7eb.png">

### 4. `Shader` の設定を変える
変更前 `Standard`
<img width="554.25" alt="image.png (8.0 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/48dc2222-5a2f-4160-8ef4-fb87619778f6.png">

変更後 `Meta/Depth/BiRP/Occlusion Standard`
<img width="552.75" alt="image.png (20.9 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/4e9d4291-1e5a-42b7-94c5-76b5f72edf8d.png">

## シーンに `EnvironmentDepthOcclusion` を追加
### 1. `Project` で `EnvironmentDepthOcclusion` を検索して、シーンにドラッグ
<img width="408" alt="image.png (29.2 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/7ea7aacf-1dc6-4d66-be6e-6c4df5f543d4.png">

<img width="551.25" alt="image.png (36.8 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/8d74b1f4-f262-40e0-bdf2-9697b48d36d6.png">


## シーンに `Cube` を追加
### 1. 現在開いている `Scene` に新しい `3D Object > Cube` を作る
<img width="339" alt="image.png (5.7 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/a4ba83f4-83ad-4180-b422-688593f6315e.png">

## `Cube` の設定を変更
### 1. `Mesh Renderer`を変更
`Mesh Renderer > Materials > Element` に先ほど作成した `DepthDemo` を設定  
<img width="552.75" alt="image.png (6.7 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/b3ec616d-1590-473b-8ad4-19ba7767e55c.png">

### 2.1 `Rigbody` を追加
`Add Component`を選択、 `Rigbody`を追加
<img width="166.5" alt="image.png (3.0 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/7049722d-b124-439a-b15b-9a0250c2194d.png">

<img width="553.5" alt="image.png (26.8 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/108275e7-7960-4e83-ae7b-36e63180dab6.png">

### 2.2 `Rigbody` を変更
`Rigbody > isKinematic` にチェックをつける
<img width="552.75" alt="image.png (12.5 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/48fc6ad3-c680-4793-b1c3-1ae84ab76947.png">

### 3.1 `OVR Grabbable` を追加
`Add Component`を選択、`OVR Grabbable`を追加
<img width="168" alt="image.png (5.3 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/3bfaa17d-4e36-40f6-8050-f900f8e03930.png">

<img width="549.75" alt="image.png (17.6 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/e5069e7a-52f7-4501-b04c-200fa5e09e6c.png">

### 3.2 `OVR Grabbable` を変更
`OVR Grabbable > Grab Points > List is empty` の  `+` をクリック
今編集している `Cube` を `Scene` からドラッグ
<img width="553.5" alt="image.png (19.0 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/88651d5a-c8bb-49ba-b4ae-e327189269cf.png">

### 4.1 `Occlusion Controller` を追加
`Add Component`を選択、`Occlusion Controller`を追加
<img width="171.75" alt="image.png (8.9 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/e0ee6d9c-ddda-4794-ae10-a21002c6dfc3.png">

<img width="552.75" alt="image.png (11.1 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/06ac7478-1bef-4f98-a336-4bf4ebeeb5dc.png">

<details><summary>NullReferenceException が出た場合</summary>

:::note warn
`NullReferenceException: SerializedObject of SerializedProperty has been Disposed.`が出た場合
Unityのプロジェクトをいったん閉じ、エクスプローラーから該当ディレクトリの `Libraly` を削除し、再度  Unity で起動することでエラーが解消されます
:::
</details>

### 4.2 `Occlusion Controller` を変更
`Occlusion Controller > Occlusion Type` に使いたいものを設定
- Hard Occlusion 
ざっくりとしたオクルージョンの設定が可能
- Soft Occlusion
Hardより細かなオクルージョンの設定が可能

今回は `Soft` を設定

`Occlusion Controller > Renderer` に今編集している `Cube` を `Scene` からドラッグ

2つの操作を行うとこんな感じ
<img width="555" alt="image.png (12.4 kB)" src="https://img.esa.io/uploads/production/attachments/13979/2024/03/05/148413/931de6e0-1cb4-44fa-9b1d-1e7dee1fbb53.png">

## 実行確認
以上の設定で `DepthAPI` を利用した オクルージョン が可能になっていると思います

# おわりに
DepthAPI はまだテスト段階の機能であり、MetaQuest3 がないと検証ができません。パッケージ関係もまだ十分に整っているとはいえず、今後の Meta の対応が待たれます。
MR 的なアプリを作るためには欠かせない オクルージョンが実装できました。

# 参考資料
MetaQuest DepthAPI Github レポジトリ

https://github.com/oculus-samples/Unity-DepthAPI

Meta Unity用 DepthAPI リファレンス
日本語

https://developer.oculus.com/documentation/unity/unity-depthapi/?locale=ja_JP

英語

https://developer.oculus.com/documentation/unity/unity-depthapi/

Mesh API と Depth API による Meta Quest 3 のMRエクスペリエンスの構築

https://note.com/npaka/n/n31f9bd108dbd