scenario-godot-shaders について
Godot 4.7.2を使うテクニカルアーティストやコーディングエージェント向けのシェーダースキルです。複数レンダラーでのコンパイルと描画、パラメーター検証、GPUコスト測定を通じてシェーダーを確認します。
主な機能
- 01レンダラー別のシェーダー検査とコンパイル
- 02シーン要素への描画テスト
- 03パラメーター掃引とコンタクトシート確認
- 04マテリアル基準とのGPUコスト比較
- 05VisualShaderグラフとコンピュート処理の構築
活用シーン
- 01対象レンダラーごとのシェーダー検証
- 02水面、ディゾルブ、ポストエフェクトの確認
- 03StandardMaterial3D基準での効果測定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-godot-shadersインストール後、Claude Code で/scenario-godot-shadersを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/gd_shaders.pyscripts/agentkit/shaders/dissolve_swap.gddissolve.gdshaderfullscreen_depth.gdshadergame_time.gdhit_flash.gdshaderportal_reader.gdshaderportal_writer.gdshadershader_tools.gdsky_toon.gdshaderwater_common.gdshaderincwater_lite.gdshaderwater_stylized.gdshaderscripts/agentkit/shaders/examples/animate_instance_uniform.gdbuild_dissolve_scene.gdbuild_flash_scene.gdbuild_fx_scenes.gdbuild_global_scene.gdbuild_visual_shader.gdbuild_water_scene.gdcompile_probe.gdcompute_texture.gdfullscreen_old_trap.gdshader.txtrender_probe.gdvs_ports.gd詳細
Godot シェーダー(テクニカルアーティスト、シェーディング)
対象:Godot 4.7.2.stable、macOS Apple Silicon(デフォルトでは Metal、GPU のタイミング計測には MoltenVK 経由の Vulkan を使用)。
ここでいうエキスパートレベルとは、すべてのシェーダーをエージェントが差分比較できるテキストとして扱い、各対象レンダラーでコンパイルし、ウィンドウ内の実際のメッシュに描画し、パラメーターを変化させてコンタクトシートで確認し、StandardMaterial3D をベースラインとして GPU コストを計測することです。コンパイルできても、動作するとは限りません。4.7.2 ではバックエンドが描画する段階で初めて現れる失敗が複数あり、エラーがまったく発生しないバグもいくつかあります。ここで名前を挙げた関連スキルが利用可能なスキルにない場合は、ユーザーにインストールを依頼してください(npx skills add scenario-labs/skills --skill <name>)。無人で進める場合は、ツールのスキーマに基づいて作業し、スキルが不足していることを明記してください。
必須の事前知識: scenario-godot-expert(チャネル、gd_run、レビューの反復プロセス、4.7 の注意点)。
方針(専門知識による差分)
- まずコード、グラフは必要に応じて。 テキストシェーダーなら、ループ、関数、
#includeを使え、差分もすっきりします(Godotneers、Shaderland [01:10:09]、VisualShader の不足点についての Daniel Ilett)。人間がグラフを必要とする場合は、コードで VisualShader を構築し(add_node、connect_nodes、計算用の Expression ノード)、.tresとして保存します。ポート名は GDScript から参照できないため、出力インデックスはハードコードし、get_code()を読んで確認します[追加、2026-10-02 に実行]。 - ヘッドレスでコンパイルしてから、ウィンドウ表示で描画する。 ヘッドレスでの
get_shader_uniform_list()は、--rendering-methodごとに約 0.4 秒で言語エラーを検出します。オペークパスでのステンシル読み取りと、Compatibility のみで使うフォグシェーダーは、ウィンドウで描画して初めて失敗します。初期化されていないローカル変数と、片方の分岐でのみ書き込まれるDEPTHは、まったく失敗しないため、リンターで確認します[追加、2026-10-02 に実行]。 - メッシュ UV よりワールド空間またはオブジェクト空間を使う。 ディゾルブ、風、水、トライプラナー効果はオブジェクト空間またはワールド空間の座標を基準にすると、継ぎ目や UV の伸びがなくなります(StayAtHomeDev のディゾルブ [00:09:59]、DevPoodle のトライプラナー、Dylearn の草)。マテリアルを共有する場合は、オブジェクトごとの値(境界、量)を
instance uniformに設定します。設定しないと、各メッシュのディゾルブの高さが正しくなりません[追加]。 - 滑らない水。 継ぎ目のないセルラーノイズを 2 つコピーしてパンし、乗算して 1.25 乗し、
vertex()とfragment()の両方で共有すると、波頭が波の頂上に位置します(Bramwell [00:11:57 to 00:20:57])。トゥーンのバンドはハイブリッド方式にし、各境界付近でのみ smoothstep を使うことで、バンドのちらつきを防ぎます(Dylearn [00:13:42])。岸辺の泡は、深度テクスチャから逆 Z の式で再構成した垂直方向の深度を使って生成します[追加]。 - HDR のエッジには 3 つの要素を組み合わせる必要があります。 1.0 を超える色、EMISSION 出力、WorldEnvironment の Glow です(StayAtHomeDev [00:07:36]、Daniel Ilett [00:10:22]、Pixezy [00:06:55])。
- マテリアルが透明パスに移る条件を把握する。
ALPHAへの書き込み、または画面や深度テクスチャの読み取りによって、マテリアルは透明パスに移ります。シャドウとソートが失われ、ほかの画面読み取りマテリアルからも見えなくなります(ドキュメント)。ディゾルブにはALPHA_SCISSOR_THRESHOLDを使います。マテリアルはオペークのままで、シャドウもディゾルブします。スキッサーもアルファテストであり、discardと同様に、そのメッシュでは early-Z が無効になります(ドキュメント)。そのため、特にモバイルのタイル型 GPU ではコストが大きく、効果を使うときだけディゾルブマテリアルに切り替えます(P18)。ステンシルの読み取り側は透明である必要があり、書き込み側より高いrender_priorityを設定します(LowQualityCoding [00:07:35])。 - コンピュート:画面上ではメインデバイスを使う。 Texture2DRD では、
RenderingServer.call_on_render_thread内でメイン RenderingDevice を使い、submit や sync は行いません(The Pathfinders Codex [00:03:07])。結果を CPU に戻すには、ローカルデバイスを使い、すべての RID を解放して、CPU 版と同等の結果になるかテストします(DevPoodle [00:02:21]、Crigz [00:11:24])。 - ウィンドウ表示でエクスポートしてシェーダーをベイクする。 シェーダーベーカーは、エクスポートプロセスにレンダリングデバイスがある場合にのみ実行されます。
shader_baker/enabled=trueを指定した--headlessエクスポートでは、追加分が何も含まれず、警告も表示されません[追加、2026-10-02 に実行]。
まず決めること
- 対象レンダラー: Forward+(デスクトップ)、Mobile(スマートフォン)、Compatibility(Web、旧型 GPU)。それぞれで使用可能なヒントやステージが異なります。デフォルト:Forward+ と、名前付きのフォールバックを 1 つ。
- スタイル: トゥーン、PBR、またはピクセルアート。バンド数、アウトライン方式(ステンシルまたは反転ハル)、Glow を有効にするかどうかを決めます。
- 予算: StandardMaterial3D を基準とした、効果ごとの GPU ms。デフォルト:この Mac で 1080p の主要な効果が +0.5 ms 未満であることを、実機で確認します。
- 編集者: エージェント(テキスト)か、人間のアーティストも含むか(ヒント付きでグループ化した uniform を使う VisualShader
.tres)。 - マテリアルを共有するか、一意にするか: インスタンスごとの値に応じて、インスタンス uniform(最大 16 個、テクスチャ不可)、一意のマテリアル、グローバルのいずれかを選びます。
ワークフロー
- インストールして lint を実行します。
gd_shaders.install(project)はテンプレートをres://shaders/に、ツールをaddons/agentkit/shaders/にコピーします。次にgd_shaders.lint(path, renderers, project=P)を実行します。GATE:errorの指摘がないこと。すべてのwarnを修正するか、妥当な理由を示すこと。 - レンダラーごとにコンパイルします。
gd_shaders.compile_matrix(P, root="res://shaders/")を実行します。GATE:各対象レンダラーで、failedリストが空の状態でokになること。 - レンダラーごとに一度描画します。
gd_shaders.draw_check(P, files)は各シェーダーを、描画対象のメッシュ、キャンバスアイテム、空、パーティクルシステム、またはフォグボリュームに適用します。GATE:各実行でshader_errorsとengine_errorsがゼロであること。 - コードでテストシーンを構築します。 カメラ、ライト、Environment を明示的に設定した
.tscnを保存するジョブを作成します。AgX を使い、ブリーフの指示に従って Glow をオンまたはオフにします。水の場合は、水面を横切る地面と、その上下にオブジェクトが必要です。ディゾルブの場合は、サイズと回転が異なるメッシュを少なくとも3つ用意します。GATE:シーンがヘッドレスでokの状態で読み込まれ、project.godot のレンダラー設定と Jolt 設定を確認済みであること。 - 範囲を変えて確認します。
gd_shaders.param_sweep(P, scene, shots=...)をshader、instance、global、またはpropの種類で実行します。コンタクトシートを開きます。GATE:changesが想定どおりに動作すること(単調に進むディゾルブ、移動するフェーズなど)。また、コンタクトシートのすべてのショットで意図した見た目になっていること。 - レンダラーを比較します。
gd_shaders.renderer_captures(P, scene)を実行します。GATE:各対象レンダラーで見た目が維持されること。既知の差異を記録すること(同じ Environment でも Compatibility はより明るく、彩度が高く描画されます)。 - コストを確認します。 Vulkan、1080p で
gd_shaders.cost_compare(P, {"standard": ..., "hq": ..., "lite": ...})を実行します。GATE:ベースラインとの差が予算内であること。モバイルの数値には「desktop proxy」と記します。 - 出荷します。
shader_baker/enabled=trueを設定した macOS または対象プラットフォームのプリセットを追加します。ウィンドウプロセスから一度エクスポートします(procedures.md P14 を参照)。GATE:ログに「Baking shaders (N steps)」と表示され、パックのサイズが増えること。グローバル uniform が不足している場合、ここでエラーになります。
補足手順:
- 人間のアーティスト向け VisualShader(P9):Expression ノードを使ってグラフをコードで構築し、
.tresとして保存します。shader_tools.gd:visual_shaderで読み戻すと、生成されたコード、ノード数、uniform が返されます。その後、テキストシェーダーと同様に範囲を変えて確認します。GATE:生成されたコードに、想定される出力代入がすべて含まれていること。 - Compute(P12、P13):CPU との一致確認には
compute_probeをウィンドウ表示で実行します。画面上に出力するには Texture2DRD ジョブを使います。GATE:不一致がゼロで、RID のリークがなく、フレームが変化すること。 - Globals(P11):
register_globalでグローバルを登録します(エディターの複数行形式で書き込みます)。実行中の値はRenderingServer.global_shader_parameter_setで設定し、コピーをオートロードに保持します。getter はレンダースレッドを停止させます(ドキュメントを参照)。実行時のProjectSettings.set_settingではグローバルは登録されません。 - パラメーターのアニメーション: Tween または
instance_shader_parameters/dissolve_amountの AnimationPlayer トラックでインスタンス uniform を制御します。shader_parameter/<name>はマテリアル uniform を制御します(P8)。
専門家向けチェックリスト(計画に明記してください)
- 成果物にはコードを完全に含めます。 テンプレート全体
(
dissolve.gdshader、water_stylized.gdshaderとそのインクルードファイル) とセットアップスクリプトを貼り付けます。読者がキットを持っていない場合があるためです。 source_colorはすべての色のユニフォームとカラーサンプラーに指定し、法線、粗さ、マスク データには指定しません(lintルールsource_color)。- ユニフォームの予算はモバイルで 16,384 B です。vec3 は 16 B にパディングされます。大きな配列はテクスチャに格納します(
lintルールuniform_budget)。 TIMEは 3,600 s で折り返し、ポーズ中も進み続けます(ドキュメント)。ポーズ可能な動きには、game_time.gdのオートロード(P18)が書き込むglobal uniform float game_timeを使用します。- ディゾルブの境界。 ワールド空間ではメッシュの移動やスケーリングで破綻します。StayAtHomeDev は
@toolスクリプトから AABB の最小値と最大値を渡します(pIwQ 09:59 から 12:52)。このテンプレートではオブジェクト空間と、 メッシュごとのinstance uniform vec2 boundsを使い、移動、スケーリング、共有を行っても機能します。 - エフェクトに差し替えます。
dissolve_swap.gd:swap_in(mi, mat)はサーフェスごとに複製を 1 つ配置し (各サーフェスのアルベドカラーとテクスチャを維持)、restore用に元のものを返します(P18)。 - ソート。
depth_prepass_alphaとcull_disabledの組み合わせで、透明オブジェクトのソートアーティファクトを修正し、シャドウも維持します(pIwQ 00:01:00)。 LIGHT_VERTEX(4.3)は、VERTEXに触れずにライティング対象の位置を移動します。たとえば、ピクセルアート風の段階的なライティングのためにグリッドにスナップできます(Dylearn 00:01:25)。3 つすべてのレンダラーで描画されます(P18)。- アウトライン。 高密度メッシュには BaseMaterial3D の
stencil_modeアウトラインを、それ以外には反転ハルを使う次のパスを使用します(Daniel Ilett 15:18)。
数値
| 値 | 数値 | 比較対象 |
|---|---|---|
| ヘッドレスコンパイル、3つのレンダラー、11個のシェーダー | 1.3 s | M5 Max、実行日 2026-10-02 |
| 最初のウィンドウ描画(パイプライン構築) | Metal 7.5 s、Mobile 5.3 s、Compat 1.6 s | キャッシュなし、同じプローブセット |
| 1080pでの水のGPU p50 | 標準 2.9〜3.2 ms、HQ 3.4〜3.5、LITE 3.0〜3.1 | Vulkan、3回実行、フレーム全体 |
| HQの水(屈折)のベースライン比 | +0.35〜0.5 ms | 同じシーン、StandardMaterial3Dの水 |
| ユニフォームバッファ | デスクトップ 65,536 B、モバイル 16,384 B;vec3は16 Bにパディング | 公式ドキュメント |
| シェーダーあたりのインスタンスユニフォーム | 16、サンプラーと配列は不可 | ドキュメント、サンプラーはコンパイラーに拒否される |
| 水のノイズ | 2つのパンの積、pow 1.25 | Bramwell |
| ディゾルブのエッジ | 幅 0.06、発光 x6、Glowを有効化 | テンプレートのデフォルト値 [追加] |
| コンピュート、100万個のfloat、送信+同期 | Metal 1.2 ms、Vulkan 1.9〜2.4 ms | ローカルRD、ウィンドウ表示 |
| シェーダーベイカー、このプロジェクト | 709ステップ、パック 4.9 MBから18.3 MB、初回ベイク19 s、以降4〜12 s | ウィンドウ表示でのエクスポート、XcodeツールなしではMetalはSPIR-Vに制限 |
TIME | 3,600 sで一周し、一時停止を無視 | ドキュメント |
| シェーダー駆動のロックステップ | GPUベンダー間で約60,000フレーム後に1ピクセルずれた | Leszek Nowak [00:23:39] |
品質ゲート
- 測定可能:
lintにエラーがないこと;compile_matrixとdraw_checkで、対象レンダラーごとのシェーダーエラーが0件であること;スイープのchangesが意図と一致すること(最初のショットでは0、ディゾルブでは単調増加、移動フェーズでは0.005超);ピクセルプローブが期待される色に当たること;cost_compareが予算内であること;コンピュートでmismatches == 0かつleaksがないこと;ベイカーログにステップ数が表示されること。 - 視覚的(シートを開いて確認):
- 水:深度ランプ、すべての岸辺のフォームリング、動く波紋、タイル状のスクロールがないこと、水中のオブジェクトには色が付き、乾いた岩には色が付かないこと;
- ディゾルブ:エッジがノイズに沿って発光し、影も切り取られること;amountが1のときに残りがないこと;各メッシュが個別にディゾルブすること;
- ポストエフェクト:カメラを向けたときに画面全体を覆うこと;
- ステンシル:滑らかなメッシュで輪郭が途切れないこと;
- 空:バンドと太陽の円盤が、
LIGHT0_DIRECTIONの示す位置にあること。
よくある間違い
| 間違い | 症状 | 修正方法 |
|---|---|---|
Godot 3 の名前(SCREEN_TEXTURE、hint_color、WORLD_MATRIX) | コンパイルエラーが発生し、メッセージに使用すべき uniform の名前が表示されます | hinted uniforms と MODEL_MATRIX を使用します。lint の godot3 ルールを使います |
POSITION = vec4(VERTEX, 1.0) を使った全画面クワッド | Forward+ と Mobile では、エフェクトが空にしか表示されません。Compatibility では問題が隠れます | vec4(VERTEX.xy, 1.0, 1.0)、flip_faces クワッド、extra_cull_margin 16384 を使います |
canvas_item での texture(TEXTURE, UV) * COLOR | スプライトが暗くなります(チャンネル値が 54 から 11 になります) | COLOR にはすでにテクスチャと modulate を掛けた値が含まれています |
[shader_globals] にない Global uniform | 実行時にエラーなくコンパイルされ、別の Global の値を読み取ります。ベイカーとエディターはこれを報告します | シェーダーを保存する前に gd_shaders.register_global を実行します |
.gdshader の #include | 「Unknown character #35」 | .gdshaderinc のみを include します |
| 不透明マテリアルでのステンシル読み取り | 描画時に「reads stencil but is not in the alpha queue」と表示され、何もマスクされません | ALPHA を書き込みます(または深度描画か深度テストを無効にします)。render_priority を上げます |
| ボックスでのステンシルアウトライン | 角でアウトラインが崩れます(法線が分割されています) | 高密度で滑らかなメッシュ、または反転したハルを使います |
1 つの bounds を使った共有 dissolve マテリアル | 小さなメッシュはすぐに消え、大きなメッシュは最後まで消えません | メッシュごとに instance uniform vec2 bounds を使います |
ミップマップフィルターなしでの、画面テクスチャに対する textureLod | ぼかしがシャープなままです | filter_linear_mipmap を使います |
Mobile または Compatibility での hint_normal_roughness_texture | そのレンダラーでコンパイルエラーが発生します | Forward+ のみで使用するか、#if CURRENT_RENDERER 分岐を使います |
シェーダーベイカーを有効にした状態での --headless エクスポート | パックサイズが変わらず、ログ行も出力されません | ウィンドウ表示のプロセスからエクスポートします |
デフォルト値のままの shader_parameter/x に対する Tween | 「Type mismatch ... Nil and float」と表示され、Tween が完了しません | Tween の前に一度 set_shader_parameter を実行します(未設定の値は null を返します) |
| キャプチャフレーム数からの動きの測定 | フレーム間で水が止まっているように見えます | 位相オフセットとして wave_speed をスイープします |
ゲームプレイと同期する動きに TIME を使用 | ポーズメニューでもスクロールし続けます | オートロードの game_time グローバルを使います(P18) |
引き継ぎ
- 受け取るもの: renderer、Environment、Compositor のニーズ(scenario-godot-rendering-lighting); パーティクルとカードのシェーダー(scenario-godot-vfx);スプライトエフェクト(scenario-godot-2d);タイル可能なマップ (scenario-textures)。
- 提供するもの:
.gdshader、.gdshaderinc、VisualShader.tresファイル、ShaderMaterial のセットアップ コード、範囲を含むインスタンスおよびグローバルユニフォーム名、スイープシート、コスト表。 - 引き継ぎ先: scenario-godot-performance-export(スタッター、CI でのベイキング、デバイスのタイミング計測);
scenario-godot-animation(
instance_shader_parameters/<name>上のトラック); scenario-godot-rendering-lighting(CompositorEffect 用の全画面エフェクト)。
Godot 4.7 の注意点
- 4.3 以降は深度が逆転しています(Forward+ および Mobile)。Compatibility では OpenGL の深度を維持します。NDC の式には
#if CURRENT_RENDERER == RENDERER_COMPATIBILITY(4.4 以降)を使用してください。 - ステンシル(4.5、引き続き実験的):シェーダーの
stencil_modeと、BaseMaterial3D のstencil_modeプリセット(輪郭、X 線)を使用します。これらは独自のnext_passを作成します。これらは 4.7.2 の Forward+ と Compatibility で動作します。 - シェーダーベイカー(4.5):エクスポートオプションです。ユーバーシェーダー(4.4)によって残りのスタッターを軽減します。
- Texture2DRD(4.2)と
texture_get_data_async(4.4)は現行機能です。 - 4.8 以降の変更点は対象外です。実験的とされているステンシルの構文を再確認してください。
参考資料
references/expert-notes.md(専門家による原則、タイムスタンプ、 4.7.2 での観察結果)、procedures.md(P1 から P18、コード、テスト、 結果)、critique.md(評価基準)、gui-paths.md(エディターのパス)、sources.md(ソースとタイムスタンプ)。scripts/gd_shaders.py:インストール、リント、ユニフォームと予算、グローバル変数、 compile_matrix、draw_check、param_sweep、renderer_captures、cost_compare。scripts/agentkit/shaders/:shader_tools.gd、dissolve_swap.gd、game_time.gd、およびテンプレート (水 HQ と LITE、ディゾルブ、fullscreen_depth、ポータルの書き込み側と読み取り側、sky_toon、hit_flash)。