概要
例えば口だけを笑顔にしたいとき、わざわざ表情登録をせずにパラメータ値を直接指定する方法です。VRoidStudioの顔パーツごとの表情パラメータの指定みたいな感じです。
私の別記事(Three-VRMで組み合わせて表情を登録する(Custom Expression))といった方法が一般的な方法だと思いますが、強制的に特定の顔パーツ(口だけ)の表情パラメータを指定する方法です。
動作確認環境
- VRoidStudio 1.29. 1 -- VRMファイルのエクスポート
- Three-VRM 3.1.2
- Firefox 131(Windows 10 22H2)
実装
最終的に、FaceグループにバインドされているSkinnedMeshオブジェクトのmorphTargetInfluences
の対応するインデックスの値にウェイトを格納し、render()
されると反映されるようです。
これを実現するには、requestAnimationFrame()
に渡されるコールバック中でそのように指定します。例えば最低限の実装は以下のようになります。
ここではscene
はルートのScene
オブジェクトです。
// SkinnedMeshのmorphTargetInfluencesを直接指定することで表情を操作する
// FaceグループのSkinnedMesh#morphTagetDictionaryから、目的のmorphTargetIndexを得る
// FaceグループにはFace_(merged)などのSkinnedMeshが登録されている
const DIC = scene.getObjectByName("Face").children[0].morphTargetDictionary;
// 対象となるSkinnedMeshを得る
const meshes = [...scene.getObjectByName("Face").children];
function tick() {
requestAnimationFrame(tick);
// render()直前で値を決めることで他の影響を受けないようにする
// DIC.Fcl_MTH_Funは32
meshes.map(m => m.morphTargetInfluences[DIC.Fcl_MTH_Fun] = 0.8);
renderer.render(scene, camera);
}
tick();
ここでは、render()
の直前で値を直接上書きすることで、他のパラメータの影響を受けないようにしています。
VRoidStudioのように、顔パーツの表情パラメータをいじるのってどうするのかな?と思ったので、試してみましたが、それ以外ではあまり使わないかも。
参考
- Three-VRMの
VRMExpressionMorphTargetBind.ts:applyWeight()
あたり