mcpField
S
scenario-godot-shaders

scenario-godot-shaders

github.com/scenario-labs开发1.2k165 次安装1 天前更新
代码仓库

关于 scenario-godot-shaders

面向使用 Godot 4.7.2 的技术美术和编码 Agent 的着色器技能。它通过多渲染器编译与绘制测试、参数扫描和 GPU 成本测量来验证着色器。

主要功能

  1. 01按渲染器检查并编译着色器
  2. 02在场景元素上绘制测试
  3. 03扫描参数并查看联系表
  4. 04与材质基准比较 GPU 成本
  5. 05构建 VisualShader 图与计算流程

适用场景

  1. 01验证着色器在目标渲染器上的表现
  2. 02检查水面、溶解或后处理效果
  3. 03将效果与 StandardMaterial3D 基准比较成本

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/scenario-labs/skills --skill scenario-godot-shaders

安装后在 Claude Code 中输入/scenario-godot-shaders确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
critique.md
expert-notes.md
gui-paths.md
procedures.md
sources.md
scripts/
gd_shaders.py
scripts/agentkit/shaders/
dissolve_swap.gd
dissolve.gdshader
fullscreen_depth.gdshader
game_time.gd
hit_flash.gdshader
portal_reader.gdshader
portal_writer.gdshader
shader_tools.gd
sky_toon.gdshader
water_common.gdshaderinc
water_lite.gdshader
water_stylized.gdshader
scripts/agentkit/shaders/examples/
animate_instance_uniform.gd
build_dissolve_scene.gd
build_flash_scene.gd
build_fx_scenes.gd
build_global_scene.gd
build_visual_shader.gd
build_water_scene.gd
compile_probe.gd
compute_texture.gd
fullscreen_old_trap.gdshader.txt
render_probe.gd
vs_ports.gd

详细介绍

Godot 着色器(技术美术、着色)

目标:Godot 4.7.2.stable,macOS Apple Silicon(默认使用 Metal,通过 MoltenVK 使用 Vulkan 进行 GPU 计时)。

此处的专家级要求是:每个着色器都是 Agent 可比较差异的文本;在每种目标渲染器下编译,在窗口中绘制到真实网格上,对其参数进行遍历并整理成联系表,并将其 GPU 开销与 StandardMaterial3D 基准进行比较。编译成功不代表能正常工作:有些 4.7.2 故障只会在后端绘制时出现,还有些错误完全不会报错。如果这里提到的同级技能不在你可用的技能中,请让用户安装它(npx skills add scenario-labs/skills --skill <name>);若无法等待,请根据工具架构继续操作,并指出这一缺失。

必备背景: scenario-godot-expert(通道、gd_run、审查循环、4.7 陷阱)。

立场(专家差异)

  1. 优先写代码,按需使用图表。 文本着色器支持循环、函数、#include,差异也清晰 (Godotneers、Shaderland [01:10:09];Daniel Ilett 谈 VisualShader 的不足)。如果需要图表, 就用代码构建 VisualShader(add_node、connect_nodes,数学运算使用 Expression 节点), 并将其保存为 .tres;端口名称不会向 GDScript 暴露,因此输出索引需要硬编码,并通过读取 get_code() 检查 [新增,运行于 2026-10-02]。
  2. 先无头编译,再开窗绘制。 无头调用 get_shader_uniform_list(),可针对每个 --rendering-method 捕获语言错误,每个渲染器耗时约 0.4 s。透明通道中的模板缓冲区读取 和仅在 Compatibility 下使用的雾效着色器,只有窗口实际绘制时才会出错。未初始化的局部变量 以及只在一个分支中写入的 DEPTH 则完全不会报错,因此 Linter 会检查这些情况 [新增,运行于 2026-10-02]。
  3. 世界空间或对象空间优于网格 UV。 溶解、风、水和三平面效果应由对象空间或世界空间坐标 驱动,这样接缝和 UV 拉伸就会消失(StayAtHomeDev 溶解效果 [00:09:59]、DevPoodle 三平面、 Dylearn 草地)。对于共享材质,应将每个对象的值(边界、量)放入 instance uniform,否则 每个网格的溶解高度都会出错 [新增]。
  4. 水面不能滑动。 使用同一无缝细胞噪声的两个平移副本,将它们相乘,再提升到 1.25 次方, 并让 vertex() 和 fragment() 共用,这样波峰就会位于波浪顶部(Bramwell [00:11:57 至 00:20:57])。使用混合卡通色带,只在每个分界附近应用 smoothstep,这样色带就不会 闪烁(Dylearn [00:13:42])。岸边泡沫由垂直深度决定,该深度通过反向 Z 公式从深度纹理重建 [新增]。
  5. HDR 边缘需要同时具备三项条件: 高于 1.0 的颜色、EMISSION 输出,以及 WorldEnvironment 中的 Glow(StayAtHomeDev [00:07:36]、Daniel Ilett [00:10:22]、Pixezy [00:06:55])。
  6. 了解哪些操作会让材质进入透明通道。 写入 ALPHA 或读取屏幕或深度纹理,都会让材质进入 透明通道。它会失去阴影和排序,并且对其他读取屏幕的材质不可见(文档)。溶解效果使用 ALPHA_SCISSOR_THRESHOLD:材质会保持不透明,阴影也会随之溶解。Scissor 仍然是 alpha 测试: 与 discard 一样,它会让该网格无法使用 early-Z(文档);这在移动端 tile GPU 上代价最大, 因此仅在需要该效果时才切换溶解材质(P18)。模板缓冲区读取器必须是透明材质,且其 render_priority 高于写入器(LowQualityCoding [00:07:35])。
  7. Compute:用于屏幕显示时,留在主设备上。 Texture2DRD 需要在 RenderingServer.call_on_render_thread 内使用主 RenderingDevice,并且不要提交或同步 (The Pathfinders Codex [00:03:07])。若要将结果取回 CPU,应使用本地设备、释放每个 RID, 并与 CPU 版本进行一致性测试(DevPoodle [00:02:21]、Crigz [00:11:24])。
  8. 从有窗口的导出中烘焙着色器。 只有导出进程拥有渲染设备时,着色器烘焙器才会运行。使用 shader_baker/enabled=true 执行 --headless 导出时,不会报错,但也不会额外打包任何内容 [新增,运行于 2026-10-02]。

先确定

  • 目标渲染器: Forward+(桌面)、Mobile(手机)、Compatibility(网页、旧款 GPU);每种 渲染器支持的提示和阶段各不相同。默认:Forward+ 加一种命名的备用渲染器。
  • 风格: 卡通、PBR 或像素艺术。确定色带数量、描边方式(模板缓冲区或反转外壳),以及是否 启用 Glow。
  • 预算: 每种效果相对于 StandardMaterial3D 基准的 GPU 毫秒数。默认:在这台 Mac 上以 1080p 运行主打效果时,额外耗时低于 +0.5 ms,并在目标设备上确认。
  • 由谁编辑: Agent(文本),还是也由人类美术师编辑(VisualShader .tres、带提示的分组 uniform)。
  • 共享还是独立材质: 每个实例的值决定使用 instance uniforms(最多 16 个,不含纹理)、 独立材质还是全局变量。

工作流

  1. 安装并检查代码规范。 gd_shaders.install(project) 会将模板复制到 res://shaders/,并将工具复制到 addons/agentkit/shaders/。然后运行 gd_shaders.lint(path, renderers, project=P)。门槛:不得有 error 发现项;每个 warn 都必须修复或说明理由。
  2. 针对每个渲染器编译。 gd_shaders.compile_matrix(P, root="res://shaders/")。门槛:每个目标渲染器的结果均为 ok,且 failed 列表为空。
  3. 针对每个渲染器绘制一次。 gd_shaders.draw_check(P, files) 会将每个着色器应用到已绘制的网格、画布项、天空、粒子系统或雾体积上。门槛:每次运行的 shader_errors 和 engine_errors 均为 0。
  4. 用代码构建测试场景。 编写一个任务,保存包含摄像机、灯光和明确设置的 Environment 的 .tscn:根据需求设置 AgX 和 Glow 开或关。水效果需要有穿过水位的地面,以及位于水面上方和下方的物体。溶解效果至少需要三个大小和旋转角度各不相同的网格。门槛:场景以无头模式加载时结果为 ok,且已检查 project.godot 中的渲染器和 Jolt 设置。
  5. 扫描并查看效果。 运行 gd_shaders.param_sweep(P, scene, shots=...),使用 shader、instance、global 或 prop 类型。打开联系表。门槛:changes 的表现符合预期(例如溶解单调变化、相位移动),且每张截图都呈现预期效果。
  6. 比较渲染器。 运行 gd_shaders.renderer_captures(P, scene)。门槛:目标渲染器均能保持预期效果;记录已知差异(相同 Environment 下,Compatibility 渲染效果更亮、饱和度更高)。
  7. 成本。 在 Vulkan、1080p 下运行 gd_shaders.cost_compare(P, {"standard": ..., "hq": ..., "lite": ...})。门槛:与基线相比的差值在预算范围内;移动端数据标记为“desktop proxy”。
  8. 交付。 添加 macOS 或目标预设,并设置 shader_baker/enabled=true。通过窗口化进程导出一次(参见 procedures.md P14)。门槛:日志显示“Baking shaders (N steps)”,且包体增大。缺失的全局 uniform 会在此处显示为错误。

其他路径:

  • 供人类美术人员使用的 VisualShader(P9):使用 Expression 节点通过代码构建图,并将其保存为 .tres。使用 shader_tools.gd:visual_shader 读回,它会返回生成的代码、节点数和 uniform。然后像处理文本着色器一样扫描。门槛:生成的代码包含所有预期的输出赋值。
  • Compute(P12、P13):以窗口化模式运行 compute_probe,进行 CPU 一致性检查。使用 Texture2DRD 任务输出屏幕内容。门槛:不一致项为 0、无泄漏的 RID,且帧会发生变化。
  • 全局变量(P11):使用 register_global 注册全局变量(它会写入编辑器的多行格式)。使用 RenderingServer.global_shader_parameter_set 设置实时值,并在自动加载脚本中保存一份副本:getter 会阻塞渲染线程(参见文档)。运行时的 ProjectSettings.set_setting 不会注册全局变量。
  • 参数动画: Tween 或 AnimationPlayer 轨道上的 instance_shader_parameters/dissolve_amount 可驱动实例 uniform;shader_parameter/<name> 可驱动物料 uniform(P8)。

专家检查清单(在计划中说明这些内容)

  • 交付物中的完整代码。 粘贴完整模板 (dissolve.gdshader、 water_stylized.gdshader 及其 include) 和设置脚本:读者可能没有这套工具包。
  • 每个颜色 uniform 和颜色采样器都使用 source_color, 法线、粗糙度或蒙版 数据则不能使用(lint 规则 source_color)。
  • Uniform 预算: 移动端为 16,384 B,vec3 会填充到 16 B;大型数组应放入纹理(lint 规则 uniform_budget)。
  • TIME 每 3,600 s 回绕一次,并且暂停时仍会继续运行(文档):需要支持暂停的运动应由 game_time.gd 自动加载脚本写入的 global uniform float game_time 驱动(P18)。
  • 溶解边界。 网格移动或缩放时,世界空间方案会失效;StayAtHomeDev 使用 @tool 脚本传入 AABB 最小值和最大值(pIwQ 09:59 至 12:52)。模板使用对象空间,并为每个网格设置一个 instance uniform vec2 bounds, 因此在移动、缩放和共享时都能正常工作。
  • 替换为该效果。 dissolve_swap.gd:swap_in(mi, mat) 会为每个表面放置一个副本 (保留每个表面的反照率颜色和纹理),并返回原始材质供 restore 使用(P18)。
  • 排序。 depth_prepass_alpha 配合 cull_disabled 可修复透明排序问题,并保留阴影(pIwQ 00:01:00)。
  • LIGHT_VERTEX(4.3)可移动受光位置,例如将其吸附到网格以实现阶梯式像素艺术光照,且无需修改 VERTEX(Dylearn 00:01:25);该效果可在全部三种渲染器上绘制(P18)。
  • 轮廓。 在高密度网格上使用 BaseMaterial3D stencil_mode 轮廓;其他情况下使用反转外壳的 next pass(Daniel Ilett 15:18)。

数值

数值数值相对于
无头编译,3 个渲染器,11 个着色器1.3 秒M5 Max,运行于 2026-10-02
首次窗口化绘制(管线构建)Metal 7.5 秒,Mobile 5.3 秒,Compat 1.6 秒冷缓存,同一组探测
1080p 下水体 GPU p50标准版 2.9 至 3.2 毫秒,HQ 3.4 至 3.5,LITE 3.0 至 3.1Vulkan,运行 3 次,完整帧
HQ 水体(折射)相对基准的开销+0.35 至 0.5 毫秒同一场景,StandardMaterial3D 水体
Uniform 缓冲区桌面端 65,536 B,移动端 16,384 B;vec3 填充至 16 B官方文档
每个着色器的实例 Uniform 数量16,不含采样器或数组文档;编译器会拒绝采样器
水体噪声两个平移相乘,pow 1.25Bramwell
溶解边缘宽度 0.06,发光 x6,启用 Glow模板默认值 [已添加]
计算着色器,1M 个浮点数,提交 + 同步Metal 1.2 毫秒,Vulkan 1.9 至 2.4 毫秒本地 RD,窗口化
本项目的着色器烘焙器709 步,打包后从 4.9 MB 增至 18.3 MB,首次烘焙 19 秒,之后为 4 至 12 秒窗口化导出,Metal 在没有 Xcode 工具时仅限 SPIR-V
TIME每 3,600 秒回绕,不受暂停影响文档
着色器驱动的锁步同步不同 GPU 厂商之间运行约 60,000 帧后出现一个像素的偏差Leszek Nowak [00:23:39]

质量门槛

  • 可测量: lint 没有错误;compile_matrix 和 draw_check 按目标渲染器检查时显示零个着色器错误;扫描结果 changes 符合预期(第一帧为 0,溶解时单调变化,移动相位时高于 0.005);像素探针命中预期颜色;cost_compare 在预算范围内;计算着色器的 mismatches == 0 且没有 leaks;烘焙器日志显示步数。
  • 视觉(打开图表):
    • 水体:深度渐变,每处岸边都有泡沫环,波纹会移动,不会出现平铺滚动;水下物体会染色,干燥的岩石则不会;
    • 溶解:边缘跟随噪声、发光,也会切除阴影;amount 为 1 时没有残留;每个网格独立溶解;
    • 后期效果:摄像机转动时覆盖整个屏幕;
    • 模板缓冲:平滑网格上的轮廓连续;
    • 天空:色带和太阳圆盘的位置由 LIGHT0_DIRECTION 决定。

常见错误

错误表现修复方法
Godot 3 名称(SCREEN_TEXTURE、hint_color、WORLD_MATRIX)编译错误;错误消息会指出应使用的 uniform使用带提示的 uniform 和 MODEL_MATRIX;lint 规则 godot3
全屏四边形使用 POSITION = vec4(VERTEX, 1.0)Forward+ 和 Mobile:效果只显示在天空区域;Compatibility 会掩盖这个问题使用 vec4(VERTEX.xy, 1.0, 1.0)、翻转面四边形、extra_cull_margin 16384
在 canvas_item 中使用 texture(TEXTURE, UV) * COLOR精灵颜色变暗(通道值从 54 变为 11)COLOR 已经包含纹理乘以调制色的结果
全局 uniform 未列入 [shader_globals]运行时编译无错误,但读取的是另一个全局值;烘焙器和编辑器会报告此问题保存着色器前先调用 gd_shaders.register_global
#include 一个 .gdshader“Unknown character #35”只能包含 .gdshaderinc
在不透明材质中读取模板缓冲区绘制时出现 “reads stencil but is not in the alpha queue”;没有任何内容被遮罩写入 ALPHA(或禁用深度绘制或深度测试),提高 render_priority
在方块上绘制模板轮廓轮廓在角落处断裂(法线被拆分)使用密集的平滑网格,或反转外壳
多个溶解材质共享一个 bounds小网格会同时消失,大网格则永远无法完成为每个网格使用 instance uniform vec2 bounds
对屏幕纹理使用 textureLod,但未设置 mipmap 过滤器模糊效果仍然锐利使用 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 实现与游戏同步的运动在暂停菜单中仍会持续滚动使用来自 autoload 的 game_time 全局变量(P18)

交接

  • 接收: 渲染器、Environment 和 Compositor 需求(scenario-godot-rendering-lighting); 粒子和卡片着色器(scenario-godot-vfx);精灵效果(scenario-godot-2d);可平铺地图 (scenario-textures)。
  • 交付: .gdshader、.gdshaderinc 和 VisualShader .tres 文件、ShaderMaterial 设置 代码、实例和全局 uniform 名称及其范围、扫描表和成本表。
  • 移交给: scenario-godot-performance-export(卡顿、CI 中的烘焙、设备计时); scenario-godot-animation(instance_shader_parameters/<name> 上的轨道); scenario-godot-rendering-lighting(用于 CompositorEffect 的全屏效果)。

Godot 4.7 说明

  • 自 4.3 起采用反向 z(Forward+ 和 Mobile);Compatibility 保留 OpenGL 深度。使用 #if CURRENT_RENDERER == RENDERER_COMPATIBILITY(4.4+)处理 NDC 公式。
  • 模板缓冲(4.5,仍处于实验阶段):着色器的 stencil_mode,以及 BaseMaterial3D 的 stencil_mode 预设(描边、X 光),这些预设会创建自己的 next_pass。在 4.7.2 中,它们可在 Forward+ 和 Compatibility 下运行。
  • 着色器烘焙器(4.5):一种导出选项;ubershader(4.4)可减少剩余卡顿。
  • Texture2DRD(4.2)和 texture_get_data_async(4.4)仍在使用。
  • 4.8 或更高版本的变更:此处未涵盖;请重新检查标记为实验性的模板缓冲语法。

参考资料

评论

支持 Markdown