本案例的目的是理解如何用GLSL实现灰度+颠倒+马赛克(共5种)
滤镜
整体的效果图如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c4SodLTT-1597156566845)(https://upload-images.jianshu.io/upload_images/2251862-be323a8ac7062d5e.gif?imageMogr2/auto-orient/strip)]
- 准备工作的代码与OpenGL ES 案例11:分屏滤镜中一致,只需要修改相应的底部item数组及对应的着色器名称等,这里不再说明这部分内容
- 顶点着色器也没有任何变化,主要是片元着色器中的实现滤镜算法
下面只针对滤镜的自定义片元着色器中的GLSL代码进行解释说明
灰度滤镜
灰度滤镜的实现原理是让RGB值保持一个平衡并填充,或者只保留一个亮度值
,即绿色,在人眼中,绿色的亮度是最显眼的,绿色值越深,在肉眼观察中图片越暗淡,这是眼睛的一种生理现象。
灰度滤镜的算法一共有5种,大致分为3类
- 权值法:处理后的图片比较逼真
- 浮点算法:
Gray = R*0.3 + G*0.59 + B*0.11
(RGB的权重总和为1) - 整数方法:
Gray = (R*30 + G*59 + B*11)/100
(RGB的权重总和为100) - 移位方法:
Gray = (R*76 + G*151 + B*28)>>8
- 浮点算法:
- 平均值法:
Gray = (R+G+B)/3
,处理后的图片比较柔和 - 仅取绿色:
Gray = G
,这种方式方便简单,且易用
在片元着色器中分别使用 浮点算法 和 仅取绿色实现灰度滤镜算法。
- 浮点算法:这里的RGB权重取自GPUImage框架
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
//RGB的变换因子,即权重值
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main(){
//获取对应纹理坐标系下色颜色值
vec4 mask = texture2D(Texture, TextureCoordsVarying);
//将颜色mask 与 变换因子相乘得到灰度值
float luminance = dot(mask.rgb, W);
//将灰度值转换为(luminance,luminance,luminance,mask.a)并填充到像素中
gl_FragColor = vec4(vec3(luminance), 1.0);
}
- 仅取绿色
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
void main(){
//获取对应纹理坐标系下色颜色值
vec4 mask = texture2D(Texture, TextureCoordsVarying);
//将RGB全部设置为G,即GRB全部取绿色值
gl_FragColor = vec4(mask.g, mask.g, mask.g,