ShaderJoy —— Film Burn (炫光光晕)效果【GLSL】

再炫的特效没有声音也是不完整的~

 

Shader 特效 —— Film Burn.mp4

 

效果图

该特效可以分为以下 5 种效果的融合。

 

 大 Blob 的效果

没添加随机性的大 Blob 示意图

 

结合代码可知,这其实就是二维 sin*cos 的效果。

sin(x)cos(y)

 

对纹理坐标增加了点随机性并随着 progress 移动后的效果如下

 

增加了随机性的大 Blob 动态示意图【gif 对颜色进行了量化】

 

增加了随机性的大 Blob 静态示意图

 

相应代码和注释如下

/// @note 大 Blob
/// 增加一点随机性,改变每个 blob 的形状
        f += .1 +
             sin(((p.x * rand(i) * 6.0) + ///< 影响 blob 的大小
                  (progress * 8.0)) +     ///< 影响 blob 的速度
                 rand(i + 1.43)) *
             cos(((p.y * rand(i + 4.4) * 6.0) + ///< 影响 blob 的大小
                  (progress * 6.0)) +           ///< 影响 blob 的速度
                 rand(i + 2.4));

 

 小粒子的效果

 

相应代码和注释如下

/// @note 小粒子
        f += 1. - clamps(length(p -
                                vec2(smoothRandom(vec2(progress * 1.3), i + 1.0),       ///< 控制粒子的运动位置和轨迹【通过插值确保产生的随机值是连续的】
                                     smoothRandom(vec2(progress * 0.5), i + 6.25))) *
                         mix(20., 70., rand(i)));                                       ///< 影响粒子的大小,值越大粒子越小

其实就是在随机的位置【连续变化】画随机大小的圆。 

 

大 Blob & 小粒子 随着 Progress 的变化

 

f 随着 progress 的变化

从上图中可以看出该效果是 “从无到有再到无” 的一个过程。

 

动态效果【gif 对颜色进行了量化】

 

静态效果

 

相应代码和注释如下

/// @note 颜色随着 progress 而变化
f = pow3(f * color,   ///< 着色
         vec3(1., 2. - sin(progress * PI), 1.3)); ///< 1., [2., 1.], 1.3
f *= sin(progress * PI);

 

纹理坐标的周期性缩放

这里对纹理坐标的值进行了调整以便显示

 纹理坐标的缩放即是对纹理进行缩放的效果

相应代码和注释如下

/// @note 图像周期性缩放
p -= .5;    ///< 以屏幕中心为原点

/// 随机对纹理坐标进行缩放
p *= 1. + (smoothRandom(vec2(progress * 5.), 6.3) * sin(progress * PI) * .05);
p += .5;    ///< 平移原点回左下角

 

带噪点的转场(结合纹理的缩放)

 

相应代码和注释如下

    float bluramount = sin(progress * PI) * .03;

    /// @note repeats 越大,毛玻璃效果越弱
    for (float i = 0.; i < repeats; i++)
    {
        /// 角度转弧度
        float rad = radians((i / repeats) * 360.);
        vec2 q = vec2(cos(rad), sin(rad)) *
                 (rand(vec2(i, p.x + p.y)) + bluramount); ///< 生成噪点

        vec2 uv2 = p + (q * bluramount); ///< 随机噪点偏移纹理坐标,毛玻璃效果
        blurred_image += textureSmoothMix(uv2); ///< 叠加随机偏移的纹理(同时随着 progress 变化)
    }
    blurred_image /= repeats; ///< 平均,模糊
/// @brief 纹理平滑混合
vec4 textureSmoothMix(vec2 p)
{
    return mix(getFromColor(p), getToColor(p), sigmoid(progress, 10.));
}

 

sigmoid 示意图

 

综上

综合以上所有效果后,完整代码和解释如下

float seed = 2.31;

#define PI 3.141592653589
#define PI_HALF (PI/2.)
#define clamps(x) clamp(x, 0., 1.)

#iChannel0 "file://./images/私の初めて、キミにあげます/1 (6).jpeg"
#iChannel1 "file://./images/私の初めて、キミにあげます/timg (4).jpg"

float progress = 0.f;

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

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

float sigmoid(float x, float a)
{
    float b = pow(x * 2., a) / 2.;
    if (x > .5)
    {
        b = 1. - pow(2. - (x * 2.), a) / 2.;
    }
    return b;
}

float apow(float a, float b)
{
    return pow(abs(a), b) * sign(b);
}

/// @brief 三通道的 apow
vec3 pow3(vec3 a, vec3 b)
{
    return vec3(apow(a.r, b.r), apow(a.g, b.g), apow(a.b, b.b));
}

/// @brief 平滑混合
float smoothMix(float a, float b, float c)
{
    return mix(a, b, sigmoid(c, 2.));
}

/// ---------------------------------------------------------
/// 随机函数部分
float rand(float co)
{
    return fract(sin((co * 24.9898) + seed) * 43758.5453);
}

float rand(vec2 co)
{
    return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
}

float rand(vec2 co, float shft)
{
    co += 10.;
    return smoothMix(fract(sin(dot(co.xy, vec2(12.9898 + (floor(shft) * .5), 78.233 + seed))) * 43758.5453),
                     fract(sin(dot(co.xy, vec2(12.9898 + (floor(shft + 1.) * .5), 78.233 + seed))) * 43758.5453),
                     fract(shft));
}

float smoothRandom(vec2 co, float shft)
{
    return smoothMix(smoothMix(rand(floor(co), shft),
                               rand(floor(co + vec2(1., 0.)), shft), fract(co.x)),
                     smoothMix(rand(floor(co + vec2(0., 1.)), shft),
                               rand(floor(co + vec2(1., 1.)), shft), fract(co.x)),
                     fract(co.y));
}
/// ---------------------------------------------------------

/// @brief 纹理平滑混合
vec4 textureSmoothMix(vec2 p)
{
    return mix(getFromColor(p), getToColor(p), sigmoid(progress, 10.));
}

#iUniform vec3 color = vec3(1., 0.7, 0.6)
#iUniform float repeats = 50.0 in {0.0, 100.0}

vec4 transition(vec2 p)
{
    /// @note 粒子效果
    vec3 f = vec3(0.);
    /// 粒子的个数
    for (float i = 0.; i < 20.; i++)
    {
        /// @note 大 Blob
        /// 增加一点随机性,改变每个 blob 的形状
        f += .1 +
             sin(((p.x * rand(i) * 6.0) + ///< 影响 blob 的大小
                  (progress * 8.0)) +     ///< 影响 blob 的速度
                 rand(i + 1.43)) *
             cos(((p.y * rand(i + 4.4) * 6.0) + ///< 影响 blob 的大小
                  (progress * 6.0)) +           ///< 影响 blob 的速度
                 rand(i + 2.4));
        // -------------------------------------------------------------------------

        /// @note 小粒子
        f += 1. - clamps(length(p -
                                vec2(smoothRandom(vec2(progress * 1.3), i + 1.0),       ///< 控制粒子的运动位置和轨迹
                                     smoothRandom(vec2(progress * 0.5), i + 6.25))) *
                         mix(20., 70., rand(i)));                                       ///< 影响粒子的大小,值越大粒子越小

    }
    f += 4.;
    f /= 11.;  ///< 变暗

    /// @note 颜色随着 progress 而变化
    f = pow3(f * color,                  ///< 着色
             vec3(1., 2. - sin(progress * PI), 1.3)); ///< 1., [2., 1.], 1.3
    f *= sin(progress * PI);


    /// @note 图像周期性缩放
    p -= .5;    ///< 以屏幕中心为原点
    /// 随机对纹理坐标进行缩放
    p *= 1. + (smoothRandom(vec2(progress * 5.), 6.3) * sin(progress * PI) * .05);
    p += .5;    ///< 平移原点回左下角


    vec4 blurred_image = vec4(0.);

    /// @note 带噪点的转场效果
    float bluramount = sin(progress * PI) * .03;

    /// @note repeats 越大,毛玻璃效果越弱
    for (float i = 0.; i < repeats; i++)
    {
        /// 角度转弧度
        float rad = radians((i / repeats) * 360.);
        vec2 q = vec2(cos(rad), sin(rad)) *
                 (rand(vec2(i, p.x + p.y)) + bluramount); ///< 生成噪点

        vec2 uv2 = p + (q * bluramount); ///< 随机噪点偏移纹理坐标,毛玻璃效果
        blurred_image += textureSmoothMix(uv2); ///< 叠加随机偏移的纹理(同时随着 progress 变化)

    }
    blurred_image /= repeats; ///< 平均,模糊


    return blurred_image + vec4(f, 0.); ///< 毛玻璃+粒子

}

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

    progress = fract(.5 * iTime); ///< 线性速度

    gl_FragColor = transition(uv);
}

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShaderJoy

您的打赏是我继续写博客的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值