OpenGL ES分屏滤镜实现

737 阅读1分钟

现在在抖音快手等平台常见的"左右分屏"的小视频是如何实现的呢?我们可以通过图片看下,分屏滤镜是如何实现的?因为这样的分屏视频,也是通过对每一帧的静态图片处理来实现的.

GLSL渲染图片

使用GLSL渲染一张图片的步骤,和之前的案例一模一样EGL&OpenGL着色语言及案例.我们可以再次回忆下大致的过程.

其中我们重点看以下几点.

设置渲染&帧缓冲区

编译着色器源码

纹理加载

二分屏

  • 当y在00.5之间时,取值范围在0.250.75

  • 当y在0.51之间时,取值范围在0.250.75

片元着色器源码中,添加取值逻辑

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

void main(){
    vec2 uv = TextureCoordsVarying;
    if (uv.y > 0.0 && uv.y <= 0.5) {
        uv.y = uv.y + 0.25;
    }else{
        uv.y = uv.y - 0.25;
    }
    vec4 mask = texture2D(Texture,uv);
    gl_FragColor = vec4(mask.rgb, 1.0);
}

三分屏

  • 当x在01/3之间时,取值范围在1/32/3
  • 当x在2/31之间时,取值范围在1/32/3
  • 中间部分就正常取值

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

void main(){
    vec2 uv = TextureCoordsVarying;
    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;
    }
    vec4 mask = texture2D(Texture,uv);
    gl_FragColor = vec4(mask.rgb, 1.0);
}

四分屏

  • 当x在00.5之间时,取值范围在01
  • 当x在0.51之间时,取值范围在01
  • 当y在00.5之间时,取值范围在01
  • 当y在0.51之间时,取值范围在01

x和y的取值范围,都存在2倍的关系

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

void main(){
    vec2 uv = TextureCoordsVarying;
    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;
    }
    vec4 mask = texture2D(Texture,uv);
    gl_FragColor = vec4(mask.rgb, 1.0);
}

六分屏

  • 当x在01/3之间时,取值范围在1/32/3
  • 当x在2/31之间时,取值范围在1/32/3
  • 当y在00.5之间时,取值范围在0.250.75
  • 当y在0.51之间时,取值范围在0.250.75
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;

void main(){
    vec2 uv = TextureCoordsVarying;
    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.0 && uv.y <= 1.0/2.0) {
        uv.y = uv.y + 1.0/4.0;
    }else {
        uv.y = uv.y - 1.0/4.0;
    }
    vec4 mask = texture2D(Texture,uv);
    gl_FragColor = vec4(mask.rgb, 1.0);
}

九分屏实现和六分屏同理,这里我们只是提供了分屏的解决逻辑,实际如何分屏,还要由产品经理来决定.



推荐

OpenGL ES 案例11:分屏滤镜