OpenGL 滤镜进阶(缩放+灵魂出窍+抖动+闪白+毛刺+幻觉)

·  阅读 175

效果图

流程逻辑

详细解析参照 :OpenGL 分屏滤镜

滤镜算法

缩放

  • 原理 :随着时间戳改变放大顶点坐标的倍率

  • 顶点着色器算法流程:

    • 定义缩放效果的周期0.6ms和最大放大幅度1.3倍
    • 用当前时间戳对周期取模,计算当前时间处于效果周期的哪个阶段
    • 计算振幅倍率amplitude
    • 将顶点x,y乘以放大倍率amplitude作为新顶点
  • 振幅计算

用sin函数控制变化曲线, sin(time/ duration * PI )

amplitude = 1.0 + maxAmplitude * abs(sin(time * (PI / duration)))的变化曲线如下:

  • 缩放原理

正常显示对应关系如下

放大1.3倍后显示的对应关系为:

  • 顶点着色Scale.vsh

灵魂出窍

  • 原理

片元着色器中实现算法:两个层的叠加,并且上面的那层随着时间的推移,会逐渐放大且不透明度逐渐降低

  • 片元色器算法流程:

    • 定义一次效果时长0.7,叠加层最大透明度,叠加层最大的放大倍率
    • 计算叠加层当前时间下在周期变化的进度 progress = mod(Time, duration) / duration
    • 计算当前时间下的叠加层的透明度、放大倍率
    • 计算缩小后的纹理坐标
    • 获取叠加层的纹素和原纹素
    • 将原纹理和放大后的纹理进行颜色混合
  • 放大原理

将顶点坐标对应的纹理往中心位置靠拢 不放大时纹理映射关系如下: 放大1.3倍时的纹理映射关系如下:

  • 片元着色器 SoulOut.fsh

抖动

  • 原理

片元着色器中 颜⾊偏移 + 微弱的放大效果

  • 片元着色器算法:

    • 根据当前时间戳计算当前进度的百分比
    • 计算当前进度对应的颜色偏移
    • 计算当前进度对应的缩放比例
    • 获取放大后的纹理坐标
    • 将放大后的纹理纹素进行颜色偏移,获得3组颜色
    • 从3组颜色中分别获取RGBA的值
  • 片元着色器 Shake.fsh

闪白

  • 原理

片元着色器 :添加⽩色图层 ,⽩色图层的透明度随着时间变化

  • 片元着色器算法

    • 通过mod函数计算当前时间戳对应的时间周期

    • 设置一个白色遮罩

    • 计算白色遮罩的振幅,振幅范围是[0,0, 1.0]

    • 获取原图纹理的纹素,并与白色遮罩颜色混合

    • 颜色混合的方式有多种,常用的一般是mix函数或者默认的混合方程式:mask*(1-alpha) + weakMask*alpha

  • 片元着色器 ShineWhite.fsh

毛刺

  • 原理 : 撕裂 + 微弱的颜⾊偏移

    每⼀行像素随机偏移 -1 ~ 1 的距离(这⾥的 -1 ~ 1 是对于纹理坐标来说的),但是如果整个画面都偏移⽐较⼤的值,那我们可能都看不出原来图像的样子。所以我们的逻辑是,设定一个阈值,小于这个阈值才进行偏移,超过这个阈值则乘上一个缩小系数。

    最终呈现的效果是:绝大部分的⾏都会进⾏行微⼩的偏移,只有少量的行会进行较大偏移

  • 片元着色器算法步骤

    • mod函数计算时间周期
    • 计算振幅,范围是「0, 1]
    • 获取像素点随机偏移值,范围是[-1,1]
    • 判断是否需要偏移 & 计算纹理的x坐标
    • 需要偏移,撕裂较大,即x的颜色偏移较大
    • 不需要,撕裂较小,即x的颜色偏移值很微小
    • 获取撕裂后的纹理坐标
    • 计算撕裂后的3组纹素,并获取不同组中的RGBA值
  • 片元着色器 Glitch.fsh

幻觉

  • 原理 :残影和颜⾊色偏移的叠加

    残影的效果: 是在移动的过程中,每经过一段时间间隔,根据当前的位置去创建⼀个新层,并且新层的不透明度随着时间逐渐减弱。于是在一个移动周期内,可以看到很多透明度不同的层叠加在一起,从⽽形成残影的效果。残影,让图片随着时间做圆周运动

    颜⾊偏移: 物体移动的过程是蓝⾊在前面,红色在后面。所以整个过程可以理解成:在移动的过程中,每间隔一段时间,遗失了一部分红⾊通道的值在原来的位置,并且这部分红⾊通道的值,随着时间偏移,会逐渐恢复.

  • 片元着色器算法

    • 通过mod函数计算当前时间周期
    • 设置放大倍数
    • 计算放大后的纹理坐标
    • 获取转全过程中像素点的纹素
    • 通过for循环来新建图层,即幻影颜色
    • 获取由原始图层和新建层叠加的颜色
  • 片元着色器 Vertigo.fsh

完整代码参考 :github

分类:
iOS
标签:
分类:
iOS
标签:
收藏成功!
已添加到「」, 点击更改