[Godot] Shader实现几种简单的效果

发布于:2025-04-03 ⋅ 阅读:(21) ⋅ 点赞:(0)

前言

静态场景太过单调了,写一些shader让纹理动起来吧,这里给大家分享几种Shader效果

目录

草地晃动

波浪效果 

波纹效果 

雪花屏效果

果冻效果

呼吸膨胀效果

扫描线效果 


实现

首先创建一个场景,场景里面有一个纹理

草地晃动

首先,我们可以点击纹理的材质来创建一个着色器材质文件

然后再创建着色器脚本

接下来可以在着色器脚本中输入以下代码来实现晃动效果

大家可以根据自己的需要更改值,注意别改太大,可能会渲染到节点外面,就看不见了

shader_type canvas_item;

uniform float wind = 0.01; //摇晃程度
uniform float speed = 3.0; //摇晃速度
void fragment() {
// 获取当前像素的UV坐标
vec2 uv = UV;
// 将草的倾斜效果应用于纹理坐标
uv.x += sin((uv.y + TIME) * speed) * wind * uv.y;
// 从纹理中获取像素颜色
vec4 color = texture(TEXTURE, uv);
// 输出像素颜色
COLOR = color;
}

波浪效果 

这个场景我用Godot的图标作为纹理,接下来我们写Shader,代码如下

shader_type canvas_item;

uniform float time_factor : hint_range(0.0, 10.0) = 1.0;  // 控制波动速度
uniform float wave_amplitude : hint_range(0.0, 10.0) = 5.0;  // 控制波动幅度(像素级)
uniform float wave_frequency : hint_range(0.0, 10.0) = 10.0; // 控制波长(波动的紧密程度)

void fragment() {
    vec2 uv = UV;  // 纹理坐标
    vec2 screen_uv = SCREEN_UV;  // 屏幕坐标(更适用于全屏效果)

    // 让波浪随着时间运动
    float wave = sin(uv.x * wave_frequency + TIME * time_factor) * wave_amplitude / 100.0;

    // 对 Y 轴坐标进行波动变换
    uv.y += wave;

    // 采样纹理并应用变换后的 UV
    vec4 tex_color = texture(TEXTURE, uv);
    COLOR = tex_color;
}

实现效果

波纹效果 

话不多说,直接上代码

shader_type canvas_item;

uniform float ripple_strength : hint_range(0.0, 0.2) = 0.02; // 波纹扭曲强度
uniform float ripple_speed : hint_range(0.0, 5.0) = 1.5; // 波纹扩散速度
uniform float ripple_density : hint_range(5.0, 50.0) = 10.0; // 波纹密度

void fragment() {
    vec2 uv = UV;
    
    // 计算距离中心的半径
    float dist = length(uv - vec2(0.5));

    // 计算波纹偏移
    float ripple = sin(dist * ripple_density - TIME * ripple_speed) * ripple_strength;

    // 应用波纹变形
    vec2 distorted_uv = uv + ripple * normalize(uv - vec2(0.5));

    // 采样原始颜色
    vec4 color = texture(TEXTURE, distorted_uv);

    COLOR = color;
}

 实现效果

雪花屏效果

上代码

shader_type canvas_item;

uniform float noise_intensity : hint_range(0.0, 1.0) = 0.5;  // 控制雪花的强度
uniform float scanline_intensity : hint_range(0.0, 1.0) = 0.1;  // 控制扫描线的强度
uniform float time_speed : hint_range(0.0, 5.0) = 0.1;  // 控制雪花闪烁速度

// 伪随机函数
float random(vec2 uv) {
    return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453);
}

void fragment() {
    vec2 uv = UV;  // 改为 UV 坐标,确保兼容性

    // 生成随机噪声
    float noise = random(uv * TIME * time_speed);

    // 模拟水平扫描线
    float scanline = sin(uv.y * 800.0) * scanline_intensity;  // 800 控制扫描线的密度

    // 计算最终颜色
    float final_color = mix(noise, scanline, scanline_intensity) * noise_intensity;

    COLOR = vec4(vec3(final_color), 1.0);
}

 实现效果

果冻效果

上代码

shader_type canvas_item;

uniform float jelly_strength : hint_range(0.0, 1.0) = 0.05; // 控制果冻抖动强度
uniform float time_speed : hint_range(0.0, 5.0) = 1.0; // 控制抖动速度

void fragment() {
    vec2 uv = UV;
    
    // 计算果冻的弹性变形
    float jelly_x = sin(TIME * time_speed + uv.y * 10.0) * jelly_strength;
    float jelly_y = cos(TIME * time_speed + uv.x * 10.0) * jelly_strength;

    // 应用果冻变形
    vec4 color = texture(TEXTURE, uv + vec2(jelly_x, jelly_y));

    COLOR = color;
}

 实现效果

呼吸膨胀效果

上代码

shader_type canvas_item;

uniform float scale_strength : hint_range(0.0, 0.2) = 0.04; // 控制膨胀收缩幅度
uniform float time_speed : hint_range(0.0, 5.0) = 1.0; // 控制呼吸速度

void fragment() {
    vec2 uv = UV;

    // 计算呼吸缩放
    float scale = 1.0 + sin(TIME * time_speed) * scale_strength;

    // 调整UV,实现膨胀收缩效果
    vec2 scaled_uv = (uv - 0.5) * scale + 0.5;
    
    // 采样原始纹理
    vec4 color = texture(TEXTURE, scaled_uv);

    COLOR = color;
}

实现效果

扫描线效果 

上代码

shader_type canvas_item;

uniform float line_intensity : hint_range(0.0, 1.0) = 0.3;  // 扫描线强度
uniform float line_density : hint_range(100.0, 1000.0) = 300.0; // 扫描线密度
uniform float flicker_speed : hint_range(0.0, 5.0) = 3.0; // 扫描线闪烁速度

void fragment() {
    vec2 uv = UV;
    
    // 计算扫描线模式
    float scanline = sin(uv.y * line_density + TIME * flicker_speed) * line_intensity;

    // 采样原始纹理颜色
    vec4 color = texture(TEXTURE, uv);

    // 叠加扫描线效果
    color.rgb -= scanline;

    COLOR = color;
}

实现效果


网站公告

今日签到

点亮在社区的每一天
去签到