Quest2のパススルーはHoloLens2の代替になるのか試してみた

# 環境

- 開発環境
  - Windows 10
  - Unity 2021.3.5
- HoloLens 2
  - Windows version	20348
  - Microsoft Mixed Reality Toolkit v2.8.2
- Quest 2
  - Version 42
  - OculusIntegration_v41.0.unitypackage

# 経緯

-  最近、HoloLens 2と Quest 2 のクロスプラットフォーム対応の検証をしています
- 2つの端末において「MRという側面」で比較してみました
  - Quest 2のMR機能（ビデオパススルー）は、HoloLesn 2の代替になるのか？、ずっと気になっていました(やっと自分で試せました)
- 私の脳内は、以下のように、HoloLens 2に迫りくるQuest 2(Meta社)って感じでした
  - （週末、なんとなく描き始めた落書き（幻想）が止まらず…怒られたら全力で謝罪します）
![ss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/40066312-16e6-bb0d-502c-0a20b0ed8333.png)

# 各端末の用途などの整理

- 各端末において、用途とターゲットと価格帯が異なる点、頭にとめておく必要があると思います
- 各端末で、用途とターゲットが完全に異なるので、比較するものではないかもしれませんが、
- 踏まえた上で、向き、不向きを考察したいと思います

## 用途とターゲット

- HoloLens 2:企業向け、業務・ビジネス利用がメイン
- Quest 2：個人向け、エンタメ利用がメイン

## HoloLens 2と Quest 2の価格差

- HoloLens 2: ￥422,180
- Quest 2：￥37,180
- 10倍以上（11.3550295858）の差！

### 参照情報

- 2022/7/26時点で以下のページで得られた価格
  - https://www.microsoft.com/ja-jp/hololens/buy
  - https://store.facebook.com/jp/quest/products/quest-2
-  Quest 2の価格が変更になるようです
  - https://www.itmedia.co.jp/news/articles/2207/27/news078.html

> 米Metaは7月26日（現地時間）、スタンドアロンVRヘッドセット「Meta Quest 2」の値上げを発表した。128GBモデルは現在の3万7180円から5万9400円に、256GBモデルは4万9280円から7万4400円にと、それぞれ2万円以上の値上げだ。

# ハードウェア性能、特徴の比較

- CPU単体の処理能力：performance coresの数はHoloLens 2の方が多い、周波数が高い（と思います）
  - HoloLens 2：Snapdragon 850(2019 Q1)
    - HoloLens 2：High performance cores: 4x Qualcomm Kryo 385 Gold @ 2,95 GHz	
  - Quest 2：Snapdragon XR2 Platform(2020 Q1)
    - Quest 2：High performance cores: 2x Qualcomm Kryo Gold @ 2,5 GHz
- GPU単体の処理能力；Quest2の方が上（だと思います）
  -  HoloLens 2: 737 GFLOPS、Meta Quest2 :1,418 GFLOPS（単精度）
- HoloLens 2は、HPU(Second-generation custom-built holographic processing unit)など搭載されているため、CPU/GPUだけの比較では演算処理の性能比較にならない（と思います）
- Depthカメラ：HoloLens 2のみ搭載

## 参照にした情報

- https://gadgetversus.com/processor/qualcomm-snapdragon-xr2-vs-qualcomm-sdm850-snapdragon-850/
- https://en.wikichip.org/wiki/qualcomm/snapdragon_800/850
- 各端末として述べられているわけではないので、合ってないかもしれません

# Quest 2のビデオパススルー機能をMRとして利用することを試す
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/a388a6b3-4641-ef8e-35bf-23e2ba62f62a.png)
## Quest 2のビデオパススルーの留意点

- Quest 2のビデオパススルー機能は、
- 「トラッキング」、「外界の様子をなんとなく伺う」用途のカメラで実現いると認識しています
- 機能は限定的であるが（グレースケール画像など）、「用途によっては、はまることがあるかもしれない」、「将来への布石」で提供していると推測しています

## パススルーとハンドトラッキングをMRとして使うことを試した結果

- 以下の点で、「作業の手順を手助けをする情報を現実世界の映像に合成して表示するような用途」には向かないと思いました
  - カメラ映像が歪む
  - フレームレートが低い
  - 解像度が低い
  - グレースケール
  - コントラストが低い（現実世界の文字などを読むのはかなり難しい）
  - 現実世界の距離感がつかみづらい
  - 標準仕様では、バイザーをあげて、手軽に現実世界に戻ることができない
- ハンドトラッキングは違和感を感じませんでした

![q1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/bca8be56-6662-531d-3720-57ebf7ac33eb.gif)



## 「カメラ映像」と「バーチャルオブジェクト」の重ね方について

- 「カメラ映像」と「バーチャルオブジェクト」どちらかを先に描画するか選択できます
  - [OVRPassthroughLayer]の[Placement]で設定する
    - [Overrlay] パススルーの映像をバーチャルオブジェクトの手前に描画する（Opacityで透過設定するなどして利用する）
    - [Underlay] パススルーの映像をバーチャルオブジェクトの奥に描画する

![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/637387ea-99fd-4473-85d3-bd99485a1d86.png)

### 個人的にMRするときに、使い勝手がよさそうだと感じた手法

- MRするならば、先に「カメラ映像」を描いて、その上から「バーチャルオブジェクト」を重ねるのが使い勝手がよさそうです
- これをすると、リアルな手がバーチャルオブジェクトの背面になります（現実世界の手を利用する場合、かなりの違和感を感じます）
- 対策として、ハンドトラッキング機能を利用して、手の部分マスクする手法（バーチャルオブジェクトをオクルージョンする手法）があるようです
- 当然ながら、手以外のオブジェクト（以下の例だと消しゴム）は、手前にあると人間が捉えても、必ず背面になります
![q2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/698c0209-d1dc-9f5e-f673-94bc7975c6ac.gif)
- 現実の手とハンドトランキングの手が完全に一致するわけではなく、ズレることがあります、更新頻度は[Hand Tracking Frequency]に依存すると思われます
  - OculusIntegrationのサンプルに、手の領域を調整するサンプルがありました
  - Assets/Oculus/SampleFramework/Usage/Passthrough/Scenes/PassthroughHands.unity
  - 以下、調整できる項目です
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/9549676b-1dbe-a6ca-c8db-289e095d2014.png)

### 手のオクルージョンの方法

- 概要を図示します
  - 上層：バーチャルオブジェクトの赤い部分はデプステストで失敗するので描かれず、下層の現実の手が描画される
  - 中層：手の部分のみデプスを描く
  - 下層：カメラ映像
![occlusion.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/8b2031f3-fd22-0483-01f8-890ab350cfa3.jpeg)

- デプスのみ（RGBAは、0,0,0,0）を書き込むシェーダーを作る
- すべてのバーチャルオブジェクトが描画される前に、バーチャルハンドをデプスのみで描画する
  - Unityの[Render Queue]を2000より低くする、など
  - バーチャルハンドの奥にある他のオブジェクトは、デプステストで失敗するため、手の部分がパススルーの映像になる
- このシェーダーコードのマテリアルを作り、バーチャルハンドに割り当てる


![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/e89f9815-427b-79a6-9621-b1e47f3f5507.png)

- The World Beyondでもこの手法が使われていそうです
  - The World Beyondのリポジトリにあるデプスのみを書き込むシェーダー
  - https://github.com/oculus-samples/Unity-TheWorldBeyond/blob/main/Assets/MultiToy/Materials/DepthOnly.shader

- The World Beyondで、バーチャルキャラクターの額に現実世界の手をあてる様子

![twb.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/21500264-405c-2fbf-6646-cd3c74a23c2b.jpeg)


- 以下、シェーダーのコード
```glsl:DepthOnly.shader
Shader "TheWorldBeyond/DepthOnly" {
  Properties {
  }
  SubShader {
    Tags{"RenderType" = "Transparent"} LOD 100

        // First Pass: render outside shell of hand, as depth object
        Pass {
      ColorMask 0 Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog

#include "UnityCG.cginc"

          struct appdata {
        float4 vertex : POSITION;
      };

      struct v2f {
        UNITY_FOG_COORDS(1)
        float4 vertex : SV_POSITION;
      };

      v2f vert(appdata v) {
        v2f o;
        o.vertex = UnityObjectToClipPos(v.vertex);
        UNITY_TRANSFER_FOG(o, o.vertex);
        return o;
      }

      fixed4 frag(v2f i) : SV_Target {
        //clip(mask.r - 0.5);
        return float4(0,0,0,0);
      }
      ENDCG
    }
  }
}
```

- Single pass instancing (MultiView) には対応してないので、Multi Passにするか、自分でSingle pass instancing対応する必要があります
- Multi passに設定する場合は以下の項目で設定します
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/5ee78107-0537-5f70-e1ad-985fccef7166.png)

### 他に考えられる手法

- 現実世界の手は使わず、バーチャルコントローラ、バーチャルハンドを現実世界の映像の上に描く
- 先にバーチャルオブジェクトを描いて、後にカメラ映像を半透明で重ねる
- 背面をパススルーの映像にして、一番手前のピクセルだけを半透過でカメラ映像に合成する
  - デプスを先に計算する必要があると思います
  - すべてのオブジェクトを半透明にすると、描画負荷が高い、見せたくない部分が見えて使いづらいと思います

## Quest 2のパススルーが向いていそうな用途

- 「現実世界」と「仮想世界」の表示を完全に切り替えられるのは、ビデオパススルーの強みだと思いました
- 「The World Beyond」の例がそれを見事に表現しています
  - https://www.oculus.com/experiences/quest/4873390506111025/
  - 事前に現実世界の部屋にあるオブジェクトの位置と大きさを手動で設定することで実現しています
- 現実世界と仮想空間をいったりきたりする演出に向いていそうです

- 以下、Questの開発ページより、シーンの設定の図解
![287783492_1061908301406348_130692455430144985_n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/4256c539-560e-f5d9-a315-962ecb07b6a4.png)


# HoloLens 2の機能を改めて確認
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/7bda7d7c-0ea4-6c59-4086-293e005992b8.png)
## 「現実世界の手」と「バーチャルオブジェクト」

- HoloLens 2は「光学シースルー型ディスプレイ」ということもあり、完全に不透明なバーチャルオブジェクトを配置しても、現実世界が透けてみえます
  - HoloLens 2では、ゴーグル越しの視界をバーチャルオブジェクトで、完全に覆い隠すことができないという認識です
- 透けてみえることによって、「現実世界の手」より「バーチャルオブジェクト」が手前に描画されても違和感が少ないです

## HoloLens 2(MRTK)のSpatial awareness

- デプスカメラがあることもあって、現実世界の深度情報を得ることができるのが、HoloLens 2の特徴のひとつだと思っています
  - ステレオ方式で深度情報を計算できるかもしれませんが
- とはいえ、現状、HoloLens 2のSpatial awarenessは、意図した絵にならないことがある、処理負荷が高いなどで、使いどころを選ぶ印象です
- 更新間隔、生成されるポリゴンの詳細さなどが、今後改善されれば、活躍の場が広がりそうと感じています
- 一方で、事前準備なしで、現実世界の固定された机や床にバーチャルオブジェクトを配置できるのは、MRとして利用するときに重宝すると考えています

- 以下の画像は、[Level of Detailを[Fine]で設定した場合
  - ポリゴンを生成するため、10cm程度の丸みが帯びた円柱などは精度を期待しづらい
  - 30cm程度の角ばっている物ならば、精度が期待できる
  - 消しゴムのような、3cm程度のオブジェクトは、オクルージョンが難しい
  - 部屋などで使うことを想定していると思っています（意地悪テストになってしまいました）
![h1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/bc1e447c-de14-8b94-8d89-fd33fc9a2f98.gif)
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/cdf0f393-97ce-5c15-6a71-3934a4f9a08f.png)

- 以下の図は、https://docs.microsoft.com/en-us/windows/mixed-reality/design/spatial-mapping より

![surfacereconstruction.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/df91f8a0-e68b-1ea1-41f1-9eaaf47c2b80.jpeg)

## 手のデプスを書き込む手法をHoloLens 2でも試してみた

- 何もしないより、こちらの方が違和感が大きいと感じました
  - ハンドトラッキングの精度と更新頻度の問題と思います
- Research Modeで取得できる、デプス画像をマスク画像として使うと、綺麗になるかもしれません
  - 近距離であれば、45FPSでデプス画像を取得できるそうです

![h2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/5dbaa322-4eec-edda-cd93-c84cc18b1af9.gif)
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/d6be06a0-0990-f6d2-1907-6456f8ea5fa5.png)

# まとめ

- 各端末において用途にあった使い方をするために、機能を正しく理解することが重要と改めて実感しました
  - 当然ながら、Quest 2は、HoloLens 2の代替にはならいないと思いました、
  - （Quest 2は、現実の作業の手順を手助けをする情報を表示する用途には向いていないと思いました）
  - 今更、記事で改めて述べることではなく大変恐縮です
- 個人的に、Quest 2のビデオパススルー（MR）機能は、Project Cambriaなど将来への伏線と考えるのが自然だと感じました
  - 様々な制約の中で、「The World Beyond」をQuest 2で実現して、ソースまで含めて公開したのは驚きです
- 用途は違えど、HoloLens 2 と Quest 2は、共に時代を変えた端末といえると思っています
  - 今後、各社の端末に更に磨きがかかることを、利用者として期待しています
  - この時代に、2つの端末を触ることができたことに感謝します

# さいごに
![02s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/50448b33-3265-f5dd-71ea-bf280259ead9.png)
- さて、次の形態を試してみるか…つづく…

# 参考にした情報

## HoloLesn 2 (www.microsoft.com)

- Head tracking　4 visible light camera
- Depth　1-MP time-of-flight (ToF) depth sensor
- SoC　Qualcomm Snapdragon 850 Compute Platform
- Memory　4-GB LPDDR4x system DRAM
- https://www.microsoft.com/en-us/hololens/hardware

## HoloLesn 2 Research mode

> Depth Camera Operates in two modes:
> AHAT, high-frequency (45 FPS) near-depth sensing used for hand tracking. Differently from the first version short-throw mode, AHAT gives pseudo-depth with phase wrap beyond 1 meter.
> Long-throw, low-frequency (1-5 FPS) far-depth sensing used by Spatial Mapping

AHAT：Articulated HAnd Tracking

https://docs.microsoft.com/en-us/windows/mixed-reality/develop/advanced-concepts/research-mode

## HoloLens 2 (www.cpu-monkey.com)

https://www.cpu-monkey.com/en/igpu-qualcomm_adreno_630-171
FP16 (Half Precision) 1,474 GFLOPS
FP32 (Single Precision)737 GFLOPS

## Quest 2 (www.qualcomm.com)

- GPU Name: QualcommR Adreno 630 GPU
- API Support: VulkanR 1.1, OpenCL 2.0 Full, DirectXR 12, OpenGLR ES 3.2
- https://www.qualcomm.com/products/application/mobile-computing/snapdragon-8-series-mobile-compute-platforms/snapdragon-850-mobile-compute-platform


## Quest 2 business.oculus.com

- Processor Qualcomm Snapdragon XR2 Platform
- https://business.oculus.com/products/specs/

## Quest 2 (vr-compare.com)

- CPU Octa-core Kryo 585 (1 x 2.84 GHz, 3 x 2.42 GHz, 4 x 1.8 GHz)
- GPU Adreno 650
- https://vr-compare.com/headset/snapdragonxr2hmdreferencedesign

## Quest 2 (history-computer.com)

- Memory:	6 GB
- Graphics:	Adreno 650 (~1.2 TFLOPS)
- Camera:	Four Infrared Cameras
- https://history-computer.com/oculus-quest-2-guide/

## Quest 2 www.cpu-monkey.com

FP32 (Single Precision) 1,418 GFLOPS
https://www.cpu-monkey.com/en/igpu-qualcomm_adreno_650-167

## HoloLens 2 vs Quest 2

https://gadgetversus.com/processor/qualcomm-snapdragon-xr2-vs-qualcomm-sdm850-snapdragon-850/

## Quest 2 Unity-TheWorldBeyond

- https://github.com/oculus-samples/Unity-TheWorldBeyond/
- https://github.com/oculus-samples/Unity-TheWorldBeyond/blob/main/Assets/MultiToy/Materials/DepthOnly.shader

> Apply a DepthOnly material to any object you'd like to be Passthrough, e.g., the hand mesh. This "invisible" DepthOnly material exists in Assets/MultiToy/Materials. Please note that the render queue is under 2,000.


## Quest 2 Passthrough Layer
https://developer.oculus.com/documentation/unity/unity-passthrough/


## Quest 2 Scene System

https://developer.oculus.com/documentation/unity/unity-scene-overview/

> Scene includes two important concepts: Scene Capture and Scene Model.
> Scene Capture is a system flow that lets users walk around and capture their scene to generate a Scene Model. Users have complete control over the manual capture experience and decide what they want to share about their environment.
> Scene Model is a single, comprehensive, up-to-date representation of the real physical world that is easy to index and query. 

## Quest 2 (動作検証で使ったサンプル)

- OculusIntegration_v41.0.unitypackage
- Assets/Oculus/Interaction/Samples/Scenes/Examples/TouchGrabExamples.unity

## イラスト描くときに使った素材

- "Hololens 2" (https://skfb.ly/onHXB) by Faber is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
- "Oculus quest 2" (https://skfb.ly/otI9p) by Nosakhae is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).