web3d-animation について
web3d-animation は、three.js のアニメーションシーンを設計・実装するチーム向けのスキルです。共有クリップ規約を使ってアセットとランタイムを調整し、手法の選択、リグや書き出しの確認、再生パターンを扱います。
主な機能
- 01対象に応じたモーション手法の選択
- 02クリップ名とループ規則の共通化
- 03リグ、書き出し、アニメーションライセンスの確認
- 04ミキサー、遷移、ルートモーションの実装
- 05アニメーション検証とモーション軽減の計画
活用シーン
- 01キャラクタークリップとランタイム再生の調整
- 02足滑りやバインドポーズへの復帰の診断
- 03glTF アニメーションアセットの準備と検証
- 04多数のキャラクターのアニメーション処理の最適化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ssheleg/ web3d-dev --skill web3d-animationインストール後、Claude Code で/web3d-animationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/asset-animation.mdclip-canon.mdruntime-patterns.md詳細
web3d-animation — 動き方を決めて、両方を一致させる
アニメーション付きのシーンは、会ったことのない二人の間にある継ぎ目で破綻します。クリップを作った人と、それを再生する人です。クリップ名は Armature|mixamo.com|Layer0 なのに、コードは run を要求し、キャラクターは滑り、死亡ポーズから T ポーズに戻ってしまいます。このスキルは、その継ぎ目をまたぐ アセット側 と ランタイム側 の契約であり、両者が共有する規範(references/clip-canon.md)です。
最初のアクション — 調査してから報告する
- バージョン。
package.jsonのthreeを読み取ります。ここに記載されている API の情報はすべて [email protected] に照らして確認済みです。古いリリースの場合は、名称を信頼する前にreferences/runtime-patterns.md→ Version notes を確認してください。 - 何が動くか。 動くものをそれぞれ列挙し、現時点で何が動かしているかを記します。クリップ、コード、シェーダー、物理演算、またはまだ何もない状態です。
- 何があるか。 すべての
.glb/.gltfについて、npx @gltf-transform/cli inspect <file>を実行し、アニメーション(名前、再生時間、チャンネル)、スキン(ジョイント数)、モーフターゲット、ファイルが圧縮されているかを確認します。クリップ名を規範と照合してください。 - アセットの入手元。 このセッションで Asset Foundry ツール(
foundry_capabilities)またはasset-foundryスキルが利用できる場合は、発注をそちら経由で行います。そうでない場合は、入手元をweb3d-assetsで決定します。
表を1つだけ報告します — オブジェクト · 現在の手法 · 必要な手法 · ギャップ — そして次のアクションをちょうど1つ報告します。読み取れることを質問せず、検出してください。
ステップ 1 — アセットに触れる前に手法を選ぶ
| 動くもの | 手法 | 次の行ではなくこれを選ぶ理由 |
|---|---|---|
| ドア、小道具、カメラ、3D UI などの剛体オブジェクト | フレームループ内でトランスフォームを更新するか、作成済みの場合はキーフレームクリップを使います | 剛体にスケルトンを使うのは純粋なコストです |
| 葉、布の揺れ、水、脈動など、表面の環境的な動き | マテリアル上の TSL:time、positionLocal.add(offset) | GPU のみで処理でき、インスタンスごとの CPU 処理は不要です |
| 顔、ブレンドシェイプ、補正シェイプ | モーフターゲット | スキニングでは笑顔を表現できません |
| 作成済みの動きがあるキャラクター | SkinnedMesh + AnimationMixer を介したクリップ | 標準的な経路であり、以下はすべてその最適化です |
| 同じポーズの複製が多数 | スキン付きインスタンシング。すべてに対してミキサーを1回更新 | 1回のスケルトン評価ですべてのインスタンスを駆動します |
| 個別のタイミングで動く複製が多数 | インスタンスごとの mixer.setTime + 1回のコンピュートスキニングパス | CPU コストはインスタンス数に応じて増加します。計測してから止めてください |
| インタラクションがなく、動きが固定された数千のオブジェクト | TSL による頂点アニメーションテクスチャ(VAT) | ランタイムにスケルトンは不要ですが、three.js に組み込まれてはいないため、自分で実装します |
| 力への反応:転倒、衝突、ラグドール | 固定ステップの物理演算 | 作成済みのクリップでは反応できません |
| パーティクル、群れ、シミュレーション | compute(web3d-runtime) | そもそもアニメーションデータではありません |
BatchedMesh はスキニングできません。 小道具はバッチ化しても、キャラクターはバッチ化しないでください。
Step 2 — アセット側
キャラクターごとにこのリストを確認します。各項目は助言ではなく、チェック項目です。
- リグ。 TポーズまたはAポーズ、単位はメートル、+Yが上、+Z方向を向くようにします。自動リギングサービスがリグを作成できるのはヒューマノイドです。非ヒューマノイドで得られるのは、よくてもロコモーションです。作成できないリグを依頼するのではなく、Step 1でプロシージャル方式、モーフ、VATのどれにするか決めます。
- 正規化。
references/clip-canon.mdに従い、すべてのクリップに正規名、ループモード、変位ルールを設定します。プロバイダー名のマッピングはインポート時に一度だけ行います。 - ソース。 Asset Foundryが利用できる場合は、リグの実現可能性を先に確認してから発注します(球体のリグを作るより、リグの確認のほうが低コストです)。利用できない場合は、
references/asset-animation.mdのプロバイダーテーブルとライセンスルールを参照します。モーションデータとメッシュのライセンスは異なるため、両方を記録します。 - リターゲット。 別のスケルトン向けに作成されたクリップは、
references/asset-animation.md→ Retargetingに従ってリターゲットするか、実行時にSkeletonUtils.retargetClipを使います。 - エクスポート。 GLB、30 fps、インプレース、頂点あたりの影響数は4以下(three.jsは
JOINTS_0/WEIGHTS_0の1セットを読み込み、残りを警告なしで破棄します)、ボーン名は安定したものにします。 - 予算。 ジョイント数、影響数、クリップ数、ファイルサイズをターゲットプロファイル(
web3d-assets)に照らして確認します。r186ではユニフォームバッファーのボーン数上限が撤廃されたため、予算はパフォーマンス上のものであり、厳密な上限ではありません。 - ゲート。
npx @gltf-transform/cli validateが成功すること、すべてのクリップがビューアーで再生できること、ループに継ぎ目がないこと、クリップで意図した速度で足が接地していること、どのクリップもバインドポーズで終了しないことを確認します。実行されていないゲートはNOT_RUNです。
Step 3 — ランタイム側
- クロックは1つ。
new Timer()(r186でコアに追加。Clockは非推奨)を使い、timer.connect(document)を設定して、非表示タブから戻った際に巨大なデルタ値が発生しないようにします。フレームごとにtimer.update()を一度呼び出し、ミキサーには上限を設けたdt(例:Math.min(dt, 0.1)のようなパターン)を渡します。物理演算は、同じクロックから値を受け取る独自の固定ステップ式アキュムレーターで実行します。 - フレーム順序:
mixer.update(dt)→ コンピュートパス → レンダリング。コンピュートスキニングパスは、ミキサーが直前に書き込んだボーン行列を読み取ります。 - キャラクターのルートごとにミキサーは1つ。 複製には
SkeletonUtils.cloneを使います。通常の.clone()では、スケルトンが元のボーンにバインドされたままになります。リターゲットしたクリップは、SkinnedMesh自体をルートとするミキサーで再生します。 - 遷移。 ロコモーションの切り替えはクロスフェードします(
crossFadeTo(next, duration, warp))。syncWithを使うと、歩行↔走行の切り替え時にサイクル位相を維持できます。単発アニメーションにはLoopOnceを使い、'finished'イベントはアクションではなくミキサーで受け取ります。deathではclampWhenFinished = trueを設定します。 - レイヤー。 呼吸、照準、上半身のジェスチャーには、ベースとなるロコモーションに重ねる加算クリップ(
AnimationUtils.makeClipAdditive)を使い、別の状態ではなくウェイトで制御します。 - ルートモーションと滑り。 インプレースクリップとコード駆動の移動を組み合わせます。
timeScaleは実際の速度をクリップに設定された速度で割った値に合わせます。そうしないと足が滑ります。_rmクリップの腰の移動はコードで抽出します。three.jsにはルートモーションがありません。 - 画面外では処理を減らす。 視錐台の外や遠くにいるキャラクターについては、
mixer.updateをスキップするか頻度を下げます。タブが非表示の場合は、すでにTimerが対処しています。 - 動きの軽減。
prefers-reduced-motionが指定されている場合、装飾的な動き(環境ループ、カメラの漂い、アイドル時の動き)は停止し、意味を伝える動き(被弾、状態変化)は維持します。ページ全体のルールはsheleg-designの「落ち着いた表示への段階的な切り替え」です。3Dシーンも同じシグナルを参照します。 - 後処理。
stopAllAction、uncacheRootの順に実行してから、ジオメトリとマテリアルを破棄します。
各ステップのコードについては、references/runtime-patterns.mdを参照してください。
注意点 — どれも、誰かが確認するまで気づかれません
clampWhenFinished = falseのLoopOnceアクションが終了すると、自動的に無効になります。ボディはバインドポーズに戻ります。死亡時や最終ポーズではクランプが必要です。'finished'と'loop'は、ここで唯一のイベントディスパッチャーであるミキサーで発火します。AnimationActionにはaddEventListenerがないため、アクションに追加しようとするとエラーになります。positionNode = …は、スキニング、モーフ、インスタンシングの適用後に位置を置き換えます。positionLocal.add(x)ならアニメーションを維持できますが、positionGeometry.add(x)ではアニメーションが失われます。- glTF にある2組目のスキンウェイトは、マージされずに破棄されます。4つに正規化し直してください。
- drei の
useAnimationsと R3F のuseFrameは、非推奨のClockからクランプされていないデルタを渡すため、タブを非表示にした後はすべてのキャラクターが跳ねます。フレームコールバック内でクランプしてください。 KHR_animation_pointer(glTF からマテリアルやライトのプロパティをアニメーションさせる機能)は、GLTFLoader に組み込まれていません。別途プラグインを登録する必要があります。sheleg-designでは、スクロールセクション間のクロスフェードが禁止されています。このルールはページの動きに関するものです。キャラクターのクリップをクロスフェードするのは、適切で標準的なトランジションです。
不足しているものがある場合
- このホストでツールが一切使えない → 結果ではなく、コマンドとコードを記述してください。測定されていないサイズ、合格判定、フレーム時間、「完了」は捏造された証拠です。そのようなチェックはそれぞれ
NOT_RUNと記し、人が何を実行すべきかを説明してください。 - このホストでブラウザーやヘッドレス GPU が使えない → 構造を実装して検証したうえで、視覚的な確認項目を、人がどこを見るべきかとともに
NOT_RUNと記してください。コードを読んだだけで動作を検証したと報告してはいけません。 @gltf-transform/cliが使えない(ネットワークなし、npx なし) → glTF JSON を読み取ってください(.gltfは直接、.glbはチャンク 0)。animations、skins、targetsを確認し、実行できないチェック(検証、圧縮を考慮した調査)を明記してください。- Asset Foundry が利用できない →
web3d-assetsを通じて手動で入手してください。その原則は引き続き適用されます。 - オペレーターの判断が必要な場合(予算超過の有料注文、適用範囲が不明なライセンス)→ その箇所で止まり、必要な判断を明記してください。回避してはいけません。
参考資料
| 参照先 | 内容 |
|---|---|
references/clip-canon.md | クリップの命名、ループ、読み込み、プロバイダー名のマッピング — web3d-assets との共通仕様 |
references/runtime-patterns.md | ループ、ミキサー、トランジション、レイヤー、リターゲティング、群衆、モーフインスタンシング、VAT、R3F の実装 |
references/asset-animation.md | リグやクリップの制作・購入:プロバイダー、リグのチェック、モーションのライセンス、リターゲティングのパイプライン、エクスポート、QA |
ランタイム(レンダラー、TSL、コンピュート、パフォーマンス)は web3d-runtime、ファイルのパイプラインと予算は web3d-assets が担当します。このスキルが扱うのはモーションのみです。
トリガー
この項目に振り分けるその他のフレーズ:「blend idle walk run」/「アニメーション間の遷移」、「crowd of characters」/「キャラクターの群衆」、「morph targets」/「モーフターゲット」。