视频效果
Shader特效——“圆角五角星的变换” 的实现 【GLSL】
图片效果
核心代码及思路详解
首先,我们通过 将纹理坐标换算为极坐标 ,然后再将取值范围从 [-, ] 变换到 [-1.5, 0.5] 。
即 ,
该函数三维视图如下
等高线图如下
接着,我们将 angle 送入 函数中,并利用 segments 变量来控制余弦的周期。
函数视图为:
扫描二维码关注公众号,回复:
8963637 查看本文章
将 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 的时候 的函数图
这样我们就把五角星变成了六角,其他形状也可如法炮制。
完整代码
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);
}