阅读 53

OpenGL ES 滤镜——分屏滤镜

本篇文章讲述如何利用GpenGL ES来来实现分屏特效,话不多说,先上效果图一睹为快。

1.项目架构

项目代码放在了github上了,可以下载下来,对照下面的方法架构图来理解整个的流程。

2.着色器实现

2.1 Normal

顶点着色器,有两个属性,Position顶点坐标和TextureCoords纹理坐标属性。Position赋值给内建变量gl_PositionTextureCoords赋值给varying``修饰的TextureCoordsVarying,传递到纹理着色器,以供使用。

attribute vec4 Position;
attribute vec2 TextureCoords;
varying vec2 TextureCoordsVarying;

void main (void) {
    gl_Position = Position;
    TextureCoordsVarying = TextureCoords;
}
复制代码

片元着色器,TextureCoordsVarying用来接收顶点着色器传进来的纹理坐标。Texture是传进来的纹理对象。main函数实现中,通过texture2D函数,获取与纹理坐标一一对应纹素,来进行纹理着色。

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

void main (void) {
     gl_FragColor = texture2D(Texture, TextureCoordsVarying);
}
复制代码

2.2 SplitScreen_2

效果图如下: 通过效果图我们可以看出,这时纹理的显示,不再与纹理坐标一一对应。而是以水平中轴线为标记,进行了上下的便宜。当y小于0.5时,纹理坐标向下便宜了0.25个位置。当y>0.5是,纹理坐标又向上偏移了0.25。使得最终的显示效果是显示了两个红框位置处的纹理图像。 片元着色器实现如下:

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

void main(){
    vec2 uv = TextureCoordsVarying.xy;
    float y;
    if (uv.y>0.0 && uv.y<=0.5) {
        y = uv.y+0.25;
    } else {
        y = uv.y-0.25;
    }
    gl_FragColor = texture2D(Texture, vec2(uv.x, y));
}
复制代码

2.3 SplitScreen_3

三分屏实现与二分屏实现类似,同样是向上或向下偏了1/3的位置。当然,中间的1/3部分就不好用偏移啦。

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

void main(){
    vec2 uv = TextureCoordsVarying.xy;
    if (uv.y < 1.0/3.0) {
        uv.y = uv.y + 1.0/3.0;
    } else if (uv.y > 2.0/3.0){
        uv.y = uv.y - 1.0/3.0;
    }
    gl_FragColor = texture2D(Texture, uv);
}
复制代码

2.4 SplitScreen_4

四分屏是一个田字形的显示。相当于占用屏幕1/4的面积大小,来显示原来的整个纹理大小。相当于将坐标的x,y进行了放大2倍的操作。 代码如下:

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

void main(){
    vec2 uv = TextureCoordsVarying.xy;
    if(uv.x <= 0.5){
        uv.x = uv.x * 2.0;
    }else{
        uv.x = (uv.x - 0.5) * 2.0;
    }
    
    if (uv.y<= 0.5) {
        uv.y = uv.y * 2.0;
    }else{
        uv.y = (uv.y - 0.5) * 2.0;
    }
    gl_FragColor = texture2D(Texture, uv);
}
复制代码

2.5 SplitScreen_6

六分屏的效果如下: 结合前面的分析,是在x轴上了取了原来的三分之一大小,y轴上去了和原来的二分之一大小。

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

void main(){
    vec2 uv = TextureCoordsVarying.xy;
     if (uv.x < 1.0/3.0) {
           uv.x = uv.x + 1.0/3.0;
       } else if (uv.x > 2.0/3.0){
           uv.x = uv.x - 1.0/3.0;
       }
    
    if (uv.y < 0.5) {
        uv.y = uv.y + 0.25;
    }else{
        uv.y = uv.y - 0.25;
    }
    gl_FragColor = texture2D(Texture, uv);
}
复制代码

2.6 SplitScreen_9

九分屏的实现与四分屏的实现相类似,无非就是将原来的放大2倍变为了放大3倍。

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

void main(){
    vec2 uv = TextureCoordsVarying.xy;
    if(uv.x <= 1.0/3.0){
        uv.x = uv.x * 3.0;
    }
    else if (uv.x <= 2.0/3.0){
        uv.x = (uv.x - 1.0/3.0) * 3.0;
    }
    else{
        uv.x = (uv.x - 2.0/3.0) * 3.0;
    }
    
    if(uv.y <= 1.0/3.0){
        uv.y = uv.y * 3.0;
    }
    else if (uv.y <= 2.0/3.0){
        uv.y = (uv.y - 1.0/3.0) * 3.0;
    }
    else{
        uv.y = (uv.y - 2.0/3.0) * 3.0;
    }
    gl_FragColor = texture2D(Texture, uv);
}

复制代码
文章分类
阅读
文章标签