HOME / 第 6 部分 · 数据与进阶开发 / 第 74 课
MODULE 6 · 数据与进阶开发

第 74 课 · 着色器实战:特效进阶

⏱ 预计时长 40 分钟📊 难度 进阶📚 模块 第 6 部分 · 数据与进阶开发

🎯 本课学习目标

第 43 课入了门,本课用着色器做几个「秀肌肉」的实战特效。

📖 详细教学步骤

溶解消失代码

死亡时物体像被烧掉一样溶解:

GDSCRIPTshader_type canvas_item;

uniform sampler2D noise_tex;         // 噪声图
uniform float dissolve : hint_range(0.0, 1.0) = 0.0;  // 0-1
uniform vec4 edge_color : source_color = vec4(1.0, 0.6, 0.2, 1.0);

void fragment() {
    vec4 tex = texture(TEXTURE, UV);
    float noise = texture(noise_tex, UV * 4.0).r;   // 采样噪声
    float cutoff = dissolve;
    // 低于阈值的像素丢弃(透明)
    if (noise < cutoff) {
        discard;
    }
    // 边缘发光
    float edge = smoothstep(cutoff, cutoff + 0.08, noise);
    COLOR = mix(edge_color, tex, edge);
}

用代码驱动溶解代码

配合 tween 做死亡动画:

GDSCRIPTfunc die_with_dissolve():
    var mat: ShaderMaterial = sprite.material
    var tween = create_tween()
    tween.tween_method(func(v):
        mat.set_shader_parameter("dissolve", v)
    , 0.0, 1.0, 1.2)
    tween.tween_callback(queue_free)

扫描线 / 复古故障代码

模拟 CRT 屏幕扫描线:

GDSCRIPTshader_type canvas_item;

uniform float scanline_strength : hint_range(0.0, 1.0) = 0.5;
uniform float noise_amount : hint_range(0.0, 1.0) = 0.2;

void fragment() {
    vec4 tex = texture(TEXTURE, UV);
    // 扫描线:按行交替变暗
    float scan = 0.95 + 0.1 * sin(UV.y * 400.0);
    // 随机噪点
    float noise = fract(sin(dot(UV * 100.0, vec2(12.9898, 78.233))) * 43758.5453);
    vec3 col = tex.rgb * scan;
    col += (noise - 0.5) * noise_amount;
    COLOR = vec4(col, tex.a);
}

全屏后期特效(CanvasLayer)实操

给整个画面加特效:

  1. 加一个 CanvasLayer + ColorRect 铺满全屏
  2. 给 ColorRect 加 ShaderMaterial 挂着色器
  3. ColorRect 在最上层,对整个画面叠加特效
  4. 注意 Mouse Filter 设为 Ignore(不影响点击)

💡 用 ColorRect 的 UV 是屏幕坐标,可做全屏扫描线/噪点/暗角。

暗角(Vignette)代码

画面四周变暗,聚焦中心:

GDSCRIPTshader_type canvas_item;

void fragment() {
    vec2 uv = UV;
    // 到中心的距离
    float dist = distance(uv, vec2(0.5, 0.5));
    float vignette = 1.0 - smoothstep(0.3, 0.9, dist) * 0.6;
    COLOR = vec4(vec3(vignette), 1.0);
}

性能与注意注意

  • 全屏着色器每帧对每个像素执行,注意别太复杂
  • 移动端慎用全屏后期
  • discard 会打断 GPU 优化,适度使用
⚠️
discard 后边缘锯齿?

溶解边缘发光(edge_color)能掩盖锯齿,多调 smoothstep 范围。

⚠️
全屏特效挡住了游戏?

ColorRect 的 Mouse Filter 设 Ignore,且颜色混合模式选对。

🧪 动手试一试

🏋️ 课后练习

给敌人做「溶解死亡」:死亡时 1.2 秒溶解消失,边缘橙色发光。

噪声图 + dissolve uniform + tween 驱动。

💡

找免费噪声图(noise texture)是溶解/云朵效果的关键。

💡

着色器参数全部用 uniform 暴露,检查器直接调。

🎓 本课小结

着色器实战:噪声 + discard 做溶解消失、扫描线噪点做复古、CanvasLayer 全屏后期(暗角/故障);uniform 驱动 + tween 动画化。