OpenGL ES案例-抖音系滤镜实现

一、缩放滤镜

1、效果:

缩放滤镜.gif

2、着色器代码

这里我们的缩放采用的是在顶点着色器里面实现的,当然也可以在片源着色器中实现,并且我们也推荐在片源着色器中实现,这里我们只是为了展示在顶点着色器中也是可以做到的。

1)顶点着色器

attribute vec4 Position;
attribute vec2 TextureCoords;
varying vec2 TextureCoordsVarying;
//时间戳(随着定时器的方法调用及时更新):从0开始一直递增
uniform float Time;
const float PI = 3.1415926;

void main(){
    //一次缩放效果的时长
    float duration = 0.6;
    //最大缩放幅度
    float maxAmplitude = 0.3;
    
    //表示传入的事件周期,即time的范围被控制在0.0~0.6
    //mod(a, b),求模运算 等价于 a%b,GLSL中不支持%求模
    float time = mod(Time,duration);
    
    //amplitude表示振幅,引入PI的目的是为了使用sin函数,将amplitude的范围控制在1.0 ~ 1.3之间,并随着时间变化
    //这里可以不用取绝对值,因为角度的范围是【0,π】,不会出现负数的情况
    float amplitude = 1.0 + maxAmplitude * abs(sin(time * (PI / duration)));
    
    //放大关键代码:将顶点坐标的x和y分别乘以一个放大系数,即振幅,在纹理坐标不变的情况下,就达到了拉伸的效果
    //xy放大,zw保持不变
    gl_Position = vec4(Position.x * amplitude, Position.y * amplitude, Position.zw);
    
    //纹理坐标传递给TextureCoordsVarying
    TextureCoordsVarying = TextureCoords;
}

重点说一下float amplitude = 1.0 + maxAmplitude * abs(sin(time * (PI / duration)));
sin(time * (PI / duration))就相关于sin(time /duration*PI),假设角度α = time /duration*PI先算出当前时间占整个动画时间的比例再得乘以π得到相应的角度,最后得到sin(α)的值;
sin(α)的结果范围是【-1,1】,abs()就是去绝对值,保证得到的范围是正数。

2)片源着色器

precision highp float;

uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;

void main (void) {
    vec4 mask = texture2D(Texture, TextureCoordsVarying);
    gl_FragColor = vec4(mask.rgb, 1.0);
}

二、灵魂出窍滤镜

灵魂出窍实际上两个纹理的混合,因为使用的都是同一个纹理,所以我们并不需要传2个纹理,只需要同时计算原纹理和放大纹理的坐标,取得对应的纹理再混合即可。
大概过程就是:

在动画时间内纹理从1.0放大到1.8并且透明度从0.4减低到0.0,并重复以上过程。

1、效果:

灵魂出窍.gif

2、着色器代码

1)顶点着色器

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

void main (void) {
    gl_Position = Position;
    TextureCoordsVarying = TextureCoords;
}

1)片源着色器

precision highp float;

uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
//当前时间
uniform float Time;

void main (void) {
    //动画总时间
    float duration = 0.7
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值