Skip to content

Shader 暗角 虚化 黑白 缩放 瓷砖动画(条纹 方形 扇形 斑点 棋盘 图片 旋转/平移动画)

使用演示

Godot Shader 代码

glsl
shader_type canvas_item;

uniform bool graph_switch = false; // 图形开关

uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
uniform float intensity: hint_range(0.0, 1, 0.01) = 1.0; // 整体强度
uniform float blur: hint_range(0.0, 5.0) = 3.0; // 模糊强度
uniform float diffusion = 0.4; // 暗角强度
uniform float zoom: hint_range(0.0, 1.0, 0.01) = 1.0; // 缩放强度
// 动画参数
group_uniforms animation;
uniform int graph_type: hint_range(0, 10, 1) = 0; // 数量
uniform float number: hint_range(0.0, 100.0, 1.0) = 8.0; // 数量
uniform float size: hint_range(0.0, 1.0, 0.01) = 0.1; // 大小
uniform float rotate_speed: hint_range(0.0, 1.0, 0.01)  = 0.1; // 偏移速度
uniform float offset_speed: hint_range(0.0, 1.0, 0.01)  = 0.1; // 偏移速度
uniform float angle = 0.7854; // 旋转角度
uniform float alpha: hint_range(0.0, 1.0, 0.01) = 0.1; // 透明度
uniform sampler2D pattern_sampler : filter_linear_mipmap; // 图片

// 计算暗角
float vignette(vec2 uv){
	uv *= 1.0 - uv.xy; // 取反再相乘,获得中间大边缘小的过度
	float vignette = uv.x * uv.y * 16.0; // 转为浮点,然后归一化
	return pow(vignette, diffusion); // 强度控制
}

void fragment(){
	// 模糊/缩放
	vec4 pixel = texture(SCREEN_TEXTURE, (SCREEN_UV - 0.5) * mix(zoom, 1.0, intensity) + 0.5, mix(blur, 0.0, intensity)); // 获取屏幕颜色
	// 黑白
	vec3 grayscale_value = mix(vec3(dot(pixel.rgb, vec3(0.299, 0.587, 0.114))), pixel.rgb, intensity); // 计算灰度值(加权平均法)
	// 暗角
	float get_vignette = mix(vignette(UV), 1.0, intensity);
	if (graph_switch) {
	COLOR.rgb = grayscale_value * get_vignette; // 综合应用
	} else {
	
	// 旋转动画
	float rotate = angle + (rotate_speed * TIME);

	// 生成条纹
	//float uv = cos(rotate) * UV.x + sin(rotate) * UV.y - offset_speed * TIME; // 旋转偏移 UV
	//float strip = round(mod(uv * number, 1.0)); // 计算条带
	//COLOR.rgb = grayscale_value * get_vignette + (strip * (1.0 - get_vignette) * alpha); // 综合应用

	// 生成图形
	vec2 screen_uv = FRAGCOORD.xy * SCREEN_PIXEL_SIZE.x; // 无拉伸屏幕 UV
    vec2 rotated_uv = vec2(
        cos(rotate) * screen_uv.x - sin(rotate) * screen_uv.y,
        sin(rotate) * screen_uv.x + cos(rotate) * screen_uv.y
    ) - offset_speed * TIME; // 旋转偏移 U
	vec2 tile = mod((rotated_uv) * number, 1.0); // 瓷砖切割
	// 请选择其中一个效果
	float get_graph;
	switch (graph_type) {
		case 0:
			// 生成条纹
			get_graph = round(mod(tile.x * number, 1.0)); // 计算条带
			break;
		case 1:
			// 计算扇形
			get_graph = round(clamp(tile.x * tile.y / size, 0, 1));
			break;
		case 2:
			// 计算方形
			vec2 get_square = round(clamp(tile / (size * 2.0), 0, 1));
			get_graph = get_square.x * get_square.y;
			break;
		case 3:
			// 计算斑点
			tile = tile - 0.5;
			get_graph = round(1.0 - clamp(length(tile) / size, 0, 1));
			break;
		case 4:
			// 计算棋盘
			tile = tile - 0.5;
			get_graph = round(clamp(tile.x * tile.y / size, 0, 1));
			break;
		case 5:
			// 图片平铺
			get_graph = texture(pattern_sampler, tile / size).x;
	};
	COLOR.rgb = grayscale_value * get_vignette - (get_graph * (1.0 - get_vignette) * alpha); // 综合应用
	//COLOR.rgb = vec3(1.0 - get_graph); // 测试效果使用
	}
}

以上为 Godot Shader 代码,有任何问题欢迎进行留言

Tuclink - Old Page