模拟窗户的效果如下代码。
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform float u_time;
#define GRID_SIZE 5.0
#define SQUARE_SCALE 0.1 // 定义缩放因子为常量
// 绘制一个正方形
// 参数:
// - st: 当前片段的归一化坐标
// - pos: 正方形的位置坐标(归一化)
// - size: 正方形的大小
// - color: 正方形的颜色
// - brightness: 正方形的闪烁亮度
// 返回值:包含颜色和透明度的正方形片段
vec4 square(vec2 st, vec2 pos, float size, vec3 color, float brightness) {
// 计算当前片段与正方形位置的差值
vec2 uv = step(pos, st) - step(pos + vec2(size), st);
// 计算正方形片段的颜色和透明度
vec4 result = vec4(color * brightness * uv.x * uv.y, 1.0);
// 返回正方形片段
return result;
}
void main(){
vec2 st = gl_FragCoord.xy / u_resolution.xy;
vec3 color = vec3(0.0);
// 定义正方形位置数组
vec2 positions[10];
positions[0] = vec2(0.1, 0.15); // index 1
positions[1] = vec2(0.35, 0.35); // index 4
positions[2] = vec2(0.6, 0.25); // index 7
positions[3] = vec2(0.9, 0.2); // index 10
positions[4] = vec2(0.2, 0.6); // index 13
positions[5] = vec2(0.4, 0.9); // index 16
positions[6] = vec2(0.7, 0.55); // index 19
positions[7] = vec2(0.8, 0.85); // index 22
positions[8] = vec2(0.55, 0.65); // index 25
positions[9] = vec2(0.3, 0.85); // index 24
float size = 1.0 / GRID_SIZE * SQUARE_SCALE; // 用 SQUARE_SCALE 控制正方形的大小
vec3 squareColor = vec3(1.0, 0.0, 0.0); // 正方形颜色
for(int i = 0; i < 10; i++) {
vec2 pos = positions[i];
float brightness = abs(sin(u_time + float(i) * 0.5)); // 计算闪烁亮度
vec4 squareColorBrightness = square(st, pos, size, squareColor, brightness);
color += squareColorBrightness.rgb;
}
gl_FragColor = vec4(color, 1.0);
}
square 函数的作用是根据输入的片段坐标 st、位置 pos、大小 size、颜色 color 和闪烁亮度 brightness 绘制一个正方形。
具体步骤如下:
- 首先,我们计算片段坐标
st与正方形的位置pos的差值,并将其存储在向量uv中。这个向量表示了当前片段相对于正方形的位置关系。 - 然后,我们使用
step函数对uv进行处理,生成一个遮罩向量。对于遮罩向量的每个分量,如果当前片段的位置小于等于正方形的位置pos,则对应分量的值为 1,表示当前片段位于正方形内部;否则,对应分量的值为 0,表示当前片段位于正方形外部。 - 接下来,我们将遮罩向量的分量相乘,得到一个新的遮罩值。这个遮罩值在正方形内部为 1,外部为 0,用于限制正方形的绘制范围。
- 然后,我们将颜色
color与闪烁亮度brightness相乘,再乘以遮罩值,得到一个带有颜色和透明度的正方形片段。