通过矩阵操作坐标系。
1.平移
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution; // uniform变量,用于传入画布分辨率
uniform float u_time; // uniform变量,用于传入当前时间
// 定义一个函数,生成矩形形状
float box(in vec2 _st, in vec2 _size){
_size = vec2(0.5) - _size*0.5;
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 cross(in vec2 _st, float _size){
return box(_st, vec2(_size,_size/4.)) +
box(_st, vec2(_size/4.,_size));
}
void main(){
vec2 st = gl_FragCoord.xy / u_resolution.xy; // 将片元的坐标规范化到[0,1]的范围内
vec3 color = vec3(0.0); // 初始化颜色为黑色
vec2 translate = vec2(cos(u_time), sin(u_time)); // 根据当前时间计算平移向量
st += translate * 0.35; // 将平移向量乘以0.35,应用于坐标空间,实现形状的移动效果
color += vec3(cross(st, 0.25)); // 将生成的十字形状应用于当前坐标,将结果加到颜色上
gl_FragColor = vec4(color, 1.0); // 将最终的颜色值设置为输出颜色
}
效果如下。
2.旋转
#ifdef GL_ES
precision mediump float;
#endif
#define PI 3.14159265359
uniform vec2 u_resolution; // uniform变量,用于传入画布分辨率
uniform float u_time; // uniform变量,用于传入当前时间
// 定义一个函数,用于进行二维旋转
mat2 rotate2d(float _angle){
return mat2(cos(_angle), -sin(_angle),
sin(_angle), cos(_angle));
}
// 定义一个函数,生成矩形形状
float box(in vec2 _st, in vec2 _size){
_size = vec2(0.5) - _size*0.5;
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 cross(in vec2 _st, float _size){
return box(_st, vec2(_size,_size/4.)) +
box(_st, vec2(_size/4.,_size));
}
void main(){
vec2 st = gl_FragCoord.xy / u_resolution.xy; // 将片元的坐标规范化到[0,1]的范围内
vec3 color = vec3(0.0); // 初始化颜色为黑色
// 从中心将坐标空间移动到vec2(0.0)
st -= vec2(0.5);
// 对坐标空间进行旋转
st = rotate2d(sin(u_time) * PI) * st;
// 将坐标空间移动回原始位置
st += vec2(0.5);
// Show the coordinates of the space on the background
// color = vec3(st.x,st.y,0.0);
// Add the shape on the foreground
color += vec3(cross(st, 0.4));
gl_FragColor = vec4(color, 1.0); // 将最终的颜色值设置为输出颜色
}
效果如下
3.缩放
#ifdef GL_ES
precision mediump float;
#endif
#define PI 3.14159265359
uniform vec2 u_resolution; // uniform变量,用于传入画布分辨率
uniform float u_time; // uniform变量,用于传入当前时间
// 定义一个函数,用于进行缩放
mat2 scale(vec2 _scale){
return mat2(_scale.x, 0.0,
0.0, _scale.y);
}
// 定义一个函数,生成矩形形状
float box(in vec2 _st, in vec2 _size){
_size = vec2(0.5) - _size*0.5;
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 cross(in vec2 _st, float _size){
return box(_st, vec2(_size,_size/4.)) +
box(_st, vec2(_size/4.,_size));
}
void main(){
vec2 st = gl_FragCoord.xy / u_resolution.xy; // 将片元的坐标规范化到[0,1]的范围内
vec3 color = vec3(0.0); // 初始化颜色为黑色
st -= vec2(0.5); // 将坐标空间从中心移动到vec2(0.0)
st = scale(vec2(sin(u_time) + 1.0)) * st; // 对坐标空间进行缩放,缩放因子根据时间变化而变化
st += vec2(0.5); // 将坐标空间移动回原始位置
// Show the coordinates of the space on the background
// color = vec3(st.x,st.y,0.0);
// Add the shape on the foreground
color += vec3(cross(st, 0.2));
gl_FragColor = vec4(color, 1.0); // 将最终的颜色值设置为输出颜色
}
效果如下
4. YUV颜色
YUV 是个用来模拟照片和视频的编码的色彩空间。这个色彩空间考虑人类的感知,减少色度的带宽。
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution; // uniform变量,用于传入画布分辨率
uniform float u_time; // uniform变量,用于传入当前时间
// YUV转RGB矩阵
mat3 yuv2rgb = mat3(1.0, 0.0, 1.13983,
1.0, -0.39465, -0.58060,
1.0, 2.03211, 0.0);
// RGB转YUV矩阵
mat3 rgb2yuv = mat3(0.2126, 0.7152, 0.0722,
-0.09991, -0.33609, 0.43600,
0.615, -0.5586, -0.05639);
void main(){
vec2 st = gl_FragCoord.xy / u_resolution; // 将片元的坐标规范化到[0,1]的范围内
vec3 color = vec3(0.0); // 初始化颜色为黑色
// UV值范围为-1到1,所以需要重新映射st (0.0到1.0)
st -= 0.5; // 变为-0.5到0.5
st *= 2.0; // 变为-1.0到1.0
// 将st作为三维向量的y和z值传入
// 以便与一个3x3矩阵正确相乘
color = yuv2rgb * vec3(0.5, st.x, st.y);
gl_FragColor = vec4(color, 1.0); // 将最终的颜色值设置为输出颜色
}
结果如下。