shader-效果-窗户

247 阅读2分钟

模拟窗户的效果如下代码。

#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 绘制一个正方形。

具体步骤如下:

  1. 首先,我们计算片段坐标 st 与正方形的位置 pos 的差值,并将其存储在向量 uv 中。这个向量表示了当前片段相对于正方形的位置关系。
  2. 然后,我们使用 step 函数对 uv 进行处理,生成一个遮罩向量。对于遮罩向量的每个分量,如果当前片段的位置小于等于正方形的位置 pos,则对应分量的值为 1,表示当前片段位于正方形内部;否则,对应分量的值为 0,表示当前片段位于正方形外部。
  3. 接下来,我们将遮罩向量的分量相乘,得到一个新的遮罩值。这个遮罩值在正方形内部为 1,外部为 0,用于限制正方形的绘制范围。
  4. 然后,我们将颜色 color 与闪烁亮度 brightness 相乘,再乘以遮罩值,得到一个带有颜色和透明度的正方形片段。