最近修改滤镜,发现这篇文章终于把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);
}