【VRCFT/OSCmooth】カザリスちゃんのフェイストラッキングを改変してみよう

この記事の対象者

  • フェイストラッキングの改変をしてみたい人
  • PICO 4 Pro/Enterpriseを使っている人
  • VIVE XR EliteやVIVE Focus Visionを使っている人
  • Quest Proだけど目力に自信がない人(?)

手元の機器では思うように動かせない部分があったので、「目元の動作を口元で制御するように改変」してみます。カザリスちゃん付属のフェイストラッキングはシンプルで見やすい構成だと感じましたので、内容を読み取って改変するのはそこまで難しくはないです。

※本記事では、BOOTHの半熟りんご様にて販売されている『フォレ・ノワールの少女 カザリス』を用いています。

【5/6まで1500円!】『フォレ・ノワールの少女 カザリス』【オリジナル3Dモデル】 - 半熟りんご - BOOTH
幽邃なる境域へ、ようこそ。 発売記念セール! 5000円→1500円 5/6の24時まで ※サンプル版はAndroid、iOSにも対応していますが製品版は非対応です。 ご留意ください!  またR-18テクスチャは付属していません

長い前置き

VRCFT4.0のレガシーパラメーターについて

カザリス付属のフェイストラッキングでは、目元の制御で「LeftEyeLidExpandedSqueeze」と「RightEyeLidExpandedSqueeze」が使用されています。

EyeLidExpandedSqueeze
動作するパラメーター名挙動
EyesSqueeze-1.0~0.0まぶたをギュッと閉じる
EyeLid0.0~0.8まぶたを閉じる・目を開ける
EyesWiden0.8~1.0目を大きく見開く

アイトラッキングの実装方法を調べるといくつかの情報が引っ掛かりますが、このパラメーターはVRCFT4.0時代のものなので既にレガシー扱いになっています。

Eye Tracking Parameters | VRCFaceTracking
|Parameter Name (Case Sensitive)|Description|Eye|

カザリスではEyeLidの範囲内では通常の瞬きとなり、マイナス値となってEyesSqueezeの範囲に入ると「笑い閉じ目」に切り替わる実装になっていました。

上手く動作しない環境がある

さて、この「EyesSqueeze」部分が少々くせ者で、思ったように動作しない環境が存在します。

例えばPICOの場合はマイナス値がほぼ来ないのでEyesSqueezeが動作しないほか、VIVEでも両目を閉じてるとマイナス値にならないという現象が確認できました。(※VIVE XR EliteかつVIVE Hub使用時)

VIVE XR Eliteで両目を閉じているとき

また、VIVEでは片目を閉じているときに限りマイナス値が-0.5まで来るという挙動になっており、0.0でピッタリ止める制御も非常にシビアなので使い分けが困難です。

片目だけ閉じている場合

恐らくちゃんと動くであろうQuest Proについては、所有していないので分かりません。Quest Proユーザーのフレンド達の様子を観察していると、目が閉じきらずに半目を開けた状態になりがちなのをよく見かけるので、目だけで自由に使い分けるのは難しそうな気がします。

VRCFT5.0以降での扱い

VRCFT5.0以降ではEyeLidExpandedSqueezeが廃止となり、「v2/EyeLid」と「v2/EyeSquint」に分離しているように見えます。

v2/EyeLid
動作するパラメーター名挙動
EyeClosed0.0~0.75まぶたを閉じる・目を開ける
EyeWide0.75~1.0目を大きく見開く
v2/EyeSquint
動作するパラメーター名挙動
EyeSquint0.0~1.0下まぶたを押し上げて目を細める
VRCFaceTracking Parameters | VRCFaceTracking
Parameters that can be used to control expressions on avatars!

分離していると言っても全く同じではなさそうなので、挙動が異なるかと思われます。ドキュメントやいくつかのVRCFTモジュールを眺めた感じでは、Quest Proの場合はLID_TIGHTENER_LがEyeSquintLeftとして扱われているほか、VIVEはEye_Left_Squeeze、PICOはEyeSquint_LがEyeSquint扱いのようです。(※左目の場合)

OpenXRのMovement拡張機能のブレンドシェイプのビジュアルリファレンス
OpenXRのMovement拡張機能で提供されているブレンドシェイプのビジュアルリファレンス。
Unity: Getting Data of Facial Tracking | VIVE OpenXR - Developer Resources
Face Tracking | PICO Developer

口元で目の閉じ方を制御したい

ニッコリと笑うときは口も笑っていることが殆どですので、「閉じ目と笑い閉じ目の制御を口で行うように変更しよう!」というのが今回の趣旨です。目で使用しているパラメーター数よりも、口で使用しているパラメーターの方が種類が多いので、口元で制御する方が融通が利きやすいという利点もあります。

口での制御に変更するだけなら弄るところは少しだけなので、やり方自体は簡単です。ついでに他のところを自分好みに弄ってみてもいいですね。例えば、半目を開けた状態でもアバター側の目が閉じるようにもできます。

OSCmoothの使い方を知りたい

カザリス付属のフェイストラッキングは既にスムージングされている状態なので、これを分解して再構築する必要があります。BOOTHで販売されているフェイストラッキングアドオンもOSCmoothが適用済みだと思います。

VRChatでのOSCは、送受信頻度の都合上スムージングしないとリモート側(相手から見たとき)でカクカクの動作になってしまいます。このスムージングに使われているのがOSCmoothです。

Releases · regzo2/OSCmooth
Create smooth parameters that mimic IK Sync for OSC or general use. - regzo2/OSCmooth

このOSCmoothの使い方を理解するまで何が何だか分からなかったので、詳細を書き残しておこうという目的もあります。

前置きはここまでにして、早速改変していきましょう。

改変の前準備

OSCmoothをインポート

Unityに突っ込んでおいてください。最新のv1.1.1を使用します。

Releases · regzo2/OSCmooth
Create smooth parameters that mimic IK Sync for OSC or general use. - regzo2/OSCmooth

OSCmoothの適用を解除する

カザリス付属のフェイストラッキングのアニメーターコントローラーを編集します。Ctrl + Dで複製しておいてそちらを編集するのが良いかと思います。

OSCmoothを使う都合上、まずはフェイストラッキング編集用としてカザリスのPrefabをシーンに配置し、Playable LayersのFXを「Cazalis_FX」から「Cazalis_FacialTracking」に差し替えておいてください。(※複製した場合は複製した方に差し替える)

Cazalis > FacialTracking > FacialTracking_Animation > Cazalis_FacialTracking.controller

アニメーターコントローラーの中身を確認すると、「_OSCmooth_Binary_Gen」と「_OSCmooth_Smoothing_Gen」というレイヤーが入っていることが分かります。

ツールからOSCmoothを呼び出し、Avatarの欄に先程シーンに配置したカザリスを指定します。

一番下の「Revert OSCmooth from Layer」を押すとスムージングが解除されます。

パラメーターを削除する

パラメータータブに切り替えて一覧を確認すると、下の方に1~8までの数字やNegativeと書かれたパラメーターが存在していることが分かると思います。ここの数字とNegativeの有無はあとで使うので、どこかに書き留めておいてください。

メモを終えたら、それらを右クリックして全て削除します。ちなみにDeleteキー連打で次々と消えます。

使用されていないパラメーターであれば、警告無しにそのまま消えます。警告が出る場合は使用中のパラメーターなので、消してはいけないパラメーターです。

誤ってEyeTracking_ONを消そうとした場合

カザリスの場合は、「GestureExpression_OFF」よりも下にあるパラメーターが生成された物なので削除してOKです。

一通り消した後

不要なパラメーターの削除を終えたら準備完了です。

改変を行う

口元が笑ったときに閉じ目も笑うように改変します。

パラメーター名を変更する

今回はレガシーパラメーターを使用しない方式に変更するので、「LeftEyeLidExpandedSqueeze」と「RightEyeLidExpandedSqueeze」を「v2/EyeLidLeft」と「v2/EyeLidRight」に書き換えてください。

ブレンドツリーを編集する

レイヤータブに切り替えて「EyeTracking_Control」を選択すると、オレンジ色の「EyeTracking_ON」が中央に表示されていると思いますのでダブルクリックしてください。

ブレンドツリーが展開されるので、下の方にある「EyeLeft」と「EyeRight」の部分を編集します。

パラメーター名を確認しておく

「EyeLeft」を選択するとParameterに「v2/EyeLidLeft」が割り当てられており、そこから5つのアニメーションに分岐していることが分かります。(※Parameterが「LeftEyeLidExpandedSqueeze」になっている場合は、パラメーター名を変更し忘れています。)

既存のアニメーションを削除する

「EyeLeft_Blink」と「EyeLeft_Smile」を右クリックから削除しておいてください。こちらは消すかどうか警告が出ますので、間違った物を選んでないかよく確認してから「Delete」を選択します。

ブレンドツリーを追加する

+ボタンから「New Blend Tree」を選んでください。

ブレンドツリーの名前は適当に付けておきましょう。今回は「EyeClosed_Left」としました。

名前を付けたらThresholdを0に設定します。(目が閉じきらない人は0.1とかでもいいかも?)

口元で制御したい部分なので、「EyeClosed_Left」ブレンドツリーのParameterに「v2/SmileSadLeft」を入れておきます。

アニメーションを追加する

Motionの欄にある+ボタンから「モーションフィールドを追加」してください。2つ必要です。

追加したフィールドに先程削除した「EyeLeft_Blink」と「EyeLeft_Smile」を入れてください。これらは目を閉じた状態の表情アニメーションと笑い閉じ目の表情アニメーションです。

このままでは値が編集できないので、「Automate Threshold」のチェックを外します。「EyeLeft_Blink」が0で「EyeLeft_Smile」を0.6~0.8ぐらいにThresholdを設定します。

Blink側は0ではなく0.1~0.2ぐらいでも良さそうですね。口元の笑い具合(SmileSadの値)がどこまで来たら切り替えるかの調整になるので、この辺りはお好みで。

右目も同じ操作をする

以上で左目用の設定が完了したので、右目の方も同じように編集しておきましょう。LeftをRightに読み替えるだけです。

OSCmoothを適用する

パラメータを読み込む

OSCmoothのウィンドウを出して、「Use Playable Layer Parameters」を押してパラメーターを読み込んでください。

読み込んだら「v2/」から始まるパラメーター以外を赤い「X」ボタンを押して全て削除してください。

Smoothnessの個別設定を行う

「Default Parameter Values」は初期設定です。今回は変更しないでおきます。

「Parameter Configuration」内のそれぞれのパラメーターの「>」ボタンを押すと、個別に設定が変更できます。

初期設定ではLocal Smoothnessが0.1でRemote Smoothnessが0.7になっていると思いますが、解説できるほど内容を把握できていないので今回は弄らないでおきます。Proxy Conversionは「v2/xxx」のパラメーターを「OSCm/Proxy/v2/xxx」に変換してくれるようです。

変更が必要なのは「Binary Resolution」と「Combined Parameter(+1 Bit)」の部分です。

勘の良い方はお気付きかと思いますが、ここで最初にメモをしたパラメーターを確認しましょう。

Binary ResolutionとCombined Parameterの設定

メモしておいたそれぞれのパラメーターを確認して、末尾の数字が「1・2・4」だけであれば「8(3 Bit)」を、「1・2・4・8」なら「16(4 Bit)」を指定します。末尾に「Negative」があれば「Combined Parameter(+1 Bit)」にチェックを入れます。

例えば「v2/SmileSadLeft 1」「v2/SmileSadLeft 2」「v2/SmileSadLeft 4」「v2/SmileSadLeft 8」「v2/SmileSadLeftNegative」とあった場合は、「16(4 Bit)」の設定に加えて「Combined Parameter」のチェックが必要です。

末尾の数字がないものは「OFF」のままにしておきましょう。

パラメーター名Binary ResolutionCombined Parameter(+1 Bit)
v2/EyeLeftX・EyeRightXOFF
v2/EyeYOFF
v2/EyeLidLeft・RightOFF
v2/JawOpenOFF
v2/LipPuckerOFF
v2/TongueOut8(3 Bit)
v2/MouthClosedOFF
v2/SmileSadLeft・Right16(4 Bit)
v2/CheekPuffSuckLeft・Right8(3 Bit)
v2/MouthX8(3 Bit)
v2/MouthRaiserLower8(3 Bit)
v2/MouthUpperUp16(4 Bit)
v2/BrowDownLeft・Right16(4 Bit)
v2/BrowInnerUp8(3 Bit)
v2/BrowOuterUpLeft・Right8(3 Bit)

今回は使用していませんが、MouthLowerDownは4 Bit・EyeSquintは3 Bit・NoseSneerは2 Bitぐらいになる(?)かと思います。挙動が怪しくなる場合はビット数を増やしてみましょう。

これは何をしてる?

これについては詳しくないので正しく説明できません。それほど精密に動作させる必要のないFloatパラメーターを、Boolを使って表現できるように分割・圧縮しているものだと個人的に認識してます。

例えばSmileSadであれば「4 Bit・16パターン」に加えて正負の判定用に「1 Bit追加」し、合計「5 Bit・32パターン」となっています。それだけあれば、間をスムージングでアニメーションさせることで、十分表現できるということなのだと思います。但し、視線の動きや目の閉じ具合は精密である必要があるので、Boolに圧縮せずにFloatのまま使用します。

設定を保存しておく

「Save Config」を押すとここまでの設定をファイルに保存しておけます。スムージングなどの設定をすぐに呼び出せて便利ですね。

OSCmoothを適用する

一旦ここでアニメーターコントローラーを複製しておきましょう。OSCmooth適用後に間違いに気が付いたとき、戻すのが少し面倒です。

「Apply OSCmooth to Layer」を押すとOSCmoothが適用されます。少し時間が掛かるので、処理が終わるまで待ってください。

処理が終わったら、「_OSCmooth_Binary_Gen」と「_OSCmooth_Smoothing_Gen」のレイヤーが生成されていることを確認します。また、OSCmoothフォルダ内にスムージングされたアニメーションが大量に生成されているはずです。

Assets > OSCmooth > Generated

MA用のPrefabを編集する

パラメーター名を修正する

付属のフェイストラッキングPrefabを確認し、MA Parametersの内容を変更します。

Cazalis > Cazalis_FacialTracking.prefab

「LeftEyeLidExpandedSqueeze」や「OSCm/Local/LeftEyeLidExpandedSqueezeSmoother」といった変更前のパラメーターが入っていますので、「v2/EyeLidLeft」や「OSCm/Local/v2/EyeLidLeftSmoother」に書き換えてください。

統合されるアニメーターを変更する

必要に応じて、MA Merge AnimatorでFXレイヤーへ統合するアニメーターを、改変後のアニメーターに変更してください。

【任意】FXレイヤーを元に戻す

シーンに配置したアバターのFXレイヤーを変更してあったので、元のFXレイヤーに戻すこともできます。とはいえ、フェイストラッキング改変用に配置したアバターなので、戻す必要はあんまりないです。シーンに新たなPrefabを配置すれば元の状態のはずなので、やらなくても構いません。

顔を改変しているとフェイストラッキングで目が閉じきらなかったり、変な形になるときは

顔の改変をしていると、目が閉じきらなくなることがあると思います。上の画像の場合、Eyelid_Up_LとRを設定したことで、瞬きが綺麗にできなくなっています。

Zatoolsでいい感じに調整しよう

「Zatools Mix BlendShapes on Build」を追加して、改変に使用したシェイプキーをフェイストラッキング用シェイプキーにブレンドする方法があります。

Ad-Hoc BlendShape Mix :: kb10uy's Various Tools
収録パッケージ: kb10uy’s Various Tools / org.kb10uy.zatools (>= 1.3.1)概要 アバターのビルド時に BlendShape (シェイプキー) の値を合成するコンポーネントです。 Blend...

今回の場合では、コピー元に「Eyelid_Up_L」を指定し、「eyeBlinkLeft」や「eyeSmileLeft」宛に係数-1でブレンドします。Eyelid_Upを75にしているなら-0.75でブレンドすると良いでしょう。(※右目側でも同様の設定をする)

ブレンドシェイプの限界突破に使用したり、フェイストラッキング周りの表情調整にも活用できます。

詳しい使い方・活用方法は以下をどうぞ。

応用編

一度弄り方が分かれば、自分好みにできますね!悲しい顔の代わりに怒った顔を出せるようにしてみたり、涙や汗を出せるようにしてみたりと自由に改変してみましょう。

細かく調整して歯を見せずに笑えるようにするなど、凝ったことをしようとすると分岐だらけになって大変なことになりますので、どこまで弄るのかはやる気次第です。

涙を出す

目を閉じた状態でSmileSadにマイナス値が入ったとき(口をへの字にしたとき)に涙を浮かべるようにしてみました。

EyeLeft_BlinkとEyeRight_Blinkのアニメーションを複製して、EyeLeft_Blink_SadとEyeRight_Blink_Sadに名前を変更しておきます。FaceEmoなどを使用して、涙のシェイプキーを追加します。

先程SmileSadで判定するように改変したEyeClosed部分にモーションフィールドを追加して、Thresholdをマイナスに設定したEyeLeft_Blink_Sadを入れます。

笑ったときに頬を赤らめる

こちらは表情アニメーションだけを変更して簡易的に行います。

FaceEmoなどを用いて、v2SmileLeft(口の左側を上げる)のアニメーションに頬を赤らめるシェイプキーを追加しただけです。自分は高度な顔芸をする予定がないのと、左右対称にSmileSadが入るようにVRCFTモジュールを改変してあるので右側には設定しませんでした。

改変結果を確認

眉のトラッキングがあまりされない環境なので、EyeLeft_Blink_SadとEyeRight_Blink_SadにbrowInnerUpLeft/Rightを入れて眉をハの字にするように変更してみたり、いくつか調整を加えた結果が以下です。

Threshold値の調整が必要な部分がありますが、思った通りに動かせるようになったと思います。肝心のリモート側でも正常に動作しているかどうかですが、自力で確認しようと思うとちょっと面倒です。動きがカクカクしてないかどうか、フレンドに確認してもらいましょう。

【5/6まで1500円!】『フォレ・ノワールの少女 カザリス』【オリジナル3Dモデル】 - 半熟りんご - BOOTH
幽邃なる境域へ、ようこそ。 発売記念セール! 5000円→1500円 5/6の24時まで ※サンプル版はAndroid、iOSにも対応していますが製品版は非対応です。 ご留意ください!  またR-18テクスチャは付属していません
タイトルとURLをコピーしました