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

相關文章
相關標籤/搜索