フェイストラッキングことはじめ
iPhone (ARKit) で試してみる
https://docs.vrcft.io/docs/hardware/iphone-arkit
PCにVRCFaceTrackingをインストール
iPhoneにLive Link Faceをインストール
VRCFaceTrackingにLiveLinkモジュールを追加
LiveLinkアプリでPCのローカルアドレスを指定
サンプルアバターをアップロード
https://booth.pm/ja/items/5231123
まぶたの開き具合や口の開き具合が反映されることを確認
口の位置や目線のトラッキングはアバターをセットアップする必要がある?
https://docs.vrcft.io/docs/hardware/interface-compatibilities
ARKitとQuestProの比較
ARKitは視線トラッキングができない?
Gaze: EyeExpression, Gaze Convergence: N/Aになってる
https://hinzka.hatenablog.com/entry/2021/12/02/005814
これを見るとeyeLookのブレンドシェイプがある
舌トラッキングはどちらも可能?
LiveLinkは舌をトラッキングしていないように見える
TODO: パーフェクトシンクのアバターで試してみる
https://twitter.com/hinzka/status/1765192559553581290
パーフェクトシンクのアバターなら、VRCFT - Jerry's Templatesで簡単に導入できる
https://github.com/Adjerry91/VRCFaceTracking-Templates/blob/main/Packages/adjerry91.vrcft.templates/VRCFaceTracking%20Template%20Setup.pdf
Jerry's TemplatesにはVRCFury用のprefabが同梱されているが、こちらを使えばMAで導入できる
プレハブ置くだけでフェイシャルトラッキング by いるかのおみせ
また、これを使うと一緒にOSCmoothも適用できるのが良い
FrameTimeCounterがある
https://notes.sleightly.dev/advanced-blendtrees/
これのFrameTimeDetectionか?
AAO T&Oを入れていると、DirectBlendTreeがマージされる
凪にポン入れで適用してみる
ローカルテストだと動かない
その他のすべての条件を同じにして、ローカルテストとアップロードで比較
なぜ動かない?
目が常時プルプルしてる
HMDの方のトラッキング精度やスムージングが良くない?
メガネ越しだからか?
あまり表情が豊かになる印象がない
目の開閉と口の開閉ぐらい
目の大きさや口の位置は変わらない
販売されてるFTパッケージは可動域を調整している?
フェイスミラー見てるのがバレバレ
VRCFTのExMenuで目のトラッキングを切ると寄り目気味になる
VRCFT非対応アバターと同じ挙動
MAで入れる場合、FaceEmoの後から結合すれば普通に共存できる
ARKit用のシェイプキーを表情で使っていなければあまり干渉しない
とはいえ、アイトラで目を閉じているときに、更に目閉じの表情を再生すると普通に破綻する
まばたきは常時オフにする必要あり
FTの後でFaceEmoを結合する場合
「除外シェイプキー」にARKit用のシェイプキーをすべて追加すればOK
TODO
テンプレートのカスタマイズ
Wolferia(ウルフェリア)'s FacialTracking Setting
これを使ってみる
VRCFTのテンプレートよりも自然な気がするが、どちらかというと、表情が豊かにならないのは自分の表情筋やHMDの設定が原因なのでは?
商品動画のように動かすのは難しい
舌出しはboolっぽい
大きめに突き出すと反応する
FaceEmoとの共存
FacialTrackingのシェイプキーをすべて除外
FT Visemeはパターンマッチングでvisemeシェイプキーと認識されるので元から除外されている
AvatarDescriptorのLipSyncが一部FT Visemeに置き換えられている
Wolferia_FX_FT
boolで済むパラメータをfloatにしているのはなぜか?
AnimatorControllerの方ではfloatだが、ExParamの方ではboolにしている
EyeTrackingActiveやLipTrackingActiveはDirectBlendTreeの閾値として使用している
0の場合は顔トラのBlendTreeのウェイトが0になる
ExMenuで操作するパラメータ
EyeTrackingActive (bool)
Jerry's Templatesと同じ
LipTrackingActive (bool)
Jerry's Templatesと同じ
GestureExpressionDisabled (bool)
Jerry's TemplatesではFacialExpressionsDisabled
QPro/Tongure_Toggle (bool)
Eye Lid LR Sync (bool)
元々のFXからAutoBlink Controlレイヤーを削除
HandsLayerでBlink (bool) を変更し、その値に応じてTrackingControlを切り替える
HandsLayerの変更
ジェスチャー表情に合わせて、EyeTracking_GestureControlやLipTracking_GestureControlの値を変更する
目閉じ表情の場合は顔トラで動かさない
EyeTrackingActiveやLipTrackingActiveと同様に、DirectBlendTreeの閾値として使用される
Thumbs up_Altステートを追加
QPro/Tongue_Toggleが有効なときこちらに遷移
Idle_NonFTステートを追加
EyeTrackingActiveが有効な場合、目のTrackingControlはAnimation
EyeTrackingActiveが無効な場合、目のTrackingControlはTracking
なぜかLipTracking_Activeも遷移条件に含まれている
目のTrackingControlはEyeTrackingStateレイヤーで変更しているが、ここでも変更するのはあまり良くないのでは…?
Lypsync Controlレイヤーを追加
VisemeとOSCm/Proxy/v2/TongueOutで分岐
VisemeはVRCのパラメータ
口のTrackingControlを変更
Visemeが0のとき、もしくはTongueOutが無効のときはTracking
TongureOutが有効のときはAnimation
つまり口トラはリップシンクと共存している
EyeTrackingStateレイヤーを追加
目のTrackingControlを変更
EyeTrackingActiveが有効のときAnimation
EyeTrackingActiveが無効のときTracking
AFK用のステートあり
目と口のTrackingControlをAnimationにする
口もこのレイヤーで変更してしまう
EyeTrackingActiveとLipTrackingActiveを無効にする
AFKからの復帰は別レイヤーでやっており、EyeTrackingActiveとLipTrackingActiveを有効にする
FactialTrackingStateレイヤーを追加
AFKからの復帰
FacialTrackingレイヤーを追加
DirectBlendTree
MouthDefaultCorrectionレイヤーを追加
口変形キャンセル
あいうえおとωと^をリセット
OSCm/Proxy/v2の下記のパラメータが0.1より大きいときに口変形をキャンセルする
MouthRaiserLower
LipSuckLower
LipPucker
TougueOut
LipSuckUpper
MouthUpperUp
JawOpen
一部の口トラと、表情用の口シェイプキーが干渉するからだろうか?
目トラを使う場合はTrackingControlをAnimationにする
口トラを使う場合でもTrackingControlはTrackingでいい
Jerry's TemplatesのFacialExpressionsDisabledって使われてなくない?
ExMenuで有効にしてもジェスチャー表情が無効化されない
ジェスチャー表情を無効化するには、リセットアニメーションを再生するか、HandsLayerをいじるかしないといけないが、どちらもされていない
Furyで結合するケースを試していないので、Furyではそういう処理をしているのかも
顔トラでどこまで動かすのは個人の好みかも
没入感を高めるならまばたきだけトラッキングというのもアリ?
目線はトラッキングしない
FaceEmoとフェイストラッキングの共存
Jerry's Templatesのカスタマイズ(凪)
ARKitのFXを調整していく
GestureManagerのDebugタブで値をセットして変化をプレビューする
FT/v2でフィルターする
AAPを編集しても値は変化せず、コンソールに警告が出る
OSCm/とBinaryOut/
BinaryOutの接頭辞は何を意味する?
OSCmoothのレイヤーで使われてる
floatとboolの変換に関係するなにか
EyeLeftXとEyeRightXが独立でない
左目の視線が動いたとき、右目も動くようになっている
EyeLeftXによる右目の動きは、EyeRightXのそれよりも少し小さい
EyeLeftXとEyeRightXの両方が1になってもギリギリ破綻しないようになっている
凪のシェイプキーを確認したところ、視線の左右と上下が一緒に動くように設定されていた
おそらく独立に動くことで不自然な表情になってしまうことを防ぐためにこうなっている
他にも、jawForwardがまったく動かなかったりする
Y方向の目線はEyeYにまとめられている
VRCFTのドキュメントではEyeLeftYとEyeRightYになっているが…?
(more) Simplified Tracking Parametersのところにあった
左右を平均したり、関連性のあるパラメータをマージしたりして簡略化したパラメータ
逆にEyeLidは左右独立のパラメータしかない
EyeLidは0.75が平常状態で、それ以上になると目を見開く
EyeLidとは別に、EyeSquint(目を細める)パラメータがある
なぜEyeLidとEyeSquintを区別している?
FT/v2/EyeSquintLeft1のようなパラメータが左右合わせて6つ存在するが、使われてなさそう
https://docs.vrcft.io/docs/tutorial-avatars/tutorial-avatars-extras/parameters/types/binary
2進数の各桁を表しているようだが、GestureManagerで操作しても特に変化がない
というか、これらのパラメータはBool型であるべきでは?
ExParamでFloatの代わりにBoolを有効にした場合にこれらのパラメータが使われる?
ExParamを確認したところ、EyeSquintLeft1, EyeSquintLeft2, EyeSquintLeft4の3つがboolで定義されている代わりに、EyeSquintLeftのfloatパラメータは存在しなかった
GestureManagerでEyeSquintLeft1, EyeSquintLeft2, EyeSquintLeft4をすべて1にしても顔が変わらないのはなぜか?
VRC上でEyeSquintは正しく動作しているのか?
2進数のパラメータはリモートでのみ使用されるため、GestureManagerでIsLocalをfalseにしてからEyeSquintLeft1, EyeSquintLeft2, EyeSquintLeft4を変化させることで動作を確認できる
EyeSquintLeft1, EyeSquintLeft2, EyeSquintLeft4の順で重みが大きくなる
Pupilのパラメータが存在しない
眉毛のパラメータで有効なものはBrowExpressionLeft, Rightだけ
NoseSneerが1になると目と眉がキリッとする
CheekPuffで頬が膨らむ
CheekPuffLeftと書かれているがRightが存在せず、Leftが1になると両方膨らむ
顎はJawOpenとJawXだけ動く
口の開閉と顎の左右
人間の顎って左右に動くものなのか…?
Lipのパラメータ
Pucker: すぼめる
Funnel: 「お」の形
SuckUpper: 口角が上がる
SuckLower: 口角が下がる
Mouthはそこそこ多いので一旦省略
Mouth Raiserでなぜか眉毛が下がる
MouthClosedが1になると口が破綻する
というかVRCFTにはMouthClosedが定義されていない…
なぜテンプレートに入っている?
TongueOutで舌が出るが、口は開かないので破綻する
舌を出しているときはたいてい口も開いているので問題ないのかも
口のトラッキングを切っているときに舌のトラッキングを有効にしてはいけない
いろいろ例外っぽい動きが多いので、これは特定のアバター用に調整されたものでは?という気がしてくる
EyeTrackingActive, ExpressionTrackingActive, LipTrackingActiveはVRCFTがセットするパラメータ
トラッキングが失敗しているときfalseになる
説明文がよくわからない
結局ExMenuで使ってもいいの?
テンプレートのExMenuでは使っている
VRCFTが取り扱うモーフ
https://docs.vrcft.io/docs/tutorial-avatars/tutorial-avatars-extras/unified-blendshapes
Unified Expressionsというモーフを独自に定義することで、各FT方式との互換性を高めている
ARKitとQuestProの対応表
https://docs.vrcft.io/docs/tutorial-avatars/tutorial-avatars-extras/compatibility/overview
QuestProでtongueOutを動作させるために特別な条件は必要か?
Jerry's Template内での制限
Funnelが1のとき、TongueOutが1になっていても再生されない
他にもありそう
JawOpenが条件になっていなくても大丈夫?
JawOpenとFunnelは同時に有効になりやすく、なおかつ破綻しやすいためにこうなっている?
https://booth.pm/ja/items/5123304
これはQuestProが舌出しに対応していない時期に作成されたため、ジェスチャーで迂回している?
中身を見るとそんな感じがする
QuestProが舌出しに対応したのでこの機能が不要になっている?
https://www.uploadvr.com/virtual-desktop-now-supports-quest-pro-tongue-tracking/
VirtualDesktopでtongueOutを使うためにはVDXRランタイムを使う必要がある?
SteamVRでも動いた(2024/07)
VRXRランタイムについて
https://www.uploadvr.com/virtual-desktops-vdxr-runtime/
VDの設定でOpenXR RuntimeをVDXRにする
Automaticの場合はSteamVRが選択される
OpenXRランタイムの選択について
https://note.com/kikjin/n/nd81d2097a849
Questから face/eye/hand/bodyトラッキングのデータをVDXRランタイム経由で送信できます。ゲーム側がこれを利用するにはOpenXRの拡張機能を実装する必要があります。なお。VRChatは現状OpenXRには対応していません。
https://qiita.com/Kazu_Sack/items/14460dac1dd149bf1ff5#openxrランタイムの話
VD・SteamLinkの場合
ランタイムは SteamVR にしてください。
https://x.com/Minie_vrc/status/1722189730237047191
vrchatがopenXR非対応でVDXR動かないらしい問題、
VDXRでsteamVRを動かせばvrchatも動いたで。(当たり前)
tongueOutが1になる条件について
口を閉じた状態で舌を出すと1になる
舌を出したまま口を開けると0になる
OSCデバッグ画面で値を確認した
float値を確認したが、ほぼboolのような動きをする
Jerry's Templateでローカルの舌出しが反映されない?
TongueOut1, TongueOut2, TongueOut4がtrueになることを確認
GestureManagerではIsLocalがtrueのとき、TongueOut1, TongueOut2, TongueOut4がtrueになっても舌が出ない
FT/v2/TongueOut (float) をExParamに追加しても、そのパラメータの値が変化しない
SyncedでもNot Syncedでもダメ
FacialSettingsMAがOSCmoothの適用ミスってる気がしてきた
同期パラメータをBoolにしている場合、ローカルに適用されなくなっているのでは?
ローカルとリモートで分岐しているが、正直ローカルでもリモートと同様に見えた方が嬉しい
とりあえずBinary_GenとSmoothing_Genからローカル側の処理を削除
IsLocalで分岐する部分は残っているが、子が1つなので必ずリモート側が実行される
ローカル側の処理を削除してリモート側の処理を使うようにしたらかなり表情豊かになった…
本来パーフェクトシンクってこのくらいの表現力があるんだな…
あと、ローカル側でもスムージングかけた方がきれいに見える
おそらくVRCFTから送られてくるパラメータがカクついている
視線追従を無効化する
Jerry's Templateの改変
FacialSettingsMAのAdditiveEyeQPは目のボーンを制御するためのレイヤーなので、これをMAで追加しないようにする
BlendShapeDriverレイヤーから下記のアニメーションを探し、すべてのキーを0にする
下記のLeftとRight
EyeLookUp
EyeLookDown
EyeLookIn
EyeLookOut
TrackingStateレイヤーから、目のTracingControlを制御しているサブステートマシンを削除する
Jerry's Templateの視線追従を無効化しても、目のTrackingControlがtrueになっているとVRC標準のアイトラが動作する
Jerry's Templateのまばたきを残している場合、まばたきが二重に有効化されて破綻する
AvataDescriptorで、目のボーンとまぶたのシェイプキーをともにNoneにしておくといい
凪の場合は目のボーンの可動域が±5なので、ほぼ疑似アイトラが使用されていなかった
視線のチラつきが発生するのも嫌なので、いっそ目のTrackingControlに関わる要素はすべて無効化しておく
舌出しの調整
Jerry's Templateでは、JawOpenHelperのBlendTreeによって、TongueOutが有効なときにJawOpenも一緒に有効化するようにしている
JawOpenを1にするBlendShapeの閾値が4なので、TongueOutが1のとき、JawOpenが0.25となる
凪の場合、舌が貫通しないようにするには閾値を1(つまりJawOpenを1)にする必要がある
さすがに口が開きすぎなので、ARKit用の舌出しシェイプキーを追加する
JawOpenが55のときにちょうど良くなるように、TongueUpと組み合わせて新しいシェイプキーを作る
TongueUpは25にした
JawOpenを55にしたいので、閾値を1.82にする
tongueOutはほぼbool的な変化をするので、0の場合と1の場合についてのみ調整すればいい
EyeLidの閾値0の部分を0.3に変更し、目が閉じ切るようにする
自アバターでのFaceEmoとの干渉対策
FT→FaceEmoの順で適用
FaceEmo側で干渉対策をするため
ARKitのシェイプキーをすべて除外
まばたきアニメーションを空にする
まばたき無効時に、FTのまぶたの変形をキャンセル
リップシンク無効時に、FTの口の変形をキャンセル
口変形キャンセルの対象にFTのシェイプキーを追加
自アバターの場合、リップシンクで崩れる表情はリップシンクを無効にしているので、口変形キャンセルにあまり依存していない
口変形キャンセルに依存しているアバターの場合は別途対策が必要
FTのパラメータが有効な場合キャンセル、あたりになるだろうか…?
0が平常状態とは限らないのでちょっと難しい?
パラメータがすべて既知なのでむしろ簡単かも
閾値の設定には気を使う必要あり
リップシンクで崩れにくい表情は口変形キャンセルを無効にして、口変形キャンセルの対象にFTのシェイプキーを追加
口変形キャンセルはVoiceが正のとき有効化されるが、FTによる口の変形はVoiceが0のときにも発生する
口変形キャンセルはリップシンク優先、リップシンク無効は表情優先なのでそもそも目的が逆
ハンドトラッキング中はジェスチャー使いたくないかも
設定でオフにできる?
TODO
表情を変えるのに必要なリアルの動きを小さくする