[Astro #101] VRM Thumbnail Generator 単品ツール化
経緯
前回の[Astro #100]で、VRMアバターのサムネイルを自動生成する機能をlain-lab本体に組み込みました。
[Astro #100] VRMサムネイル自動生成 & メニュー表示 // PROTOCOL.LAIN
Three.jsのオフスクリーンレンダリングでVRMモデルのサムネイルを自動生成し、IndexedDBにBase64で保存。WiredAvatarMenuとWiredVRMenuの両方でサムネ付きモデル選択UIを実装した記録。
lain-lab.comインポートが全部npmパッケージだけで、PROJECT.LAINのコード本体に一切依存していないので、これは単品のWEBツールとして切り出せると思い、 VRMのサムネ作成ツールを作ってみました。
まだ初期バージョンで、昨日が最小限しかないので、ポーズを増やして、背景を変えたり色々機能追加する予定です。
動画:
VRM Thumbnail Generator
「VRMの証明写真機」を作った。
やっていること
- VRMファイルをドラッグ&ドロップ(またはファイル選択)
- リアルタイム3Dプレビューで確認
- カメラ位置・ズーム・回転をスライダーで調整
- ポーズを選択(プリセット5種 + カスタム.vrma読み込み)
- サイズ・フォーマットを指定してキャプチャ
- ダウンロード
証明写真を撮る機械やプリクラと同じ発想。
構成
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-animationのVRMAnimationLoaderPluginとcreateVRMAnimationClipで.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のドロップにも対応。