3d-falling-leaves について
3Dシーンで落ち葉のアニメーションを作るスキルです。グラフィックス開発者向けに、自然な回転と漂いの実装から、シーンへの統合、動作確認までを扱います。
主な機能
- 01両面リーフ形状とシェーディング
- 02葉ごとに固定した動きの変化
- 03風と連動する回転と漂い
- 04インスタンシングと再配置
- 05深度、影、季節との統合
活用シーン
- 013D環境への控えめな落ち葉の追加
- 02フレーム間の揺れを抑えた落下アニメーション
- 03建物や室内での落ち葉の挙動確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mengto/ skills --skill 3d-falling-leavesインストール後、Claude Code で/3d-falling-leavesを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yamlREFERENCES.md
詳細
3Dの落ち葉
シーンの中を漂いながら、葉が表、縁、裏の順に回転するようにします。縁が見える瞬間が、この効果には欠かせません。
説得力のある葉を1枚作る
両面表示の四角形、またはわずかに湾曲したメッシュを使い、葉らしいシルエット、茎、控えめな葉脈のディテールを表現します。カメラの方向を向くポイントスプライトは、縁が見える向きに回転できません。枚数を増やす前に、まずゆっくり動く葉を1枚作ります。
裏面は表面よりわずかに明るく、彩度を抑えた見た目にし、ライティングの法線を正しく向けます。カスタムシェーダーでは gl_FrontFacing を使って表裏を判別できます。エンジンのマテリアルがすでに両面ライティングを処理している場合は、法線を二重に反転しないでください。光の透過は控えめにし、常に葉を発光させるのではなく、シーンの太陽光に連動させます。
複数のシルエットには、パディングを設けたテクスチャアトラスを使います。透明テクセルまで端の色を延長し、ミップレベルでもパディングを維持して、暗い縁やアトラスのにじみを防ぎます。カラーアトラスは sRGB として扱い、マスクやマテリアルチャンネルを符号化したアトラスはデータとして扱います。Seijaku のプロシージャルアトラスはチャンネルを符号化したもので、一般的な葉の写真ではありません。
回転と漂いを連動させる
葉ごとに、位置シード、スケール、位相、回転速度、ロール速度、落下速度、横滑り、パレットの変化量をシード付きの値として割り当てます。毎フレーム、新しいランダム値を生成しないでください。
横方向の速度は回転に追従させ、葉が縁を向いたときに最も速く横滑りするようにします。角速度 omega はゼロから十分離れた値に制限します。
const angle = phase + omega * time;
const sideOffset = -(slip / omega) * Math.cos(angle);
// d(sideOffset)/dt = slip * sin(angle)
このオフセットを、葉ごとに選んだ水平方向に適用します。別途、ゆっくりとしたロールと傾きを加え、すべての葉が同じリズムで動かないようにします。小さな葉ごとの応答の違いを加えた、共通の風フィールドを使います。変化する風は、上限のあるシミュレーションステップで積分するか、閉形式のフィールドを使います。非表示タブだった時間分を、上限のないループで一気に追いつかせないでください。
インスタンス化して再利用する
中程度の枚数には再利用可能な CPU 作業用オブジェクトを使った InstancedMesh を、大規模なフィールドにはインスタンス属性とシェーダーアニメーションを使います。シード付き属性は一度だけアップロードし、時間、風、季節の強さ、カメラのアンカーはユニフォームで更新します。CPU パスを使う場合は、インスタンスの行列と境界を正しく更新してください。InstancedMesh を参照してください。
カメラの水平方向の視線に沿って、その前方に葉を再配置するボリュームの中心を置きます。ほぼ真上または真下を向いているときに備えて、代替の水平方向を保持します。カメラが動いても、既存の葉のワールド座標を維持します。動いているすべての葉をカメラの子にするのではなく、生成境界と折り返し境界を移動させます。
見える中央のボリュームの外側で折り返します。境界付近では 1.0 - smoothstep(inner, outer, distance) でフェードし、inner < outer とします。GLSL では、逆順の smoothstep の境界は未定義です。リセットイベントは、フォグの向こう側、ボリュームの上部付近、またはソフトな境界フェードの背後に隠します。フレーム間のちらつきを避けつつ変化を加えるため、落下サイクルごとにシードを設定します。
まずはまばらなフィールドから始め、枚数を増やす前に、見えるボリュームを狭めます。容量、アクティブ数、実際に見えている葉の数を区別します。手前に数枚、中景に見やすい層を作り、遠くの葉は小さくします。最も近い葉が巨大なぼやけた形になってカメラを覆わないようにします。
世界に統合する
- 建築物や地面に対して深度テストを行います。覆われた屋内空間を除外するか、屋根や地形の衝突プロキシを用意してください。深度テストだけでは、葉が部屋の中に落ちるのを防げません。
- 輪郭を鮮明にするには、深度書き込みを伴うアルファテストが有効なデフォルト設定です。MSAA のアルファ・トゥ・カバレッジでエッジを滑らかにできるのは、実際のターゲットがマルチサンプルの場合に限られます。カスタムシェーダーではアルファによる除外処理を実装する必要があります。マテリアル設定だけでは、任意のカスタムシェーダーロジックは挿入されません。
- アルファブレンディングが必要な場合は、深度書き込みとソートを意図的に処理してください。デフォルトでは、インスタンスは個別に深度ソートされません。
- シャドウパスやオクルージョンパスでも、葉の切り抜きと風による変形を反映してください。コストやアーティファクトが視覚的な効果を上回る場合は、葉のシャドウキャストを無効にしてください。
- 季節の状態に応じて色調とアクティブな密度を切り替えます。季節ごとに新しいリーフシステムを割り当てないでください。
検証する
葉が1枚、回転しながら落下し、落下サイクルを最後まで完了する様子を確認します。表面と裏面に違いがあること、端が薄くなること、リセットが見えないことを確かめてください。横に歩き、向きを変え、見上げ、部屋に入り、タブを非表示にした後で再開します。狭いビューポートと広いビューポート、最終トーンマッパーを通した状態、そして合成された状態で動きを停止するモーション軽減設定で、フィールドを確認してください。パーティクルは無料だと決めつけず、オーバードローと更新コストを測定します。
リファレンス実装については REFERENCES.md を参照してください。Seijaku の leafFall は閉形式のアニメーションパターンを提供しています。ハードコードされた屋根の矩形を、対象シーンのジオメトリまたはボリュームに置き換えてください。