scenario-godot-shaders

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Godot shaders (technical artist, shading)

Godot shaders(技术美术与着色)

Target: Godot 4.7.2.stable, macOS Apple Silicon (Metal by default, Vulkan through MoltenVK for GPU timing).
Expert level here means every shader is text the agent can diff, compiled under each target renderer, drawn on a real mesh in a window, swept across its parameters and looked at on a contact sheet, with its GPU cost measured against a StandardMaterial3D baseline. Compiling is not the same as working: several 4.7.2 failures only appear when the backend draws, and several bugs produce no error at all. If a sibling skill named here is missing from your available skills, ask the user to install it (
npx skills add scenario-labs/skills --skill <name>
); unattended, proceed from tool schemas and flag the gap.
REQUIRED BACKGROUND: scenario-godot-expert (channels,
gd_run
, the review loop, 4.7 traps).
目标:Godot 4.7.2.stable、macOS Apple Silicon(默认使用 Metal,通过 MoltenVK 运行 Vulkan 以进行 GPU 计时)。
这里的专家级意味着,每个 shader 都必须是 Agent 可以 diff 的文本,在每种目标 renderer 下完成编译,在窗口中的真实 mesh 上绘制,遍历其参数并在 contact sheet 上检查,同时相对 StandardMaterial3D baseline 测量 GPU 成本。能够编译并不等于能够正常工作:4.7.2 中的若干故障只有在 backend 实际绘制时才会出现,另有若干 bug 根本不会报告错误。如果此处提到的某个同级 skill 不在可用 skills 中,请让用户安装(
npx skills add scenario-labs/skills --skill <name>
);在无人值守的情况下,则根据 tool schema 继续操作并标注该缺口。
必需背景: scenario-godot-expert(channels、
gd_run
、review loop、4.7 traps)。

Stance (the expert delta)

原则(专家级差异)

  1. Code first, graphs on request. Text shaders give loops, functions,
    #include
    and clean diffs (Godotneers, Shaderland [01:10:09]; Daniel Ilett on the gaps of VisualShader). When a human wants a graph, build the VisualShader in code (
    add_node
    ,
    connect_nodes
    , an Expression node for the maths) and save it as
    .tres
    ; port names are not exposed to GDScript, so output indices are hard-coded and checked by reading
    get_code()
    [added, run 2026-10-02].
  2. Compile headless, then draw windowed. Headless
    get_shader_uniform_list()
    catches language errors per
    --rendering-method
    in about 0.4 s per renderer. Stencil reads in the opaque pass and fog shaders under Compatibility only fail when a window draws them. Uninitialized locals and
    DEPTH
    written in one branch never fail at all, so the linter checks those [added, run 2026-10-02].
  3. World or object space beats mesh UVs. Dissolve, wind, water and triplanar effects should be driven from object-space or world-space coordinates, so seams and UV stretch disappear (StayAtHomeDev dissolve [00:09:59], DevPoodle triplanar, Dylearn grass). For a shared material, put the per-object values (bounds, amount) in
    instance uniform
    s, or each mesh dissolves at the wrong height [added].
  4. Water that does not slide. Use two panned copies of one seamless cellular noise, multiply them, raise to 1.25, and share them between
    vertex()
    and
    fragment()
    so the crests sit on the wave tops (Bramwell [00:11:57 to 00:20:57]). Use hybrid toon bands, a smoothstep only near each cut, so the bands do not flicker (Dylearn [00:13:42]). Shore foam comes from vertical depth, reconstructed from the depth texture with the reversed-z formula [added].
  5. HDR edges need three things together: a color above 1.0, the EMISSION output, and Glow in the WorldEnvironment (StayAtHomeDev [00:07:36], Daniel Ilett [00:10:22], Pixezy [00:06:55]).
  6. Know what moves a material to the transparent pass. Writing
    ALPHA
    or reading the screen or depth texture moves it there. It loses shadows and sorting, and it is invisible to other screen-reading materials (docs). Use
    ALPHA_SCISSOR_THRESHOLD
    for dissolves: the material stays opaque and the shadow dissolves too. Scissor is still an alpha test: like
    discard
    , it gives up early-Z for that mesh (docs), which costs most on mobile tile GPUs, so swap the dissolve material in only for the effect (P18). Stencil readers must be transparent, with a
    render_priority
    above the writer's (LowQualityCoding [00:07:35]).
  7. Compute: on screen, stay on the main device. Texture2DRD needs the main RenderingDevice inside
    RenderingServer.call_on_render_thread
    , and no submit or sync (The Pathfinders Codex [00:03:07]). To get results back on the CPU, use a local device, free every RID and test parity against a CPU version (DevPoodle [00:02:21], Crigz [00:11:24]).
  8. Bake shaders from a windowed export. The shader baker runs only when the export process has a rendering device. A
    --headless
    export with
    shader_baker/enabled=true
    silently packs nothing extra [added, run 2026-10-02].
  1. 代码优先,按需使用 graph。 文本 shader 支持 loop、function、
    #include
    ,并且 diff 清晰(Godotneers、Shaderland [01:10:09];Daniel Ilett 谈 VisualShader 的不足)。当用户需要 graph 时,以代码构建 VisualShader(
    add_node
    、
    connect_nodes
    ,并用 Expression node 处理数学运算),然后保存为
    .tres
    ;port 名称不会暴露给 GDScript,因此 output index 必须硬编码,并通过读取
    get_code()
    进行检查 [新增,运行于 2026-10-02]。
  2. 先进行 headless 编译,再在窗口中绘制。 Headless
    get_shader_uniform_list()
    可针对每种
    --rendering-method
    在约 0.4 s 内捕获语言错误。Opaque pass 中的 stencil read,以及 Compatibility 下的 fog shader,只有在窗口绘制时才会失败。未初始化的局部变量,以及仅在某个分支中写入的
    DEPTH
    ,完全不会报错,因此需要由 linter 检查 [新增,运行于 2026-10-02]。
  3. World space 或 object space 优于 mesh UV。 Dissolve、wind、water 和 triplanar effect 应由 object-space 或 world-space 坐标驱动,从而消除接缝与 UV 拉伸(StayAtHomeDev dissolve [00:09:59]、DevPoodle triplanar、Dylearn grass)。对于共享 material,应通过
    instance uniform
    设置逐对象值(bounds、amount),否则每个 mesh 都会在错误的高度发生 dissolve [新增]。
  4. 不会滑动的 water。 使用同一份 seamless cellular noise 的两个 panned copy,将二者相乘并提升至 1.25,再在
    vertex()
    与
    fragment()
    之间共享,使波峰位于浪尖(Bramwell [00:11:57 至 00:20:57])。使用 hybrid toon band,并且只在每个 cut 附近使用 smoothstep,从而避免 band 闪烁(Dylearn [00:13:42])。Shore foam 来自垂直深度,而该深度需要通过 reversed-z 公式从 depth texture 重建 [新增]。
  5. HDR edge 需要三者同时具备: 高于 1.0 的颜色、
    EMISSION
    output,以及 WorldEnvironment 中的 Glow(StayAtHomeDev [00:07:36]、Daniel Ilett [00:10:22]、Pixezy [00:06:55])。
  6. 了解哪些操作会将 material 移入 transparent pass。 写入
    ALPHA
    ,或读取 screen/depth texture,都会触发这一过程。Material 将失去 shadow 和 sorting,并且不会被其他读取屏幕的 material 看见(docs)。对于 dissolve,应使用
    ALPHA_SCISSOR_THRESHOLD
    :material 会保持 opaque,shadow 也会随之 dissolve。Scissor 仍然是一种 alpha test:与
    discard
    一样,它会让该 mesh 放弃 early-Z,而这在 mobile tile GPU 上成本最高,因此仅在效果期间换入 dissolve material(P18)。Stencil reader 必须处于 transparent 状态,并且其
    render_priority
    要高于 writer(LowQualityCoding [00:07:35])。
  7. Compute 在屏幕上使用时,应留在主 device 上。 Texture2DRD 需要在
    RenderingServer.call_on_render_thread
    内使用主 RenderingDevice,并且不能执行 submit 或 sync(The Pathfinders Codex [00:03:07])。若要将结果取回 CPU,应使用 local device,释放每一个 RID,并与 CPU version 进行一致性验证(DevPoodle [00:02:21]、Crigz [00:11:24])。
  8. 从窗口化 export 烘焙 shader。 只有 export 进程拥有 rendering device 时,shader baker 才能运行。使用
    --headless
    export 并设置
    shader_baker/enabled=true
    时,不会额外打包任何内容,也不会给出提示 [新增,运行于 2026-10-02]。

Establish first

首先确定

  • Target renderers: Forward+ (desktop), Mobile (phones), Compatibility (web, old GPUs); each decides which hints and stages exist. Default: Forward+ plus one named fallback.
  • Style: toon, PBR or pixel art. Decide the band count, the outline method (stencil or inverted hull) and whether Glow is on.
  • Budget: GPU ms per effect against a StandardMaterial3D baseline. Default: under +0.5 ms at 1080p on this Mac for a hero effect, confirmed on the device.
  • Who edits: an agent (text) or a human artist too (VisualShader
    .tres
    , grouped uniforms with hints).
  • Shared or unique materials: per-instance values decide between instance uniforms (at most 16, no textures), unique materials and globals.
  • 目标 renderer: Forward+(desktop)、Mobile(phone)、Compatibility(web、老旧 GPU);每种 renderer 决定可用的 hint 和 stage。默认使用 Forward+,并指定一个命名的 fallback。
  • 风格: toon、PBR 或 pixel art。确定 band 数量、outline 方法(stencil 或 inverted hull),以及是否启用 Glow。
  • 预算: 每种效果相对 StandardMaterial3D baseline 的 GPU ms。默认目标是在此 Mac 上以 1080p 渲染单个重点效果时不超过 +0.5 ms,并在目标设备上确认。
  • 编辑者: Agent(文本),或者人类美术师也参与编辑(VisualShader
    .tres
    、带 hint 的 grouped uniform)。
  • 共享或独立的 material: 根据逐实例值,在 instance uniform(最多 16 个且不能包含 texture)、独立 material 和 global 之间做出选择。

Workflow

工作流

  1. Install and lint.
    gd_shaders.install(project)
    copies the templates into
    res://shaders/
    and the tools into
    addons/agentkit/shaders/
    . Then
    gd_shaders.lint(path, renderers, project=P)
    . GATE: no
    error
    findings; every
    warn
    fixed or justified.
  2. Compile per renderer.
    gd_shaders.compile_matrix(P, root="res://shaders/")
    . GATE:
    ok
    with an empty
    failed
    list for every target renderer.
  3. Draw once per renderer.
    gd_shaders.draw_check(P, files)
    puts each shader on a drawn mesh, canvas item, sky, particle system or fog volume. GATE: zero
    shader_errors
    and
    engine_errors
    in each run.
  4. Build the test scene in code. Write a job that saves a
    .tscn
    with the camera, the light and the Environment set explicitly: AgX, Glow on or off as the brief says. Water needs ground crossing the water level and objects above and below it. A dissolve needs at least three meshes with different sizes and rotations. GATE: the scene loads headless with
    ok
    , and the project.godot renderer and Jolt settings were checked.
  5. Sweep and look. Run
    gd_shaders.param_sweep(P, scene, shots=...)
    with kinds
    shader
    ,
    instance
    ,
    global
    or
    prop
    . Open the contact sheet. GATE:
    changes
    behave as expected (a monotonic dissolve, a moving phase), and the sheet shows the intended look in every shot.
  6. Compare renderers.
    gd_shaders.renderer_captures(P, scene)
    . GATE: the look holds under each target renderer; known differences are written down (Compatibility renders brighter and more saturated with the same Environment).
  7. Cost.
    gd_shaders.cost_compare(P, {"standard": ..., "hq": ..., "lite": ...})
    on Vulkan at 1080p. GATE: the delta against the baseline is within budget; mobile numbers are marked "desktop proxy".
  8. Ship. Add a macOS or target preset with
    shader_baker/enabled=true
    . Export once from a windowed process (see procedures.md P14). GATE: the log shows "Baking shaders (N steps)" and the pack grows. A missing global uniform shows up here as an error.
Side paths:
  • VisualShader for a human artist (P9): build the graph in code with an Expression node and save it as
    .tres
    . Read it back with
    shader_tools.gd:visual_shader
    , which returns the generated code, the node counts and the uniforms. Then sweep it like a text shader. GATE: the generated code contains every expected output assignment.
  • Compute (P12, P13): run
    compute_probe
    windowed for the CPU parity check. Use the Texture2DRD job for on-screen output. GATE: zero mismatches, no leaked RIDs, and frames that change.
  • Globals (P11): register the global with
    register_global
    (it writes the editor's multi-line format). Set live values with
    RenderingServer.global_shader_parameter_set
    and keep a copy in an autoload: the getter stalls the render thread (docs).
    ProjectSettings.set_setting
    at runtime does not register a global.
  • Animating parameters: a Tween or an AnimationPlayer track on
    instance_shader_parameters/dissolve_amount
    drives an instance uniform;
    shader_parameter/<name>
    drives a material uniform (P8).
  1. 安装并执行 lint。
    gd_shaders.install(project)
    会将模板复制到
    res://shaders/
    ,并将工具复制到
    addons/agentkit/shaders/
    。随后执行
    gd_shaders.lint(path, renderers, project=P)
    。 通过条件: 不存在
    error
    级发现;每个
    warn
    都已修复或有合理说明。
  2. 按 renderer 编译。
    gd_shaders.compile_matrix(P, root="res://shaders/")
    。 通过条件: 每种目标 renderer 的结果均为
    ok
    ,且
    failed
    列表为空。
  3. 按 renderer 各绘制一次。
    gd_shaders.draw_check(P, files)
    会将每个 shader 放到已绘制的 mesh、canvas item、sky、particle system 或 fog volume 上。 通过条件: 每次运行中的
    shader_errors
    和
    engine_errors
    均为零。
  4. 以代码构建测试场景。 编写一个 job,保存包含 camera、light 和明确 Environment 设置的
    .tscn
    :AgX,以及按 brief 要求开启或关闭 Glow。Water 场景需要地面穿过水位,并同时放置水面上下方的物体。Dissolve 场景至少需要三个尺寸和旋转各不相同的 mesh。 通过条件: 场景以 headless 方式加载并返回
    ok
    ,同时已检查 project.godot 中的 renderer 和 Jolt 设置。
  5. 扫参并查看。 使用 kind 为
    shader
    、
    instance
    、
    global
    或
    prop
    的
    gd_shaders.param_sweep(P, scene, shots=...)
    ,然后打开 contact sheet。 通过条件:
    changes
    的行为符合预期(dissolve 单调变化、phase 持续移动),且每张图都呈现预期效果。
  6. 比较不同 renderer。
    gd_shaders.renderer_captures(P, scene)
    。 通过条件: 每种目标 renderer 下的效果都保持一致;已知差异应记录在案(Compatibility 在使用相同 Environment 时会渲染得更亮、饱和度更高)。
  7. 成本。 在 Vulkan 上以 1080p 执行
    gd_shaders.cost_compare(P, {"standard": ..., "hq": ..., "lite": ...})
    。 通过条件: 相对 baseline 的增量处于预算内;mobile 数值标记为“desktop proxy”。
  8. 交付。 添加 macOS 或目标 preset,并设置
    shader_baker/enabled=true
    。从窗口化进程执行一次 export(参见 procedures.md P14)。 通过条件: 日志显示“Baking shaders (N steps)”,且 pack 体积增大。缺失的 global uniform 会在此处报告为错误。
旁路流程:
  • 面向人类美术师的 VisualShader(P9):以代码构建 graph,加入 Expression node,并保存为
    .tres
    。使用
    shader_tools.gd:visual_shader
    读回,该工具会返回生成的代码、node 数量和 uniform。随后像处理文本 shader 一样对其进行参数扫描。 通过条件: 生成的代码包含每一项预期的 output assignment。
  • Compute(P12、P13):以窗口化方式运行
    compute_probe
    ,执行 CPU parity check。对于屏幕输出,使用 Texture2DRD job。 通过条件:
    mismatches
    为零、不存在泄漏的 RID,并且画面会发生变化。
  • Global(P11):使用
    register_global
    注册 global,该函数会按编辑器的多行格式写入。通过
    RenderingServer.global_shader_parameter_set
    设置实时值,并在 autoload 中保留一份副本:getter 会阻塞 render thread(docs)。在运行时调用
    ProjectSettings.set_setting
    不会注册 global。
  • 参数动画: 在
    instance_shader_parameters/dissolve_amount
    上使用 Tween 或 AnimationPlayer track,可驱动 instance uniform;在
    shader_parameter/<name>
    上使用相同方式,则可驱动 material uniform(P8)。

Expert checklist (state these in the plan)

专家检查清单(需在计划中明确说明)

  • Complete code in the deliverable. Paste the full templates (
    dissolve.gdshader
    ,
    water_stylized.gdshader
    plus its include) and setup script: readers may lack the kit.
  • source_color
    on every color uniform and color sampler, never on normal, roughness or mask data (
    lint
    rule
    source_color
    ).
  • Uniform budget 16,384 B on mobile, vec3 padded to 16 B; big arrays go in a texture (
    lint
    rule
    uniform_budget
    ).
  • TIME
    wraps at 3,600 s and keeps running while paused (docs): drive pausable motion from
    global uniform float game_time
    , written by the
    game_time.gd
    autoload (P18).
  • Dissolve bounds. World space breaks when the mesh moves or scales; StayAtHomeDev feeds AABB min and max from an
    @tool
    script (pIwQ 09:59 to 12:52). The template uses object space plus an
    instance uniform vec2 bounds
    per mesh, which survives movement, scale and sharing.
  • Swap in for the effect.
    dissolve_swap.gd:swap_in(mi, mat)
    puts one duplicate per surface (keeping each surface's albedo color and texture) and returns the originals for
    restore
    (P18).
  • Sorting.
    depth_prepass_alpha
    with
    cull_disabled
    fixes transparent sorting artifacts and keeps shadows (pIwQ 00:01:00).
  • LIGHT_VERTEX
    (4.3) moves the lit position, for example snapped to a grid for stepped pixel-art light, without touching
    VERTEX
    (Dylearn 00:01:25); it draws on all three renderers (P18).
  • Outlines. BaseMaterial3D
    stencil_mode
    outline on dense meshes; an inverted-hull next pass elsewhere (Daniel Ilett 15:18).
  • 交付物中包含完整代码。 粘贴完整模板(
    dissolve.gdshader
    、
    water_stylized.gdshader
    及其 include)和 setup script,因为使用方可能没有安装 kit。
  • 每个颜色 uniform 和 color sampler 都要设置
    source_color
    ,但 normal、roughness 或 mask 数据绝不能设置(
    lint
    rule
    source_color
    )。
  • Uniform 预算: mobile 为 16,384 B,vec3 会填充至 16 B;大型数组应放入 texture(
    lint
    rule
    uniform_budget
    )。
  • TIME
    :
    在 3,600 s 处回绕,并且暂停时仍会继续运行(docs)。可暂停的 motion 应由
    global uniform float game_time
    驱动,并由
    game_time.gd
    autoload 写入(P18)。
  • Dissolve bounds。 World space 在 mesh 移动或缩放后会失效;StayAtHomeDev 通过
    @tool
    script 提供 AABB min 和 max(pIwQ 09:59 至 12:52)。模板使用 object space,并按 mesh 设置
    instance uniform vec2 bounds
    ,从而支持移动、缩放和共享。
  • 为效果换入 material。
    dissolve_swap.gd:swap_in(mi, mat)
    会为每个 surface 放置一份副本,同时保留各 surface 的 albedo color 和 texture,并返回原始 material,供
    restore
    使用(P18)。
  • Sorting。
    depth_prepass_alpha
    配合
    cull_disabled
    可以修复 transparent sorting artifact,并保留 shadow(pIwQ 00:01:00)。
  • LIGHT_VERTEX
    (4.3)
    可移动受光位置,例如对齐到 grid,以实现阶梯式 pixel-art lighting,而无需改动
    VERTEX
    (Dylearn 00:01:25);它支持全部三种 renderer(P18)。
  • Outline。 对高密度 mesh 使用 BaseMaterial3D
    stencil_mode
    outline;其他情况使用 inverted-hull next pass(Daniel Ilett 15:18)。

Numbers

数值

ValueNumberRelative to
Headless compile, 3 renderers, 11 shaders1.3 sM5 Max, run 2026-10-02
First windowed draw (pipeline build)Metal 7.5 s, Mobile 5.3 s, Compat 1.6 scold cache, same probe set
Water GPU p50 at 1080pstandard 2.9 to 3.2 ms, HQ 3.4 to 3.5, LITE 3.0 to 3.1Vulkan, 3 runs, whole frame
HQ water (refraction) over baseline+0.35 to 0.5 mssame scene, StandardMaterial3D water
Uniform buffer65,536 B desktop, 16,384 B mobile; vec3 pads to 16 Bofficial docs
Instance uniforms per shader16, no samplers or arraysdocs, sampler rejected by the compiler
Water noiseproduct of 2 pans, pow 1.25Bramwell
Dissolve edgewidth 0.06, emission x6, Glow ontemplate defaults [added]
Compute, 1M floats, submit + syncMetal 1.2 ms, Vulkan 1.9 to 2.4 mslocal RD, windowed
Shader baker, this project709 steps, pack 4.9 MB to 18.3 MB, 19 s first bake, 4 to 12 s laterwindowed export, Metal limited to SPIR-V without Xcode tools
TIME
wraps at 3,600 s, ignores pausedocs
Shader-driven lockstepdiverged by one pixel after about 60,000 frames across GPU vendorsLeszek Nowak [00:23:39]
数值数字相对于
Headless 编译、3 种 renderer、11 个 shader1.3 sM5 Max,运行于 2026-10-02
首次窗口化绘制(pipeline build)Metal 7.5 s、Mobile 5.3 s、Compat 1.6 s冷缓存,相同 probe set
1080p 下的 water GPU p50standard 2.9 至 3.2 ms、HQ 3.4 至 3.5、LITE 3.0 至 3.1Vulkan,运行 3 次,整帧测量
HQ water(refraction)相对 baseline+0.35 至 0.5 ms同一场景中的 StandardMaterial3D water
Uniform bufferDesktop 65,536 B、mobile 16,384 B;vec3 填充至 16 B官方 docs
每个 shader 的 instance uniform16 个,不能包含 sampler 或 arraydocs,compiler 会拒绝 sampler
Water noise2 个 pan 的乘积,pow 1.25Bramwell
Dissolve edgewidth 0.06、emission x6、Glow 开启模板默认值 [新增]
Compute、1M floats、submit + syncMetal 1.2 ms、Vulkan 1.9 至 2.4 mslocal RD、窗口化
Shader baker,本项目709 steps,pack 从 4.9 MB 增至 18.3 MB,首次 bake 19 s,之后 4 至 12 s窗口化 export;没有 Xcode 工具时,Metal 仅支持 SPIR-V
TIME
在 3,600 s 处回绕,忽略 pausedocs
Shader 驱动的 lockstep跨 GPU 厂商运行约 60,000 帧后偏差一个像素Leszek Nowak [00:23:39]

Quality gates

质量关卡

  • Measurable:
    lint
    has no errors;
    compile_matrix
    and
    draw_check
    show zero shader errors per target renderer; sweep
    changes
    match the intent (0 at the first shot, monotonic for a dissolve, above 0.005 for a moving phase); pixel probes hit the expected colors;
    cost_compare
    within budget; compute
    mismatches == 0
    with no
    leaks
    ; the baker log shows its step count.
  • Visual (open the sheet):
    • water: a depth ramp, a foam ring at every shore, ripples that move, no tile scroll, and submerged objects tinted while dry rocks are not;
    • dissolve: the edge follows the noise, glows, and cuts the shadow too; no leftover at amount 1; each mesh dissolves independently;
    • post effect: it covers the whole screen when the camera turns;
    • stencil: the outline is continuous on smooth meshes;
    • sky: the bands and the sun disc are where
      LIGHT0_DIRECTION
      puts them.
  • 可测量:
    lint
    无错误;
    compile_matrix
    和
    draw_check
    在每种目标 renderer 下均显示零 shader error;sweep
    changes
    符合预期(首张图为 0、dissolve 单调变化、运动 phase 高于 0.005);pixel probe 命中预期颜色;
    cost_compare
    处于预算内;compute 的
    mismatches == 0
    且不存在
    leaks
    ;baker 日志显示 step 数量。
  • 视觉检查(打开 sheet):
    • water:具有 depth ramp,每处岸边都有 foam ring,ripple 会移动,没有 tile scroll,水下物体会被染色,而露出水面的干燥岩石不会;
    • dissolve:edge 沿 noise 变化、发出 glow,并同时 cut shadow;amount 为 1 时没有残留;每个 mesh 独立 dissolve;
    • post effect:camera 转动时仍覆盖整个屏幕;
    • stencil:outline 在平滑 mesh 上保持连续;
    • sky:band 和 sun disc 位于
      LIGHT0_DIRECTION
      指定的位置。

Common mistakes

常见错误

MistakeWhat it looks likeFix
Godot 3 names (
SCREEN_TEXTURE
,
hint_color
,
WORLD_MATRIX
)
compile error; the message names the uniform to usehinted uniforms and
MODEL_MATRIX
;
lint
rule
godot3
Full-screen quad with
POSITION = vec4(VERTEX, 1.0)
Forward+ and Mobile: the effect shows only over the sky; Compatibility hides the bug
vec4(VERTEX.xy, 1.0, 1.0)
, flip_faces quad,
extra_cull_margin
16384
texture(TEXTURE, UV) * COLOR
in canvas_item
sprite darker (channel 54 becomes 11)
COLOR
already holds texture times modulate
Global uniform not in
[shader_globals]
compiles at runtime with no error and reads another global's value; the baker and editor report it
gd_shaders.register_global
before saving the shader
#include
of a
.gdshader
"Unknown character #35"include
.gdshaderinc
only
Stencil read in an opaque material"reads stencil but is not in the alpha queue" at draw time; nothing maskswrite
ALPHA
(or disable depth draw or depth test), raise
render_priority
Stencil outline on a boxbroken outline at the corners (split normals)dense smooth meshes, or an inverted hull
Shared dissolve material with one
bounds
small meshes vanish at once, big ones never finish
instance uniform vec2 bounds
per mesh
textureLod
on the screen texture without a mipmap filter
blur stays sharp
filter_linear_mipmap
hint_normal_roughness_texture
on Mobile or Compatibility
compile error under that rendererForward+ only, or a
#if CURRENT_RENDERER
branch
Shader baker enabled,
--headless
export
same pack size, no log lineexport from a windowed process
Tween on
shader_parameter/x
left at its default
"Type mismatch ... Nil and float"; the tween never finishes
set_shader_parameter
once before tweening (unset values read null)
Measuring motion from capture frame countswater looks frozen between framessweep
wave_speed
as a phase offset
TIME
for gameplay-synced motion
keeps scrolling in the pause menu
game_time
global from an autoload (P18)
错误表现修复方式
Godot 3 名称(
SCREEN_TEXTURE
、
hint_color
、
WORLD_MATRIX
)
编译错误;错误消息会指出应使用的 uniform使用带 hint 的 uniform 和
MODEL_MATRIX
;
lint
rule
godot3
全屏 quad 使用
POSITION = vec4(VERTEX, 1.0)
Forward+ 和 Mobile:效果仅显示在天空上;Compatibility:隐藏该 bug
vec4(VERTEX.xy, 1.0, 1.0)
、flip_faces quad、
extra_cull_margin
16384
canvas_item 中使用
texture(TEXTURE, UV) * COLOR
Sprite 变暗(channel 54 变为 11)
COLOR
已包含 texture 乘以 modulate 的结果
Global uniform 不在
[shader_globals]
中
运行时可正常编译且不报错,但读取到另一个 global 的值;baker 和 editor 会报告该问题保存 shader 前调用
gd_shaders.register_global
对
.gdshader
使用
#include
出现“Unknown character #35”只能 include
.gdshaderinc
在 opaque material 中读取 stencil绘制时报“reads stencil but is not in the alpha queue”,且没有任何遮罩写入
ALPHA
,或禁用 depth draw/depth test,并提高
render_priority
对 box 使用 stencil outline边角处的 outline 断裂(split normal)使用高密度平滑 mesh,或改用 inverted hull
多个 mesh 共享一个只有一组
bounds
的 dissolve material
小 mesh 同时消失,大 mesh 永远无法完全 dissolve每个 mesh 使用
instance uniform vec2 bounds
对 screen texture 使用
textureLod
,但未设置 mipmap filter
模糊效果仍然锐利设置
filter_linear_mipmap
在 Mobile 或 Compatibility 上使用
hint_normal_roughness_texture
在该 renderer 下编译错误仅限 Forward+,或使用
#if CURRENT_RENDERER
branch
启用 shader baker 后使用
--headless
export
pack 体积不变,且没有日志行从窗口化进程执行 export
Tween 作用的
shader_parameter/x
仍保持默认值
出现“Type mismatch ... Nil and float”,且 Tween 永远无法完成Tween 前先调用一次
set_shader_parameter
(未设置的值会读取为 null)
根据 capture frame count 测量 motionWater 在不同帧之间看起来像是冻结将
wave_speed
作为 phase offset 进行 sweep
使用
TIME
驱动与 gameplay 同步的 motion
在 pause menu 中仍会继续滚动使用 autoload 提供
game_time
global(P18)

Handoffs

交接

  • Receives: renderer, Environment and Compositor needs (scenario-godot-rendering-lighting); particle and card shaders (scenario-godot-vfx); sprite effects (scenario-godot-2d); tileable maps (scenario-textures).
  • Delivers:
    .gdshader
    ,
    .gdshaderinc
    and VisualShader
    .tres
    files, ShaderMaterial setup code, instance and global uniform names with ranges, the sweep sheet and the cost table.
  • Hands off to: scenario-godot-performance-export (stutter, baker in CI, device timing); scenario-godot-animation (tracks on
    instance_shader_parameters/<name>
    ); scenario-godot-rendering-lighting (full-screen effects for a CompositorEffect).
  • 接收: renderer、Environment 和 Compositor 需求(scenario-godot-rendering-lighting);particle 与 card shader(scenario-godot-vfx);sprite effect(scenario-godot-2d);可平铺 map(scenario-textures)。
  • 交付:
    .gdshader
    、
    .gdshaderinc
    和 VisualShader
    .tres
    文件、ShaderMaterial setup code、带范围的 instance 与 global uniform 名称、sweep sheet 和 cost table。
  • 转交: scenario-godot-performance-export(卡顿、CI 中的 baker、设备计时);scenario-godot-animation(
    instance_shader_parameters/<name>
    上的 track);scenario-godot-rendering-lighting(用于 CompositorEffect 的全屏效果)。

Godot 4.7 notes

Godot 4.7 说明

  • Reversed-z since 4.3 (Forward+ and Mobile); Compatibility keeps OpenGL depth. Use
    #if CURRENT_RENDERER == RENDERER_COMPATIBILITY
    (4.4+) for the NDC formula.
  • Stencil (4.5, still experimental): shader
    stencil_mode
    , and the BaseMaterial3D
    stencil_mode
    presets (outline, X-ray), which create their own
    next_pass
    . These run in Forward+ and Compatibility on 4.7.2.
  • Shader baker (4.5): an export option; ubershaders (4.4) reduce the remaining stutter.
  • Texture2DRD (4.2) and
    texture_get_data_async
    (4.4) are current.
  • Changes in 4.8 or later: not covered; recheck the stencil syntax, which is marked experimental.
  • 从 4.3 开始使用 reversed-z(Forward+ 和 Mobile);Compatibility 仍使用 OpenGL depth。使用
    #if CURRENT_RENDERER == RENDERER_COMPATIBILITY
    (4.4+)处理 NDC 公式。
  • Stencil(4.5,仍处于 experimental 状态):shader
    stencil_mode
    ,以及 BaseMaterial3D
    stencil_mode
    preset(outline、X-ray),后者会创建自己的
    next_pass
    。这些功能在 4.7.2 的 Forward+ 和 Compatibility 中均可运行。
  • Shader baker(4.5):一项 export 选项;ubershaders(4.4)可减少剩余的卡顿。
  • Texture2DRD(4.2)和
    texture_get_data_async
    (4.4)属于当前版本功能。
  • 不涵盖 4.8 或更高版本的变化;需要重新检查仍标记为 experimental 的 stencil 语法。

References

参考资料

  • references/expert-notes.md
    (principles by expert, timestamps, 4.7.2 observations),
    procedures.md
    (P1 to P18, code, tests, results),
    critique.md
    (rubric),
    gui-paths.md
    (editor paths),
    sources.md
    (sources and timestamps).
  • scripts/gd_shaders.py
    : install, lint, uniforms and budget, globals, compile_matrix, draw_check, param_sweep, renderer_captures, cost_compare.
  • scripts/agentkit/shaders/
    :
    shader_tools.gd
    ,
    dissolve_swap.gd
    ,
    game_time.gd
    and the templates (water HQ and LITE, dissolve, fullscreen_depth, portal writer and reader, sky_toon, hit_flash).
  • references/expert-notes.md
    (专家提出的原则、时间戳、4.7.2 观察结果)、
    procedures.md
    (P1 至 P18、代码、测试、结果)、
    critique.md
    (评分标准)、
    gui-paths.md
    (editor 路径)、
    sources.md
    (来源和时间戳)。
  • scripts/gd_shaders.py
    :install、lint、uniform 与预算、globals、compile_matrix、draw_check、param_sweep、renderer_captures、cost_compare。
  • scripts/agentkit/shaders/
    :
    shader_tools.gd
    、
    dissolve_swap.gd
    、
    game_time.gd
    ,以及 water HQ 和 LITE、dissolve、fullscreen_depth、portal writer 和 reader、sky_toon、hit_flash 等模板。