空間マッピング
空間マッピングは、現実世界のサーフェスを HoloLens の周囲の環境に詳細に表現する機能です。これにより、開発者は自然な複合現実エクスペリエンス作成することができます。 現実世界を仮想環境と融合させることで、アプリケーションのホログラムをリアルに見せることができます。 また、アプリケーションでは、現実世界での馴染みのある動作やインタラクションを取り入れることで、ユーザーが予期しやすい、自然な体験を提供することができます。
デバイスのサポート
機能 | HoloLens (第 1 世代) | HoloLens 2 | イマーシブ ヘッドセット |
空間マッピング | ✔️ | ✔️ | ❌ |
空間マッピングが重要な理由
空間マッピングにより、オブジェクトを実際のサーフェスの上に配置できるようになります。 これにより、現実世界の深度を手掛かりにして、オブジェクトをユーザーの世界に固定することができます。ホログラムを他のホログラムや現実世界のオブジェクトに基づいてオクルージョンすることで、それらのホログラムがユーザーの空間内に実際に存在するように感じさせることができます。 空中に浮かんでいるホログラムや、ユーザーと一緒に移動するホログラムは、実際に存在するように見えません。 なるべく、アイテムはどこかに置くようにしましょう。
ホログラムを配置したり移動したりするときには、サーフェスを視覚化します (投影グリッドを使用します)。 これにより、ホログラムを最適に配置できる場所がユーザーにわかるようになり、ホログラムを配置しようとしている場所がマップされていない場合も、そのことがわかるようになります。 ユーザーの向きが範囲から外れるような場合には、"アイテムをビルボード化する" こともできます。
概念の概要
部屋全体をカバーする空間マッピング メッシュの例
空間マッピングで主に使用されるオブジェクトの種類は、"空間サーフェス オブザーバー" と "空間サーフェス" の 2 種類です。
空間サーフェス オブザーバーには、空間マッピング データを受信する領域を定義するために、アプリケーションにから 1 つ以上の境界ボリュームが提供されます。 空間マッピングを行うと、これらのボリュームごとに、一連の空間サーフェスがアプリケーションに提供されます。
これらのボリュームは、固定 (現実世界に基づく固定の場所) である場合もあれば、HoloLens にアタッチされている場合もあります (後者の場合、HoloLens が環境内を移動するとボリュームも移動しますが、回転はしません)。 各空間サーフェスは、小さな空間内にある現実世界のサーフェスを表します。これらは、ワールドロック型の空間座標系に接続された、三角形メッシュとして表されます。
HoloLens で新しいデータが収集され、環境への変化が発生するのに応じて、空間サーフェスは表示されたり、消えたり、変更されたります。
空間認識の設計概念のデモ
空間認識の設計概念が実際に動作するのを見るには、以下に示す「ホログラムのデザイン - 空間認識」のビデオ デモをご覧ください。 終わったら、続けて特定のトピックについて詳しく見ていきます。
このビデオは、"Designing Holograms" HoloLens 2 アプリから撮影されました。 完全なエクスペリエンスをダウンロードしてご利用いただくには、ここから入手できます。
空間マッピングとシーンの理解の WorldMesh
HoloLens 2 では、シーンの理解 SDK (EnableWorldMesh 設定) を使って、静的バージョンの空間マッピング データに対してクエリを実行できます。 空間マッピング データにアクセスする 2 つの方法の違いを次に示します。
- 空間マッピング API:
- 範囲が限られている: ユーザーの周囲にある、限られたサイズのキャッシュ済みの "バブル" 内にある空間マッピング データを利用できます。
- SurfacesChanged イベントを使用して、変更されたメッシュ領域の更新を短い待機時間で取得できます。
- "立方メートルあたりの三角形" パラメーターによって、可変の詳細レベルが制御されます。
- シーンの理解 SDK:
- 範囲の制限がない - クエリ半径内にあるすべてのスキャン済み空間マッピング データが提供されます。
- 提供されるのは、空間マッピング データの静的スナップショットです。 更新された空間マッピング データを取得するには、メッシュ全体に対して新しいクエリを実行する必要があります。
- RequestedMeshLevelOfDetail 設定によって、一貫した詳細レベルが制御されます。
空間マッピングの品質に影響を与えるもの
ここで詳しく説明するいくつかの要因は、関連するエラーの頻度と重大度に影響を与える可能性があります。 ただし、アプリケーションは、空間マッピング データにエラーが存在する場合でもユーザーが目標を達成できるように設計する必要があります。
一般的な利用シナリオ
配置
空間マッピングは、自然で使い慣れた形の対話式操作をユーザーに提供する機会をアプリケーションに提供します。結局、携帯をデスクに置くような動作が一番自然です。
ホログラムの配置 (より一般的には、空間位置の任意の選択) をサーフェス上に制約することで、3D (空間内のポイント) から 2D (サーフェス上のポイント) への自然なマッピングを実現できます。 これにより、ユーザーがアプリケーションに提供しなければならない情報量が減り、ユーザーの対話はより速く、簡単で、正確になります。 なぜなら、"自分からの距離" は、他のユーザーやコンピューターとの身体的な意思伝達において、使い慣れた概念ではないからです。 何かを指差す場合、それは距離ではなく、方向を示します。
ここで重要な注意点は、アプリケーションで方向から距離を推論する場合 (たとえば、ユーザーの視線の方向に沿ってレイキャストを実行し、最も近い空間サーフェスを特定する場合)、ユーザーが確信を持って予測できる結果を生成しなければならないという点です。 そうしないと、ユーザーはコントロールの感覚を失い、すぐにストレスを感じる可能性があります。 これをサポートする 1 つの方法は、レイキャストを 1 つだけではなく複数実行する方法です。 集計結果は、より滑らかで予測可能性が高く、一時的な "外れ値" の結果による影響を受けにくいものである必要があります (外れ値の影響は、光線が小さな穴を通過したり、ユーザーに認識されない小さなジオメトリにヒットしたりする場合に発生する可能性があります)。 集計やスムージングは、時間の経過に伴って実行することもできます。たとえば、ホログラムとユーザーの距離が変わる最大速度を制限することもできます。 距離の最小値と最大値を制限するだけでも、効果が出る可能性があります。これにより、移動中のホログラムが突然遠くへ離れたり、急にユーザーの目の前に近づいたりする現象を回避できます。
アプリケーションでは、サーフェスの形状と方向を使用してホログラムの配置をガイドすることもできます。 ホログラムのいすは壁を通り抜けないようにし、床が少し傾いている場合でも、床にぴったりとくっついて配置されるようにする必要があります。 この種の機能は通常、レイキャストではなく物理衝突の使用によって実装されますが、その場合にも同様の懸念事項が当てはまります。 配置されるホログラムに、突き出た形状の小さな多角形 (いすの足など) が多数ある場合は、それらの多角形の物理表現を拡張し、より幅広く滑らかにして、空間サーフェス上をガタガタさせずにスライドできるようにするのが合理的かもしれません。
極端にいえば、ユーザー入力を徹底的に簡略化し、空間サーフェスを使って完全に自動のホログラム配置を実行することもできます。 たとえば、ホログラムの照明スイッチを壁のどこかに配置して、ユーザーがそれを押せるようにすることもできます。 この場合も、予測可能性に関する同じ注意点があります。ユーザーがホログラムの配置を制御したい場合で、アプリケーションがホログラムを必ずしも期待どおりの場所に配置するとは限らない場合 (ユーザーの届かない場所に照明スイッチが表示されるような場合)、これはストレスを伴うエクスペリエンスとなります。 実際、自動配置をユーザーがときどき修正しなければならないようなことになると、ユーザーが毎回自分で配置しなければならない場合よりもストレスを感じる可能性があります。自動配置が成功することを期待していた分、手動修正を負担に感じるからです。
また、配置に空間サーフェスを使用する場合、その性能はアプリケーションのスキャン エクスペリエンスによって大きく左右されます。 サーフェスがスキャンされていない場合、そのサーフェスは配置に使用できません。 アプリケーションでは、このことをユーザーに明示する必要があります。そうすることで、ユーザーが新しいサーフェスをスキャンしたり、新しい場所を選択したりできるようになります。
配置の際には、ユーザーに対する視覚的フィードバックがきわめて重要となります。 接地効果を使用し、最も近いサーフェスに基づいて、ユーザーがホログラムの場所を把握できるようにする必要があります。 ホログラムの移動に制約がある理由がユーザーにわかるようにしましょう (たとえば、近くにある別のサーフェスと衝突するなど)。 ホログラムを現在の場所に配置できない場合は、視覚的なフィードバックによって、その理由がわかるようにしましょう。 たとえば、ユーザーがホログラムのソファーを壁の中に半分入り込むように配置しようとしている場合、壁の向こう側にはみ出しているソファーの一部は、赤い色で点滅するように表示する必要があります。 逆に、ユーザーから現実世界のサーフェスが見えている場所に、アプリケーションが空間サーフェスを見つけられなかった場合は、アプリケーションでそのことを明示する必要があります。 この目的は、そのエリア内に接地効果が表示されないようにすることで達成できる可能性があります。
オクルージョン
空間マッピング サーフェスの主な用途の 1 つとして、単にホログラムをオクルージョンするという使い方があります。 このシンプルな動作は、ホログラムの現実感に大きな影響を与えます。これにより、ホログラムがユーザーと同じ物理的空間内に存在するかのように、直感的に感じさせることができます。
また、オクルージョンには、ユーザーに情報を提供する効果もあります。ホログラムが現実世界のサーフェスによって遮られたように見せることで、ワールド内でのホログラムの空間的位置について、さらなる視覚的フィードバックが提供されます。 逆に、オクルージョンによって、情報をユーザーから見えなくすることもでいます。壁の後ろにホログラムを隠すことにより、視覚的な混乱を直感的な方法で軽減することができます。 ホログラムを隠したり表示させたりするために必要なことは、ユーザーが頭を動かすことだけです。
オクルージョンは、日頃から馴染みのある物理的相互作用に基づいて、ユーザー インターフェイスの自然な動作をユーザーに予期させるうえでも活用できます。ホログラムがサーフェスによって遮られている場合、それはそのサーフェスがソリッドだからなので、ユーザーはホログラムがそのサーフェスと衝突し、そこを通過しないことを予期できます。
場合によっては、ホログラムのオクルージョンが望ましくないこともあります。 ユーザーがホログラムと対話する必要がある場合は、現実世界のサーフェスの後ろにある場合でも、そのホログラムを表示する必要があります。 そのような場合は、通常、それらのホログラムについて、オクルージョンされているときのレンダリング方法を変えるのが合理的です (たとえば、明るさを減らすなど)。 そうすれば、ホログラムがユーザーに見える状態のまま、それが何かの後ろにあることもわからせることができます。
物理計算
空間マッピングを使用して、ホログラムがユーザーの物理空間内に存在する感覚を強めるためのもう 1 つの手段に、物理シミュレーションがあります。 ホログラムのボールがリアルな動きでデスクから転がり落ち、床にはね返ってソファーの下に隠れた場合、それがそこに存在しないと感じるのは難しいかもしれません。
物理シミュレーションは、自然で馴染みのある物理ベースの相互作用をアプリケーションに反映させる手段でもあります。 床の上でホログラムの家具を移動させる場合、その家具が適切な慣性と摩擦の影響を受けながら床の上をスライドしているように反応させると、ユーザーのエクスペリエンスはより快適になります。
リアルな物理動作を再現するには、通常、穴の塗りつぶし、浮遊感の除去、粗いサーフェスのスムージングなど、いくつかのメッシュ処理を行う必要があります。
また、アプリケーションのスキャン エクスペリエンスが物理シミュレーションにどのような影響を与えるかも考慮する必要があります。 まず、欠落しているサーフェスは何とも衝突しません。ゴムのボールが廊下に転がり落ち、既知のワールドの端よりも外に出た場合はどうなるでしょうか。 次に、時間の経過に伴う環境の変化に対応し続けるかどうかを決定する必要があります。 場合によっては、可能な限り迅速に反応しなければならない場合もあるでしょう。たとえば、ユーザーが、自分に向かって大量に飛んでくるローマ人の矢から身を守るために、ドアや家具を移動可能なバリケードとして使っているような場合です。 しかし反対に、環境の変化を無視したほうがよい場合もあるでしょう。床の上に投影されたレース場でホログラムのスポーツ カーを走らせているときに、愛犬がコースの真ん中に来て座ってしまったら、ユーザーはたちまち興ざめするかもしれません。
「ナビゲーション」
アプリケーションでは、空間マッピング データを使用して、ホログラムのキャラクター (またはエージェント) に、本物の人間と同じような方法で現実世界をナビゲートさせることができます。 その場合、ホログラム キャラクターの動作を、ユーザーや友人と同様の自然で見慣れた動作セットに制限することで、キャラクターのリアルさを高めることができます。
ナビゲーション機能はユーザーにとっても有益です。 特定の領域にナビゲーション マップが構築されたら、それを共有して、その場所に不慣れな新規ユーザーにホログラムで方向を示すことができます。 このマップは、歩行者の流れをスムーズに維持したり、建設現場などの危険な場所で事故を回避したりする目的で設計できます。
ナビゲーション機能の実装に関連する重要な技術的課題は、歩行可能なサーフェスの信頼性の高い検出 (人間はテーブルの上を歩かない)、環境の変化に対する適切な適応 (人間は密室を歩かない) です。 仮想のキャラクターによる経路計画やナビゲーションにメッシュを使用できるには、まずメッシュに対して何らかの処理が必要となる場合があります。 メッシュのスムージングや幻影の除去を行うことで、キャラクターが立ち往生するのを防げる場合があります。 また、キャラクターの経路計画やナビゲーションの計算を高速化したい場合は、メッシュを大幅に簡略化することも手段となり得ます。 これらの課題は、ビデオ ゲーム テクノロジの開発において大きな注目を集めており、これらのトピックについては豊富な研究資料が存在します。
Unity の組み込みの NavMesh 機能は、アプリケーションが起動するまでサーフェスが認識されないため、空間マッピング サーフェスには既定では使用できません。 ただし、実行時に NavMeshComponents をインストールすることで、NavMesh をビルドできます。 空間マッピング システムでは、ユーザーの現在の場所から 遠く離れたサーフェスに関する情報 は提供されません。大きな領域のマップを作成するには、アプリケーションでサーフェスを "記憶" する必要があります。 空間認識プロファイルで 観測範囲 の設定を増やすこともできます。これにより、NavMesh を作成できる領域が増えます。
グラフ
ほとんどの場合、空間サーフェスを非表示にすることは適切な処置です。これにより、視覚的な混乱を最小限に抑え、現実世界そのものの表現力を高めることができます。 ただし、状況によっては、対応する実物のサーフェスが見えていても、空間マッピング サーフェスを直接視覚化することが有用な場合もあります。
たとえば、ユーザーがホログラムをサーフェス上に配置しようとする場合 (ホログラムのキャビネットを壁に配置するなどの場合)、サーフェスに影を付け、ホログラムを "ぴったり配置" できるようにすると便利です。 そうすることで、ホログラムとサーフェスとの間の物理的な近さを、ユーザーがより正確に把握できるようになります。 また、より一般的な例で言うと、ユーザーが変更をコミットする前に、その変更を視覚的に "プレビュー" できるようにすることもできます。
サーフェスを視覚化すると、アプリケーションで把握されている環境をユーザーと共有することができます。 たとえば、ホログラムのボード ゲームの場合、"テーブル" として識別された水平サーフェスを視覚化することで、操作の対象となる場所をユーザーに示すことができます。
サーフェスの視覚化は、現在表示されていない空間を、その近くにいるユーザーに見せたい場合にも役立ちます。 これにより、リビング ルームにいるユーザーを、キッチン (およびそこにあるすべてのホログラム) へと案内することもできます。
空間マッピングによって提供されるサーフェス メッシュは、特に "クリーン" というわけではない場合もあります。 重要なのは、それらを適切に視覚化することです。 従来の照明計算では、サーフェス法線のエラーを示す強調表示が視覚的に混乱を招くような場合もありますが、サーフェスに "クリーンな" テクスチャを投影すれば、見た目をよりすっきりとさせることができます。 また、サーフェスがレンダリングされる前に、メッシュ処理を実行してメッシュのプロパティを改善することもできます。
Note
HoloLens 2 には、新しいシーンの理解ランタイムが実装されています。これは、構造化された高レベルの環境表現を Mixed Reality の開発者に提供するものであり、配置、オクルージョン、物理計算、およびナビゲーションの実装を簡素化できるように設計されています。
サーフェス オブザーバーの使用
サーフェス オブザーバーは、空間マッピングの開始点となるものです。 プログラムのフローは次のとおりです。
- サーフェス オブザーバー オブジェクトを作成する
- 1 つ以上の空間ボリュームを指定して、アプリケーションで空間マッピング データを受信する、目的の領域を定義します。 空間ボリュームは、簡単に言うと、空間領域を定義するシェイプです (球やボックスなど)。
- ワールドロック型の空間座標系を使った空間ボリュームを使用して、物理世界の固定領域を識別します。
- 空間ボリューム (ボディロック型の空間座標系を使って各フレームを更新したもの) を使用して、ユーザーと一緒に移動する (ただし回転はしない) 空間領域を識別します。
- これらの空間ボリュームは、アプリケーションやユーザーの状態が変化するのに応じて、後からいつでも変更される可能性があります。
- ポーリングまたは通知を使用して、空間サーフェスに関する情報を取得する
- 空間サーフェスの状態については、いつでもサーフェス オブザーバーを "ポーリング" して確認できます。 また、サーフェス オブザーバーの "surface changed" イベントに登録することもできます。これは、空間サーフェスが変更された際にアプリケーションに通知を送るものです。
- 動的空間ボリューム (視錐台など) やボディロック型ボリュームの場合、アプリケーションでは、関心領域を設定し、現在の空間サーフェス セットを取得することで、フレームごとに変更をポーリングする必要があります。
- 静的ボリューム (1 つの部屋をカバーするワールドロック型キューブなど) の場合、アプリケーションでは、そのボリューム内の空間サーフェスが変更された場合に通知される "surfaces changed" イベントに登録することができます。
- サーフェスの変更を処理する
- 指定された一連の空間サーフェスを反復処理します。
- 空間サーフェスを、追加済み、変更済み、または削除済みとして分類します。
- 追加済みと変更済みの空間サーフェスについては、必要に応じて非同期要求を送信し、サーフェスの現在の状態を表す更新済みメッシュを必要な詳細レベルで受信します。
- 非同期メッシュ要求を処理します (詳細については、以下のセクションを参照してください)。
メッシュのキャッシュ
空間サーフェスは、高密度の三角形メッシュで表されます。 これらのメッシュの格納、レンダリング、および処理には、大量の計算リソースやストレージ リソースが消費される可能性があります。 そのため、各アプリケーションでは、ニーズに適したメッシュ キャッシュ スキームを採用して、メッシュの処理と格納に使用されるリソースを最小限に抑える必要があります。 このスキームによって、どのメッシュを保持してどれを破棄するかや、各空間サーフェスのメッシュをいつ更新するかが決定されることになります。
ここで検討される考慮事項の多くは、アプリケーションでメッシュ キャッシュをどのように処理するかについての、直接的な判断材料となります。 具体的には、ユーザーが環境内をどのように移動するかや、どのサーフェスが必要か、異なるサーフェスがいつ確認されるか、そして環境内の変更がいつキャプチャされるかを検討してください。
サーフェス オブザーバーによって提供された "surface changed" イベントを解釈する際、メッシュ キャッシュの基本的なロジックは次のようになります。
- アプリケーションで、これまでに確認されていない ID の空間サーフェスが表示された場合、それは新しい空間サーフェスとして扱われます。
- 表示された空間サーフェスについて、ID は既知のものだが、更新日時が新しい場合、それは更新された空間サーフェスとして扱われます。
- 既知の ID を持つ空間サーフェスが表示されなくなった場合、それは削除された空間サーフェスとして扱われます。
その後、各アプリケーションで次の選択を行う必要があります。
- 新しい空間サーフェスの場合、メッシュを要求する必要はあるか?
- 一般に、新しい空間サーフェスについてはすぐにメッシュを要求する必要があります。これにより、ユーザーに役立つ新しい情報が提供される可能性があります。
- ただし、ユーザーの近くや前方にある新しい空間サーフェスを優先とし、それらのメッシュを最初に要求する必要があります。
- 新しいメッシュが必要ない場合 (たとえば、環境のモデルをアプリケーションで永続的または一時的に "固定" している場合)、メッシュの要求は行いません。
- 更新された空間サーフェスの場合、メッシュを要求する必要はあるか?
- 更新された空間サーフェスについては、ユーザーの近くや前方にあるものを優先とし、それらのメッシュを最初に要求する必要があります。
- また、更新されたサーフェスよりも新しいサーフェスを優先する方が適切な場合もあります (特にスキャン エクスペリエンス中)。
- 処理コストを抑えるために、アプリケーションで、空間サーフェスの更新の処理速度を調整したほうがよいかもしれません。
- 場合によっては、空間サーフェスへの変更が軽微であることを推論できる可能性もあります (たとえば、サーフェスの境界が小さい場合、その更新は処理を必要とするほど重要ではない可能性があります)。
- ユーザーの現在の関心領域よりも外にある空間サーフェスへの更新は、完全に無視できる可能性があります。ただし、その場合は、サーフェス オブザーバーで使用されている空間境界ボリュームを変更する方が効率的である可能性があります。
- 削除された空間サーフェスの場合、メッシュを破棄する必要があるか?
- 一般に、削除された空間サーフェスについてはメッシュを直ちに破棄して、ホログラムのオクルージョンが正しい状態に維持されるようにする必要があります。
- ただし、空間サーフェスが (ユーザー エクスペリエンスの設計に基づいて) その後すぐに再表示されるという十分な根拠がある場合は、メッシュを破棄して後で再作成するよりも、そのまま維持した方が効率的である可能性があります。
- アプリケーションでユーザーの環境の大規模なモデルを構築している場合は、メッシュを一切破棄しないのが合理的である可能性があります。 ただし、その場合でも、空間サーフェスが表示されなくなったときにメッシュをディスクにスプールするなどして、リソースの使用量を制限する必要があります。
- 比較的まれなケースですが、空間サーフェスの生成中に発生したイベントが原因で、空間サーフェスが、同じような場所にある新しい空間サーフェス (ただし ID は異なる) に置き換えられることがあります。 そのため、削除されたサーフェスを破棄しないアプローチをとる場合は、同じ場所をカバーする複数のサーフェス メッシュがいくつも重なり合う結果にならないよう、注意を払う必要があります。
- その他の空間サーフェスについては、メッシュを破棄する必要があるか?
- 空間サーフェスが存在している間でも、ユーザーのエクスペリエンスにとって有益でなくなった場合には、破棄するのが合理的です。 たとえば、アプリケーションで、出入り口の向こう側の部屋を別の仮想空間に置き換える場合、その部屋の空間サーフェスは不要になります。
次に示すのは、空間およびテンポラル ヒステリシスを使用した、メッシュ キャッシュ戦略の例です。
- あるアプリケーションで、ユーザーが周囲を見回したり歩き回ったりする際にその視線に追従する、視錐台形の空間ボリュームを関心対象として使用しているとします。
- ユーザーが特定の空間サーフェスから視線を離したり、そこから離れた場所に移動したりすると、そのサーフェスはボリュームから一時的に消えますが、後でユーザーがもう一度後ろを振り返ったり、もう一度近くに移動する可能性もあります。 そのような場合、そのサーフェスのメッシュを破棄して再作成すると、多くの冗長処理が発生します。
- 処理される変更の数を減らすために、このアプリケーションでは 2 つの空間サーフェス オブザーバーが使用されています (一方がもう一方に包含されています)。 大きいほうのボリュームは球形で、ユーザーに "緩やかに" 追従します。このボリュームは必要な場合にのみ移動し、その中心からユーザーまでの距離を 2.0 m 以内に維持します。
- 新しい空間サーフェス メッシュと更新された空間サーフェス メッシュは、常に小さいほうの内部サーフェス オブザーバーから処理されますが、メッシュは、外側の大きいサーフェス オブザーバーから消えるまでキャッシュされます。 そのため、ローカル ユーザーが移動しても、多くの冗長な変更を処理しなくて済むようになっています。
- なお、空間サーフェスは追跡損失が原因で一時的に消える可能性もあるのでこのアプリケーションでは、追跡損失の際、削除された空間サーフェスの破棄を延期するようになっています。
- 一般に、アプリケーションでは、更新処理の削減とメモリ使用量の増加のトレードオフを評価したうえで、理想的なキャッシュ戦略を決定する必要があります。
表示
空間マッピング メッシュをレンダリングに使用する場合、主に次の 3 つの方法で使用される傾向があります。
- サーフェスの視覚化のため
- 多くの場合、空間サーフェスは直接視覚化するのが有益です。 たとえば、オブジェクトから空間サーフェスに '影' をキャストすると、サーフェス上にホログラムを配置する際に、ユーザーに視覚的なフィードバックを提供することができます。
- なお、空間メッシュは、3D アーティストが作成するメッシュとは種類が異なるという点に注意してください。 三角形のトポロジは人が作成したトポロジほど "クリーン" にはならず、メッシュは、さまざまなエラーの影響を受けます。
- 見栄えの良いビジュアルを作成するために、メッシュ処理を行ったほうがよい場合があります (穴の塗りつぶしや、サーフェス法線のスムージングなど)。 また、メッシュ トポロジや法線を直接視覚化する代わりに、シェーダーを使用して、アーティストがデザインしたテクスチャをメッシュに投影することもできます。
- 現実世界のサーフェスの後ろにあるホログラムをオクルージョンするため
- 空間サーフェスは、深度のみのパスでレンダリングすることができます。このパスは深度バッファーにのみ影響し、カラー レンダー ターゲットには影響しません。
- これにより、空間サーフェスの後ろにレンダリングされるホログラムをオクルージョンするための深度バッファーが準備されます。 ホログラムを正確にオクルージョンすると、ホログラムがユーザーの物理領域内に本当に存在するような感覚が高まります。
- 深度のみのレンダリングを有効にするには、ブレンドの状態を更新し、すべてのカラー レンダー ターゲットについて、RenderTargetWriteMask を 0 に設定します。
- 現実世界のサーフェスによってオクルージョンされたホログラムの外観を変更するため
- 通常、レンダリングされたジオメトリは、オクルージョンされると表示されなくなります。 これは、深度ステンシルの状態の深度関数を "次の値以下" に設定することで実現されます。こうすると、ジオメトリは、以前にレンダリングされたすべてのジオメトリよりもカメラに近い場所にある場合にのみ、表示されるようになります。
- ただし、オクルージョンされた場合でも、特定のジオメトリはそのまま表示されるようにしたり、ユーザーに視覚的なフィードバックを提供するために、オクルージョンされたときの外観を変更したりするのが効果的な場合もあります。 たとえば、オブジェクトの場所をユーザーに表示しながらも、それが現実世界のサーフェスの後ろにあることをわからせるように表示することもできます。
- これを実現するには、適切な 'オクルージョン時の' 外観を作成する別のシェーダーを使って、ジオメトリをもう一度レンダリングします。 ジオメトリの 2 回目のレンダリングを行う前に、深度ステンシルの状態に対して、2 つの変更を加えます。 まずは、深度関数を "次の値以上" に設定します。こうすると、そのジオメトリは、以前にレンダリングされたすべてのジオメトリよりもカメラから離れている場合にのみ、表示されるようになります。 次に、DepthWriteMask を 0 に設定して、深度バッファーが変更されないようにします (深度バッファーは引き続き、カメラに最も近いジオメトリの深度を表すことになります)。
パフォーマンスは、空間マッピング メッシュをレンダリングする際の重要な考慮事項です。 次に示すのは、空間マッピング メッシュのレンダリングに特化した、レンダリング パフォーマンス手法です。
- 三角形の密度を調整する
- サーフェス オブザーバーから空間サーフェス メッシュを要求する際には、ニーズに見合った、三角形メッシュの最低密度を要求します。
- サーフェス上の三角形の密度は、ユーザーからの距離やユーザー エクスペリエンスとの兼ね合いに応じて、サーフェスごとに変えたほうがよい場合があります。
- 三角形の数を減らすことは、GPU のメモリ使用量と頂点の処理コストを軽減することにつながりますが、ピクセルの処理コストには影響しません。
- 視錐台カリングを使用する
- 視錐台カリングを使用すると、現在の表示の視錐台よりも外にあるために表示されない描画オブジェクトをスキップすることができます。 これにより、CPU と GPU の両方の処理コストを削減できます。
- カリングはメッシュごとに実行されますが、空間サーフェスが大きい場合もあるため、各空間サーフェス メッシュを小さなチャンクに分割すると、より効率的にカリングを実現できる可能性があります (画面の外でレンダリングされる三角形が減るため)。 ただし、トレードオフもあります。メッシュの数が多いほど描画呼び出しが多くなるため、CPU コストが増加する可能性があります。 極端な場合、視錐台カリングの計算だけで、相当な CPU コストを消費する可能性もあります。
- レンダリング順序を調整する
- 空間サーフェスは、ユーザーを取り囲む環境全体を表すため、サイズが大きくなる傾向があります。 GPU でのピクセル処理コストは、可視ジオメトリのレイヤー (空間サーフェスとその他のホログラムを含む) が複数存在する場合に、特に大きくなる可能性があります。 その場合、ユーザーに最も近いレイヤーによって、それより離れたレイヤーがオクルージョンされるため、それらの離れたレイヤーをレンダリングするための GPU 時間が無駄になります。
- GPU 上のこの冗長な作業を減らすには、不透明なサーフェスを、前方から後方へと向かう順序でレンダリングする (近いものから先に処理していく) のが効果的です。 この場合、'不透明' とは、DepthWriteMask が深度ステンシルの状態の値に設定されたサーフェスのことを意味します。 最も近いサーフェスがレンダリングされると、深度バッファーが準備されるため、GPU のピクセル プロセッサによって、離れたサーフェスが効率的にスキップされるようになります。
メッシュ処理
アプリケーションでは、ニーズに応じて、空間サーフェス メッシュに対するさまざまな操作を行ったほうがよいかもしれません。 各空間サーフェス メッシュで提供されるインデックス データと頂点データでは、あらゆる最新のレンダリング API で三角形メッシュのレンダリングに使用される頂点バッファーおよびインデックス バッファーと同じ、馴染みのあるレイアウトが使用されます。 ただし、1 つ重要な注意点として、空間マッピングの三角形は、正面から見て時計回りの回転順序になります。 各三角形はメッシュのインデックス バッファー内にある 3 つの頂点インデックスによって表されますが、これらのインデックスでは、三角形の頂点が時計回りの順序で識別されます (三角形を正面から見た場合)。 空間サーフェス メッシュの前面 (または外側) は、皆さんが予期するとおり、現実世界のサーフェスの前面 (表示される側) に対応します。
アプリケーションでは、サーフェス オブザーバーによって提供された最も粗い三角形密度がまだ十分な粗さになっていない場合にのみ、メッシュの単純化を行うようにしてください。この作業は計算負荷が高く、さまざまな詳細レベルを生成するために、ランタイムによって既に実行中です。
各サーフェス オブザーバーでは複数の未接続空間サーフェスが提供される可能性があるため、アプリケーションによっては、これらの空間サーフェス メッシュを相互にクリップして、それらをひとまとめにしたほうがよいかもしれません。 一般的に、隣接する空間サーフェス メッシュは少し重なることが多いため、クリッピングの手順は必須となります。
レイキャスティングと衝突
物理計算 API (Havok など) を使ってアプリケーションに空間サーフェスのレイキャスティング機能と衝突機能を提供するには、そのアプリケーションで、物理計算 API に空間サーフェス メッシュを提供する必要があります。 物理計算に使用されるメッシュには、多くの場合、次の特性があります。
- 少数の三角形しか含まれていない。 物理計算操作では、レンダリング操作よりも計算負荷が大きくなります。
- きわめて緊密である。 ソリッドになるよう意図されたサーフェスには、小さな穴もあってはいけません。目に見えないほど小さな穴でも、問題の原因となる可能性があります。
- 凸包に変換される。 凸包にはポリゴンがほとんどなく、穴は一切ありません。また、生の三角形メッシュよりも計算処理がはるかに効率的です。
空間サーフェスに対してレイキャストを実行する場合、それらのサーフェスは多くの場合に複雑で、細かな表現を含んだ、処理しにくい形状となっている場合が多いことに注意してください (机などもその例です)。 つまり、1 つのレイキャストでは、サーフェスの形状や、その近くにある空間の形状に関する十分な情報を得られないことがよくあります。 通常は、小さな領域内で多数のレイキャストを実行し、その集計結果を使って、サーフェスに関するより信頼性の高い情報を抽出することをお勧めします。 たとえば、サーフェス上にホログラムを配置する場合、平均 10 個のレイキャストをガイドとして使用することで、1 つのレイキャストだけを使用する場合に比べて、はるかに滑らかで "ちらつき" の少ない結果を得ることができます。
ただし、レイキャストを増やすごとに、計算コストが高くなる可能性があることに注意してください。 用途のシナリオに応じて、レイキャストの追加 (フレームごとに実行される操作) による計算コストと、空間サーフェスの穴をスムージングしたり除去したりするメッシュ処理 (空間メッシュが更新されたときに実行される操作) の計算コストを比較して、両者の兼ね合いを検討してください。
環境のスキャン エクスペリエンス
空間マッピングを使用する各アプリケーションでは、"スキャン エクスペリエンス" を提供することを検討する必要があります。これは、アプリケーションを正常に機能させるために必要なサーフェスをスキャンできるよう、ユーザーをガイドするプロセスのことです。
スキャンの例
このスキャン エクスペリエンスの性質はアプリケーションのニーズによって大きく変わってくる可能性がありますが、設計の原則としては、主に 2 つことが挙げられます。
1 つ目は、ユーザーとの明確なコミュニケーションがきわめて重要であるということです。 ユーザーは、アプリケーションの要件が満たされているかどうかを常に把握する必要があります。 要件が満たされていない場合は、その理由をユーザーに直ちに通知し、ユーザーが適切な処置を実行できるよう、迅速に誘導する必要があります。
2 つ目は、アプリケーションで、効率性と信頼性のバランスを図る必要があるということです。 アプリケーションでは、ユーザー時間を節約するために、空間マッピング データを自動的に分析する必要があります (信頼性を持って実行できる場合)。 信頼性を持ってこれを実行できない場合は、代わりに、必要な追加情報をユーザーが迅速に提供できるようにする必要があります。
適切なスキャン エクスペリエンスを設計するには、ご自分のアプリケーションについて、次のいずれが当てはまるかを検討してください。
スキャン エクスペリエンスがない
- アプリケーションによっては、ガイド付きのスキャン エクスペリエンスがなくても完璧に機能できる場合もあります。自然なユーザー移動を通じて、検出されたサーフェスの情報を学習できるような場合です。
- たとえば、ユーザーがホログラムの塗装スプレーを使ってサーフェス上に絵を描けるアプリケーションの場合、必要となるのは、現在ユーザーに表示されているサーフェスの情報だけです。
- 場合によっては、環境が既にスキャンされている可能性もあります。ユーザーがその環境を HoloLens で既に長時間使用している場合です。
- ただし、空間マッピングで使用されるカメラでは、ユーザーの前方 3.1 m までしか認識されないことに注意してください。それよりも離れたサーフェスについては、ユーザーが過去にそれらをより近くで見ていない限り、情報が取得されていません。
- どのサーフェスがスキャン済みなのかをユーザーが把握できるように、アプリケーションでは、この効果に対する視覚的なフィードバックを提供する必要があります。たとえば、スキャン済みのサーフェスに仮想の影をキャストすれば、ユーザーがそれらのサーフェスにホログラムを配置しやすくなります。
- その場合は、空間サーフェス オブザーバーの境界ボリュームをボディロック型の空間座標系に対してフレームごとに更新して、ユーザーを追従できるようにする必要があります。
適切な場所を検索する
- アプリケーションによっては、特定の要件を満たした場所で使用するように設計されている場合もあります。
- たとえば、ユーザーがホログラムのカンフーを安全に練習できるように、ユーザーの周囲に何もない領域があることを要件としている場合などです。
- アプリケーションでは、具体的な要件を事前にユーザーに伝え、わかりやすい視覚的なフィードバックによって、その理解を強化する必要があります。
- この例の場合、アプリケーションでは必要な空白領域の範囲を視覚化し、そのゾーン内に望ましくないオブジェクトがある場合には、その存在を視覚的に強調表示する必要があります。
- その場合、空間サーフェス オブザーバーの境界ボリュームでは、選択された場所にワールドロック型の空間座標系を使用する必要があります。
適切なサーフェス構成を特定する
- アプリケーションでは、サーフェスについて特定の構成が必要になる場合があります。たとえば、大きくて平らな壁を 2 つ向かい合わせて、ホログラムによる鏡の広間を作成するような場合です。
- そのような場合、アプリケーションでは、空間マッピングによって提供されたサーフェスを分析して適切なサーフェスを検出し、それらの方向を向くようにユーザーを誘導する必要があります。
- アプリケーションのサーフェス分析が信頼できない場合には、ユーザーにフォールバック オプションを提供する必要があります。 たとえば、出入り口が誤って平らな壁として識別された場合に、ユーザーがそのエラーを簡単に修正できるようにする必要があります。
環境の一部をスキャンする
- 場合によっては、ユーザーの指示に従って、環境の一部のみをキャプチャするのが合理的な場合もあるでしょう。
- たとえば、部屋の一部をスキャンして、ユーザーが自分の売りたい家具にホログラムの広告を貼り付けられるようにするような場合です。
- その場合は、アプリケーションでスキャンを行う際に、ユーザーが見ている領域内の空間マッピング データをキャプチャする必要があります。
部屋全体をスキャンする
- 場合によっては、ユーザーの背後にあるものも含め、現在の部屋にあるすべてのサーフェスをスキャンしなければならないこともあるでしょう。
- たとえば、ゲームの中でガリバーになってプレイするユーザーを、何百ものリリパット人があらゆる方向から攻撃してくるような場合です。
- そのような場合、アプリケーションでは、現在の部屋で既にスキャンされているサーフェスの数を特定し、重要な不足領域を埋めるために、ユーザーの視線を誘導する必要があります。
- このプロセスで重要となるのは、どのサーフェスがまだスキャンされていないのかをユーザーに明確に示すために、視覚的なフィードバックを提供することです。 たとえば、距離ベースのフォグを使用すれば、空間マッピング サーフェスでカバーされていない領域を視覚的に強調表示することができます。
環境の初期スナップショットを取得する
- 場合によっては、初期の "スナップショット" を取得した後、環境内のすべての変化を無視したほうがよいこともあるでしょう。
- たとえば、ユーザーによって作成されたデータが環境の初期状態と密接に結び付いている場合に、そのデータが壊れないようにしたいような場合です。
- その場合、アプリケーションでは、スキャンの完了後、空間マッピング データの初期状態のコピーを作成する必要があります。
- ホログラムがまだ環境によって正しくオクルージョンされていない場合は、空間マッピング データへの更新を引き続き受信する必要があります。
- 空間マッピング データを引き続き更新することで、発生したすべての変更を視覚化し、環境の以前の状態と現在の状態との違いをユーザーに明確に示すことができます。
環境のスナップショットをユーザーの指示で取得する
- アプリケーションによっては、ユーザーから指示された場合にのみ、環境の変化に対応したほうがよい場合もあるでしょう。
- たとえば、ユーザーが友人の立体像を複数作成する場合に、その友人のさまざまな瞬間のポーズをキャプチャしたいような場合です。
ユーザーが環境を変更できるようにする
- アプリケーションによっては、ユーザーの環境で起きた変化にリアルタイムで対応するように設計される場合もあります。
- たとえば、ユーザーがカーテンを引くことで "シーンの変更" がトリガーされ、カーテンの向こう側でホログラムの演劇が開始されるような場合です。
空間マッピング データのエラーを回避するようにユーザーをガイドする
- アプリケーションでは、ユーザーが環境をスキャンする際に、ユーザーにガイダンスを提供することもできます。
- そうすることで、空間マッピング データ内での特定の種類のエラーをユーザーが回避しやすくなります (たとえば、日光が当たっている窓や鏡から離れるなど)。
もう 1 つ、細かな注意点があります。それは、空間マッピング データの "範囲" は無制限ではないということです。 空間マッピングでは、大きなスペースの永続的なデータベースが作成されますが、アプリケーションで使用できるのは、ユーザーを取り囲む、サイズの限られた 'バブル' 内のデータのみとなります。 長い廊下の端から歩き始めて、そこから遠く離れた位置まで移動した場合、最終的に、歩き始めた位置の空間サーフェスは失われることになります。 この現象は、それらのサーフェスが使用可能な空間マッピング データから消えた後、それらをアプリケーションにキャッシュすることで軽減できます。
メッシュ処理
メッシュ処理は、サーフェス内にある一般的な種類のエラーを検出し、必要に応じて空間マッピング データをフィルター処理、削除、または変更するのに役立ちます。
なお、空間マッピング データでは、現実世界のサーフェスをできるだけ忠実に再現するのが理想なので、処理を適用することにより、サーフェスと "本物" との違いが大きくなる恐れがあることに注意してください。
次に示すのは、役に立つ可能性がある各種のメッシュ処理の例です。
穴の塗りつぶし
- 暗いマテリアルで作成された小さなオブジェクトのスキャンに失敗した場合、その周囲のサーフェスに穴が残ることになります。
- 穴はオクルージョンに影響します。不透明であるはずの現実世界のサーフェスに穴があると、その向こうのホログラムが見えてしまう可能性があります。
- 穴はレイキャストに影響します。ユーザーがサーフェスを操作しやすくなるようにレイキャストを使用する場合、それらの光線が穴を通過するのは望ましくありません。 1 つの緩和策としては、複数のレイキャストをバンドルして、適切なサイズの領域をカバーさせる方法があります。 そのうえで、"外れ値" の結果をフィルター処理すれば、1 つのレイキャストが小さな穴を通過した場合でも、集計結果が有効になるようにすることができます。 ただし、このアプローチには計算コストが伴います。
- 穴は物理的な衝突に影響します。物理シミュレーションによって制御されるオブジェクトが、床の穴を通過し、失われる可能性があります。
- サーフェス メッシュに生じたこのような穴はアルゴリズムによって埋めることができます。 ただし、窓や出入り口などの "本物の穴" が埋められないように、アルゴリズムを調整する必要があります。 "本物の穴" と"想像上の穴" を確実に区別するのは難しい場合もあるので、"サイズ" や "境界形状" などのさまざまなヒューリスティックを試してみる必要があります。
幻影の除去
- 反射、明るい光、および移動するオブジェクトによって、空中に小さな "幻影" が生じ、存在し続ける場合があります。
- 幻影はオクルージョンに影響します。幻影は、他のホログラムの前面で動く暗いシェイプとして表示され、そのホログラムの表示を遮ることがあります。
- 幻影はレイキャストに影響します。ユーザーがサーフェスを操作しやすくなるようにレイキャストを使用する場合、それらの光線が、後ろにあるサーフェスではなく、幻影に当たる可能性があります。 穴の場合と同様に、緩和策として、1 つのレイキャストではなく多数のレイキャストを使用することはできますが、この場合も計算コストが発生します。
- 幻影は、物理的な衝突に影響を与えます。物理シミュレーションによって制御されるオブジェクトが、幻影に遮られて、何もないように見える領域を通過できなくなる可能性があります。
- このような幻影は、サーフェス メッシュからフィルター処理できます。 ただし、穴の場合と同様、現実世界の小さなオブジェクト (照明スタンドやドア ハンドルなど) が削除されないように、アルゴリズムを調整する必要があります。
スムージング
- 空間マッピングでは、返されたサーフェスが、現実世界の対応物と比べて粗い外観になったり、"乱れた" 外観になることがあります。
- 滑らかさは、物理的な衝突に影響します。床が粗い場合、物理的にシミュレートされたゴルフ ボールが床の上をまっすぐスムーズに転がらない可能性があります。
- 滑らかさはレンダリングに影響します。サーフェスが直接視覚化される場合、粗いサーフェス法線がその外観に影響を与え、"クリーンな" 見た目を損なう可能性があります。 この現象は、サーフェスのレンダリングに使用されるシェーダー内で適切な照明とテクスチャを使用することにより、軽減することができます。
- サーフェス メッシュの粗さはスムージングすることができます。 ただし、これを行うと、そのサーフェスが現実世界の対応するサーフェスよりも遠くに移動される可能性があります。 近接性を維持することは、ホログラムのオクルージョンを正確に生成するうえで重要です。また、ユーザーがホログラムのサーフェスとの相互作用を予測し、正確に実行できるようにするうえでも重要です。
- 表面的な変更のみが必要な場合は、頂点の位置を変更せず、頂点の法線をスムージングするだけで十分な場合もあります。
平面の検索
- アプリケーションでは、空間マッピングによって提供されるサーフェスに対して、さまざまな形式の分析を実行することができます。
- シンプルな例としては、"平面検索" があります。これは、サーフェスの境界領域 (主に平面領域) を識別するものです。
- 平面領域は、ホログラムのコンテンツを自動的に配置できる、ホログラムの作業台として使用できます。
- 平面領域では、ユーザー インターフェイスを制限して、ユーザーが自分のニーズに最も合うサーフェスと相互作用できるようにガイドすることができます。
- 平面領域は、LCD 画面、テーブル、ホワイトボードなどの機能オブジェクトに対応するホログラムとして、現実世界と同じように使用できます。
- 平面領域では、プレイ領域を定義して、ビデオ ゲームの基準面を形成できます。
- 平面領域は、仮想エージェントが現実世界を移動する際の補助としても使用できます (本物の人間が通常は歩かない床の領域を特定するなど)。
プロトタイピングとデバッグ
便利なツール
- HoloLens エミュレーターを使用すれば、物理的な HoloLens を使わずに、空間マッピングを使用したアプリケーションを開発できます。 HoloLens でのライブ セッションをリアルな環境でシミュレートできるだけでなく、アプリケーションで通常使用されるすべてのデータを使用できます (HoloLens モーション、空間座標系、空間マッピング メッシュなど)。 これを使えば、信頼度の高い、反復可能な入力を提供できるので、問題をデバッグしたり、コードの変更を評価したりするのに役立ちます。
- シナリオを再現したい場合、ライブの HoloLens からネットワーク経由で空間マッピング データをキャプチャし、それをディスクに保存すれば、その後のデバッグ セッションで再利用できます。
- Windows デバイス ポータルの 3D ビューでは、空間マッピング システムを通じて現在使用できる、すべての空間サーフェスを表示できます。 これにより、アプリケーション内の空間サーフェスを比較するための基準が提供されます。たとえば、不足している空間サーフェスがないかや、間違った場所に表示されている空間サーフェスがないかどうかを簡単に確認できます。
プロトタイピングの一般的なガイダンス
- 空間マッピング データ内のエラーはユーザーのエクスペリエンスに大きな影響を与える可能性があるため、アプリケーションのテストはさまざまな環境で行うことをお勧めします。
- いつも同じ場所で (たとえば、自分のデスクで) テストするのが習慣にならないようにしてください。 位置、形状、サイズ、およびマテリアルの異なる、さまざまなサーフェスでテストするようにしてください。
- 同様に、合成データや記録済みのデータはデバッグに役立ちますが、少数の同じテスト ケースに依存することは避けてください。 多様なテストをすれば早期に検出できたはずの重要な問題を、なかなか検出できない結果となる恐れがあります。
- 実際のユーザー (できれば指導を受けていないユーザー) でテストを実施することをお勧めします。それらのユーザーは、開発者とは異なる方法で HoloLens やアプリケーションを使用する可能性があります。 実際、ユーザーの行動、知識、および考え方がいかに多様であるかを知って、驚かれるかもしれません。
トラブルシューティング
- サーフェス メッシュが正しい向きになるには、各 GameObject が SurfaceObserver に送信されてメッシュが構築される前に、それらがアクティブになっている必要があります。 そうでないと、空間にメッシュが表示されても、おかしな角度に回転される結果になります。
- SurfaceObserver と通信するスクリプトを実行するオブジェクトは、原点に設定される必要があります。 そうでない場合、GameObjects を作成し、SurfaceObserver に送信してメッシュを構築しても、それらのオブジェクトはすべて、親ゲーム オブジェクトのオフセットと同じオフセットになります。 その結果、メッシュが数メートル離れて表示され、その現象を簡単にデバッグすることはできなくなります。