缩放
原理
可以通过修改顶点坐标和纹理理坐标的对应关系来实现放大和缩小
代码实现
attribute vec4 Position;
attribute vec2 TextureCoords;
varying vec2 TextureCoordsVarying;
//时间戳(及时更新)
uniform float Time;
//
const float PI = 3.1415926;
void main(){时长
//一次缩放效果shi'chang
float duration = 0.6;
//最大缩放幅度
float maxAmplitude = 0.3;
//表示传入的时间周期,time控制在[0,0.6]范围内
//mod(a,b)是求模运算相当于 a % b
float time = mod(Time, duration);
//缩放的幅度,添加sin是为了使用PI,保证缩放幅度在[1.0, 1.3]之间,并随着时间变化
float edutilpma = 1.0 + maxAmplitude * abs(sin(time *(PI/duration)));
//x、y缩放,zw不变
gl_Position = vec4(Position.x * edutilpma,Position.y * edutilpma,Position.zw);
TextureCoordsVarying = TextureCoords;
}
效果
灵魂出窍
原理
两个层的叠加,并且上面的那层随着时间的推移,会逐渐放大且 不透明度逐渐降低 。
代码实现
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
uniform float Time;
void main(){
//一次灵魂出窍的时长
float duration = 0.7;
//最大透明度
float maxAlpha = 0.3;
//最大缩放值
float maxScale = 1.8;
//进度(0,1)
float progress = mod(Time, duration) / duration;
//缩放的透明度
float alpha = maxAlpha * (1.0 - progress);
//缩放的值
float scale = (maxScale - 1.0) * progress + 1.0;
//获得x的缩放
float weakX = 0.5 + (TextureCoordsVarying.x - 0.5)/scale;
//获得y的缩放
float weakY = 0.5 + (TextureCoordsVarying.y - 0.5)/scale;
//获得新的坐标
vec2 weakTextureCoordsVarying = vec2(weakX, weakY);
//读取放大后的颜色值
vec4 maskColor = texture2D(Texture, weakTextureCoordsVarying);
//读取原来的颜色值
vec4 mask = texture2D(Texture, TextureCoordsVarying);
//颜色混合,
gl_FragColor = mask * (1.0 - alpha) + maskColor * alpha;
}
效果
抖动
原理
颜色偏移加上微弱的放大即可实现
代码实现
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
uniform float Time;
void main(){
//一次抖动的时长
float duration = 0.7;
//放大的上限
float maxScale = 1.1;
//颜色偏移最大步长
float offset = 0.02;
//进度0-1
float progress = mod(Time, duration) / duration;
//获得偏移后的颜色(根据时间变化)
vec2 offsetCoords = vec2(offset, offset) *progress;
//获得缩放比例
float scale = 1.0 + (maxScale - 1.0) * progress;
//获得放大后的纹理
vec2 scaleTextureCoords = vec2(TextureCoordsVarying.x / scale, TextureCoordsVarying.y / scale);
//获取偏移后的R、G、B
vec4 maskR = texture2D(Texture, scaleTextureCoords + offsetCoords);
vec4 maskB = texture2D(Texture, scaleTextureCoords - offsetCoords);
//获得原始颜色
vec4 mask = texture2D(Texture, TextureCoordsVarying);
gl_FragColor = vec4(maskR.r, mask.g, maskB.b, mask.a);
}
效果
闪白
原理
添加⽩白⾊色图层 ,⽩白⾊色图层的透明度随着时间变化
代码实现
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
uniform float Time;
const float PI = 3.1415926;
void main(){
//一次闪白时长
float duration = 0.6;
//时间周期0.0-0.6
float time = mod(Time,duration);
//白色
vec4 whiteColor = vec4(1.0, 1.0, 1.0, 1.0);
//振幅(实际就是透明度)0.0-1.0
float amplitude = abs(sin(time * (PI/duration)));
//原始颜色
vec4 mask = texture2D(Texture, TextureCoordsVarying);
//混合颜色
gl_FragColor = mask * (1.0 - amplitude) + whiteColor * amplitude;
}
效果
毛刺
原理
撕裂加上微弱的颜色偏移。
具体实现:就是我们让每⼀一⾏行行像素随机偏移 -1 ~ 1 的距离(这⾥里里的 -1 ~ 1 是对于纹理理坐标来说的),但是如果整个 画⾯面都偏移⽐比较⼤大的值,那我们可能都看不不出原来图像的样⼦子。所以我们的逻辑是,设定⼀一个阈值,⼩小于这个阈值才进⾏行行偏 移,超过这个阈值则乘上⼀一个缩⼩小系数。最终的结果就是 绝⼤大部分的⾏行行都会进⾏行行微⼩小的偏移,只有少量量的⾏行行会进⾏行行较⼤大偏移
代码实现
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
uniform float Time;
const float PI = 3.1415926;
float rand(float n) {
return fract(sin(n) * 43758.5453123);
}
void main(){
float duration = 0.3;
//最大抖动
float maxJitter = 0.06;
//
float colorROffset = 0.01;
//
float colorBOffset = -0.025;
//time范围是0.0-0.6
float time = mod(Time, duration * 2);
//设置振幅,将振幅控制在1.0-1.3之间并随时间变化
float amplitude = max(sin(time * (PI / duration)), 0.0);
//设置像素偏移-1~1
float jitter = rand(TextureCoordsVarying.y) * 2.0 - 1.0;
//是否需要撕裂,如果jitter小于最大抖动*振幅
bool needOffset = abs(jitter) < maxJitter *amplitude;
//获得纹理x的坐标,根据needOffset判断是撕裂大还是小
float textureX = TextureCoordsVarying.x + (needOffset ? jitter : (jitter * amplitude * 0.006));
//获得撕裂后的纹理坐标
vec2 textureCoords = vec2(textureX, TextureCoordsVarying.y);
//获得3组颜色
vec4 mask = texture2D(Texture, textureCoords);
vec4 maskR = texture2D(Texture, textureCoords + vec2(colorROffset * amplitude), 0.0);
vec4 maskB = texture2D(Texture, textureCoords + vec2(colorBOffset * amplitude), 0.0);
gl_FragColor = vec4(maskR.r, mask.g, maskB.b, mask.a);
}