ShaderJoy —— 果冻般的弹性 “抖抖抖“ 特效【GLSL】

1,397 阅读2分钟

效果图

由于最近工作比较忙,有一段时间没有更新特效专栏了,但是期间也收集了一些挺有意思的特效代码,后续经过整理会陆续加入到专栏里面来和各位读者进行分享~ ( ゚∀゚) ノ♡

并且尽量以简单的语言来解释原理而不是用枯燥乏味的长篇大论以及堆砌晦涩难懂的公式【我自己遇到这样的文章以很头疼 (ノへ ̄、) 】,当然如果有什么地方读者大大觉得我没有说清楚,也欢迎留言,提醒我进行补充。

核心算法

该特效关键用到 sin(sin(x * a))*b, a = 3., b = 20. 这个数学公式,很神奇 (๑•̀ㅂ•́)و✧ 有木有?!

/// @note 不同网格错开不同的偏移   
vec2 offs = vec2(sin(uv.y * scale + sin(iTime * 3.) * 20. + id.y * 0.2),                      sin(uv.x * scale + sin(iTime * 3.) * 20. + id.x * 0.2));

这个数学公式的函数图如下

显然纹理坐标在 x y 方向上都是遵循这种 “震荡” 的方式,而且本例中周期都是相同的,只不过各个纹理坐标由于所处的网格不同、本身坐标不同,而进行了一定程度的偏移

某一时刻的 offs 可视化如下所示

注意,黑色的区域不都是 0,有些其实是负值

正是有了各个坐标的不同偏移量以及随着时间的周期性震荡,才最终实现了最开头的那个神奇效果~

完整代码和注释

#iChannel0 "file://../images/19.jpg"

#iUniform float scale = 60. in {1., 100.}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    /// @note 归一化的屏幕坐标(from 0 to 1)
    vec2 uv = fragCoord / iResolution.xy;
    /// @note 划分网格
    vec2 id = floor(uv * scale);

    /// @note 不同网格错开不同的偏移
    vec2 offs = vec2(sin(uv.y * scale + sin(iTime * 3.) * 20. + id.y * 0.2),
                     sin(uv.x * scale + sin(iTime * 3.) * 20. + id.x * 0.2));

    offs *= .01;
    uv.xy += offs ;

    /// @note 采样图像并显示
    vec3 col = texture(iChannel0, uv).rgb;
    fragColor = vec4(col, 1.0);
}

不知道怎么运行的同学可以参考我的这篇文章 — 《非常方便的 VSCode 的 Shader 插件 -- Shader Toy》