美文网首页
利用OpenGL ES实现灰度滤镜及马赛克滤镜

利用OpenGL ES实现灰度滤镜及马赛克滤镜

作者: 丸疯 | 来源:发表于2020-08-27 22:31 被阅读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;

相关文章

网友评论

      本文标题:利用OpenGL ES实现灰度滤镜及马赛克滤镜

      本文链接:https://www.haomeiwen.com/subject/cixwdktx.html