GLSL生成一个会旋转缩放的雪花❄

先推荐一个在线的编辑器

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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值