在學習完灰度、翻轉、旋渦、馬賽克濾鏡後是否是以爲濾鏡也就這麼回事,今天學習抖音部分濾鏡:縮放、靈魂出竅、抖動、閃白、毛刺,其中那個靈魂出竅我最喜歡。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