上文講到如何將YUV轉換成RGB,之後就可以根據自己的設計,製作自己需要的濾鏡了,例如將紅色變的更紅,增加亮度等。本文以Instagram上的Hefe濾鏡爲例
濾鏡的製作,基本上採用圖層+曲線,結合一些其他屬性的調節,例如這篇文章講解了如何用PS模擬Instagram上的濾鏡。
1.添加邊框
下面是從Instagram中找到的圖片資源,首先是添加邊框
將圖片載入bitmap,然後將圖片綁定給紋理,獲取紋理索引
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
// Set filtering
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
// Load the bitmap into the bound texture.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
然後交給shader
// Set program handles
inputUniformHandler2 = glGetUniformLocation(gProgram, "inputImageTexture2");
// Set the active texture1 unit to texture unit 2.
glActiveTexture(GL_TEXTURE2);
// Bind the texture to this unit.
glBindTexture(GL_TEXTURE_2D, inputTextureHandler2);
// Tell the texture uniform sampler to use this texture in the shader by
// binding to texture unit 1.
glUniform1i(inputUniformHandler2, 2);
獲取邊框RGB
vec3 edge = texture2D(inputImageTexture2, textureCoordinate).rgb;
向量點乘,疊加,將邊框加到原圖之上,texel爲原rgb數據
texel = texel * edge;
在shader中,rgb數據用0.0~1.0之間表示,例如color.r=0.2代表20%的紅色,例如邊框中心rgb都是1,因此,中心是不變的,而邊緣部分會根據邊框的RGB值改變,相當於將邊框覆蓋到原圖之上。
2.改變RGB值
根據設計的效果改變RGB值,類似於PS中的曲線,可以採用單獨寫一個函數來完成,Instagram等APP採用一個255X3像素圖片來完成,3個像素從上到下分別爲R/G/B,從左到右分別代表原RGB0~255所對應的值。新的R/G/B即原來的R/G/B的值在改圖對應位置的值。例如原爲126的R值,即在shader中爲0.5,即對應的新R值爲該圖紅色中間位置的R值。
代碼如下:
texel = vec3(
texture2D(inputImageTexture3, vec2(texel.r, .16666)).r,
texture2D(inputImageTexture3, vec2(texel.g, .5)).g,
texture2D(inputImageTexture3, vec2(texel.b, .83333)).b);
3.添加其他紋理圖
下圖是來自Instagram的hefe濾鏡,需要根據右圖進行調整
代碼如下:
vec3 metal = texture2D(inputImageTexture6, textureCoordinate).rgb;
vec3 metaled = vec3(
texture2D(inputImageTexture5, vec2(metal.r, texel.r)).r,
texture2D(inputImageTexture5, vec2(metal.g, texel.g)).g,
texture2D(inputImageTexture5, vec2(metal.b, texel.b)).b
);
先取出左圖的RGB值,然後根據原圖(預覽畫面)的RGB值到右圖中去取值,例如原圖中某點灰色圖片的RGB值爲(167,173,167),預覽畫面爲棕色(125,125,125),即新的RBG值分別爲右圖中座標爲(0.65,0.5),(0.678,0.5),(0.65,0.5),將新的值繪製到屏幕中。
4.濾鏡強度
如果需要調節濾鏡強度,定義一個float變量,採用mix函數調節
metaled.rgb = mix(originColor.rgb, metaled.rgb, p1);
gl_FragColor = vec4(metaled, 1.0);
理想效果:(來自網絡)