美文网首页
利用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