scenario-godot-vfx について
scenario-godot-vfxは、Godot 4.7.2でエフェクトを制作・テストするエージェント向けスキルです。コードで2D・3Dのレイヤー構成を作り、パーティクル設定、キャプチャフレーム、レンダラーごとの挙動、性能予算を確認します。
主な機能
- 01弾道・爆発エフェクトのレイヤー構成
- 02パーティクル設定の監査
- 03レンダラー別のエフェクト段階
- 04時刻指定のフレームキャプチャ
- 05オーバードローとGPU時間の計測
- 06ライフサイクルと挙動のテスト
活用シーン
- 01弾道の軌跡や着弾エフェクトの制作
- 02複数のレンダラー向け爆発の構築
- 03暗黙に失敗するパーティクル設定の発見
- 04視覚的なタイミングと描画コストの確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-godot-vfxインストール後、Claude Code で/scenario-godot-vfxを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/gd_vfx.pyscripts/agentkit/vfx/fx_looper.gdvfx_audit.gdvfx_build.gdvfx_capture.gdvfx_jobs.gdvfx_recipes.gdvfx_selftest.gdscripts/agentkit/vfx/runtime/fx_burst.gdfx_projectile.gdjuice.gdscripts/agentkit/vfx/shaders/fx_erode_add.gdshaderfx_erode_mix.gdshaderfx_erode.gdshaderincfx_fire_head.gdshaderfx_smoke_lod.gdshaderfx_soft_core.gdshaderfx_trail_follow.gdshader詳細
Godot VFX
対象:Godot 4.7.2.stable、macOS Apple Silicon。
ここでいうエキスパートレベルとは、エフェクトが小さなシステムのレイヤーとして構築され、粒子の目立たない不具合はすべて誰かが気づく前にスクリプトで検出され、見た目やコストに関する主張は、正確な時刻にキャプチャしたフレームと、レンダラーごとに測定したオーバードローおよび GPU 時間で裏付けられていることを意味します。エージェントはコードでエフェクトを構築し、ウィンドウ表示でレンダリングし、コンタクトシートを確認します。ここで名前が挙がっている関連スキルが利用可能なスキルに含まれていない場合は、ユーザーにインストールを依頼してください
(npx skills add scenario-labs/skills --skill <name>)。無人で作業する場合は、ツールスキーマに基づいて続行し、不足しているスキルを明示してください。
必須の背景知識: scenario-godot-expert(gd_env、gd_run、gd_review、AgentKit、GD_MAX スロット、ウィンドウ表示とヘッドレスの違い)。
基本方針(エキスパートに求められる違い)
- エフェクトはレイヤーで構成し、飛翔体の先端は粒子ではありません。 飛翔体は先端、尾、火花で構成されます。先端はスクロールするノイズと 1 を超える HDR カラーを使ったシェーダーメッシュです(Le Lu 74XywaLGO5Q 00:00:34、00:08:05)。爆発は閃光、炎、煙、火花、破片、衝撃波、ライトで構成され、それぞれ動作するシステムを複製して、少数の値を変更して作る小さなシステムです(Brackeys htRjt505sPg 00:02:30、00:13:27)。衝撃波リングには、粒子システムを 1 つだけ使っても問題ありません(00:18:02)。
- 粒子の設定は不具合があっても警告なしに動作しなくなるため、コードで監査してください。
vertex_color_use_as_albedoがないとカラーとアルファのカーブは機能せず、billboard_keep_scaleがないと粒子ビルボードのスケールカーブは機能しません。トレイルにはtrail_enabled、Ribbon または Tube のトレイルメッシュ、use_particle_trailsが必要です(Godotneers cZ5Ang_Ji8E 00:09:44、00:32:54、Brackeys 00:23:44)。サブエミッター自身のamountはグローバル上限であり(Godotneers yKoGuBGZatY 00:44:48)、その AABB は継承されません(cZ5Ang_Ji8E 01:06:19)。vfx_audit.gdは、これらすべてにフラグを立てます。 visibility_aabbはカリング範囲であると同時に衝突範囲でもあります(Godotneers cZ5Ang_Ji8E 00:45:28)。推測せずに測定してください。4.7.2 ではcapture_aabb()は粒子の位置を描画メッシュの最長軸分だけ拡張し、粒子ごとのスケールは無視します(測定結果:Flash の 2 m のクアッドでは 4 m のボックスになり、4.5 m にスケールしたリングでは 2 m のままでした)[追加]。fit_aabbはスケールを補正しますが、レベル内で実行する必要があります。コライダーのない破片はワールド内を 8 m 落下するためです。amount_ratioではなく、レンダラーごとにティアを設定してください。amount_ratioは粒子を非表示にするだけで、何も節約しません(GPUParticles3D のドキュメント、Bonkahe BUa-mKHEPUM 00:01:18)。ティアごとにamountを減らし、レンダラーが描画できないレイヤーを削除してください。Compatibility ではデカールが警告なしで削除され、トレイルとサブエミッターについては警告がログに記録されます(測定結果)[追加]。- 粒子は物理演算に触れません。 ゲームプレイ上のヒット判定は、物理ティックごとにスイープするレイで行います。粒子の衝突には GPUParticlesCollision ノードが必要です。1 ティックあたりのステップは速度 / fixed_fps で、デフォルトの fixed_fps は 30 です(Godotneers cZ5Ang_Ji8E 00:44:23、00:47:17)。
- 演出はテスト可能なコードです。 ヒットストップでは
Engine.time_scaleを下げ、それを無視するタイマーで待機してから、1.0 に戻します(Mostly Mad Jwv9t5zFlqI 00:00:32、00:01:37)。シェイクには減衰を伴うスムーズノイズを使います(Mostly Mad pG4KGyxQp40 00:00:39)。トラウマの二乗と 3D カメラオフセットは[追加]です。 - インスペクターではなく、フレームで評価してください。
--fixed-fps 60を指定してウィンドウ表示でレンダリングすれば、フレーム k は t = k/60 s となります。0.03~2.2 s の範囲で確認し、レンダラーごとに 1 つのコンタクトシートを作成してください。オーバードローはレイヤーごとのキャリブレーションを測定したうえでDEBUG_DRAW_OVERDRAWから取得し、GPU 時間は Vulkan ドライバーから取得します(macOS では Metal は 0 を報告します)[追加]。 - ノードに追従するトレイルは、粒子シェーダーのテクニックです。 力は加えず、
start()とprocess()で粒子をEMISSION_TRANSFORM[3].xyzに固定します(Octodemy iPCzOe-S9EQ 00:05:42)。
最初に決めること
| 入力 | 変更内容 | デフォルト |
|---|---|---|
| 対象レンダラー | 存在するレイヤー(トレイル、デカール、サブエミッター) | Forward+ デスクトップ、モバイル端末、Compatibility ウェブ |
| 2D または 3D | ノードファミリー、コリジョン(LightOccluder2D と GPUParticlesCollision3D のどちらか) | 3D |
| カメラの距離と画面共有 | クアッドのサイズ、オーバードローの予算 | ゲームプレイカメラから 4〜10 m |
| VFX のフレーム予算 | ティアごとの量 | 開発用 Mac で 720p、6 回のバースト時に GPU が 2.5 ms 未満 [added] |
| 見た目 | シェーディングなしの加算合成と、ライティングありの煙のどちらか(Le Lu e_6ZA-xa_DQ 00:07:23) | スタイライズ調、シェーディングなしの炎、アルファブレンドの煙 |
| スポーンモデル | 完了時に解放するか、プールを使うか | fx_burst は自動で解放し、プールでは done シグナルを使用 |
ワークフロー
- プロジェクトとキット。 Base3D をクローンし、
gd_vfx.install(P)でツールをaddons/agentkit/vfx/に、 シェーダーとランタイムスクリプトをres://vfx/にコピーします(これらはゲームに同梱されます)。project.godotを読みます。 GATE:3d/physics_engine="Jolt Physics"と意図したrenderer/rendering_methodがテキストとして記述されていること、vfx_selftest.gd:compileで 10 個のスクリプトに対するエラーが 0 件と報告されること(check_allはaddons/agentkit/をスキップします)。 - コードでティアごとにビルド。
gd_vfx.build(P, "high"|"mobile"|"low")はvfx_recipes.gdからexplosion_、impact_、fireball_、shot_、burst_stage_<tier>.tscnを保存します。仕様は辞書(VB.emitter)です。 カーブとランプは CurveTexture と GradientTexture1D になり(チャンネルが 1 を超える場合は HDR)、 共有テクスチャはres://vfx/tex/*.tresに配置されます(Brackeys 00:15:04:埋め込みは決して行わないでください)。GATE:ビルドが成功し、捕捉されたエラーがないこと。キットの各レイヤー:fireball(fx_fire_headを使った引き伸ばした SphereMesh の先端、ノイズからグラデーションを引いた HDR、反転 Fresnel のfx_soft_core、INSTANCE_CUSTOM.yで制御するワールド空間の侵食されたパフ、onetupthree N9ilhL8JFes 00:05:38、速度スパーク、fx_trail_followと OmniLight3D によるリボン。どちらも low ではオフ);explosion(フラッシュ、炎、深度ソートされた煙、衝突するスパーク、Face-Y リング、high では 30 Hz の煙サブエミッターを備えた破片、ライト、low を除く焦げ跡 Decal);fx_projectile(毎ティック、レイでスイープし、ヒットした法線上に衝突エフェクトを表示し、トレイルが消えた後に自身を解放します)。 - 静的監査。
gd_vfx.audit(P, scene, tier, level)を実行します。GATE:該当するティアのエラーが 0 件であること。 警告を確認し、修正するか記録します。broken.tscnで問題を一度検出できることを証明します(検出 21 件、エラー 4 件)。 - コンテキスト内で AABB を調整。
gd_vfx.fit_aabb(P, "res://vfx/burst_stage_high.tscn", node="Explosion", play_method="Explosion:play", write=True, out=effect_scene)。 GATE:すべてのエミッターでold_encloses_liveが true であり、タイムラインのaabb_checkで範囲外が報告されないこと。 - レンダラーごとに確認。
gd_vfx.timeline(P, scene, times=[0.03,0.1,0.2,0.35,0.6,1.0,1.5,2.2], renderer=..., trigger="none", extra={"play_method": "Explosion:play", "aabb_check": True})を実行します。 弾丸ではextra={"hold": "Fireball"}を指定します。コンタクトシートを開きます。GATE:全黒、全白、または均一なフラグがないこと。目視で確認する内容:最初にフラッシュが見え、炎が煙に変わり、突然表示されるものがなく、リングが消え、スパークが床で跳ね、焦げ跡が残り、先端が炎として見え、その後ろに尾が続くこと。 - フォールバック。 Compatibility では、low ティア(リボン、デカール、ライト、サブエミッターなし)を使用するか、
CPUParticles3D 版の
gd_vfx.to_cpuを使います。GATE:lostリスト(衝突、サブエミッター、トレイル、パーティクルシェーダー、ランプにベイクされた alpha_curve、整列モード)を確認し、gl_compatibilityでその版をレンダリングすること。 - 予算。 ティアごとに
gd_vfx.overdraw(...)を実行し、gd_run.profile_scene(stress scene, size=(1280,720), driver="vulkan")を実行します。GATE:p99 レイヤー数と GPU p95 が以下の数値以内であり、low ティアが high より軽いこと。 - 動作。
vfx_selftest.gdを実行します:lifecycle(5 回生成後にノード数がベースラインに戻る)、projectile(ヒット 1 回、爆発を生成、すべて解放)、juice(time_scale が復元され、シェイクが上限内に収まり、0 に戻る)。GATE:すべて成功すること。
エキスパート向けチェックリスト(計画に明記)
- 成果物にコードをすべて含める:説明文ではなく、
vfx_recipes.gdの仕様とfx_fire_head.gdshaderを貼り付けてください。読者がキットを持っていない場合があります。 - 再生には
emitting = trueではなくrestart()を使ってください(ドキュメント)。 - 決定論的なフレーム:
use_fixed_seedを設定してから、speed_scale = 0、restart()、request_particles_process(t)の順に実行してください。0.4 秒への 2 回のシークはピクセル単位で完全に一致しました。固定シードを使わない場合は 0.50 の差が生じました(P13)。 - 1 つのシステムで炎から煙へ:プリマルチプライドブレンド(
BLEND_MODE_PREMULT_ALPHA、テクスチャは Premultiply Alpha を有効にしてインポート)を使います。低いアルファ値では加算され、高いアルファ値では混ざります。黒とアルファ 0 でフェードします(Brackeys 30:56~32:39)。グレー上で測定したところ、アルファ 0 では明るくなり、アルファ 1 では置き換わりました(P13)。 - 煙の LOD:
fx_smoke_lod.gdshaderは、黒から白へのカラーカーブを 1 つのノイズテクスチャの mip 0~8 に対応付けるため、パフはほぼコストをかけずに拡散します。色はユニフォームに移動します(Le Lu e_6ZA-xa_DQ 16:40~24:20)。ディテールの広がりは、3 つすべてのレンダラーで寿命にわたって 0.10 から 0.0 に減少しました(P13)。 - システムの複製:Brackeys の「テクスチャ以外は Make Unique Recursive」は、4.7.2 では
duplicate(true)に相当します。埋め込みカーブは固有になり、外部の.tresテクスチャは共有されたままです(P13)。メッシュは共有し、マテリアルはmaterial_overrideに保持してください(Brackeys 13:59~15:04)。 - ビルボードと方向の組み合わせ:Align Y はビルボードと競合します。
transform_alignで Z を Billboard、Y を Velocity に設定してください(Brackeys 27:07)。 - 重ねた透明オブジェクトのちらつき:まずノードをオフセットし、その後に
sorting_offsetを設定してください(Brackeys 29:57)。 - TAA のゴースト:
DRAW_ORDER_INDEX(3D のデフォルト)のみがモーションベクターを使用します。不透明なパーティクルにはこれを使い続けてください(ドキュメント)。 - Preprocess は、前処理する秒数に
fixed_fpsを掛けた回数だけシェーダーを実行するため、GPU が停止することがあります。ワンショットでは絶対に使わないでください(ドキュメント、preprocess_one_shotの監査)。 - カメラに近いクアッド:
distance_fade_modeの Pixel Alpha は深度を読み取らずに距離に応じてフェードします。近接フェードは交差部分を柔らかくします。
数値
| 値 | 比較対象 | 出典 |
|---|---|---|
| 頭部の HDR カラー(2, 1.3, 0.6);火花(2, 1.3, 0.5);火花の寿命 0.3 s | グローのしきい値 1.0 | Le Lu 00:08:05, 00:28:15 |
| 頭部の描画優先度はコアの 1 より高い 2;反転 Fresnel の累乗 4~5 | 入れ子の透明メッシュ | Le Lu 00:18:25 |
| 衝撃波:パーティクル 1 個、0.4~0.5 s | 1 回限りのバースト | Brackeys 00:18:34 |
| トンネルのステップ = v_max / fixed_fps;fixed_fps はデフォルトで 30 | 最も薄いコライダー | Godotneers 00:47:17, docs |
collision_base_size のデフォルト値は 0.01 m | パーティクルの表示サイズ | Godotneers 00:57:27 |
子の amount は、親の amount x イベントごとの数(AT_END、AT_COLLISION、AT_START)以上;CONSTANT モード:親の amount x Hz x 子の寿命 | サブエミッターの上限 | Godotneers 00:44:48(イベントごと);CONSTANT は導出 [追加]、どちらも link_sub_emitter 内 |
sub_emitter_frequency の単位は Hz:1 m/s では、点が 1/f m 間隔で並びます | 実測値 4 および 10 Hz | live V10 |
| レイヤーごとのオーバードロー:0.070 リニア輝度(Forward+、Mobile);36.6/255 生値(Compatibility、6 を超えると飽和) | DEBUG_DRAW_OVERDRAW PNG | live V11 [追加] |
| 0.6 s のピーク時の爆発の p99 レイヤー数:高 4.9~5.9、低 2.3~3.3(シードによって変動) | 約 5 m からの 640x360 表示 | live V11、3 回実行 |
| GPU p95、1280x720、Vulkan 経由の M5 Max、ほかの Godot ジョブと共用のマシン:ステージ単独 1.0~2.3 ms;6 つのループする爆発:高 3.4~4.0、モバイルティア 2.1~2.7、低 1.2 ms | フレーム | live V12、3 回実行 |
| パーティクル数、爆発 / 火球:高 208 / 57、モバイル 48 / 35、低 34 / 22 | ティアの倍率 1.0 / 0.6 / 0.4 | kit [追加] |
| ヒットストップ:時間スケール 0.05 を 0.08 s;トラウマ 1 のとき、シェイク 0.30 x 0.22 m、減衰 1.8/s | カメラ | [追加]、Mostly Mad の注記にある一般的な範囲 |
| Forward+ で中間グレーにする煙のランプは約 0.06 リニア;Compatibility では x3.6 | 同じフレーム | live V5 [追加] |
品質ゲート
測定可能な項目:
- 監査:対象ティアのエラーが0件。キットのコンパイル:解析エラーが0件。プロジェクトファイルにJoltと選択したレンダラーが含まれています。
- AABB:すべてのエミッターの稼働中のボックスが、すべてのキャプチャ時刻で
visibility_aabb内に収まっています。 - ライフサイクル:N回スポーンした後のノード数がベースラインと一致し、安全タイムアウトなしで
doneがN回発火します。 - 投射物:想定時刻に
hitが1回発生します(12 mを14 m/sで進む場合は0.867 s、52フレーム)。ツリー内に何も残りません。 - 演出効果:単独および重複した停止後に
Engine.time_scaleが1.0になり、早期に復元されません。シェイクのオフセットは最大値以下で、終了時に正確に0になります。 - 各ティアのオーバードローp99とGPU p95が表の基準を満たします。互換性ログには想定される警告が記録され、想定外の警告はありません。
ビジュアル(1600 px以下のコンタクトシート。評価基準はreferences/critique.md):フラッシュ、炎、煙の順に表示され、ポップがなく、ゲームプレイ時の距離でもシルエットが読み取りやすく、リングがフェードし、火花が跳ね、トレイルが先端に追従し、爆発が表面の法線に向き、各ティアがそれぞれのレンダラーで見栄えよく表示されます。
よくある間違い
| 間違い | 見え方 | 修正 |
|---|---|---|
| 頂点カラーがオフ | 白い四角形が表示され、カーブが無視されます | vertex_color_use_as_albedo |
| パーティクルのビルボードでスケール維持がオフ | スケールカーブが無視されます | billboard_keep_scale |
use_particle_trailsなしのトレイル | 途切れた平らな断片になります | トレイルメッシュのマテリアルで有効にします |
| 子の量が上限未満 | サブエミッターのトレイルが薄くなります | link_sub_emitterで上限を算出します |
| デフォルトの8 m AABB | エフェクトが途中で消え、コリジョンが停止します | レベル内でfit_aabbを使用します |
collision_base_sizeがスポーン高度より大きい | デブリが原点に留まります(実測:10~12 mではなく0.5 mしか移動しません) | コライダーより上でスポーンします |
モバイルティアとしてamount_ratioを使用 | パフォーマンスが改善しません | amountを下げます |
リプレイにemitting = trueを使用 | ワンショットがときどきスキップされます | restart()を使用します(ドキュメントを参照) |
| ヒット時に投射物を解放する | ワールド空間のトレイルがすぐに消えます | エミッターを停止し、トレイルが消えるのを待ってから解放します |
ビュー深度ソートでconvert_from_particlesを使用 | 「Index p_order = 3 is out of bounds」と表示され、ソートが失われます | VB.to_cpuで描画順をマッピングします |
| すべてのレンダラーで同じ色を使用 | Compatibilityで煙がほぼ黒くなります | Compatibility向けに低ティアを再調整します |
| Metalでプロファイリング | gpu_msが0になります | driver="vulkan" |
引き継ぎ
- 受け取るもの:scenario-godot-gameplay からヒットイベント(位置、法線、プーリング)、scenario-godot-performance-export から予算、scenario-godot-rendering-lighting からグローと環境を受け取ります。
- 提供するもの:ティアごとの
res://vfx/*.tscn、res://vfx/shadersとruntime(fx_burst、fx_projectile、Juice)、監査用 JSON、シート、オーバードローと GPU のテーブルを提供します。 - 依頼するもの:新しいサーフェスシェーダー(ディゾルブ、水、ディストーション)は scenario-godot-shaders に、衝撃音は scenario-godot-audio に、2D エフェクトの統合は scenario-godot-2d に依頼します。
Godot 4.7 に関する注意点
capture_aabb()は描画メッシュの最長軸に合わせて余白を追加し、パーティクルのスケールを無視します(4.7.2、実測)。CPUParticles3D.convert_from_particlesはdraw_orderを整数値のままコピーしますが、列挙値は異なります。GPU のビュー深度は 3、CPU のビュー深度は 2 です。CPUParticles3D にはalpha_curveがありません(4.7.2、実測)。- Compatibility では「Particle trails are only available when using the Forward+ or Mobile renderer」と「does not support particle sub-emitters」というログが出ます。デカールは警告なしで消えます。
- ヘッドレスでは何も描画されないため、キャプチャにはウィンドウ表示での実行が必要です。macOS では Metal が GPU 時間を 0 として報告するため、
--rendering-driver vulkanを使用してください。 - 4.4 以降、Curve は
min_valueとmax_valueを適用するため、1 を超えるスケールカーブでは範囲を広げてください。AgX は 4.4 で導入されました。Glow のデフォルト値は 4.6 で変更されています(強度が 0.8 から 0.3 に変更)。古いエフェクトは再調整してください。 - パーティクルシェーダーでは
start()とprocess()を使用します。VELOCITYに書き込む Godot 3 のvertex()は失敗します。 - トレイルセクションの更新バグ(Octodemy、4.7 世代)と Godotneers の 4.2 のトレイルおよび SDF のバグは、まだ 4.7.2 で実行していません。
参考資料
references/procedures.md(P1~P13、呼び出し、コード、実行結果)、expert-notes.md(タイムスタンプ付きの原則)、critique.md(評価基準)、gui-paths.md(エディター内のパス)、sources.md(ソースとタイムスタンプ)。scripts/gd_vfx.py:インストール、ビルド、監査、タイムライン、オーバードロー、fit_aabb、to_cpu、計算処理。scripts/agentkit/vfx/:vfx_build、vfx_recipes、vfx_audit、vfx_capture、vfx_jobs、vfx_selftest。shaders/(fx_smoke_lodを含む)とruntime/はゲームに同梱されています。