自宅のPCと外出先のquest2とをつないで無料ソフトだけでPCVR

# やりたいこと
出先で自宅のPCにつないでPCVRする手段について、以下の条件で探してみた。

1.「Virtual Desktop」などの有償ソフトは利用しない
2.自宅/quest側ともにグローバルIP不要
3.自宅/quest側ともにルータ機器の設定(VPN設定等)が不要
4.回線が多少ショボくても、それなりに遊べる(10Mbps程度。出先のwifiも不安定な2.4GHz)

インターネット経由でのPCVRを試した情報はかなり見つかるものの、1または3のどちらかの条件を満たさない方法がほとんどの様子。
上記条件をすべて満たしているものもゼロではないが、情報が古いのか、そのままの方法では私の環境では動作しなかった。
いろいろな手段を試行錯誤した結果、それなりに遊べる環境が見つかったので晒してみる。

# 必要な環境

【自宅側PC環境】
・PCVRに対応しているWindows PC(nVidia GPU)
・SteamおよびSteam VR
・ZeroTier (Windows版)
・ALVR (Windows版)

【quest2側環境】
・開発者モードの有効化
・ZeroTier (android版)
・ALVR (quest版)

【そのほかに必要なもの】
・adbコマンドまたはSideQuest等、questをUSB接続してapkをインストールするための環境

# 環境の概要
ALVRを使えばネットワーク経由でのPCVRができる。
しかしALVRは、お互いが別のプライベートLAN上にいる機器同士の接続はできない。
そこでZeroTierを使って、PCとquest2を直結されたLAN上の機器のように見せてしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/a4bbbf26-afdd-6f72-ddcb-d4611608137c.png)

これだけです。

# 作業手順

### PC側の事前準備

1.PC側にSteam / SteamVRを入れて、PCVR向け環境を構築しておく

steamのインストール方法はググれば各所にあるので調べてください。
steamvrは、steamをインストールして起動すると、その画面上からインストールできたはず。

2.ZeroTierの導入
https://www.zerotier.com からWindows版を入手
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/ef533503-c6a4-2044-2888-507bd1808ff2.png)
ダウンロードしたインストーラを実行するだけでインストールされる。(ウィザードなど無し)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/f8617905-cb89-b87e-2ff5-517ad975926a.png)

タスクバーにアイコンが表示されているのでクリック。
するとMy Addressが表示されているので、どこかにメモしておく(My Address:～をクリックすると、クリップボードにコピーされる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/fcb0742a-70d6-bec0-a685-d969a10005a5.png)


次に、PCとquestとを互いに接続する仮想ネットワークを用意する。
ZeroTierでは、サーバ上でネットワークIDを管理しており、同じネットワークIDに接続した機器が同じ仮想LAN上に接続される仕組み。
どの機器の接続を許可/拒否するといった設定もサーバ上で行う。

ZeroTierに無償のアカウントを作って、Create A Networkでネットワーク作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/54c415af-6371-80c9-4894-1c569f1602d1.png)

Network IDが生成される。PCとquestの両方を、このIDに接続させる必要があるので、このIDもメモっておく。

Network IDを選択すると詳細設定画面が開くので
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/793d964b-80cc-90ce-2870-e105b565e22b.png)

Advancedのところで、VPNで使用するIPアドレスセグメントを設定する。
自宅LANとquestのインターネット接続用環境のどちらとも重複していないセグメントであればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/64ec7b5e-86e0-1dc2-a03a-2db31d7a9c7c.png)

接続を許可するデバイスに、先程に「My Address」からコピーした自分のIDを登録して、「Auth?」を有効化しておく。
※下図はちょっと先のタイミングで取得した画面なので、PCのMACアドレスや、割てられたManaged IPsまで表示されてしまっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/8371172d-c2d4-c10e-45e7-4b80574a2f44.png)


タスクアイコンからOpen Control Panelを開いて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/fcb0742a-70d6-bec0-a685-d969a10005a5.png)

画面下の方に、先程発行されたNetwork IDを登録し、Join Networkをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/da1678a4-39d9-a8a9-0b71-f7f7c1952ff5.png)

ネットワークIDが登録されるので、その詳細を開いて確認する。接続がうまくいくとStatusがOKになり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/a6388948-d67e-6c1e-f61b-384f8945a191.png)

VPN用の仮想アダプタ[QeroTier One]に、先程の画面に表示されていたVPN間通信用のアドレス(Managed IPs)が設定されているはず。
ここで169.254.x.xなどが設定されている場合は、うまく接続できていないので調査が必要。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/2551e981-570f-8d16-ac2c-25730f3d99cd.png)

この段階で先程にNetwork IDを確認したページを見てみると、デバイスのMACアドレスやManaged IPsが表示されるようになっているはず。


3.ALVR導入
githubからALVR_Installer_*****.exeを入手してインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/6c0e3bd8-1311-102f-843c-6bc78b6158e6.png)

ライセンス規約などのお決まりのウィザードがあるが、設定はすべてデフォルトでOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/823dcb3f-e1a6-0e46-42dc-3ea2c0aeff4a.png)

「Launch ALVR」をチェックしたままインストールウィザードを終えると自動的に起動してくるので
ファイアウォール設定の追加ボタンをおして追加してもらう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/cc7b3a9a-7a47-572d-8363-421cbbb68385.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/b1fd3e42-e753-f250-6ba0-4f13b82696c4.png)

その後、トラッキングの頻度やパフォーマンス設定を選べるが、実際にNWの様子みて動かしてみないと最適解がわからないので適当。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/2a5cfe9a-57bc-cc00-f4bc-b617297f5421.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/284b5676-fb7d-cccf-2e5f-c6d5915f0de2.png)

presetは無視して次へすすめば、初期設定は完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/59f8f253-8336-3637-d0ee-7251894bfd2a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/58d7d7d0-e116-1fcf-6b64-0b197b324c21.png)


### quest側の事前準備

1.questの開発者モードを有効化しておく
ググればいろいろ情報がでてくるし、questを更新する都度に設定画面もコロコロ変わるので詳細は省略。

2.ZeroTierの導入
https://www.zerotier.com からAndroid版のapkを入手
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/ef533503-c6a4-2044-2888-507bd1808ff2.png)

adb installで導入すると

```
C:\WINDOWS\system32>adb install c:\work\com.zerotier.one_165_apps.evozi.com.apk
Success

C:\WINDOWS\system32>

```
身元不明アプリに追加されているので起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/2418671b-91e0-0063-f240-ec6fea77f95c.png)

Windows版と違って、導入直後の段階でMy Addressを確認できないが、とりあえずADD NETWORKから発行されたNWIDを入力してAdd Networkしておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/8d79dacc-3623-6cdc-9bab-1e63acd3c3b6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/4b35fb08-f28b-7448-b05c-721bad1d4e96.png)

登録されたNetworkを有効化しようとすると警告が出るのでOKする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/5523b923-40df-fc96-bd8f-5edaa0e54b54.png)

この時点でなぜか「ONLINE」と表示されてMy Addressも表示されるのだが、当然、まだ繋がっていいない。
これだけつながるようなら、Network IDを知っている人なら誰でも接続できるということなので大問題。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/81fe8f21-706a-ede2-97ea-15a0dba68ab7.png)

ZeroTierのネットワーク管理画面を見ると、questから接続要求が来たことで2つめのデバイスが自動的に追加されている。
ただ、「Auth?」のチェックは外れているので、これをチェックすることでquestからの接続が許可される。
しばらくするとquest側にもVPN用のManaged IPsが割り当てられるが、これもあとで必要になるのでメモっておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/b6277381-7da7-52c9-c895-b66f8e6d5854.png)

これで、quest側でも接続完了している。
ここで表示されるManaged IPsは、先程の画面でquestデバイスのManaged IPsに表示されたもと同じはず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/fce30ac5-ed46-59cc-3bd6-ef7d5a2ca412.png)

PC側と同じプライベートネットワークに接続されているはずなので、PC側からpingでも試しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/e9811c9f-a9c0-5524-69ff-eb9d028bc129.png)


3.ALVR導入

githubからalvr_client_oculus_quest.apkを入手
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/6c0e3bd8-1311-102f-843c-6bc78b6158e6.png)

同じようにapkをインストール

```
C:\WINDOWS\system32>adb install c:\work\alvr_client_oculus_quest.apk
Success

C:\WINDOWS\system32>

```

身元不明アプリに追加されているので起動。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/e18bf5cd-64d6-6c12-7af8-c994a6b040c2.png)

音声録音が必要かどうかは、起動するゲームがマイクを必要とするかどうかで判断かな？許可しなくてもOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/2b8ade83-cb13-81f4-3266-2bde6afb61b8.png)

ALVRを起動すると、接続待ちの空間が表示されるので、表示されるhostnameを覚えておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/9f21ae80-faac-7e6f-84a9-61d2f001b722.png)


### 接続する

改めてPC側のALVRアプリからコントロールパネルの「接続」タブを開いて、「クライアントを手動で追加」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/ee1847a4-61b2-160d-af6d-aa3375971b54.png)

先程の画面に表示されたhostnameと、quest側に割り当てられたvpn ipを入力して追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/3e8c9e7c-23dd-dbe9-87da-ef50f68efeea.png)

自動的にsteam vrが起動して以下の画面が出るので「ツールを起動」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/268386a7-0681-1bdf-45bd-ecba679c501d.png)

するとALVR側にいろいろ表示されて、接続されたことが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/1cb96c86-d2e3-50e3-aa6b-ff9c3f2d2502.png)

改めてquest側を見ると、steamのホームが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/b4c2c47d-cad9-fa30-5cb3-08dad5a58d8d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/8e612c3f-e0aa-d0b3-50b8-e824d9fe8f64.png)

# チューニング
FPSが30を切ることが頻発するようだと厳しいので、そのような場合はチューニングする

### PC側負荷を軽減するための設定

ALVRを使っているので、普通にPCVRで遊ぶよりもPC側の負荷がかかる。
どうせインターネット経由だと高い解像度の転送は無理なので、SteamVRの解像度を下げてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/7de419a8-0750-30ab-38bb-bba7e158a4d5.png)

SteamVR全体の設定だけでなく、アプリごとの個別設定にもあるので注意。

### 細い回線に合わせたALVR設定

インターネット上を飛んでいく映像データは、steamVRに出力した映像をALVRで圧縮したものなので、PC側の性能が十分ならばALVR側の設定をいじるだけで良い。

ALVRのデフォルト設定は宅内LANだけを経由したPCVRを想定しているので、インターネット経由での細い回線でそのまま使うと、映像の乱れ、カクつき、音飛びが頻発する。

これらの問題に一番効果が出るのは、コントロールパネルの映像タブにある「解像度」「映像ビットレート」「bitrateMaximum」を下げること。
解像度が犠牲になるので、下げすぎると小さな文字が読めなくなる。

次に、その下にある「フォービエイテッドレンダリング」を有効化し、その強度を上げる。
有効化すると、視界中央の解像度をそのままに、周辺視野の解像度が下がる。
強度を上げすぎると周辺視野の解像度が不自然に下がりすぎて、直線が歪んで見えたりするかも。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/a1db50e9-7667-08f2-6646-8bb7bc183912.png)


quest側の回線が、downloadは早くてuploadが遅いタイプの場合、ヘッドセットタブから「Tracking speed」設定を「普通」に下げると効果あるきがする。
ただし、高速にコントローラを動かすゲームだとコントローラの動きが認識されない。（beatsaberだと、振りかぶってから落としたのに、振りかぶらずにそのまま落としたように認識されたり。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/0e0eb59e-cadd-5ecd-80ac-16c7656b120b.png)

この設定でカクつきが減る気がするのだがなぜだろうか。VRデバイス側のセンサデータが届くまでPC側で処理待ちとかしているのだろうか？（こういったゲーム用の入力機器って、センサデータがPCに届かない間は、「前frameと同じ入力のまま」として処理してくれると思っていたのだが、仕様調べてもいまいちはっきりしない。）


### その他の設定

PC側のrssを無効化することも有効かも。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/3279b0cf-3c24-732d-4535-d6cb74bd22fa.png)


# 補足

■突然ゲームが落ちたor固まったor処理落ちが酷くなった場合の対応
とりあえずquest側でalvrを落として起動しなおせばだいたい治る。
ALVRを落としても、PC上で動いているゲーム自体は動き続けているので注意。
ゲーム機のスリープ機能みたいにポーズ状態で待ってくれないです。

ALVR画面が「Searching for server....」のままになっている場合は、VPN接続が切れているかもしれないので、quest側のZeroTierを開き直してVPNを再接続し、改めてALVR起動。
PC側のarpテーブルが更新されるまで少し待つか、PC側を触れる環境ならarp -dを実行。
それでも治らなければ、PC側か、通信回線に原因があると思われる。

■PCを再起動するとALVRが起動しなくなった
steamvrの起動後に「ツールを起動」を押すことでALVRが起動するはずが、なぜかPC再起動後に以下のエラーを吐いて起動しなくなることがよくある。

```
障害が発生しているアプリケーション名: ALVR Launcher.exe、バージョン: 16.0.0.0、タイム スタンプ: 0x61325352
障害が発生しているモジュール名: ucrtbase.dll、バージョン: 10.0.20348.1、タイム スタンプ: 0xdacb234c
例外コード: 0xc0000409
障害オフセット: 0x000000000007ca9e
```

ALVRのインストーラを再度実行して、一度uninstall→再度installすれば治る。repairでは治らない。
起動できない原因は不明だが、uninstall→再installは1分以下で終わるし、設定も消えることなく残っているので、そこまで不便はしない。


■ZeroTierでVPN接続するなら、わざわざALVR使わなくても、Air Linkで接続できないのか？
試行錯誤してみたが、駄目っぽい。
おそらくAir Linkはquest側のWifiアダプタからPCを探索する仕組みなので、VPN用の仮想アダプタに接続されている機器は見つけてくれない。


■NICE DCVならUSBをリモート接続できるから、wifiよりも安定するのでは？
試したところ、ALVRやZeroTierは使わずにNICE DCVだけでも同じようにPCVRは可能だったが、FPSが安定しなかった。
また、回線が不安定になると、すぐに「Oculus Linkが利用できなくなりました。」が発生する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421201/eaf10e95-2fb6-250e-51cd-152444759a40.png)

いろいろ切り分けた結果、レイテンシの悪いネットワークでUSBのリモート接続を使うのはNGという結論に至る。
自宅回線の性質次第かもしれないが、うちの環境では明らかにZeroTier+ALVRの方が安定する。

ただ、こちらの手法であれば、oculus linkでUSB接続している状態と同じように認識されるため、oculus storeから購入したrift用ソフトなど、steamvr以外の規格のVRゲームでも遊べるというメリットはある。（本記事の方法では、仮にoculus softwareを入れても「ヘッドセットが見つかりません」状態になって遊べない。）
自宅、questの両方で十分に高速安定/低レイテンシな回線が用意できるなら、こちらの手段もアリかもしれない。

■自宅側の回線帯域について
「4.回線が多少ショボくても、それなりに遊べる(up/downともに10Mbps程度)」と入れましたが、あくまでPCとquestとの間の通信帯域がショボくても、、、という意味です。
MMOFPSのように、遊ぶゲーム自体の通信量が多い場合は、PC側に相応の帯域が必要になります。

なお、自宅→quest方向は画面情報を転送する必要があるため10Mbpsは必要ですが、quest→自宅はセンサデータの転送程度程度なので、おそらく1Mbps程度でもなんとかなります。
ですので、questの接続用に持ち運ぶモバイルカードは、ダウンロードは早いがアップロードが遅いようなヤツでも、それなりに行けると思われます。


■2.4GHz/5GHz両対応環境について
Wifiは5GHzに対応しているのが望ましいが、questは通信データ量や電波状況に応じて5GHzと2.4GHzとが自動的に切り替わる様子。
ALVRの利用中に5GHzと2.4GHzの切り替えが発生する都度に画面状況が酷いことになるので、wifiルータは5GHzに固定しておく必要がある。
出先で提供されるwifiを使う場合などで固定が難しい場合は、できるだけ電波状況の良いところにいると5GHzで安定しやすいかも？
また、電波状況が良くてもデータ通信量が多いと強制的に2.4GHzに切り替えられる？ように見えるので、解像度を十分に落として通信量を減らしておく必要がある。（これはquest側の機能なのか、それともWifiルータ側の一般的な動作なのだろうか）