skew.glsl
3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
uniform float left;
uniform float top;
uniform int dir;
uniform float intensity;
uniform float origin;
uniform bool sh;
uniform float shx;
uniform float shy;
uniform float shr;
uniform float shz;
uniform float shv;
uniform float prange;
uniform float progress;
uniform vec4 resolution;
uniform sampler2D src1;
uniform sampler2D src2;
varying vec2 vUv;
float pi = 3.141592653;
float map(float a, float b, float c, float d, float v) {
return clamp((v - a) * (d - c) / (b - a) + c, 0., 1.);
}
vec2 mirror(vec2 v) {
vec2 m = mod(v, 2.0);
return mix(m, 2.0 - m, step(1.0, m));
}
vec2 rotateUV(vec2 uv, float rotation, vec2 mid) {
return vec2(cos(rotation) * (uv.x - mid.x) + sin(rotation) * (uv.y - mid.y) + mid.x, cos(rotation) * (uv.y - mid.y) - sin(rotation) * (uv.x - mid.x) + mid.y);
}
vec2 getAngle(vec2 p1) {
return vec2(.5, .5) * normalize(p1);
}
float qinticOut(float t, float power) {
return 1.0 - pow(1. - t, power);
}
float elasticOut(float t) {
return sin(13.0 * t * pi / shv) * pow(5.5, 3. * (t - 1.0));
}
vec2 shake(vec2 uv, float p, float shx, float shy, float tilt, float z) {
float m = elasticOut(p);
float n = (1. - p) * p;
if (tilt != 0.) {
float tmc = (1. - m) * m * n;
uv = rotateUV(uv, tmc * tilt, vec2(.5, .5));
}
if (z != 0.) {
p = p * p;
uv.x -= 0.5;
uv.y -= 0.5;
uv *= (z * p * n + 1.);
uv.x += 0.5;
uv.y += 0.5;
}
if (shx != 0. && shy != 0.) {
uv.x += m * shx * 2. * n;
uv.y -= m * (1. - m) * shy * n;
}
return uv;
}
void main() {
vec2 uv = vUv;
vec2 vw = uv;
vec2 vwo = vw;
float m = progress;
float steps = 1.0 / (max(abs(left), abs(top)) + 2.);
float ms = m;
if (sh) ms = qinticOut(m, 10.);
float flip = (m - 0.5) * 2.;
float mult = sin(ms * pi);
mult = min(mult, 0.5);
if (dir == 1 || dir == 2) mult /= 10.;
if (dir == 1) {
float shift = origin <= 0.5 ? uv.y - origin : origin - uv.y;
float shift2 = origin == 0. || origin == 1. ? 1. : origin;
vw.x += sign(left) * mix(shift, shift - 1., ms) * intensity;
} else if (dir == 2) {
float shift = origin <= 0.5 ? uv.x - origin : origin - uv.x;
float shift2 = origin == 0. || origin == 1. ? 1. : origin;
vw.y += sign(top) * mix(shift, shift - shift2, ms) * intensity;
} else {
vec2 d1 = getAngle(vec2(0.5 * top, 0.5 * left));
vec2 d2 = getAngle(vec2(0.5 * top, 0.5 * left));
float l1 = length(vec2(left > 0. ? 1. - uv.x : uv.x, top > 0. ? 1. - uv.y : uv.y));
float l2 = length(vec2(left > 0. ? uv.x : 1. - uv.x, top > 0. ? uv.y : 1. - uv.y));
vec2 a = vw + l1 * d1 * flip * (step(top * left, 0.) - 0.5) * intensity;
vec2 b = vw + l2 * d2 * flip * (step(top * left, 0.) - 0.5) * intensity;
vw = mix(a, b, ms);
}
uv = mix(vwo, vw, mult);
if (sh) uv = shake(uv, 1. - m, shx, shy, shr, shz);
vec2 nUv = vec2(uv.x + ms * left, uv.y + ms * top);
nUv = mirror(nUv);
vec2 nUvIn = nUv;
if (mod(left, 2.0) != 0.) nUvIn.x *= -1.;
if (mod(top, 2.0) != 0.) nUvIn.y *= -1.;
float nprog = map((0.5 - prange), (0.5 + prange), 0., 1., ms);
vec4 col = mix(TEXTURE2D(src1, nUv), TEXTURE2D(src2, nUvIn), nprog);
gl_FragColor = col;
}