WEB上でVRMをアニメーション表示させてみる

# やりたいこと
- WEB上でVRMを表示させたい
- できるだけ簡単に(依存関係で悩みたくない！)
- モーションを付けたい
- カメラポジションを自動制御したい
:::note info
VRMは、メタバース時代のインターオペラビリティ（相互運用性）を想定した、プラットフォーム非依存の日本発3Dアバター向けファイル形式です。
:::

# 環境
- Windows11
- VSCode(Live Serverインストール済)

# まずはサンプルソフトを動かしてみる
1.[pixiv/three-vrm](https://github.com/pixiv/three-vrm)からソースコードをダウンロードします。
複数のサンプルソースが入っていますが、今回は以下のファイルをカスタマイズしていきます。
\packages\three-vrm-animation\examples\loader-plugin.html

2.このままでは動作しないため、```@pixiv/three-vrm-animation```をCDNに変更します。
~~~ruby:変更前
"@pixiv/three-vrm-animation": "../lib/three-vrm-animation.module.js"
~~~

~~~ruby:変更後
"@pixiv/three-vrm-animation": "https://cdn.jsdelivr.net/npm/@pixiv/three-vrm-animation@3/lib/three-vrm-animation.module.js"
~~~

3.変更したファイルをVSCodeのLive ServerでWEB表示します。

WEB上にVRMが表示されました！とても簡単です。
![初期状態169.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/c108c0a3-88f3-6753-6c41-126de5ccba47.gif)
ただし、見た目にもう少し変化が欲しいですね。

# VRMを変更してみる
1.[VRMまとめサイト](https://note.com/apollo_metaverse/n/n3915fd2ab225)から、好みのアバターをダウンロードします。
2.ソースコードの以下の部分を変更し、ダウンロードしたVRMファイルを読み込むようにします。
~~~
const gltfVrm = await loader.loadAsync( './models/VRM1_Constraint_Twist_Sample.vrm' );
~~~

3.カメラポジションを調整します。キャラクターが後ろ向きになっている場合、カメラポジションを以下のように変更します。
~~~ruby:変更前
camera.position.set( 0.0, 1.0, 5.0 );
~~~
~~~ruby:変更後
camera.position.set( 0.0, 1.0, -5.0 );
~~~

# モーションを変更してみる
1.このソースコードではVRMAを使用してモーションを付けています。

:::note info
VRMAはVRMで定義された人型モデルの骨格や表情の動き方を扱うアニメーションデータです。
VRMAは2024年に正式リリースされたばかりで、まだ数が少ないので、[このサイト](https://booth.pm/ja/browse/3D%E3%83%A2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%BB%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3?q=VRM)から入手するのがよさそうです。
:::
2.ソースコードの以下の部分を変更し、ダウンロードしたVRMAファイルを読み込むようにします。
~~~
const gltfVrma = await loader.loadAsync( './models/test.vrma' );
~~~
3.変更したファイルをVSCodeのLive ServerでWEB表示します。
![VRM_VRMA変更後.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/f97100c9-9451-5550-ea8c-cff0b87ca034.gif)
良い感じに仕上がってきました！

# カメラポジションを自動制御してみる
[Tween.js](https://blog.cotapon.org/javascript-tweenjs/)を使用してカメラポジションを自動で移動させてみます。
1.CDNを追加します。
~~~
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/25.0.0/tween.umd.js" integrity="sha512-UB3eFQlXP9zz/G459VyviWSLDbYnrU9jRY81/yjdMSh/GtILylnyRB77EnyCBLal6TLInl4gn6ix5hSON/JXXQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
~~~

2.カメラポジションを右に移動させます。
~~~
camera.position.set( -5.0, 1.0, -5.0 );
~~~
3.その下にカメラポジションを右から左に移動させる処理を追加します。
~~~
const tween = new TWEEN.Tween(camera.position)
    .to({ x: 5, y: 1.0, z: -5.0 }, 10000)
    .easing(TWEEN.Easing.Quadratic.InOut)
    .onUpdate(() => {
        camera.lookAt(scene.position);
    })
    .start();

//もう１つのトゥイーン設定。戻ってくる動きの方
const tweenBack = new TWEEN.Tween(camera.position)
    .to({x: -5.0, y: 1.0, rotation: -5.0}, 10000)
    .easing(TWEEN.Easing.Quadratic.InOut)
    .onUpdate(() => {
        camera.lookAt(scene.position);
    })

//メソッドチェーンでアニメーションループ
tween.chain(tweenBack);
tweenBack.chain(tween);
~~~

4.``function animate()``内に以下を追加します。
~~~
tween.update();
tweenBack.update();
~~~

5.カメラの視野角を広くします。
~~~ruby:変更前
const camera = new THREE.PerspectiveCamera( 30.0, window.innerWidth / window.innerHeight, 0.1, 20.0 );
~~~
~~~ruby:変更後
const camera = new THREE.PerspectiveCamera( 45.0, window.innerWidth / window.innerHeight, 0.1, 20.0 );
~~~

6.変更したファイルをVSCodeのLive ServerでWEB表示します。
![カメラポジション変更後.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659381/86b71836-e255-21ae-76fa-926428f50827.gif)

# 最後に
ここまでの手順で、WEB上でVRMを表示し、モーションを加え、カメラポジションを自動制御することができました。
簡単なサンプルから少しずつ変更を加えていくことで、より自分らしいアバター演出が可能になります。
自分だけのカスタムアバターを動かす楽しさを、ぜひ色々なアイデアで広げてみてください！