一个最简单的 2D Shader
最简单的将一张图片渲染为经典品红色的Shader
shader_type canvas_item;
void fragment() {
COLOR = vec4(1, 0, 1, 1);
}

下面可以正确的渲染一张贴图
shader_type canvas_item;
void fragment() {
COLOR = texture(TEXTURE, UV);
}
TEXTURE为传入的贴图,UV就是像素点的位置信息,简单来说就是取TEXTURE中对于UV位置的颜色。需要注意的是UV是一个标准化坐标,它的原点为左下角,值的范围为[0, 1]。

将贴图对应像素点的颜色取出来了,就可以对图片的颜色进行操作了,比如下面的代码可以把一张图片变为灰度图。
shader_type canvas_item;
void fragment() {
vec4 color = texture(TEXTURE, UV);
float gray = 0.299 * color.r + 0.587 * color.g + 0.114 * color.b;
COLOR = vec4(vec3(gray), color.a);
}
这个就是根据亮度加权公式 (Y = 0.299 * R + 0.587 * G + 0.114 * B) 来计算每个像素的亮度信息,所以展示出来的就是一张只有灰度信息的图片。

以上就是对于贴图最基本的操作了。
让贴图动起来
UI中有一种非常常见的效果,比如卡片溶解消失的效果就可以使用Shader来实现。
shader_type canvas_item;
uniform float dissolve_value : hint_range(0.0, 1.0);
uniform sampler2D noise_texture;
void fragment() {
float noise = texture(noise_texture, UV).r;
if (noise < dissolve_value) {
COLOR.a = 0.0;
} else {
COLOR = texture(TEXTURE, UV);
}
}
dissolve_value就是定义一个变量,这个变量可以在外部去控制。noise_texture就是一张噪声图,这个代码也很简单易懂就是通过判断噪声值的范围控制贴图Alpha。

当然这种消失比较单调,有时候希望的有那种被火烧掉的感觉。
shader_type canvas_item;
uniform float dissolve_value : hint_range(0.0, 1.0);
uniform sampler2D noise_texture;
uniform vec4 burn_color = vec4(1.0, 0.2, 0.0, 1.0);
uniform float edge_width : hint_range(0.0, 0.2) = 0.05;
void fragment() {
float noise = texture(noise_texture, UV).r;
vec4 base_col = texture(TEXTURE, UV);
float edge = 1.0 - smoothstep(dissolve_value, dissolve_value + edge_width, noise);
if (noise < dissolve_value) {
COLOR = vec4(0.0);
} else {
COLOR = base_col;
}
COLOR.rgb = mix(COLOR.rgb, burn_color.rgb, edge);
}
最主要就是对边缘进行一个平滑插值计算,这样就可以获得一个边缘范围,然后根据插值结果做一个颜色混合,就会有被点燃的感觉。

如果dissolve_value外部使用代码去控制变化,就能实现一个溶解消失的效果,非常的简单有效。