一、缩放滤镜
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