「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战」
缩放效果
纹理中心缩放实现原理是调整纹理顶点坐标和纹理坐标的关系。调整后的顶点坐标是以(0.5,0.5)
为中心点,然后根据缩放系数计算缩放大小。amplitude
缩放系数越接近1缩放大小就越小。
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
//中心点
vec2 anchorPoint = vec2(0.5, 0.5);
float amplitude = 1.5;
vec2 textCoords = vec2(anchorPoint.x + (uv.x - anchorPoint.x) / amplitude, anchorPoint.y + (uv.y - anchorPoint.y) / amplitude);
gl_FragColor = texture(iChannel2, textCoords);
}
缩放动画
具备缩放能力后再增加iTime
参数来缩放具备动画效果。
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
// 缩放时间周期
float duration = 3.;
//缩放中心点
vec2 anchorPoint = vec2(0.5, 0.5);
//根据当前时间进度计算缩放幅度
float time = mod(iTime, duration);
float amplitude = 1.0 + time;
//转化纹理坐标变化
vec2 textCoords = vec2(anchorPoint.x + (uv.x - anchorPoint.x) / amplitude, anchorPoint.y + (uv.y - anchorPoint.y) / amplitude);
gl_FragColor = texture(iChannel2, textCoords);
}
缓动函数
在实际使用动画的过程中经常会去实现不同速度的动画效果。像是线性动画会显得效果比较平淡,可以通过改变动画执行速率让动画效果更加灵动具有弹性自然,可以提高动画效果的高级感。
例如下图所示是比较常用的缓动动画曲线表,通过不同算法函数来实现动画速率不同表现形式。
下面选取几个类别来实现缩放运用缓动函数后的动画效果。首先使用线性函数举个例子,
t
表示当前时间,b
表示初始值,c
是变化量,d
是持续时间,将之前动画例子中time
替换为缓动函数即可,线性函数动画效果与上述动画效果是一致的。
//t: current time(当前时间);
//b: beginning value(初始值);
//c: change in value(变化量);
//d: duration(持续时间)。
float linear(float t, float b, float c, float d) {
return c*t/d + b;
}
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
// 缩放时间周期
float duration = 3.;
//缩放中心点
vec2 anchorPoint = vec2(0.5, 0.5);
//根据当前时间进度计算缩放幅度
float time = mod(iTime, duration);
//
float amplitude = 1.0 + linear(time, 0., 1.5,duration);
//转化纹理坐标变化
vec2 textCoords = vec2(anchorPoint.x + (uv.x - anchorPoint.x) / amplitude, anchorPoint.y + (uv.y - anchorPoint.y) / amplitude);
gl_FragColor = texture(iChannel2, textCoords);
}
Quad
easeInQuad
:开始慢,后来快easeOutQuad
:开始快,后来慢easeInQuad
:开始快,后来快,中间过渡慢
float easeInQuad(float t, float b, float c, float d) {
return c * (t /= d) * t + b;
}
float easeOutQuad(float t, float b, float c, float d) {
return -c * (t/= d) * (t-2.) + b;
}
float easeInOutQuad(float t, float b, float c, float d) {
return (t /= d / 2.) < 1. ? c / 2. * t * t + b : -c / 2. * ((--t) * (t-2.) - 1.) + b;
}
easeInQuad | easeOutQuad | easeInOutQuad |
---|---|---|
Back
easeInBack
:开始慢,后来快,中间会有一段低于起始值easeOutBack
:开始快,后来慢,中间会有一段高于最终值easeInOutBack
:开始快,后来快,中间过渡慢,其中中间会有低于起始值,高于最终值的情况
float easeInBack(float t, float b, float c, float d) {
float s = 1.70158;
return c * (t /= d) * t * ((s + 1.) * t - s) + b;
}
float easeOutBack(float t, float b, float c, float d) {
float s = 1.70158;
return c * ((t = t/d - 1.) * t * ((s + 1.) * t + s) + 1.) + b;
}
float easeInOutBack(float t, float b, float c, float d) {
float s = 1.70158;
if ((t /= d / 2.) < 1.) return c / 2. * (t * t * (((s *= (1.525)) + 1.) * t - s)) + b;
return c / 2.*((t -= 2.) * t * (((s *= (1.525)) + 1.) * t + s) + 2.) + b;
}
easeInBack | easeOutBack | easeInOutBack |
---|---|---|
Bounce
easeInBounce
:开始一段跳跃式,最后一个跃进easeOutBounce
:开始一个跃进,最后一段跳跃式easeInOutBounce
:开始一段跳跃式,最后一段跳跃式,中间是一个跃进
float easeOutBounce(float t, float b, float c, float d) {
if ((t /= d) < (1. / 2.75)) {
return c * (7.5625 * t * t) + b;
} else if (t < (2. / 2.75)) {
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
} else if (t < (2.5 / 2.75)) {
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
} else {
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
}
}
float easeInBounce(float t, float b, float c, float d) {
return c - easeOutBounce(d-t, 0. ,c, d) + b;
}
float easeInOutBounce(float t, float b, float c, float d) {
if (t < d / 2.) {
return easeInBounce(t * 2., 0., c, d) * .5 + b;
} else {
return easeOutBounce(t * 2. - d, 0., c, d) * .5 + c * .5 + b;
}
}
easeInBounce | easeOutBounce | easeInOutBounce |
---|---|---|
总结
除了Bounce
和Quad
缓动函数之外还有其他例如Sine
、Cubic
等其他动画效果不一一例举,在glsl
没有内置方法因此需要开发者自行实现。