【SHADER】Shader实例学习2:Loading Wheel

这篇文章介绍了从GitHub项目中获取的简洁Shader代码,主要讲解了旋转矩阵、UV处理、偏移技巧和循环计算区域等对初学者有益的内容,强调这些经典技巧在实际项目中的应用价值。
摘要由CSDN通过智能技术生成

简介

shader代码来自github上一个项目,compose libraries,但是链接找不到了。。。,代码很简洁,但是里面的技巧适合我这种初学者领会。

Shader代码

const float PI = 3.14159265359;

// 按角度旋转。(安卓的坐标由于从左上开始,所以旋转角度与正常坐标系相反)
mat2 rot(float a) {
    float s = sin(a), c = cos(a);
    return mat2(c, -s, s, c);
}

// 矩形区域
float sdBox(vec2 p, vec2 b) {
    vec2 d = abs(p)-b;
    return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}

// 光柱数量
const float MAX_STEPS = 24.0;

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
    // 坐标系变换至-1到1
    vec2 uv = fragCoord / iResolution.xy * 2.0 - 1.0; // -1..0..1 coordinate system
    float aspect = iResolution.y / iResolution.x;      // aspect ratio
    if (aspect > 1.0) { // landscape mode?
        uv.y *= aspect;
    } else {
        uv.x /= aspect;
    }
    
    // 随时间变化的角度
    float angle = -PI * 2.0 * iTime;

    float l = 0.0; // luminance
    for (float i = .0; i < MAX_STEPS; i++) {
        // 光柱角度
        float rectAngle = PI * 2.0 / MAX_STEPS * i;
        // 旋转
        vec2 p = uv * rot(rectAngle); // rotate
        // 位移
        p.x += 0.4; // move outside
        // 与当前角度的差
        float angleDistance = mod(rectAngle - angle, 2.0 * PI);
        // 随当前角度距离越远,强度越低
        float intensity = 1.0 -  (angleDistance / (PI * 2.0));
        // 矩形区域,长度随强度变化
        float box = sdBox(p, vec2(0.2 * (intensity + .7), 0.003));
        // 矩形随强度平滑缩小
        box = smoothstep(0.0, max(0.03, 0.13 * intensity) , box);
        //l = max(l, 1.0 - box);
        // 绘制矩形区域
        l += 1.0 - box;
    }
    // 校正至0 1区间。(shadertoy网页版clamp的实现有些问题,返回的都是1.;暂不清楚原因)
    l = clamp(0., 1., l);
    vec3 col = vec3(.1, 1., 0.) * l;
    //col = mix(vec3(1.), col, l);
    fragColor = vec4(col, l);
}

代码很少,但是效果还不错,个人觉得这里值得初学者领会的有几点:
1 旋转。涉及到二维变换矩阵。
2 旋转后绘制。与安卓Canvas画图时旋转画布的原理类似,不同的是这里是uv,对我个人来讲,直接面对uv,理解上总是会绕。
3 偏移。p.x += 0.4; 非常实用的小技巧,可以让光柱偏离圆心,视觉效果上,由于长度跟随intensity(角度)变化,看上去就是一个缓慢变化的位移。
4 循环,绘制区域的计算。l += 1.0 - box; 这里用到+号,但是由于输入是uv,而uv实际上只会存在于某个光柱区域,所以实际上累加到其它区域时加的是0,而循环的效果其实就是计算当前帧所有光柱区域。

总结

前面在写shader的时候,习惯于算相对位置和区域,对比这个例子,旋转、位移、循环,用的都很经典,值得好好领会。(我觉得领会这个词对我学习shader很适用,就是很多场景,你觉得你理解了,但其实并没有。。。)

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值