关于 shader-basics
面向 Godot 4.3+ 开发者的着色器技能,涵盖语言基础、2D/3D 配方及渲染效果,并说明较新版本的功能与常见问题。
主要功能
- 01着色器类型与语言基础
- 022D 和 3D 效果配方
- 03Visual Shader 图形编辑
- 04后期处理与合成器效果
- 05Godot 4.5+ 渲染功能说明
适用场景
- 01制作溶解、描边等 2D 效果
- 02为 3D 材质添加卡通着色或水面
- 03构建屏幕空间后期效果
- 04排查着色器参数与性能问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jame581/ godotprompter --skill shader-basics安装后在 Claude Code 中输入/shader-basics确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/2d-shader-recipes.md3d-shader-recipes.mdcompositor-effects.mdpost-processing.mdshader-baker.mdstencil-buffer.mdvisual-shaders.md详细介绍
Godot 4.3+ 中的着色器
所有示例均面向 Godot 4.3+,不使用已弃用的 API。
相关技能: animation-system 用于命中闪光等由着色器驱动的效果,godot-optimization 用于着色器性能注意事项,camera-system 用于后期处理摄像机效果,2d-essentials 用于 2D 光照、像素风着色器和 CanvasTexture 法线贴图,3d-essentials 用于空间着色器和环境材质,particles-vfx 用于自定义粒子着色器,tween-animation 用于在运行时为着色器参数添加动画。
1. 核心概念
着色器类型
| 着色器类型 | 应用于 | 用途 |
|---|---|---|
canvas_item | 2D 节点(Sprite2D、Control 等) | 2D 效果——描边、溶解、颜色替换 |
spatial | 3D 网格(MeshInstance3D) | 3D 材质——水面、地形、卡通着色 |
particles | GPUParticles2D/3D | 自定义粒子行为 |
sky | WorldEnvironment | 程序化天空渲染 |
fog | FogVolume | 体积雾效果 |
Shader 与 ShaderMaterial
Shader (.gdshader) → The code (GLSL-like language)
ShaderMaterial → Instance of a shader with specific uniform values
CanvasItemMaterial / StandardMaterial3D → Built-in materials (no code needed)
多个节点可以共享同一个 Shader,同时使用具有不同 uniform 值的 ShaderMaterial 实例(例如,使用同一个溶解着色器,但为每个敌人设置不同的溶解进度)。
创建着色器
- 选择一个节点(例如 Sprite2D)
- 在 Inspector → Material → New ShaderMaterial
- 在 ShaderMaterial → Shader → New Shader
- 在内置编辑器中编辑
.gdshader文件
也可以直接在 FileSystem 面板中创建 .gdshader 文件。
2. Godot 着色器语言基础
Godot 使用类似 GLSL ES 3.0 的语言,并加入了 Godot 特有的扩展。
最简 Canvas Item 着色器
shader_type canvas_item;
void fragment() {
// COLOR is the output pixel color
// TEXTURE is the sprite's texture
// UV is the texture coordinate (0,0 top-left to 1,1 bottom-right)
vec4 tex = texture(TEXTURE, UV);
COLOR = tex;
}
最简空间着色器
shader_type spatial;
void fragment() {
// ALBEDO is the base color (vec3)
ALBEDO = vec3(0.8, 0.2, 0.2);
}
内置变量(canvas_item)
| 变量 | 类型 | 说明 |
|---|---|---|
UV | vec2 | 纹理坐标 |
COLOR | vec4 | 输出颜色(在 fragment() 中设置) |
TEXTURE | sampler2D | 节点的纹理 |
VERTEX | vec2 | 顶点位置(在 vertex() 中) |
TIME | float | 已流逝的秒数 |
SCREEN_UV | vec2 | 屏幕空间 UV(用于屏幕效果) |
SCREEN_TEXTURE已在 Godot 4.0 中移除。要读取屏幕内容,请声明一个 uniform:uniform sampler2D screen_texture : hint_screen_texture, filter_linear_mipmap;
内置变量(spatial)
| 变量 | 类型 | 说明 |
|---|---|---|
ALBEDO | vec3 | 表面基础颜色 |
METALLIC | float | 金属度值(0.0–1.0) |
ROUGHNESS | float | 粗糙度值(0.0–1.0) |
NORMAL | vec3 | 表面法线(用于法线贴图) |
EMISSION | vec3 | 自发光颜色 |
ALPHA | float | 透明度(写入该变量会使材质进入透明渲染通道) |
VERTEX | vec3 | 顶点位置(在 vertex() 中) |
Uniform(着色器参数)
Uniform 会将着色器值公开到 Inspector 和代码中。
shader_type canvas_item;
uniform float speed : hint_range(0.0, 10.0, 0.1) = 1.0;
uniform vec4 tint_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform sampler2D noise_texture : filter_linear_mipmap;
void fragment() {
vec4 tex = texture(TEXTURE, UV);
COLOR = tex * tint_color;
}
常用 Uniform 提示
| 提示 | 类型 | 说明 |
|---|---|---|
hint_range(min, max, step) | float/int | Inspector 中的滑块 |
source_color | vec4 | Inspector 中的颜色选取器 |
filter_linear_mipmap | sampler2D | 纹理过滤模式 |
repeat_enable | sampler2D | 允许纹理平铺 |
hint_normal | sampler2D | 将纹理作为法线贴图处理 |
从代码设置 Uniform
GDScript
var mat: ShaderMaterial = $Sprite2D.material
mat.set_shader_parameter("speed", 2.0)
mat.set_shader_parameter("tint_color", Color.RED)
C#
var mat = GetNode<Sprite2D>("Sprite2D").Material as ShaderMaterial;
mat.SetShaderParameter("speed", 2.0f);
mat.SetShaderParameter("tint_color", Colors.Red);
3. 常见 2D 着色器配方
大多数项目需要的 canvas_item 配方:溶解(噪声 + 边缘发光)、描边(采样邻近像素,扩展 alpha)、白色闪光(由 uniform 驱动的受击效果)、颜色替换(调换调色板)、UV 滚动(水面/熔岩/云层)、波浪扭曲。
所有六种配方的完整着色器代码请参阅 references/2d-shader-recipes.md。
4. 常见 3D 着色器配方
空间着色器配方:卡通/赛璐珞着色(分段 NdotL)、边缘光照/菲涅耳(1 - NdotV)、简单水面(UV 滚动 + 法线贴图混合 + 菲涅耳)。
每种配方的完整着色器源码请参阅 references/3d-shader-recipes.md。
5. 可视化着色器
可视化着色器是一种基于节点的图编辑器(New ShaderMaterial → New VisualShader)。可用于快速原型、便于美术人员调整的数值和简单效果;复杂数学运算、分支或循环则应使用代码。两者编译后会生成相同的 GPU 代码,因此性能相同。
选择表、操作步骤、关键节点和 4.7 节点变更请参阅 references/visual-shaders.md。
6. 后期处理效果
标准模式:在游戏画布上方放置一个全矩形 ColorRect,并为其使用 canvas_item 着色器。对于 3D,可使用 WorldEnvironment 的 Adjustment、Glow 或自定义着色器。若要串联多个效果,可将场景渲染到 SubViewport,然后在最终着色器处理阶段采样其纹理。
关于 ColorRect 叠加模式、暗角 + CRT/扫描线着色器源码、SubViewport 流程以及 WorldEnvironment 3D 后期处理说明,请参阅 references/post-processing.md。
7. 合成器效果(Godot 4.3+)
CompositorEffect 会在 3D 渲染管线的五个位置运行自定义渲染处理阶段,从不透明物体处理阶段之前到透明物体处理阶段之后,均在内置后期效果和色调映射之前。若 ColorRect 叠加无法满足需求,可使用它实现多阶段效果、景深感知效果、自定义 AO/SSR 变体。其设置比屏幕空间着色器更复杂,仅在需要时使用。
关于设置、自定义 CompositorEffect GDScript 示例以及内置 Compositor 使用场景,请参阅 references/compositor-effects.md。
8. 渲染模式
渲染模式写在 shader_type 后的第一行,用于控制着色器与渲染管线的交互方式。
Canvas Item 渲染模式
shader_type canvas_item;
render_mode unshaded; // Ignore all lighting
render_mode light_only; // Only visible where lit
render_mode blend_add; // Additive blending (glow, fire)
render_mode blend_mix; // Standard alpha blending (default)
render_mode blend_premul_alpha; // Pre-multiplied alpha
Spatial 渲染模式
shader_type spatial;
render_mode unshaded; // No lighting calculations
render_mode cull_disabled; // Render both sides of faces
render_mode depth_draw_always; // Always write to depth buffer
render_mode specular_toon; // Toon specular model
render_mode diffuse_toon; // Toon diffuse model
render_mode blend_add; // Additive blending
9. 模板缓冲区效果(Godot 4.5+)
Godot 4.5 通过 stencil_mode 语句(stencil_mode write, 1; / stencil_mode read, compare_equal, 1;)在空间着色器中开放模板写入/读取功能,并在 StandardMaterial3D 中提供该功能(Stencil:Outline / X-Ray / Custom),适用于所有渲染后端。canvas_item 着色器不支持模板模式。此功能可实现传送门、X 射线视觉、轮廓遮罩和几何体打洞效果,而这些效果此前需要在合成器层面处理。
关于
stencil_mode参考和 X 射线视觉传送门的完整示例,请参阅 references/stencil-buffer.md。
10. SMAA 抗锯齿(Godot 4.5+)
子像素形态学抗锯齿(SMAA 1x)是 Godot 4.5 新增的内置后期处理抗锯齿模式。它的效果比 FXAA 更清晰,性能开销略高,但比 MSAA 廉价得多。
启用 SMAA
- 打开 项目设置
- 前往 渲染 → 抗锯齿 → 质量
- 将 屏幕空间 AA 设置为 SMAA
SMAA 可以与 MSAA 结合使用(用于几何边缘抗锯齿),也可以单独使用。无需更改任何着色器代码。
| AA 模式 | 清晰度 | GPU 开销 | 残影 |
|---|---|---|---|
| 已禁用 | 不适用 | 无 | 无 |
| FXAA | 低(模糊) | 极低 | 低 |
| SMAA | 高 | 低(略高于 FXAA) | 极低 |
| TAA | 中(略有模糊) | 中 | 可能出现 |
| MSAA 4x | 高 | 高 | 无 |
何时使用 SMAA: 对于大多数桌面项目,优先选择 SMAA 而非 FXAA——它只需稍高的开销,就能让文本和细边缘明显更清晰。结合使用 SMAA + MSAA 2x,可在适中开销下获得最佳质量。
项目设置仅在启动时读取。若要在运行时切换,请设置 get_viewport().screen_space_aa = Viewport.SCREEN_SPACE_AA_SMAA(C#:GetViewport().ScreenSpaceAA = Viewport.ScreenSpaceAAEnum.Smaa)。仅适用于 Forward+ 和 Mobile,不适用于 Compatibility。
11. Shader Baker — 导出时预编译(Godot 4.5+)
Shader Baker 会在导出时将项目着色器转换为目标驱动程序的格式,从而缩短首次启动加载时间——在 macOS/iOS(Metal)和 Windows(D3D12)上效果最明显,因为这些平台上的转换较慢。它无法消除材质首次渲染时的管线编译卡顿,仅适用于 Forward+ 和 Mobile 渲染器,而且只会针对导出机器的操作系统所支持的驱动程序进行烘焙。发布构建时,请在每个导出预设中启用它;开发时则保持关闭。
启用步骤以及启用前后的对比,请参阅 references/shader-baker.md。
12. 常见问题
| 现象 | 原因 | 解决方法 |
|---|---|---|
| 着色器没有可见效果 | 未分配材质或未保存着色器 | 在检查器中检查节点的 Material 属性 |
| 透明部分渲染为黑色 | 着色器未处理 Alpha | 设置 COLOR.a = tex.a; 并使用合适的混合模式 |
| 检查器中未显示 uniform | uniform 名称拼写错误或类型不正确 | 重新保存着色器;检查是否存在编译错误 |
| 纹理出现拉伸/平铺 | 缺少 repeat_enable 或 UV 缩放不正确 | 为 sampler2D uniform 添加 repeat_enable 提示 |
| 着色器在编辑器中正常,但在游戏中无效 | 屏幕纹理 uniform 需要后缓冲区 | 在 sampler2D uniform 上使用 hint_screen_texture(Godot 4.x) |
| 着色器较多时性能下降 | 每个唯一着色器都会导致绘制调用中断 | 共享 ShaderMaterial 实例;使用 uniform 实现变化 |
| 屏幕空间 UV 不正确 | 某些上下文中无法使用 SCREEN_UV | 确保节点在正确的视口中渲染 |
| 缺少 Visual Shader 节点 | 较新版本的 Godot 中重命名或移除了该节点 | 在 Godot 文档中查看当前节点名称 |
⚠️ Godot 4.7 中的更改:
textureQueryLod()仅可在片段着色器中使用,Godot 4.7 会对此进行强制检查并报出编译错误——升级后,从vertex()中调用该函数的着色器将无法编译。请将调用移至fragment()中。参见 GH-118962。
13. 实现检查清单
- 着色器类型与节点类型匹配(2D 使用
canvas_item,3D 使用spatial) - Uniform 使用适当的提示(
hint_range、source_color、filter_linear_mipmap) - 共享视觉效果使用同一个 Shader 资源,并创建独立的 ShaderMaterial 实例
- 后期处理着色器应放在 CanvasLayer(2D)或 WorldEnvironment(3D)上,而不是游戏对象上
-
canvas_item着色器中要对TEXTURE进行采样(否则会丢失精灵内容) - Alpha 透明着色器要正确设置
COLOR.a,并使用blend_mix渲染模式 - 动画着色器参数(溶解、闪烁)应由 Tweens 或 AnimationPlayer 驱动,而不是通过
_process - 读取屏幕的着色器应在
sampler2Duniform 上使用hint_screen_texture(Godot 4.x 的做法) - 使用 Godot 性能分析器分析复杂着色器,检查 GPU 帧时间
- 模板缓冲效果使用双通道材质(先写入通道,再读取通道),并设置正确的渲染优先级(Godot 4.5+)
- 桌面版本优先使用 SMAA,而不是 FXAA(边缘更清晰,开销略高)——在 Project Settings → Rendering → Anti Aliasing 中设置(Godot 4.5+)
- 为 D3D12 和 Metal 目标启用发布预设中的 Shader Baker,以缩短首次启动时的加载时间(仅限 Forward+/Mobile;Godot 4.5+)