Meta Quest Proを使ってVRChatでフェイストラッキングをする話

# 概要
この記事はMeta Quest Proを使ってVRChatでフェイストラッキングをする話です。
VRChatterでQuestProを買った方も結構いるようですが、Quest2と同じような使い方をしてしまっていませんか？
せっかく高い買い物をしたわけなので、機能をフルに使っていきましょう！
この記事はQuest(Air)Link、VirtualDeskTop、SteamLinkを使ってPCVRでVRChatをプレイできる環境にあるかつ、基本的なアバター用Animator編集等ができる方向けとなっています。

# 更新情報
2023年7月　VRCFaceTrackingの仕組みが大きく変わったので修正しました。
2023年12月　VDとSteamLinkでのやり方を追記

# 必要なもの
- [VRCFaceTracking](https://docs.vrcft.io/docs/intro/getting-started)
- (おまけ)[OSCmooth](https://github.com/regzo2/OSCmooth)

# 参考資料
- [VRCFTの公式ドキュメント](https://docs.vrcft.io/docs/intro/getting-started)
     - ほとんどの内容はここと一緒です。
- [υμβρανさんのアバターセットアップ記事](https://umbrasan.fanbox.cc/posts/4354467)
- [SteamLink用のモジュールのリポジトリ](https://github.com/ykeara/LinkFT)

# 環境構築
## VRCFaceTrackingのインストール（共通）
[ここ](https://docs.vrcft.io/docs/intro/getting-started)から最新のVRCFaceTrackingをダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/b56dfd21-0e8b-7c39-326c-c6c9f2bd21db.png)
ダウンロードしたインストーラーをダブルクリックしてインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/debf8d0c-a4d4-c1f7-32ff-6e2607657993.png)

インストールが終わったらVRCFaceTrackingのアプリを起動しておきましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/9f7b57ac-1691-48d2-4e28-b829eb12a691.png)

## Virtual Desktopを使う場合
まずQuest側でVDを開き、アイトラッキングとフェイストラッキングへのアクセスに許可を出します。
一度拒否してしまっていた場合は、プライバシー設定からオンにしてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/621f58f3-71f3-cb7e-2665-448e390f05d7.png)
次にPCにつないだらPC側のVDの設定で __Streaming__ > __Forward tracking data to PC__ にチェックを入れます。その下にある２つの項目は外して大丈夫です。(それぞれ疑似フルトラとIndexコンエミュレーターになります)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/590c263c-3abd-5583-7ca8-86206615fd97.png)


今度はVRCFTの画面に行き、__Module Registry__ から __Virtual Desktop__ を探して __install__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/4522059d-aeb8-ea2d-474b-57f9b2d2824e.png)

VDを使う場合の設定は以上です。

## Steam Linkを使う場合
__※現在まだ出たてなので今後変更がある可能性が高いです。__
こちらもまずQuest側でアプリを開いた時に出るフェイストラッキングへのアクセスへ許可を与えてください。
一度拒否してしまった場合も同様にプライバシー設定から許可を与えてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/621f58f3-71f3-cb7e-2665-448e390f05d7.png)

次に[こちら](https://github.com/ykeara/LinkFT/releases/)から最新のzipをダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/30e54daa-6c63-78a7-d388-7f7cb04b717c.png)

次にVRCFTに行き、__Module Registry__ から __Install Module from .zip__ を押して先ほどダウンロードしたzipを選んでインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/661f493a-ffc4-b328-acc6-0833a5ab786f.png)
__※現状このモジュールを入れると自動でモジュールが切り替わらない仕様になってしまっているようなので、VDとかQuestLinkを使いたい場合は一度このモジュールをアンインストールする必要があります。__

今度はSteamLinkでPCに接続し、SteamVRの中から設定のうち __VR設定__ を開き、
![image](https://raw.githubusercontent.com/VRCFaceTracking/docs/495430592e96f4b1d2888c7f99819313e4eef4a9/docs/hardware/img/quest/SVRL-VRSettings.jpg)
__Steamリンク__ からOSC関連の設定を3つオンにし、 __Output Port__ を __9015__ に変更します。
![image](https://raw.githubusercontent.com/VRCFaceTracking/docs/495430592e96f4b1d2888c7f99819313e4eef4a9/docs/hardware/img/quest/SVRL-OSC.jpg)

SteamLinkを使う場合の設定は以上です。

## Quest Linkを使う場合
今となっては設定がやや面倒なのであまりお勧めしません
### Quest Proを開発者モードにする
[公式ドキュメント](https://developer.oculus.com/documentation/native/android/mobile-device-setup/?locale=ja_JP)通りにやればよいと思います。
開発者登録として組織を作らなくちゃいけないですが適当で大丈夫です。
スマホアプリからの操作は[こちらの記事](https://bluebirdofoz.hatenablog.com/entry/2022/08/29/235158)のスクショが分かりやすいです。
### Oculusアプリでの設定
まず「 __一般__ 」タブで「 __提供元不明アプリ__ 」の許可と「 __OpenXRランタイム__ 」をOculusに設定します。
画像のようになればオッケーです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/c45ebe7e-af8e-6678-c911-4ad681a0cee6.png)
次で「 __ベータ__ 」タブで「 __開発者ランタイム機能__ 」をオンにし、そうすると現れる __アイトラッキング__ と __表情認識__ の項目をオンにします。
この時 __周囲確認__ はオフのままにしておいてください。
画像のようになればオッケーです。（公開テストチャンネルは関係ないです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/b7540686-5b3f-a01d-d940-55815ba7fe8e.png)

次にVRCFTに行き、QuestPro用のモジュールをインストールします。
![image](https://docs.vrcft.io/assets/images/vrcft_module_registry_tutorial-3e0dac40976eb22d2e86c32ea912668b.png)

QuestLinkを使う場合の設定は以上です。

# OpenXRランタイムの話
詳しい説明は省きますが、VRCFTを使う上で厄介な設定がOpenXRランタイムというものです。
接続方法によって変わるので併用する場合は特に注意が必要です。

### VD・SteamLinkの場合
ランタイムは __SteamVR__ にしてください。
SteamVRの設定から __OpenXR__ を開いて __STEAMVRをOPENXRランタイムとして設定__ を押します。
現在のOpenXRランタイムがSteamVRになっていれば何もしなくて大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/aa1b7937-8f8d-7658-b841-790376226cf6.png)

### QuestLinkの場合
ランタイムは __Oculus__ にしてください。
Oculusアプリから「 __一般__ 」タブで「 __OpenXRランタイム__ 」をOculusに設定します。
画像のようになればオッケーです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/c45ebe7e-af8e-6678-c911-4ad681a0cee6.png)

# アバターの準備
さて環境はできましたが、動かす対象のアバターがないと何もできないのでそちらをやっていきます。
現在は標準のEyeTracking設定のアバターなら眼だけは動かせるようなんですが自分がうまくいってないのでよくわかりません…
VRCFaceTracking対応Publicアバターが置いてあるらしいワールドを紹介しておきます。
- [Bread's Avatar World](https://vrchat.com/home/world/wrld_4f21d3f2-4048-4bb9-a466-2cdcb6e1dc1f)
- [Danyy59's VRCFT avatar](https://vrchat.com/home/world/wrld_35ce85ec-1ddf-4df5-81e5-ca3b7d54f794)

とはいえやはり自分のアバターをいろいろ自由に動かしたいですよね。
基本的には[υμβρανさんのアバターセットアップ記事](https://umbrasan.fanbox.cc/posts/4354467)と公式の[EyeTracking](https://github.com/benaclejames/VRCFaceTracking/wiki/Eye-Tracking-Setup)と[LipTracking](https://github.com/benaclejames/VRCFaceTracking/wiki/Lip-Tracking-Setup)のセットアップガイドを見れば分かりますが、補足を入れつつ書いていきます。

※2023年7月現在推奨パラメーター名が更新されており、下記設定のアバターはLegacyと認識されます。動作はしますが将来的に動かなくなる可能性があります。

### まずは瞬きだけやってみる
これは自分がやってみて思ったんですが、一気に視線とか口とかまでやろうとするとしんどいので、いったん瞬きだけやって実際に動かしてモチベ上げるといいんじゃないかなと思います。
### ExpressionParametersの準備
ここではデフォルトのParametersのファイルを複製してそこに追加していきます。
複製したファイルに`LeftEyeLidExpandedSqueeze`と`RightEyeLidExpandedSqueeze`という名前のFloatパラメータを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/ee3af994-7090-74f7-ecf1-3018b9afc5f3.png)
それをAvatarDescriptorのParametersに入れましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/82c8979d-12d2-875e-ecdd-3bc0c3f72cb3.png)
### AnimationControllerの準備
この部分は[υμβρανさんの記事](https://umbrasan.fanbox.cc/posts/4354467)の「 __FXの作成__ 」の章が完璧なのでそちらを参照してください。
１点アバターのシェイプキーにJoy・Wideがない場合のBlendTreeの設定について例の紹介です。
JoyもWideもない場合はこのようにすれば問題なく動作します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/ac5092b8-8728-c2ad-e00b-ceb08cd8a1ad.png)
ちなみにThreshold（閾値）ですが、例えば思ったより目が開かない場合はこのように値を小さくすると補正できたりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/d345b318-06cf-9605-6e20-6ff974df5545.png)
### アップロード
あとはアバターのAnimatorにFxのControllerがないことを確認して、PlayableLayerのFxには入っていることを確認してアップロードしましょう！
ちなみにTestでのアップロードはOSCがうまく動かないことが多かったので普通にアップロードするのが良さそうです。

# VRChatで動かしてみる
さてここから実際にVRChatを起動して動作確認をしてみましょう
1. 上記で紹介した3つのうちどれかででPCに接続する
1. VRCFaceTrackingのアプリを起動する
1. HomeでQuest Proの横の「Toggle Tracking」をこの色にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/026beec1-d331-ffe0-3fac-349deaa6a91f.png)

1. その後SteamVRを起動してVRChatを起動する。
1. アップロードしたアバターに着替える
1. メニューボタン長押しからアクションメニューを開き，Options/OSC/EnabledからOSCを有効化する
![OculusScreenshot1670756329 (2).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/af3ade42-21d9-3082-9203-728c588f64db.jpeg)
 __注　アバターを再アップロードしたら上記メニューのResetConfigをする__ 
### 動作確認
ここまで来たら、実際に瞬きしたらアバターも瞬きしてるか見てみましょう！
もしうまくいってなかったら上記メニューのOSC Debugを開きます。
![VRChat_2022-12-11_19-59-50.117_3840x2160.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/52e162a9-8045-b1c1-47c0-cb65dde923cb.png)
そこに`LeftEyeLidExpandedSqueeze`と`RightEyeLidExpandedSqueeze`があってリアルタイムで値が動いていればトラッキングデータがOSCで送信されてきているので、アバター側に問題がある可能性が高いです。
パラメータのつづりを間違えてたりする可能性があります。
もしここにその表示がなかったり動いてなかったりしたらOSC周りかトラッキング自体がうまくいってないかもしれません。
VRChatを再起動したら直ったりしたこともあります。

# 発展
### アニメーションの追加
瞬きができたらあとは大体同じ要領で、パラメータとシェープキーを紐づけたアニメーションを設定することでいろいろできます。
ただ __視線の動き__ に関しては[υμβρανさんの記事](https://umbrasan.fanbox.cc/posts/4354467)や公式の[EyeTracking](https://github.com/benaclejames/VRCFaceTracking/wiki/Eye-Tracking-Setup)ガイドでは __Additive__ レイヤーでやると書いてありますが自分はうまくいきませんでした。そこで自分はFxレイヤーでやったらうまくいったことを記しておきます。
自分は瞬きに加えて、視線の動き、あ・い・うの口の形、ほっぺのふくらみを追加しました。
あの形は`JawOpen`、いの形は`MouthUpperUpLeft`、うの形は`MouthPout`、ほっぺのふくらみは`CheekPuffRight`のパラメータを使用しました。
実際に設定した例を貼ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/9aab297b-f067-9735-7ec5-a90052e66f5f.png)

(2023/2/25追記)
追加で眉毛の動きも設定してみました。
使ったパラメーターは`BrowDown~`と`BrowInnerUp~`です。
変則的なBlendTreeですがいい感じに動いています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/53f512b7-994a-3b2d-fd44-fed770561ce8.png)


 また、アバターによっては左右の目を別々に動かすシェイプキーの用意がないこともあると思います。
そういった場合はどちらかの目のXのパラメータ(LeftEyesXなど)を選んで両方の目を動かすアニメーションを設定することでおおむね問題ないです。
画像の例では目を下に向けるシェイプキーがない場合ですがこれでもそんなに支障なかったです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/d50add2a-5bde-424d-9089-4ddc747c75c3.png)

### LipSyncの干渉を防ぐ(2023/3/12追記)
口のトラッキングを活用する場合、標準のLipSyncと干渉するのでそれをOFFにした方が良さそうです。
多分ModeをViseme Parameter Onlyにすると良さそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/a95bc3ec-150b-730c-8639-78f45bd4f11a.png)



### VIVE Pro Eye & Facial Trackerとの違い
残念ながらVIVE Pro Eye & Facial Trackerで取れて、Quest Proでは取れない値がいくつかあります。
[こちらのスプレッドシート](https://docs.google.com/spreadsheets/d/118jo960co3Mgw8eREFVBsaJ7z0GtKNr52IB4Bz99VTA/edit#gid=0)でまとめられています。多分左端がVIVEのです。
おおむね舌の動きと瞳の大きさが取れないのが大きいかなと感じています。
それらも使いたかったらVIVEの方を買いましょう()

### 他人から見たときにスムーズになるようにする
どうやらVRChatのOSCは同期感覚の問題でカクカクに見えてしまうことがあるそうです。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">VRChat + Quest Proのフェイスラッキング、OSCなので他人から見たときカクカクなんだけど、スムージングかけたら超滑らかになった！💫<br><br>めっちゃ良くない！？😆<br><br>このツールでできました！👇<a href="https://t.co/qssKzCospM">https://t.co/qssKzCospM</a><a href="https://twitter.com/hashtag/VRChat?src=hash&amp;ref_src=twsrc%5Etfw">#VRChat</a> <a href="https://twitter.com/hashtag/QuestPro?src=hash&amp;ref_src=twsrc%5Etfw">#QuestPro</a> <a href="https://twitter.com/hashtag/VRCFT?src=hash&amp;ref_src=twsrc%5Etfw">#VRCFT</a> <a href="https://t.co/KrTX7jDb6H">pic.twitter.com/KrTX7jDb6H</a></p>&mdash; オレンジ/メタバース撮影技術者 (@orange_3134) <a href="https://twitter.com/orange_3134/status/1595313527794778114?ref_src=twsrc%5Etfw">November 23, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こちらで紹介されている[OSCmooth](https://github.com/regzo2/OSCmooth) を使ってみましょう。
~~注意としてもともと設定されているAnimationControllerが上書きされ、一度設定したものに再度適用するとうまくいかないっぽいので、元のものを複製しておくとよいです。~~
アプデで修正されてました！

1. Unitypackageを開いてインストールする。
1. `Tools/OSCmooth`を開く
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/804bed8e-d11b-682a-ddc8-ff2568ebfae9.png)
1. Avatarのところに使いたい対象のアバターをセットする
1. LayerがFXなのを確認して`Use Playable Layer Parameters`を押す
1. `Apply OSCmooth to Animator`を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341187/6839bd5c-0b16-c43c-237f-db154aae639c.png)

これでいい感じにスムースしてくれるようになりました。

# まとめ
さて、ここまで多分QuestProでフェイストラッキングができているのではないでしょうか？できてたらうれしいです。
アバターにリアルの表情が反映されるのが本当にいいことなのか議論の余地がある気はしますが、自分は結構面白くて好きです。
あと手の形と表情を分離できたのが快適でした。
ぜひQuestProをお持ちの皆さんは挑戦してみてください！

最後に自分のアバターがどうなったか貼っておきます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ちょくちょくアバターのフェイストラッキング対応してたんですが、こんな感じになりました！<br>瞳が動くと活きてる感が増す気がしますね。<br>シャーロちゃんのトレードマーク？である、ほっぺぷく～も実装できたのが良かったです！<a href="https://twitter.com/hashtag/VRChat?src=hash&amp;ref_src=twsrc%5Etfw">#VRChat</a> <a href="https://twitter.com/hashtag/QuestPro?src=hash&amp;ref_src=twsrc%5Etfw">#QuestPro</a> <a href="https://t.co/kpJJFjQW95">pic.twitter.com/kpJJFjQW95</a></p>&mdash; サックー@XR (@VRC_Sakk) <a href="https://twitter.com/VRC_Sakk/status/1601920382608740352?ref_src=twsrc%5Etfw">December 11, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">フェイストラッキングで眉毛も動くようにした！<br>思ったよりわかりやすくて楽しい。<a href="https://twitter.com/hashtag/VRChat?src=hash&amp;ref_src=twsrc%5Etfw">#VRChat</a> <a href="https://twitter.com/hashtag/VRCFT?src=hash&amp;ref_src=twsrc%5Etfw">#VRCFT</a> <a href="https://twitter.com/hashtag/QuestPro?src=hash&amp;ref_src=twsrc%5Etfw">#QuestPro</a> <a href="https://t.co/8mRH4fJNjj">pic.twitter.com/8mRH4fJNjj</a></p>&mdash; サックー@XR (@VRC_Sakk) <a href="https://twitter.com/VRC_Sakk/status/1629361838411628544?ref_src=twsrc%5Etfw">February 25, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>