Shader特效——“圆角五角星的变换” 的实现 【GLSL】

视频效果

Shader特效——“圆角五角星的变换” 的实现 【GLSL】

图片效果

圆角五角星
圆角六角星

核心代码及思路详解

首先,我们通过 atan(y-0.5, x-0.5) 将纹理坐标换算为极坐标 ,然后再将取值范围从 [-\pi\pi]  变换到 [-1.5\pi, 0.5\pi] 。

即 angle= atan(y-0.5, x-0.5) - 0.5*\pi

该函数三维视图如下

 等高线图如下

 接着,我们将 angle 送入 cos(5*x+4.)/4  函数中,并利用 segments 变量来控制余弦的周期。

 cos(5*x+4.)/4 函数视图为:

扫描二维码关注公众号,回复: 8963637 查看本文章
segments=5

 将 angle 和该 cos 函数相结合,我们可得到(由于极坐标的作用,我们可以像童年做剪纸手工一样,把上图余弦首尾相接绕成了一个圈圈)

 等高线图为:

 最后,我们使用一个圆形来截断(二值化)它即可。

vec4 transition (vec2 uv)
{
    vec2 p = uv;
    vec2 center = vec2(0.5, 0.5);

    // atan 的范围是 [-PI, PI]
    // [-1.5*PI, 0.5*PI]
    float angle = atan(p.y - center.y, p.x - center.x) - 0.5 * PI;

    /// (cos(S*x)+4.)/4.
    float radius = (cos(segments * angle) + 4.0) / 4.0;
    float difference = length(p - center); ///< 用圆来截断上面的 radius

    if (difference > radius * progress)
        return getFromColor(uv);
    else
        return getToColor(uv);
}

另外,我们来看看 segments = 6 的时候 cos(6*x+4.)/4 的函数图

segments=6

这样我们就把五角星变成了六角,其他形状也可如法炮制。

完整代码

float segments = 6.; // 控制余弦函数的周期

#define PI 3.141592653589
#define PI_HALF (PI/2.)

#iChannel0 "file://./images/0.jpg"
#iChannel1 "file://./images/2.jpg"

float progress = 0.f;

vec4 getFromColor(vec2 uv)
{
    return texture2D(iChannel0, uv);
}

vec4 getToColor(vec2 uv)
{
    return texture2D(iChannel1, uv);
}

vec4 transition (vec2 uv)
{
    vec2 p = uv;
    vec2 center = vec2(0.5, 0.5);

    // atan 的范围是 [-PI, PI]
    // [-1.5*PI, 0.5*PI]
    float angle = atan(p.y - center.y, p.x - center.x) - 0.5 * PI;

    /// (cos(S*x)+4.)/4.
    float radius = (cos(segments * angle) + 4.0) / 4.0;
    float difference = length(p - center); ///< 用圆来截断上面的 radius

    if (difference > radius * progress)
        return getFromColor(uv);
    else
        return getToColor(uv);
}

void main()
{
    vec2 uv = gl_FragCoord.xy / iResolution.xy;

    progress = fract(.5 * iTime); ///< 线性速度
    gl_FragColor = transition(uv);
}
发布了233 篇原创文章 · 获赞 221 · 访问量 106万+

猜你喜欢

转载自blog.csdn.net/panda1234lee/article/details/104155690