深度
ARDK Depth Estimationは、現実世界のピクセル単位の深度マップを提供し、アプリケーションはデバイスのカメラから画面上の各ピクセルまでの現実世界の距離(メートル単位)を推定することができます。 この機能には、以下のようなさまざまな使用例があります(ただし、これらに限定されません):
- オクルージョン用のzbufferに深度値を書き込む。
- 深度バッファから3次元位置をフェッチして、オブジェクトをワールドに配置する。
- メッシングシステムの一部としてメッシュを構築する。
- 被写界深度などの視覚効果を利用して、近くの被写体に焦点を合わせる。
これは深度カメラを使って、近くから遠くへ伝わる「パルス」を作り出す例である:
AR Occlusion Manager
ARDK 3.0はUnityのAR Foundation Occlusion Subsystemと統合されています(新しいタブで開きます)。 XR設定でLightshipが有効になっていると、Lightshipの高度な深度を活用したサブシステムを実装することができます。 開発者としては、標準の AROcclusionManager (opens in new tab)をシーンに配置するだけです。
AROcclusionManager
のインターフェイスはAR Foundationと同じですが、オプションでできることは異なります:
- 環境深度モード。 ライトシップでは、このパラメーターによって、いくつかの修正されたニューラル・ニューワーク・アーキテクチャーの中から選択することができる:
- ミディアム:社内のマルチデプスアーキテクチャを使用して深度を推定。
- 最良:前のタイムステップからの深度マップを考慮に入れた修正マルチ深度アンチフリッカーモデルを使用して深度を推定する。
- 最速:より小さいが、より正確でない可能性のあるモデルを使用して深度を推定する。
- Temporal Smoothing:ライトシップではサポートされていません。
- 人間のセグメンテーション:ライトシップには、人間を含む、より大きなアイテムのセグメンテーションのための独立した機能があります(セマンティクス機能のページを参照)。 このセクションのオプションはライトシップでは使用しないので、無効のままにしておくことができる。
- オクルージョン優先モード:これは通常、環境オクルージョンと人間オクルージョンを切り替えるために使用します。 ライトシップでは、オクルージョンをオフにするためにのみ使用します。
テクスチャとしての奥行きへのアクセス
シーンにAROcclusionManager
コンポーネントがあれば、MonoBehaviour
内のGPUテクスチャとして最新のデプスマップにアクセスできます:
を使って
public class AccessDepthMap : MonoBehaviour
{
public AROcclusionManager _occlusionManager;
using ...
void Update()
{
if (!_occlusionManager.subsystem.running)
{
return;
}.
...
var depthTexture = _occlusionManager.environmentDepthTexture;
...
}
...
}
Lightshipの深度推定が使用するニューラルネットワークのため、ここでオクルージョンマネージャから表面化される深度テクスチャ
は、反時計回りに90度回転され、固定アスペクト比を持ちます。 入力画像の例を、対応する深度テクスチャ(右)とともにここに示す(左)。
Display Depth as a ShaderHow-Toでは、画像を時計回りに90度回転させ、出力された深度画像をディスプレイマトリクスを使って適切なアスペクト比に変換するシェーダの例を紹介しています。
CPUでデプスマップをサンプリングする
シーンにAROcclusionManager
コンポーネントがあれば、MonoBehaviour
内で最新のデプスマップをサンプリングできます。 このスニペットは、CPU上で深度マップを取得し、画面のほぼ中央の深度を見つける方法を示しています。
を使って
public class SampleDepthMap : MonoBehaviour
{
public AROcclusionManager _occlusionManager;
private Matrix4x4 m_DisplayMatrix;
XRCpuImage? depthimage;
void Update()
{
if (!_occlusionManager.subsystem.running)
{
return;
}
if (_occlusionManager.TryAcquireEnvironmentDepthCpuImage(out
var image))
{
depthimage?Dispose();
depthimage = image;
}
else
{
return;
}
var uvCenter = new Vector2(0.5, 0.5); // 画面中心
var depthCenter = depthimage.Value.Sample<float>(uv, m_DisplayMatrix);
}.
}
}
ここでも、depthImage
はLightshipからの生出力(反時計回りに90度回転、アスペクト比固定)である。 Convert a Point to a World Position Using DepthHow-Toでは、CPU上で深度マップを取得し、カメラの表示マトリックスを使ってサンプリングする方法を紹介しています。
詳細はこちら
デプスの使い方は、デプス関連のハウツーで見ることができる:
デプス関連のサンプルもご覧ください: