滤镜实际上就是在片元着色器对特定的像素点进行处理。
灰度滤镜
灰度滤镜原理:
- 浮点算法:Gray = R * 0.3 + G * 0.59 + B * 0.11
- 整数算法:Gray = (R30 + G59 + B*11) / 100
- 移位算法:Gray = (R76 + G151 + B*28)>>8
- 平均值法:Gray = (R+G+B)/3
- 仅取绿色:Gray = G
思路:
- 获取原始图片的纹素值
- 选择合适的灰度算法
- 将计算所得赋给gl_FragColor
实例代码
- 顶点着色器(滤镜并不需要操作顶点着色器,所以不同滤镜顶点着色器代码一致):
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) {
vec4 mask = texture2D(Texture, TextureCoordsVarying);
}
权值法(各个颜色的权值参考了GPUImage ,也可以用上面的权值)
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main (void) {
vec4 mask = texture2D(Texture, TextureCoordsVarying);
float luminance = dot(mask.rgb, W);
gl_FragColor = vec4(vec3(luminance), 1.0);
}
平均值法:
float color = (mask.r + mask.g + mask.b) / 3.0;
vec4 tempColor = vec4(color,color,color,1);
gl_FragColor = vec4(vec3(tempColor), 1.0);
一般由于人眼对不同颜色的敏感度不一样,所以三种颜色值的权重不一样,一般来说绿色最高,红色其次,蓝色最低,最合理的取值分别为Wr = 30%,Wg = 59%,Wb = 11%,所以权值法相对效果更好一点。
image.png
暖色滤镜
思路:
- 获取原始图片的纹素值
- 将rgb通道的颜色添加相应的红/绿色值,再作为rgb通道的值,
- 将计算所得赋给gl_FragColor
vec4 mask = texture2D(Texture, TextureCoordsVarying);
gl_FragColor = mask + vec4(0.3,0.3,0.0,0.0);
image.png
冷色滤镜
思路:
- 获取原始图片的纹素值
- 将rgb通道的颜色添加相应的蓝色值,再作为rgb通道的值,
- 将计算所得赋给gl_FragColor
vec4 mask = texture2D(Texture, TextureCoordsVarying);
gl_FragColor = mask + vec4(0.0,0.0,0.3,0.0);
image.png
颠倒滤镜
思路:
- 获取原始图片的纹素值
- 将纹理坐标做映射 (y -> 1 - y)
- 将计算所得赋给gl_FragColor
vec4 color = texture2D(Texture, vec2(TextureCoordsVarying.x, 1.0 - TextureCoordsVarying.y));
image.png
网友评论