前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenGLES(八)-GLSL案例:分屏滤镜原理OpenGLES(八)-GLSL案例:分屏滤镜原理

OpenGLES(八)-GLSL案例:分屏滤镜原理OpenGLES(八)-GLSL案例:分屏滤镜原理

作者头像
用户8893176
发布2021-08-09 11:19:01
1.3K0
发布2021-08-09 11:19:01
举报
文章被收录于专栏:小黑娃Henry

OpenGLES(八)-GLSL案例:分屏滤镜原理

效果图

本文中着重介绍glsl的分屏逻辑,对于iOS端的代码就省略了。如果对这部分有兴趣跳转OpenGLES(五)- ESLS案例:纹理贴图

顶点着色器

代码语言:javascript
复制
attribute vec4 position;
attribute vec2 texCoord;
varying lowp vec2 varyTexCoord;

void main(void){
    gl_Position = position;
    varyTexCoord = texCoord;
}

片元着色器

对于分屏功能,最重要的就是顶点坐标和纹素的获取关系;也就是对于分屏滤镜算法的理解。

二分屏
  • 图中的数字都是纹理坐标
  • 左图中的红线代表了二分屏后的展示内容
  • 图中展示就是通过运算将原图中的纹理坐标,转换成目标图中的纹理坐标

认真观察两张图的坐标关系:

  1. 转换前原坐标(0.25,0),(0.75,0)-> 转换后纹理坐标(0,0),(0.5,0)
  2. 转换前(0.25,0),(0.75,0)-> 转换后(0.5,0),(1,0)
  3. 转换前(0.25,1),(0.75,1)-> 转换后(0,1),(0.5,1)
  4. 转换前(0.25,1),(0.75,1)-> 转换后(0.5,1),(1,1)

这种会涉及到一个简单的算法,具体看片元着色器中的处理:

代码语言:javascript
复制
precision highp float;
varying lowp vec2 varyTexCoord;
uniform sampler2D colorMap;

void main(void){
    vec2 temp = varyTexCoord;
    if (temp.x <= 0.5) {
        temp.x = temp.x + 0.25;
    }else{
        temp.x = temp.x - 0.25;
    }
    gl_FragColor = texture2D(colorMap, temp);
}

这里的计算不考虑顶点坐标,完全就是纹理坐标的映射关系。只需考虑在某一个纹理位置,你想要显示哪个坐标的纹素。

四分屏

因为4分屏中的每一部分都是完成的纹理图片,所以在计算上会略有不同。

坐标关系就不一一举例。

代码语言:javascript
复制
precision highp float;
varying lowp vec2 varyTexCoord;
uniform sampler2D colorMap;

void main(void){
    vec2 temp = varyTexCoord;
    if(temp.x <= 0.5){
        temp.x = temp.x * 2.0;
    }else{
        temp.x = (temp.x - 0.5) * 2.0;
    }
    if(temp.y <= 0.5){
        temp.y = temp.y * 2.0;
    }else{
        temp.y = (temp.y - 0.5) * 2.0;
    }
    gl_FragColor = texture2D(colorMap, temp);
}

剩下的部分大同小异,都可以通过这种画图的方式来寻找思路,这里直接放出五分屏九分屏的代码。

五分屏
代码语言:javascript
复制
precision highp float;
varying lowp vec2 varyTexCoord;
uniform sampler2D colorMap;

void main(void){
    vec2 temp = varyTexCoord;
    
    if(temp.x <= 0.5) {
        temp.x = temp.x * 2.0;
    }else{
        temp.x = (temp.x - 0.5) * 2.0;
    }
    if(temp.y <= 0.5) {
        temp.y = temp.y * 2.0;
    }else{
        temp.y = (temp.y - 0.5) * 2.0;
    }
    if((varyTexCoord.x >= 0.25 && varyTexCoord.x <= 0.75) && (varyTexCoord.y >= 0.25 && varyTexCoord.y <= 0.75)){
        temp = vec2((varyTexCoord.x - 0.25) * 2.0,(varyTexCoord.y - 0.25) * 2.0);
    }
    
    gl_FragColor = texture2D(colorMap, temp);
}
九分屏
代码语言:javascript
复制
precision highp float;
varying lowp vec2 varyTexCoord;
uniform sampler2D colorMap;

void main(void){
    vec2 temp = varyTexCoord;
    
    if(temp.x <= 1.0 / 3.0){
        temp.x = temp.x + 1.0 / 3.0;
    }else if(temp.x >= 2.0 / 3.0){
        temp.x = temp.x - 1.0 / 3.0;
    }
    
    if(temp.y <= 1.0 / 3.0){
        temp.y = temp.y + 1.0 / 3.0;
    }else if(temp.y >= 2.0 / 3.0){
        temp.y = temp.y - 1.0 / 3.0;
    }
    
    gl_FragColor = texture2D(colorMap, temp);
}
总计

简单总结一下,想要完成这种类似的滤镜效果就是要通过观察找到变换的规律,然后通过对纹理坐标的计算来完成滤镜效果。个人理解就是:找到几个关键点,然后思考这些点具体需要展示的纹素是什么,从而完成计算.

完整DEMO地址: Github
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/8/18 上,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • OpenGLES(八)-GLSL案例:分屏滤镜原理
    • 顶点着色器
      • 片元着色器
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档