godot-shaders

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Godot Shaders (4.x)

Godot着色器(4.x版本)

Write
canvas_item
(2D) and
spatial
(3D) shaders in the Godot Shading Language, animate with
TIME
/
UV
, expose
uniform
s, and read the screen. Targets Godot 4.3+.
使用Godot着色语言编写
canvas_item
(2D)和
spatial
(3D)着色器,通过
TIME
/
UV
实现动画效果,暴露
uniform
变量,并读取屏幕内容。本内容适用于Godot 4.3及以上版本

When to use

适用场景

  • Use when writing
    .gdshader
    code or a
    ShaderMaterial
    : 2D effects (outline, dissolve, flash, water), 3D surface shaders (rim light, toon, scrolling UV), or screen-space post effects.
When not to use: the cross-engine concepts of shading (UVs, vertex/fragment theory) →
shader-programming
; particles/VFX nodes → general 3D; non-shader visuals.
  • 编写
    .gdshader
    代码或
    ShaderMaterial
    时适用:如2D特效(轮廓、溶解、闪烁、水面)、3D表面着色器(边缘光、卡通风格、UV滚动),或屏幕空间后期特效。
不适用场景:跨引擎的着色概念(UV、顶点/片段理论)→ 参考
shader-programming
;粒子/视觉特效节点→ 通用3D开发;非着色器类视觉效果。

Core workflow

核心工作流程

  1. Pick the shader type on the first line:
    shader_type canvas_item;
    for 2D (Sprite2D, TextureRect, anything
    CanvasItem
    ) or
    shader_type spatial;
    for 3D materials. (
    particles
    ,
    sky
    ,
    fog
    also exist.)
  2. Attach via a
    ShaderMaterial
    .
    Create a
    ShaderMaterial
    , assign your
    .gdshader
    , and put it on the node's
    material
    . Uniforms appear in the Inspector.
  3. Write
    fragment()
    to set the output:
    COLOR
    (2D) or
    ALBEDO
    /
    EMISSION
    /
    ALPHA
    (3D). Optionally
    vertex()
    to move geometry and
    light()
    for custom lighting.
  4. Expose tunables as
    uniform
    s
    with hints (
    source_color
    ,
    hint_range
    ) so they are editable and correctly color-managed.
  5. Animate with the built-in
    TIME
    and sample textures with
    texture(tex, UV)
    .
  6. Set uniforms from code with
    material.set_shader_parameter("name", value)
    .
  1. 选择着色器类型:在第一行声明类型,2D场景(Sprite2D、TextureRect等所有
    CanvasItem
    节点)使用
    shader_type canvas_item;
    ,3D材质使用
    shader_type spatial;
    。此外还有
    particles
    sky
    fog
    等类型可选。
  2. 通过
    ShaderMaterial
    绑定
    :创建一个
    ShaderMaterial
    ,分配你的
    .gdshader
    文件,然后将其设置到节点的
    material
    属性中。Uniform变量会显示在检查器面板中。
  3. 编写
    fragment()
    函数
    设置输出:2D场景使用
    COLOR
    ,3D场景使用
    ALBEDO
    /
    EMISSION
    /
    ALPHA
    。可选编写
    vertex()
    函数来移动几何体,或
    light()
    函数实现自定义光照。
  4. 通过带提示的
    uniform
    暴露可调参数
    :使用
    source_color
    hint_range
    等提示,让参数可编辑并实现正确的色彩管理。
  5. 通过内置
    TIME
    变量实现动画
    ,并使用
    texture(tex, UV)
    采样纹理。
  6. 通过代码设置uniform变量:使用
    material.set_shader_parameter("name", value)

Patterns

常见模式

1. 2D (canvas_item): tint + scrolling UV

1. 2D(canvas_item):色调叠加+UV滚动

glsl
shader_type canvas_item;

uniform vec4 tint : source_color = vec4(1.0);     // source_color = sRGB-correct color
uniform float scroll_speed : hint_range(0.0, 2.0) = 0.3;

void fragment() {
    vec2 uv = UV;
    uv.x += TIME * scroll_speed;                  // scroll horizontally over time
    COLOR = texture(TEXTURE, uv) * tint;          // TEXTURE = the node's texture
}
glsl
shader_type canvas_item;

uniform vec4 tint : source_color = vec4(1.0);     // source_color = 符合sRGB标准的颜色
uniform float scroll_speed : hint_range(0.0, 2.0) = 0.3;

void fragment() {
    vec2 uv = UV;
    uv.x += TIME * scroll_speed;                  // 随时间水平滚动
    COLOR = texture(TEXTURE, uv) * tint;          // TEXTURE = 当前节点的纹理
}

2. 2D dissolve using a noise threshold

2. 使用噪波阈值实现2D溶解效果

glsl
shader_type canvas_item;

uniform sampler2D noise : repeat_enable;          // a NoiseTexture2D
uniform float amount : hint_range(0.0, 1.0) = 0.0;

void fragment() {
    vec4 tex = texture(TEXTURE, UV);
    float n = texture(noise, UV).r;
    if (n < amount) {
        discard;                                  // cut the pixel away
    }
    COLOR = tex;
}
glsl
shader_type canvas_item;

uniform sampler2D noise : repeat_enable;          // 一个NoiseTexture2D资源
uniform float amount : hint_range(0.0, 1.0) = 0.0;

void fragment() {
    vec4 tex = texture(TEXTURE, UV);
    float n = texture(noise, UV).r;
    if (n < amount) {
        discard;                                  // 剔除该像素
    }
    COLOR = tex;
}

3. 3D (spatial): emissive rim light

3. 3D(spatial):自发光边缘光

glsl
shader_type spatial;

uniform vec4 base_color : source_color = vec4(0.2, 0.5, 1.0, 1.0);
uniform vec3 rim_color : source_color = vec3(0.6, 0.8, 1.0);
uniform float rim_power : hint_range(0.5, 8.0) = 3.0;

void fragment() {
    ALBEDO = base_color.rgb;
    // VIEW and NORMAL are view-space built-ins; rim is strong at grazing angles.
    float rim = pow(1.0 - dot(NORMAL, VIEW), rim_power);
    EMISSION = rim_color * rim;
}
glsl
shader_type spatial;

uniform vec4 base_color : source_color = vec4(0.2, 0.5, 1.0, 1.0);
uniform vec3 rim_color : source_color = vec3(0.6, 0.8, 1.0);
uniform float rim_power : hint_range(0.5, 8.0) = 3.0;

void fragment() {
    ALBEDO = base_color.rgb;
    // VIEW和NORMAL是视图空间的内置变量;边缘光在掠射角度下效果明显。
    float rim = pow(1.0 - dot(NORMAL, VIEW), rim_power);
    EMISSION = rim_color * rim;
}

4. Screen-reading post effect (4.x hint, not SCREEN_TEXTURE)

4. 屏幕读取后期特效(4.x版本提示,替代SCREEN_TEXTURE)

glsl
shader_type canvas_item;

// 4.x: declare the screen as a uniform with hint_screen_texture.
uniform sampler2D screen_tex : hint_screen_texture, filter_linear_mipmap;
uniform float blur : hint_range(0.0, 4.0) = 1.0;

void fragment() {
    vec2 px = SCREEN_PIXEL_SIZE * blur;
    vec4 c = texture(screen_tex, SCREEN_UV);
    c += texture(screen_tex, SCREEN_UV + vec2(px.x, 0.0));
    c += texture(screen_tex, SCREEN_UV - vec2(px.x, 0.0));
    COLOR = c / 3.0;
}
Set a uniform from GDScript:
gdscript
$Sprite2D.material.set_shader_parameter("amount", 0.7)
glsl
shader_type canvas_item;

// 4.x版本:使用hint_screen_texture将屏幕声明为uniform变量
uniform sampler2D screen_tex : hint_screen_texture, filter_linear_mipmap;
uniform float blur : hint_range(0.0, 4.0) = 1.0;

void fragment() {
    vec2 px = SCREEN_PIXEL_SIZE * blur;
    vec4 c = texture(screen_tex, SCREEN_UV);
    c += texture(screen_tex, SCREEN_UV + vec2(px.x, 0.0));
    c += texture(screen_tex, SCREEN_UV - vec2(px.x, 0.0));
    COLOR = c / 3.0;
}
通过GDScript设置uniform变量:
gdscript
$Sprite2D.material.set_shader_parameter("amount", 0.7)

Pitfalls

常见陷阱

  • 3.x → 4.x renames.
    SCREEN_TEXTURE
    is removed — declare
    uniform sampler2D x : hint_screen_texture;
    and sample with
    SCREEN_UV
    . Color hints
    hint_color
    source_color
    ;
    hint_albedo
    /
    hint_white
    source_color
    ;
    hint_range
    stays. Depth/normal use
    hint_depth_texture
    /
    hint_normal_roughness_texture
    .
  • Wrong output variable. In
    canvas_item
    write
    COLOR
    ; in
    spatial
    write
    ALBEDO
    (and
    EMISSION
    ,
    ALPHA
    ,
    ROUGHNESS
    ,
    METALLIC
    ). Writing
    COLOR
    in a spatial shader does nothing.
  • Color uniforms without
    source_color
    are treated as raw linear values and look wrong (washed/dark) because Godot won't sRGB-convert them.
  • Transparency needs opt-in (3D). For
    ALPHA < 1.0
    to blend, add a render mode or set the material transparency; otherwise it's opaque/cut.
  • Sampling outside [0,1] UV without
    repeat_enable
    clamps. Add
    : repeat_enable
    to the sampler uniform for tiling/scroll.
  • TIME
    is seconds since start
    and keeps growing — wrap with
    fract()
    /
    mod()
    for periodic effects to avoid precision drift.
  • discard
    is costly
    on some hardware and breaks early-Z; prefer setting
    ALPHA
    /
    COLOR.a
    when you can.
  • 3.x到4.x的命名变更
    SCREEN_TEXTURE
    已被移除,需声明
    uniform sampler2D x : hint_screen_texture;
    并使用
    SCREEN_UV
    进行采样。颜色提示
    hint_color
    改为
    source_color
    hint_albedo
    /
    hint_white
    也改为
    source_color
    hint_range
    保持不变。深度/法线纹理使用
    hint_depth_texture
    /
    hint_normal_roughness_texture
  • 错误的输出变量:在
    canvas_item
    中使用
    COLOR
    ;在
    spatial
    中使用
    ALBEDO
    (以及
    EMISSION
    ALPHA
    ROUGHNESS
    METALLIC
    )。在spatial着色器中写入
    COLOR
    不会产生任何效果。
  • 未使用
    source_color
    的颜色uniform
    会被视为原始线性值,显示效果异常(褪色/偏暗),因为Godot不会对其进行sRGB转换。
  • 3D透明效果需手动开启:若要让
    ALPHA < 1.0
    的内容实现混合,需添加渲染模式或设置材质透明度;否则材质会是不透明或裁剪状态。
  • UV超出[0,1]范围采样:若未添加
    repeat_enable
    ,采样会被钳制。如需平铺/滚动,需在采样器uniform后添加
    : repeat_enable
  • TIME
    是从启动开始的秒数
    ,且持续增长——对于周期性效果,需使用
    fract()
    /
    mod()
    进行包裹,避免精度漂移。
  • discard
    指令在部分硬件上性能开销大
    ,且会破坏Early-Z优化;尽可能优先设置
    ALPHA
    /
    COLOR.a
    来实现透明。

References

参考资料

  • For built-in variables per shader type, render modes,
    varying
    , custom
    light()
    ,
    vertex()
    displacement, and the visual shader graph, read
    references/shading-language.md
    .
  • 如需了解各着色器类型的内置变量、渲染模式、
    varying
    变量、自定义
    light()
    函数、
    vertex()
    位移以及可视化着色器图,请阅读
    references/shading-language.md

Related skills

相关技能

  • shader-programming
    — engine-agnostic shader concepts (GLSL/HLSL).
  • godot-3d-essentials
    — materials, environment, and where spatial shaders live.
  • godot-ui-control
    — applying shaders to UI for effects.
  • shader-programming
    — 跨引擎的着色器概念(GLSL/HLSL)。
  • godot-3d-essentials
    — 材质、环境以及spatial着色器的应用场景。
  • godot-ui-control
    — 为UI应用着色器实现特效。