最近修改濾鏡,發現這篇文章終於把photoshop圖層疊加模式講清楚了 ,就想着實現這篇文章的效果,就做了個小demo
2019/09/04更新
增加了把各種濾鏡轉bitmap的方法
至於效果對不對我也不知道,因爲我沒裝ps就算裝了我也不會用
那篇文章的最後兩個沒有實現,收縮和補償值不知道是啥,也就跳過了
關於A和B,我理解爲A是背景圖片,B是疊加圖片,所以shader代碼內A是color1,B是color2,如果我的理解和文章剛好相反的話直接對調一下就可以了
接下來貼shader代碼,至於文件名,我實在不知道這麼多方法英文叫啥,而且我也懶得查就直接用拼音了
變暗 color_bian_an_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = min(color1,color2);
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
變亮 color_bian_liang_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = max(color1,color2);
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
正片疊底 color_zheng_pian_die_di_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = color1*color2;
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
濾色 color_lv_se_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = 1.0 - (1.0 - color1)*(1.0 - color2);
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
顏色加深 color_yan_se_jia_shen_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = color1 - (1.0 - color1)*(1.0 - color2)/color2;
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
顏色減淡 color_yan_se_jian_dan_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = color1 + color1*color2/(1.0 - color2);
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
線性加深 color_xian_xing_jia_shen_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = color1 + color2 - 1.0;
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
線性減淡 color_xian_xing_jian_dan_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = color1 + color2;
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
疊加 color_die_jia_fs.glsl
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba;
if(color1.r > 0.5)
rgba.r = 1.0 - 2.0 * (1.0 - color1.r) * (1.0 - color2.r);
else
rgba.r = 2.0 * color1.r * color2.r;
if(color1.g > 0.5)
rgba.g = 1.0 - 2.0 * (1.0 - color1.g) * (1.0 - color2.g);
else
rgba.g = 2.0 * color1.g * color2.g;
if(color1.b > 0.5)
rgba.b = 1.0 - 2.0 * (1.0 - color1.b) * (1.0 - color2.b);
else
rgba.b = 2.0 * color1.b * color2.b;
rgba.a = 1.0;
gl_FragColor = rgba;
}
}
強光 color_qiang_guang_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba;
if(color2.r > 0.5)
rgba.r = 1.0 - 2.0 * (1.0 - color1.r) * (1.0 - color2.r);
else
rgba.r = 2.0 * color1.r * color2.r;
if(color2.g > 0.5)
rgba.g = 1.0 - 2.0 * (1.0 - color1.g) * (1.0 - color2.g);
else
rgba.g = 2.0 * color1.g * color2.g;
if(color2.b > 0.5)
rgba.b = 1.0 - 2.0 * (1.0 - color1.b) * (1.0 - color2.b);
else
rgba.b = 2.0 * color1.b * color2.b;
rgba.a = 1.0;
gl_FragColor = rgba;
}
}
柔光 color_rou_guang_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba;
if(color2.r > 0.5)
rgba.r = color1.r*(1.0 - color2.r)+sqrt(color1.r)*(2.0*color2.r - 1.0);
else
rgba.r = 2.0 * color1.r * color2.r + color1.r * color1.r *(1.0 - 2.0*color2.r);
if(color2.g > 0.5)
rgba.g = color1.g*(1.0 - color2.g)+sqrt(color1.g)*(2.0*color2.g - 1.0);
else
rgba.g = 2.0 * color1.g * color2.g + color1.g * color1.g *(1.0 - 2.0*color2.g);
if(color2.b > 0.5)
rgba.b = color1.b*(1.0 - color2.b)+sqrt(color1.b)*(2.0*color2.b - 1.0);
else
rgba.b = 2.0 * color1.b * color2.b + color1.b * color1.b *(1.0 - 2.0*color2.b);
rgba.a = 1.0;
gl_FragColor = rgba;
}
}
亮光 color_liang_guang_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba;
if(color2.r > 0.5)
rgba.r = color1.r + color1.r*(2.0*color2.r - 1.0)/(2.0*(1.0 - color2.r));
else
rgba.r = color1.r - (1.0 - color1.r)*(1.0 - 2.0*color2.r)/(2.0*color2.r);
if(color2.g > 0.5)
rgba.g = color1.g + color1.g*(2.0*color2.g - 1.0)/(2.0*(1.0 - color2.g));
else
rgba.g = color1.g - (1.0 - color1.g)*(1.0 - 2.0*color2.g)/(2.0*color2.g);
if(color2.b > 0.5)
rgba.b = color1.b + color1.b*(2.0*color2.b - 1.0)/(2.0*(1.0 - color2.b));
else
rgba.b = color1.b - (1.0 - color1.b)*(1.0 - 2.0*color2.b)/(2.0*color2.b);
rgba.a = 1.0;
gl_FragColor = rgba;
}
}
點光 color_dian_guang_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba;
if(color2.r > 0.5)
rgba.r = min(color1.r,2.0 * color2.r - 1.0);
else
rgba.r = min(color1.r,2.0 * color2.r);
if(color2.g > 0.5)
rgba.g = min(color1.g,2.0 * color2.g - 1.0);
else
rgba.g = min(color1.g,2.0 * color2.g);
if(color2.b > 0.5)
rgba.b = min(color1.b,2.0 * color2.b - 1.0);
else
rgba.b = min(color1.b,2.0 * color2.b);
rgba.a = 1.0;
gl_FragColor = rgba;
}
}
線性光 color_xian_xing_guang_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = color1 + 2.0 * color2 - 1.0;
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
實色混合 color_shi_se_hun_he_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba;
if(color1.r + color2.r >= 1.0)
rgba.r = 1.0;
else
rgba.r = 0.0;
if(color1.g + color2.g >= 1.0)
rgba.g = 1.0;
else
rgba.g = 0.0;
if(color1.b + color2.b >= 1.0)
rgba.b = 1.0;
else
rgba.b = 0.0;
rgba.a = 1.0;
gl_FragColor = rgba;
}
}
排除 color_pai_chu_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = color1 + color2 - 2.0 * color1 * color2;
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
差值 color_cha_zhi_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp vec4 color2 = texture2D(sTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
if(color2.a == 0.0){
gl_FragColor = color1;
}else if(color2.a != 1.0){
gl_FragColor = mix(color1,color2,color2.a);
}else{
highp vec4 rgba = abs(color1 - color2);
gl_FragColor = vec4(rgba.rgb,1.0);
}
}
2019/8/30更新
又找到一篇文章圖像處理的濾鏡算法,也試着做了一下
在測試去色濾鏡的時候發現顯示效果和灰度濾鏡差不多,看代碼和他的圖片感覺不對,當rgb三個值是一樣的時候,這一像素就是灰色的,而示例圖片明顯發綠,然後我百度了一下發現去色就是指將彩色圖像通過運算轉化成灰度圖像,所以代碼應該是對的,可能圖片用錯了,當然這只是我的理解,僅供參考
裏頭的高斯模糊在我的這篇文章Android opengles 動態調節高斯模糊內實現了,我就沒加上
貼shader代碼,文件名當然還是拼音
灰度 color_hui_du_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp float grey = (color1.r+color1.g+color1.b)/3.0;
gl_FragColor = vec4(grey,grey,grey,1.0);
}
黑白 color_hei_bai_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp float grey = (color1.r+color1.g+color1.b)/3.0;
if(grey >= 100.0/255.0){
grey = 1.0;
}else{
grey = 0.0;
}
gl_FragColor = vec4(grey,grey,grey,1.0);
}
反向 color_fan_xiang_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
gl_FragColor = vec4(1.0 - color1.r,1.0 - color1.g,1.0 - color1.b,1.0);
}
去色 color_qu_se_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp float min_color = min(min(color1.r,color1.g),color1.b);
highp float max_color = max(max(color1.r,color1.g),color1.b);
highp float floor_color =(min_color + max_color)*0.5;
gl_FragColor = vec4(floor_color,floor_color,floor_color,1.0);
}
單色 color_dan_se_fs.glsl文章裏是紅色,我測試改成綠色了
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
gl_FragColor = vec4(0.0,color1.g,0.0,1.0);
}
懷舊 color_huai_jiu_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp float r = 0.393 * color1.r + 0.769 * color1.g + 0.189 * color1.b;
highp float g = 0.349 * color1.r + 0.686 * color1.g + 0.168 * color1.b;
highp float b = 0.272 * color1.r + 0.534 * color1.g + 0.131 * color1.b;
r = r < 0.0 ? 0.0 : r > 1.0 ? 1.0 : r;
g = g < 0.0 ? 0.0 : g > 1.0 ? 1.0 : g;
b = b < 0.0 ? 0.0 : b > 1.0 ? 1.0 : b;
gl_FragColor = vec4(r,g,b,1.0);
}
熔鑄 color_rong_zhu_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp float r = color1.r * 0.5 / (color1.g + color1.b);
highp float g = color1.g * 0.5 / (color1.r + color1.b);
highp float b = color1.b * 0.5 / (color1.r + color1.g);
r = r < 0.0 ? 0.0 : r > 1.0 ? 1.0 : r;
g = g < 0.0 ? 0.0 : g > 1.0 ? 1.0 : g;
b = b < 0.0 ? 0.0 : b > 1.0 ? 1.0 : b;
gl_FragColor = vec4(r,g,b,1.0);
}
冰凍 color_bing_dong_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp float r = (color1.r - color1.g - color1.b)*3.0*0.5;
highp float g = (color1.g - color1.r - color1.b)*3.0*0.5;
highp float b = (color1.b - color1.g - color1.r)*3.0*0.5;
r = r < 0.0 ? 0.0 : r > 1.0 ? 1.0 : r;
g = g < 0.0 ? 0.0 : g > 1.0 ? 1.0 : g;
b = b < 0.0 ? 0.0 : b > 1.0 ? 1.0 : b;
gl_FragColor = vec4(r,g,b,1.0);
}
連環畫 color_lian_huan_hua_fs.glsl
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp float r = abs(color1.g - color1.b + color1.g + color1.r) * color1.r;
highp float g = abs(color1.b - color1.g + color1.b + color1.r) * color1.r;
highp float b = abs(color1.b - color1.g + color1.b + color1.r) * color1.g;
gl_FragColor = vec4(r,g,b,1.0);
}
褐色 color_he_se_fs.glsl代碼和懷舊一樣的
varying highp vec2 vTexCoord;
uniform highp sampler2D sTexture;
uniform highp sampler2D uTexture;
void main() {
highp vec4 color1 = texture2D(uTexture, vec2(vTexCoord.x,1.0-vTexCoord.y));
highp float r = 0.393 * color1.r + 0.769 * color1.g + 0.189 * color1.b;
highp float g = 0.349 * color1.r + 0.686 * color1.g + 0.168 * color1.b;
highp float b = 0.272 * color1.r + 0.534 * color1.g + 0.131 * color1.b;
gl_FragColor = vec4(r,g,b,1.0);
}