OpenGL & Metal

OpenGL ES的滤镜效果 -- 分屏

2020-08-13  本文已影响0人  黑眼豆豆_

首先,我们看效果,

分屏效果.png
分屏的原理就是改变纹理坐标和纹理之间的对应关系

iOS端代码

准备工作可以看之前的代码,GLSL绘制金字塔--纹理和颜色的混合

原始效果

无滤镜就是讲纹理坐标跟纹理素材进行一一对应即可。

顶点着色器

//顶点坐标
attribute vec4 Position;
//纹理坐标
attribute vec2 TextureCoords;
//传入片元着色器的纹理坐标
varying vec2 TextureCoordsVarying;

void main () {
    //gl_Position内建变量
    gl_Position = Position;
    TextureCoordsVarying = TextureCoords;
}

片元着色器

片元着色器就是将纹理坐标和图片进行对应即可

precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;

void main (void) {
    //将纹理坐标和纹理一一对应
    vec4 mask = texture2D(Texture, TextureCoordsVarying);
    gl_FragColor = mask;
}

二分屏

二分屏

顶点着色器

顶点着色器不变,以下几种滤镜效果顶点着色器都是一致的。

片元着色器

二分屏效果就是将屏幕一分为二,然后读取上半部分。如图所示,二分屏读取的时候就是只读Y坐标为[0.5,1]这个区域,所以当Y <= 0.5的时候需要加0.5,大于0.5的时候读对应的坐标

原理图
代码如下:
precision highp float;
uniform sampler2D Texture;
varying highp vec2 TextureCoordsVarying;

void main() {
    vec2 xy = TextureCoordsVarying.xy;
    float y = 0.0;
    if (xy.y <= 0.5) {
        y = xy.y + 0.5;
    } else {
        y = xy.y;
    }
    vec4 mask = texture2D(Texture, vec2(xy.x,y));
    gl_FragColor = mask;

}

三分屏

片元着色器

三分屏.png
三分屏的效果跟二分屏类似,我们都是读Y坐标为[2/3,1]这个区域,所以当Y小于1/3时,需要加2/3,当Y大于1/3小于2/3时,Y要加1/3,当Y大于2/3时,读取对应的坐标
代码如下:
precision highp float;
uniform sampler2D Texture;
varying highp vec2 TextureCoordsVarying;

void main() {
    vec2 xy = TextureCoordsVarying.xy;
    float y = 0.0;
    if (xy.y <= 1.0/3.0) {
        y = xy.y + 2.0 / 3.0;
    } else if (xy.y > 1.0/3.0 && xy.y <= 2.0/3.0){
        y = xy.y + 1.0 / 3.0;
    }else{
        y = xy.y;
    }
    vec4 mask = texture2D(Texture, vec2(xy.x,y));
    gl_FragColor = mask;
}

四分屏

片元着色器

其实4分屏就是在X轴和y轴上同时进行2分屏,如图


四分屏.png

所以,代码如下:

precision highp float;
uniform sampler2D Texture;
varying highp vec2 TextureCoordsVarying;

void main() {
    vec2 xy = TextureCoordsVarying.xy;
    float y = 0.0;
    float x = 0.0;
    if (xy.y <= 0.5) {
        y = xy.y + 0.5;
    } else {
        y = xy.y;
    }
    
    if (xy.x <= 0.5) {
        x = xy.x + 0.25;
    } else {
        x = xy.x - 0.25;
    }
    vec4 mask = texture2D(Texture, vec2(x,y));
    gl_FragColor = mask;
}

六分屏

片元着色器

六分屏.png
六分屏效果就是在X轴上分成3等分,在Y轴上分成2等分,代码如下:
precision highp float;
uniform sampler2D Texture;
varying highp vec2 TextureCoordsVarying;

void main() {
    vec2 xy = TextureCoordsVarying.xy;
    float y = 0.0;
    float x = 0.0;
    if (xy.y <= 0.5) {
        y = xy.y + 0.5;
    } else {
        y = xy.y;
    }
    
    if (xy.x <= 1.0/3.0) {
        x = xy.x + 1.0/3.0;
    } else if (xy.x > 1.0/3.0 && xy.x <= 2.0/3.0) {
        x = xy.x;
    }else{
        x = xy.x - 1.0/3.0;
    }
    vec4 mask = texture2D(Texture, vec2(x,y));
    gl_FragColor = mask;
}

九分屏

片元着色器

九分屏.png

九分屏效果就是在X轴和Y轴上分成3等分,代码如下:

precision highp float;
uniform sampler2D Texture;
varying highp vec2 TextureCoordsVarying;

void main() {
    vec2 xy = TextureCoordsVarying.xy;
    float y = 0.0;
    float x = 0.0;
    if (xy.y <= 1.0/3.0) {
        y = xy.y + 2.0/3.0;
    } else if (xy.y > 1.0/3.0 && xy.y <= 2.0/3.0) {
        y = xy.y + 1.0/3.0;
    }else{
        y = xy.y;
    }
    
    if (xy.x <= 1.0/3.0) {
        x = xy.x + 1.0/3.0;
    } else if (xy.x > 1.0/3.0 && xy.x <= 2.0/3.0) {
        x = xy.x;
    }else{
        x = xy.x - 1.0/3.0;
    }
    vec4 mask = texture2D(Texture, vec2(x,y));
    gl_FragColor = mask;
}

源码地址:OpenGL ES的滤镜效果 --分屏

上一篇下一篇

猜你喜欢

热点阅读