OpenGL ES - 部分抖音滤镜

前言

在学习完灰度、翻转、旋涡、马赛克滤镜后是否是以为滤镜也就这么回事,今天学习抖音部分滤镜:缩放、灵魂出窍、抖动、闪白、毛刺,其中那个灵魂出窍我最喜欢。git

缩放滤镜

还记得那段时间嘛,满屏都是小姐姐就这样搞了我头晕,这个滤镜的原理以及实现就是改变顶点数据来达到这样的变化,顶点着色器的代码以下:github

attribute vec4 position;
attribute vec2 textureCoordinate;
varying lowp vec2 textureCoord;

uniform float time;
const float PI = 3.1415926;

void main(){
    
    // 缩放市场
    float duration = 0.6;
    // 缩放幅度
    float amplitude = 0.25;
    // 周期
    float period = mod(time, duration);
    // 当前幅度 [1, 1.25]
    float currentAmplitude = 1.0 + amplitude * (sin(time * (PI / duration)));
    // 纹理坐标
    textureCoord = textureCoordinate;
    gl_Position = vec4(position.x * currentAmplitude, position.y * currentAmplitude, position.z, position.w);
}
复制代码

灵魂出窍滤镜

是否是这个镜头让你趴在抖音里看而后每天被打,咱们仔细观看能够知道有一层透明的图像放大,而后消失,再根据咱们传时间以及开启定时器让他无限循环就完成了这个效果。这个是改变纹理数据,因此咱们须要片断着色器中实现:学习

precision highp float;
varying lowp vec2 textureCoord;
uniform sampler2D sampler;
uniform float time;

void main(){
    
    float duration = 0.7;
    float maxAlpha = 0.4;
    float maxScale = 1.8;
    
    float progress = mod(time, duration) / duration;
    float alpha = maxAlpha * (1.0 - progress);
    float scale = 1.0 + progress * (maxScale - 1.0);
    
    float sx = 0.5 + (textureCoord.x - 0.5) / scale;
    float sy = 0.5 + (textureCoord.y - 0.5) / scale;
    
    vec2 coord = vec2(sx, sy);
    vec4 mask = texture2D(sampler, coord);
    vec4 origin = texture2D(sampler, textureCoord);
    
    
    gl_FragColor = origin * (1.0 - alpha) + mask * alpha;
}
复制代码

抖动滤镜

同窗喜欢不喜欢我不知道,反正我不喜欢这个滤镜,看着头晕一点感受都没得,可是有点刺激的感受豁,像极了蹦迪时候的你吧😑。仔细观看能够发现有偏移和放大以及蓝色和红色两种颜色闪动,实现这个滤镜也就是这关键的两点以及时间:ui

precision highp float;
varying lowp vec2 textureCoord;
uniform sampler2D sampler;

uniform float time;

void main(){
    float duration = 0.75;
    float maxScale = 1.2;
    float offset = 0.04;
    
    float progress = mod(time, duration) / duration;
    vec2 offsetCoord = vec2(offset, offset) * progress;
    float scale = 1.0 + (maxScale - 1.0) * progress;
    
    vec2 shakeCoord = vec2(0.5, 0.5) + (textureCoord - vec2(0.5, 0.5)) / scale;
    
    vec4 maskR = texture2D(sampler, shakeCoord - offsetCoord);
    vec4 maskB = texture2D(sampler, shakeCoord + offsetCoord);
    vec4 mask = texture2D(sampler, shakeCoord);
    
    gl_FragColor = vec4(maskR.r, mask.g, maskB.b, mask.a);
    
}
复制代码

闪白滤镜

呃呃,就不说这个滤镜了,这个滤镜实现很简单,咱们观察就能知道有一层白色透明度随时间变化,因此看下代码就行啦:spa

precision highp float;
varying lowp vec2 textureCoord;
uniform sampler2D sampler;

uniform float time;
const float PI = 3.1415926;

void main(){
    
    float duration = 0.75;
    float currentTime = mod(time, duration);
    
    vec4 whiteMask = vec4(1.0, 1.0, 1.0, 1.0);
    float amplitude = abs(currentTime * sin(PI / duration));
    
    vec4 mask = texture2D(sampler, textureCoord);
    
    
    gl_FragColor = mask * (1.0 - amplitude) + whiteMask *amplitude;
}
复制代码

毛刺滤镜

是否是快看腻了,这个滤镜也是女的用的多,男的少。这个滤镜原理在于随机偏移1像素是否小于设置的最大偏移阈值与幅度的乘积时来撕裂,因此咱们看到图像只有一些撕裂的,其余的则是偏移。code

precision highp float;
varying lowp vec2 textureCoord;
uniform sampler2D sampler;

uniform float time;
const float PI = 3.1415926;

float rand(float n) {
    // fract(x) 返回x的小数部分数值
    return fract(sin(n) * 50000.0);
}

void main(){
    
    float maxJitter = 0.06;
    float duration = 0.35;
    float colorROffset = 0.03;
    float colorBOffset = -0.03;
    
    float currentTime = mod(time, duration * 2.0);
    float amplitude = max(sin(currentTime * (PI / duration)), 0.0);
    
    float jitter = rand(textureCoord.y) * 2.0 - 1.0;
    bool needOffset = abs(jitter) < maxJitter * amplitude;
    
    float textureX = textureCoord.x + (needOffset ? jitter : (jitter * amplitude * 0.006));
    vec2 textureCoords = vec2(textureX, textureCoord.y);
    
    vec4 mask = texture2D(sampler, textureCoords);
    vec4 maskR = texture2D(sampler, textureCoords + vec2(colorROffset * amplitude, 0.0));
    vec4 maskB = texture2D(sampler, textureCoords + vec2(colorBOffset * amplitude, 0.0));
    
    gl_FragColor = vec4(maskR.r, mask.g, maskB.b, mask.a);
}
复制代码

总结

感受之后都看几回抖音后,能够试着去尝试他的思路把模仿出来🤔。有兴趣的同窗能够再这里获取demo: 传送门, 若是对你有帮助,帮忙点个star✨,谢谢。orm

相关文章
相关标签/搜索