深度ベースのオクルージョン
没入感を維持したままコンテンツを現実世界のオブジェクトの背後に配置したり動かしたりします。
概要
深度を理解していないと、仮想オブジェクトが現実世界のオブジェクトの陰に隠れて非現実的に見えてしまうことがあります。たとえば、以下の比較では、オクルージョンなしの場合、仮想上のイエティ(キャラクター)は、壁の後ろに移動しても姿が見えています。オクルージョンを適用すると、イエティは姿が正しく隠れ、現実環境の中に溶け込むように表示されます。
オクルージョンは、 深度推定に対応するデバイス でサポートされています。
オクルージョンの一般的な方法
ARDKでオクルージョンを行うには、次のような方法があります。
深度ベースのオクルージョン - 動的オブジェクト(ユーザーの手など)に適していますが、オクルージョンの結果が不安定になったり、ちらついたりすることがあります。
3Dメッシュベースのオクルージョン - 静的オブジェクトに適しており、安定性にも優れていますが、動的オブジェクトではうまく動作しません。
現時点では、深度ベースのオクルージョンとメッシュベースのオクルージョンを同時に使用することはできません。このページでは、深度ベースのオクルージョンについて説明します。メッシュベースのオクルージョンについては、 メッシング を参照してください。
注釈
3つ目の方法、「深度ブレンディング」は現在、実験的な機能として提供されています。この方法では、深度ベースとメッシュベースの両方のオクルージョンを使用して、最良の結果を得ることを目的としています。詳細については、 深度ブレンディング を参照してください。
オクルージョンモード
ARDepthManager でサポートされている深度ベースのオクルージョンモードは次のとおりです。
None
: オクルージョンは無効に設定されています。Depth Buffer
: ARFrameの深度はターゲットのzバッファに書き込まれます。Screen Space Mesh
: 深度推定に基づくスクリーン空間メッシュを使用します。Auto
: 高性能なハードウェアでは深度バッファを使用し、そうでない場合は画面空間メッシュを使用するようにフォールバックします。
最良の結果が得られるように、 Depth Buffer
を使用することをお勧めします。低性能のデバイスでアプリを使用する場合にオクルージョンを Auto
に設定すると、ARDKでは深度バッファのオクルージョンがデフォルトで使用され、古いデバイスではスクリーン空間のメッシュオクルージョンにフォールバックします。
深度ベースのオクルージョンを行うためにカスタムのアプローチが必要な場合は、生の ARFrame.Depth バッファ値を使用して、独自のオクルージョンシステムを実装することができます。
オクルージョンを有効にする
深度ベースのオクルージョンを設定するには、次の手順で行います。
シーン内のGameObjectに、 ARDepthManager や ARRenderingManager が関連付けられていることを確認します。
ARDepthManager
の OcclusionTechnique (Unityインスペクターの Occlusion Mode(オクルージョンモード))を任意のモードに設定します。Depth Buffer
モードの使用が推奨されています。(オプション) ARDepthInterpolationAdapter を追加すると、
ARDepthManager
の InterpolationPreference が、現在の体験に最も適した値に自動的に変更されます。
ARDepthManager.ToggleDebugVisualization() を使用すると、シーンオブジェクトのオクルージョンに使用されている深度データまたは画面空間メッシュを視覚化することができます。
オクルージョンからのセマンティックチャンネルを抑制する
オブジェクトをオクルードする際に、セマンティックチャンネルを抑制することができます。あるチャンネルを抑制すると、そのチャンネルでラベル付けされたすべてのピクセルが最大深度に押し出されます。たとえば、すべての仮想オブジェクトが地面の上に配置されている場合に地面を抑制すると、ノイズが多い、または不正確な深度出力によって、オブジェクトが誤って隠れてしまう可能性を抑える上で効果的です。
セマンティックチャンネルを抑制するには、次のように行います。
ARSemanticSegmentationManager が、
ARDepthManager
と同じGameObjectに関連付けられていることを確認します。ARSemanticSegmentationManager.SetDepthSuppressionChannels() (Unityインスペクターの Depth Suppresion Channels(深度抑制チャンネル))で、抑制するチャンネルを設定します。
利用可能なチャンネルの最新リストについては、 セマンティック セグメンテーション を参照してください。
さらに、セマンティックデータをマスクとして使用し、特定のセマンティックチャンネルに属すると検出された現実世界のコンテンツから仮想コンテンツのオクルージョンを効果的に行うことができます。詳細については、 セマンティックテクスチャを作成する や セマンティック信頼度 <semantic_confidence> 、 ARDK使用例 のSemanticSegmentationサンプルシーンを参照してください。
スクリーン空間のメッシュオクルージョンを理解する
アプリで深度バッファのオクルージョンを使用できず、画面空間メッシュのオクルージョンを使用する必要がある場合は、以下の詳細をもとに、画面空間のオクルージョンの仕組みを理解することをお勧めします。
ScreenSpaceMesh
のオクルージョンモードでは、オクルージョンを行うために、ARDepthManager
設定で、カメラビューに垂直に平面メッシュを作成し、深度推定出力に合わせてメッシュの頂点を継続的に調整します。最適なパフォーマンスを得るために、深度はレンダリングシェーダーでのみ計算されます。
オクルージョンメッシュのアスペクト比と解像度は、デバイスのカメラや画面のものと必ずしも一致するとは限りません(これらの値は、基準となるディープラーニングモデルによって決まります)。特に、メッシュの左右と画面の端の間にパディングが含まれることがあり、その場合、その領域でオクルージョンを実行することはできません。
オクルージョンメッシュの頂点の数は、深度テクスチャのピクセルの数に、左右に存在するパディングを加えた数になります。
ScreenSpaceMeshのオクルージョンとメッシング
シーンで ScreenSpaceMesh
と メッシング の両方を使用している場合は、得られるオクルージョンの結果が望ましくないことがあります。ARDKのメッシング機能では、デフォルトでUnityのメッシュオクルージョンが有効になりますが、ARDepthManager
の ScreenSpaceMesh
テクニックを使用したオクルージョンの計算と競合する可能性があります。
メッシングのオクルージョンを無効にするには、 ARMeshManager で使用しているメッシュプレハブのUnity Mesh Rendererで Dynamic Occlusion(動的オクルージョン) を無効にします。