OpenGL ES-马赛克滤镜

122 阅读1分钟

马赛克滤镜其实就是在我们加载本地图片的基础上修改片元着色器实现的,本质上是把图片的一个区域用同一个颜色表示,从而降低图像分辨率,

使用OpenGL ES加载本地图片请移步juejin.cn/post/701290…

源码地址:github.com/visual-ios/…

普通马赛克片元着色器代码

precision highp float;


uniform sampler2D Texture;

varying vec2 TextureCoordsVarying;


const vec2 TexSize = vec2(400.0, 400.0);

const vec2 mosaicSize = vec2(16.0, 16.0);


void main (void) {

    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;

}

六边形马赛克片元着色器代码

precision highp float;

uniform sampler2D Texture;

varying vec2 TextureCoordsVarying;

const float mosaicSize = 0.03;

void main (void)

{

    float length = mosaicSize;

    float TR = 0.866025;

    float TB = 1.5;

    float x = TextureCoordsVarying.x;

    float y = TextureCoordsVarying.y;

    int wx = int(x / TB / length);

    int wy = int(y / TR / length);

    vec2 v1, v2, vn;    

    if (wx/2 * 2 == wx) {

        if (wy/2 * 2 == wy) {

            v1 = vec2(length * 1.5 * float(wx), length * TR * float(wy));

            v2 = vec2(length * 1.5 * float(wx + 1), length * TR * float(wy + 1));

        } else {

            
            v1 = vec2(length * 1.5 * float(wx), length * TR * float(wy + 1));

            v2 = vec2(length * 1.5 * float(wx + 1), length * TR * float(wy));

        }

    }else {

        if (wy/2 * 2 == wy) {

            v1 = vec2(length * 1.5 * float(wx), length * TR * float(wy + 1));

            v2 = vec2(length * 1.5 * float(wx + 1), length * TR * float(wy));

        } else {

            //(0,0),(1,1)

            v1 = vec2(length * 1.5 * float(wx), length * TR * float(wy));

            v2 = vec2(length * 1.5 * float(wx + 1), length * TR * float(wy + 1));

        }

    }

    

    float s1 = sqrt(pow(v1.x - x, 2.0) + pow(v1.y - y, 2.0));

    float s2 = sqrt(pow(v2.x - x, 2.0) + pow(v2.y - y, 2.0));

    if (s1 < s2) {

        vn = v1;

    } else {

        vn = v2;

    }

    vec4 color = texture2D(Texture, vn);

    gl_FragColor = color;    

}