利用OpenGL ES实现灰度滤镜及马赛克滤镜
2020-08-27 本文已影响0人
丸疯
实现效果
马赛克灰度.gif灰度滤镜
- 实现灰度滤镜的方式有很多,但原理都大同小异,提高绿色的权重,或者只保留绿色值。
大致分为以下五种:
1 浮点算法:Gray = R * 0.3 + G * 0.59 + B * 0.11
(RGB的权重总和为1)
2 整数方法:Gray = (R * 30 + G * 59 + B * 11)/ 100
(RGB的权重总和为100)
3 移位方法:Gray = (R*76 + G*151 + B*28)>> 8
4 平均值法:Gray = (R+G+B)/3
5 仅取绿色:Gray = G
这里我们选择第一种来实现 - 核心代码
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
const highp vec3 W = vec3(0.19757, 0.73846, 0.06397);
void main (void){
vec4 mask = texture2D(Texture, TextureCoordsVarying);
float luminance = dot(mask.rgb, W);
gl_FragColor = vec4(vec3(luminance), 1.0);
}
dot(mask.rgb, W)
,点乘函数,参数为两个向量。得到常量,我们使用得到的常量构建一个三维向量,加上透明度,就构成的RGBA
颠倒滤镜
- 实现思路
对纹理坐标的t值,用极值1减去对应的t值,就可以达到颠倒的目的。 - 核心代码
vec4 color = texture2D(Texture, vec2(TextureCoordsVarying.x, 1.0 - TextureCoordsVarying.y));
gl_FragColor = color;
矩形马赛克
-
实现思路
矩形马赛克,其实是将周围的像素点,统一成一个像素点。但我们都知道纹理坐标是[0, 1]
之间的值,我们操作起来就没有那么便捷。这里我们定义一个二维向量const vec2 TexSize = vec2(600.0, 600.0)
,用来将我们的纹理坐标做放大处理。再定义一个二维向量const vec2 mosaicSize = vec2(5.0, 5.0)
,用来处理放大后的坐标每5个单位做一个单位,换算到纹理坐标[0,1]
中,就相当于我们每5/600
个单位取同一个纹理坐标。floor()
向下取整函数。这里我们利用先放大,再转换映射关系,再还原到标准的纹理范围区间。得到马赛克纹理,然后渲染。 -
图解
矩形马赛克原理图解.png -
核心代码
vec2 intXY = vec2(TextureCoordsVarying.x*TexSize.x, TextureCoordsVarying.y*TexSize.y);
vec2 XYMosaic = vec2(floor(intXY.x/mosaicSize.x)*mosaicSize.x, floor(intXY.y/mosaicSize.y)*mosaicSize.y);
vec2 UVMosaic = vec2(XYMosaic.x/TexSize.x, XYMosaic.y/TexSize.y);
vec4 color = texture2D(Texture, UVMosaic);
gl_FragColor = color;