---
name: godot-shader-patterns
description: Godot 4 常见 Shader 特效案例，包括描边、像素化、溶解、水波、模糊等。
---

# Godot Shader 常用案例

## 1. 描边着色器（轮廓检测）

### 效果描述
为精灵或字体添加外轮廓效果，常用于 UI 元素、选中状态或卡通风格的描边效果。

### 核心代码

```gdscript
shader_type canvas_item;

uniform float outline_width = 1.0;
uniform vec4 outline_color: source_color = vec4(1, 0, 0, 1);

void fragment() {
    vec2 uv = UV;
    vec2 uv_up = uv + vec2(0, TEXTURE_PIXEL_SIZE.y) * outline_width;
    vec2 uv_down = uv + vec2(0, -TEXTURE_PIXEL_SIZE.y) * outline_width;
    vec2 uv_left = uv + vec2(TEXTURE_PIXEL_SIZE.x, 0) * outline_width;
    vec2 uv_right = uv + vec2(-TEXTURE_PIXEL_SIZE.x, 0) * outline_width;

    vec4 color_up = texture(TEXTURE, uv_up);
    vec4 color_down = texture(TEXTURE, uv_down);
    vec4 color_left = texture(TEXTURE, uv_left);
    vec4 color_right = texture(TEXTURE, uv_right);

    vec4 outline = color_down + color_up + color_left + color_right;
    outline.rgb = outline_color.rgb;

    vec4 original_color = texture(TEXTURE, UV);
    COLOR = mix(outline, original_color, original_color.a);
}
```

## 2. 像素化着色器

### 效果描述
将画面处理成像素风格，模拟复古游戏的视觉效果。

### 核心代码

```gdscript
shader_type canvas_item;

uniform float pixel_size = 4.0;  // 像素块大小

void fragment() {
    vec2 uv = floor(UV * pixel_size) / pixel_size;
    COLOR = texture(TEXTURE, uv);
}
```

## 3. 灰度/复古色着色器

### 效果描述
将图片转换为灰度图或带有复古色调。

### 核心代码

```gdscript
shader_type canvas_item;

void fragment() {
    vec4 color = texture(TEXTURE, UV);
    float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
    COLOR = vec4(vec3(gray), color.a);
}
```

## 4. 溶解/燃烧效果

### 效果描述
实现物体逐渐溶解消失的效果，溶解边缘带有燃烧的色泽。

### 核心代码

```gdscript
shader_type canvas_item;

uniform sampler2D dissolve_texture: source_color;
uniform float dissolve_value: hint_range(0, 1) = 1.0;
uniform float burn_size: hint_range(0.0, 1.0, 0.01) = 0.1;
uniform vec4 burn_color: source_color = vec4(1.0, 0.3, 0.0, 1.0);

void fragment() {
    vec4 main_texture = texture(TEXTURE, UV);
    vec4 noise_texture = texture(dissolve_texture, UV);

    float burn_size_step = burn_size * step(0.001, dissolve_value) * step(dissolve_value, 0.999);
    float threshold = smoothstep(noise_texture.x - burn_size_step, noise_texture.x, dissolve_value);
    float border = smoothstep(noise_texture.x, noise_texture.x + burn_size_step, dissolve_value);

    COLOR.a *= threshold;
    COLOR.rgb = mix(burn_color.rgb, main_texture.rgb, border);
}
```

### 使用说明
1. 创建 `NoiseTexture2D` 作为 `dissolve_texture`
2. 使用 "Simplex Smooth" 噪声类型
3. 调整 `dissolve_value`（0 = 完全溶解，1 = 未溶解）

## 5. 水波/折射效果

### 效果描述
模拟水面的波纹效果，包含波动和扭曲效果。

### 核心代码

```gdscript
shader_type canvas_item;

uniform sampler2D noise_tex;
uniform float speed = 0.25;
uniform float strength = 0.02;
uniform vec4 tint_color: source_color = vec4(1.0, 1.0, 1.0, 1.0);

void fragment() {
    vec2 uv = UV;

    float noise = texture(noise_tex, uv + vec2(TIME * speed, 0.0)).r;
    float noise2 = texture(noise_tex, uv + vec2(0.0, TIME * speed * 0.5)).r;

    vec2 offset = vec2(
        cos(TIME * speed + uv.y * 10.0) * strength,
        sin(TIME * speed + uv.x * 10.0) * strength
    ) * (noise + noise2);

    vec4 color = texture(TEXTURE, uv + offset);
    COLOR = color * tint_color;
}
```

## 6. 模糊效果

### 效果描述
对图像进行模糊处理，常用于景深效果、UI 毛玻璃效果。

### 核心代码

```gdscript
shader_type canvas_item;

uniform float blur_radius = 2.0;
uniform vec2 blur_direction = vec2(1.0, 0.0);

const float MATRIX[5] = float[](0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);

void fragment() {
    vec2 uv = UV;
    vec2 texel_size = TEXTURE_PIXEL_SIZE;

    vec3 result = texture(TEXTURE, uv).rgb * MATRIX[0];

    for (int i = 1; i < 5; i++) {
        float offset = float(i) * blur_radius;
        result += texture(TEXTURE, uv + texel_size * offset * blur_direction).rgb * MATRIX[i];
        result += texture(TEXTURE, uv - texel_size * offset * blur_direction).rgb * MATRIX[i];
    }

    vec4 original = texture(TEXTURE, uv);
    COLOR = vec4(result, original.a);
}
```

## 7. 发光/光晕效果

### 效果描述
为图像添加发光效果，常用于霓虹灯、魔法特效或 UI 高亮显示。

### 核心代码

```gdscript
shader_type canvas_item;

uniform float glow_intensity = 0.5;
uniform float glow_radius = 3.0;

void fragment() {
    vec2 uv = UV;
    vec2 texel = TEXTURE_PIXEL_SIZE * glow_radius;

    vec4 color = texture(TEXTURE, uv);

    vec3 glow = vec3(0.0);
    for (float x = -2.0; x <= 2.0; x += 1.0) {
        for (float y = -2.0; y <= 2.0; y += 1.0) {
            vec2 offset = vec2(x, y) * texel;
            glow += texture(TEXTURE, uv + offset).rgb;
        }
    }
    glow /= 25.0;

    COLOR = color + vec4(glow * glow_intensity, 0.0);
}
```

### 流光效果

```gdscript
shader_type canvas_item;

uniform sampler2D light_vector;
uniform float width = 0.08;
uniform vec4 flowlight = vec4(0.3, 0.3, 0.0, 0.3);

void fragment() {
    vec4 color = texture(TEXTURE, UV);

    if (color.a != 0.0) {
        float v = texture(light_vector, UV).r;
        float diff = v - cos(TIME * 0.5);

        if (abs(diff) < width) {
            color = color + mix(flowlight, vec4(0.0), abs(diff) / width);
        }
    }

    COLOR = color;
}
```

## 8. 卡通渲染（Cel Shading）

### 效果描述
模拟卡通/动漫风格的渲染效果，通过离散的色调过渡创造手绘感。

### 核心代码

```gdscript
shader_type canvas_item;

uniform float levels = 3.0;
uniform vec4 light_color: source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform vec4 shadow_color: source_color = vec4(0.2, 0.2, 0.3, 1.0);

void fragment() {
    vec4 color = texture(TEXTURE, UV);
    float light = dot(color.rgb, vec3(0.33));
    light = floor(light * levels) / levels;
    COLOR = mix(shadow_color, color * light_color, light);
}
```

## 9. SpriteSheet 帧动画

### 效果描述
通过 Shader 实现 SpriteSheet 图集的帧动画播放。

### 核心代码

```gdscript
shader_type canvas_item;

uniform int h_frames : hint_range(1, 100) = 4;
uniform int v_frames : hint_range(1, 100) = 1;
uniform float speed : hint_range(0.1, 30.0) = 10.0;
uniform bool loop = true;

void fragment() {
    float frame_width = 1.0 / float(h_frames);
    float frame_height = 1.0 / float(v_frames);

    int total_frames = h_frames * v_frames;
    int frame_index;

    if (loop) {
        frame_index = int(TIME * speed) % total_frames;
    } else {
        frame_index = min(int(TIME * speed), total_frames - 1);
    }

    int col = frame_index % h_frames;
    int row = frame_index / h_frames;

    float uv_x = float(col) * frame_width;
    float uv_y = 1.0 - float(row + 1) * frame_height;

    vec2 anim_uv = vec2(uv_x, uv_y) + vec2(UV.x * frame_width, UV.y * frame_height);
    COLOR = texture(TEXTURE, anim_uv);
}
```

## 10. 混合模式

### 效果描述
实现 Photoshop 风格的混合模式。

### 核心代码

```gdscript
shader_type canvas_item;

uniform sampler2D blend_texture: source_color;
uniform float opacity: hint_range(0.0, 1.0) = 1.0;
uniform int blend_mode = 0;

vec3 multiply(vec3 base, vec3 blend) {
    return base * blend;
}

vec3 screen(vec3 base, vec3 blend) {
    return 1.0 - (1.0 - base) * (1.0 - blend);
}

vec3 overlay(vec3 base, vec3 blend) {
    return mix(
        2.0 * base * blend,
        1.0 - 2.0 * (1.0 - base) * (1.0 - blend),
        step(0.5, base)
    );
}

void fragment() {
    vec4 base = texture(TEXTURE, UV);
    vec4 blend = texture(blend_texture, UV);

    vec3 result;
    if (blend_mode == 0) {
        result = multiply(base.rgb, blend.rgb);
    } else if (blend_mode == 1) {
        result = screen(base.rgb, blend.rgb);
    } else {
        result = overlay(base.rgb, blend.rgb);
    }

    COLOR = vec4(mix(base.rgb, result, opacity * blend.a), base.a);
}
```

## 11. SDF 描边效果（3D）

```gdscript
shader_type spatial;
render_mode cull_front, unshaded;

uniform vec4 outline_color : hint_color = vec4(1.0, 0.0, 0.0, 1.0);
uniform float grow = 0.05;

void vertex() {
    VERTEX += NORMAL * grow;
}

void fragment() {
    ALBEDO = outline_color.rgb;
}
```
