先推荐一个在线的编辑器
https://editor.thebookofshaders.com/
可以将以下的代码复制到编辑器中查看效果
文章的代码来自于网站: The Book of Shaders: 2D Matrices
#ifdef
GL_ES precision mediump float;
#endif
// 平移
// 给st变量加一个包含每个片段的位置的向量
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
// in 关键字表示该参数是输入参数
// 定义一个函数,用于绘制一个盒子形状
// _st 是当前片段的坐标
// _size 是盒子的大小
float box(in vec2 _st, in vec2 _size){
// 调整盒子的大小,将其从中心开始计算
_size = vec2(0.5) - _size*0.5;
// 使用 smoothstep 函数创建一个平滑的过渡,用于定义盒子的边界
vec2 uv = smoothstep(_size, _size+vec2(0.001), _st);
// 对盒子的另一侧也进行平滑过渡
uv *= smoothstep(_size, _size+vec2(0.001), vec2(1.0)-_st);
// 返回两个方向过渡的乘积,得到盒子的形状
return uv.x*uv.y;
}
float drawCross(in vec2 _st,float _size){
return box(_st,vec2(_size,_size/4.))+
box(_st,vec2(_size/4.,_size));
}
// 旋转
// 定义一个名为 rotate2d 的函数,它接受一个 float 类型的参数
mat2 rotate2d(float _angle){
// 使用 cos 和 sin 函数计算旋转矩阵的元素
// cos(_angle) 是旋转矩阵左上角的元素
// -sin(_angle) 是旋转矩阵右上角的元素
// sin(_angle) 是旋转矩阵左下角的元素
// cos(_angle) 是旋转矩阵右下角的元素
return mat2(cos(_angle),-sin(_angle),
sin(_angle),cos(_angle));
}
// 缩放
// 函数返回一个 2x2 的矩阵 mat2,用于在二维空间中进行缩放操作
mat2 scale2d(vec2 _scale){
// 使用 mat2 构造函数创建一个 2x2 的矩阵
// 矩阵的第一行第一列元素为 _scale.x,这将影响 x 轴方向的缩放
// 矩阵的第一行第二列元素为 0.0,这意味着在 x 轴缩放时不会影响 y 轴
// 矩阵的第二行第一列元素为 0.0,这意味着在 y 轴缩放时不会影响 x 轴
// 矩阵的第二行第二列元素为 _scale.y,这将影响 y 轴方向的缩放
return mat2(_scale.x,0.0,
0.0,_scale.y);
}
// 绘制雪花的函数
float drawSnowflake(in vec2 _st, float _size) {
float snowflake = 0.0;
// 定义雪花的基本形状,可以通过多个旋转的线条组合
for (int i = 0; i < 6; i++) {
float angle = radians(float(i) * 60.0);
mat2 rot = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
vec2 p = rot * (_st - vec2(0.5));
p += vec2(0.5);
snowflake += box(p, vec2(_size / 10.0, _size));
}
return snowflake;
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution;
// 初始化颜色为黑色
vec3 color = vec3(0.0);
// 定义一个平移向量,根据时间的正弦和余弦值来改变位置
// cos(u_time) 表示在 x 轴上的平移,周期性变化-1~1
// sin(u_time) 表示在 y 轴上的平移,周期性变化-1~1
// 以⚪的路径在移动
// vec2 translte = vec2(cos(u_time),sin(u_time));
vec2 translte = vec2(0.25,0.25);
// 将平移向量应用到当前片段的坐标上
// st += translte*0.35;
// 旋转的使用
st -= vec2(0.5);
st = rotate2d(sin(u_time)*6.282)*st;
st = scale2d(vec2(sin(u_time)*1.25))*st;
st += vec2(0.5);
// 调用 box 函数,传入平移后的坐标和盒子的大小
// 并将结果赋值给颜色向量
// color = vec3(box(st, vec2(0.5)));
// color += vec3(drawCross(st,0.25));
color += vec3(drawSnowflake(st, 0.2));
gl_FragColor = vec4(color,1.0);
}