[Astro #101] VRM Thumbnail Generator 単品ツール化

[Astro #101] VRM Thumbnail Generator 単品ツール化

経緯

前回の[Astro #100]で、VRMアバターのサムネイルを自動生成する機能をlain-lab本体に組み込みました。

インポートが全部npmパッケージだけで、PROJECT.LAINのコード本体に一切依存していないので、これは単品のWEBツールとして切り出せると思い、 VRMのサムネ作成ツールを作ってみました。

まだ初期バージョンで、最小限の機能しかないので、ポーズを増やして、背景を変えたり色々機能追加する予定です。

動画:

[Astro #101] VRM Thumbnail Generator 単品ツール化

VRM Thumbnail Generator

「VRMの証明写真機」を作った。

やっていること

  1. VRMファイルをドラッグ&ドロップ(またはファイル選択)
  2. リアルタイム3Dプレビューで確認
  3. カメラ位置・ズーム・回転をスライダーで調整
  4. ポーズを選択(プリセット5種 + カスタム.vrma読み込み)
  5. サイズ・フォーマットを指定してキャプチャ
  6. ダウンロード

証明写真を撮る機械やプリクラと同じ発想。

構成

src/
  components/VrmThumb/
    VrmThumb.tsx          ← メインコンポーネント
  pages/
    vrm_thumb.astro       ← ルーティング
public/
  pose/
    01.vrma 〜 05.vrma    ← ポーズプリセット

vrm_thumb.astroは最小限で、BaseLayout.astroでサイトのナビ・フッターを維持しつつ、client:only="react"でコンポーネントをハイドレートするだけ。

---
import Layout from '../layouts/BaseLayout.astro';
import { VrmThumbnailDemo } from '../components/VrmThumb/VrmThumb.tsx';
---
<Layout title="VRM Thumbnail Generator">
  <div id="vrm-thumb-app">
    <VrmThumbnailDemo client:only="react" />
  </div>
</Layout>

アーキテクチャの変更

Astro #100の実装は「VRM読み込み → 即撮影 → 破棄」のワンショット方式だった。

ツールとして使うには、VRMを保持したままリアルタイムにプレビューしながら調整し、好きなタイミングでシャッターを切れる必要がある。

主な変更点:

  • VRMとWebGLRendererをuseRefで保持し、requestAnimationFrameで常時描画
  • カメラパラメータ(X/Y/ズーム)をReact stateで管理し、refに同期してアニメーションループ内で適用
  • キャプチャ時のみ出力サイズ専用の一時レンダラーを生成し、10フレーム空回しでシェーダーコンパイルを確定させてから撮影
  • VRM差し替え時は前のVRMのジオメトリ・マテリアルを走査してdispose()

.vrmaポーズ適用

@pixiv/three-vrm-animationVRMAnimationLoaderPlugincreateVRMAnimationClipで.vrmaを読み込み、AnimationMixerで1フレーム目に固定する。

const clip = createVRMAnimationClip(vrmAnimation, vrm);
const mixer = new THREE.AnimationMixer(vrm.scene);
const action = mixer.clipAction(clip);
action.play();
mixer.setTime(0);
mixer.update(0);

ポーズデータはVrmPosingDesktopで作成し、.vrmaでエクスポートしたものをpublic/pose/に配置。プリセット5種をボタンで切り替え、カスタム.vrmaのドロップにも対応。