抖音近幾年比較火,得益于其中一些的好玩的特效與濾鏡玩法,今天簡單分析一下其中的實現原理。對做音視頻開發領域的你會有一些幫助。
涉及到的知識點:OpenGL OpenGL ES GLSL等等。
頂點坐標
頂點坐標.png
OpenGL是采用的笛卡爾坐標系,坐標是以屏幕中心為原點,X軸朝右,Y軸朝上,所以左下角的坐標為(-1,-1),右上角的坐標為(1,1)。
紋理坐標
紋理坐標.png
紋理坐標的原點在左下角(0,0).有的文章說在左上角
圖片濾鏡的原理
圖片濾鏡的原理.png
圖片濾鏡就是對圖片的每一個像素點的RGBA值進行處理。所謂的飽和度濾鏡,灰度濾鏡,奶油濾鏡就是處理原始圖片的每一個像素點,也就是修改原像素點的RGBA.
比如一張圖片有144萬個像素點,片元著色器需要執行144萬次,對每一個像素點進行填充。恁大的計算量CPU雖然可以完成,但它是撐不住的。只能交給GPU處理。
分屏特效-二分屏特效
二分屏png
二分屏特效分析.png
假如取0.25--0.75 這一個區域的像素信息(這是由產品規格所決定的)
二分屏特效計算分析
在處理左上角(0.0,0.0)時取 的是原圖片(0.0,0.25)位置的像素值,以此類推,從左往右,從上至下。
在處理(0.0,0.5)時取的是原圖片的(0.0,0.25)位置的像素值。
由于整個圖片的頂點位置沒有變化,所以頂點著色器沒有任何變化。
attribute vec4 Position;
attribute vec2 TextureCoords;
varying vec2 TextureCoordsVarying;
void main (void) {
gl_Position = Position;
TextureCoordsVarying = TextureCoords;
}
片元著色器
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
void main (void) {
vec2 uv = TextureCoordsVarying.xy;
float y;
if (uv.y >=0.0 && uv.y <= 0.5) {
y = uv.y + 0.25;
}else{
y=uv.y - 0.25;
}
gl_FragColor = texture2D(Texture, vec2(uv.x,y));
}
到這基本上我們就實現了二分屏特效了。
對片元著色器跟頂點著色器不熟悉的參考我另一篇文章:OpenGL ES GLSL相關語法.