// Bow-tie wipe transition adapted from gl-transitions.com // Author: huynx (MIT) // Original: two triangles grow from the top and bottom edges into a bow tie // that reveals the incoming image. uniform sampler2D from; uniform sampler2D to; uniform vec2 size; uniform vec4 fromCrop; uniform vec4 toCrop; uniform float progress; uniform float fromFlip; uniform float toFlip; out vec4 outColor; vec4 getFromColor(vec2 uv) { vec2 s = vec2(uv.x, fromFlip > 0.5 ? 1.0 - uv.y : uv.y); return texture(from, fromCrop.xy + s * fromCrop.zw); } vec4 getToColor(vec2 uv) { vec2 s = vec2(uv.x, toFlip > 0.5 ? 1.0 - uv.y : uv.y); return texture(to, toCrop.xy + s * toCrop.zw); } float check(vec2 p1, vec2 p2, vec2 p3) { return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); } bool pointInTriangle(vec2 pt, vec2 p1, vec2 p2, vec2 p3) { bool b1 = check(pt, p1, p2) < 0.0; bool b2 = check(pt, p2, p3) < 0.0; bool b3 = check(pt, p3, p1) < 0.0; return (b1 == b2) && (b2 == b3); } bool in_top_triangle(vec2 p) { vec2 vertex1 = vec2(0.5, progress); vec2 vertex2 = vec2(0.5 - progress, 0.0); vec2 vertex3 = vec2(0.5 + progress, 0.0); return pointInTriangle(p, vertex1, vertex2, vertex3); } bool in_bottom_triangle(vec2 p) { vec2 vertex1 = vec2(0.5, 1.0 - progress); vec2 vertex2 = vec2(0.5 - progress, 1.0); vec2 vertex3 = vec2(0.5 + progress, 1.0); return pointInTriangle(p, vertex1, vertex2, vertex3); } float blur_edge(vec2 bot1, vec2 bot2, vec2 top, vec2 testPt) { vec2 lineDir = bot1 - top; vec2 perpDir = vec2(lineDir.y, -lineDir.x); vec2 dirToPt1 = bot1 - testPt; float dist1 = abs(dot(normalize(perpDir), dirToPt1)); lineDir = bot2 - top; perpDir = vec2(lineDir.y, -lineDir.x); dirToPt1 = bot2 - testPt; float min_dist = min(abs(dot(normalize(perpDir), dirToPt1)), dist1); if (min_dist < 0.005) return min_dist / 0.005; return 1.0; } vec4 transition(vec2 uv) { if (in_top_triangle(uv)) { if (progress < 0.1) return getFromColor(uv); if (uv.y < 0.5) { vec2 vertex1 = vec2(0.5, progress); vec2 vertex2 = vec2(0.5 - progress, 0.0); vec2 vertex3 = vec2(0.5 + progress, 0.0); return mix( getFromColor(uv), getToColor(uv), blur_edge(vertex2, vertex3, vertex1, uv)); } if (progress > 0.0) return getToColor(uv); return getFromColor(uv); } if (in_bottom_triangle(uv)) { if (uv.y >= 0.5) { vec2 vertex1 = vec2(0.5, 1.0 - progress); vec2 vertex2 = vec2(0.5 - progress, 1.0); vec2 vertex3 = vec2(0.5 + progress, 1.0); return mix( getFromColor(uv), getToColor(uv), blur_edge(vertex2, vertex3, vertex1, uv)); } return getFromColor(uv); } return getFromColor(uv); } void main() { vec2 uv = gl_FragCoord.xy / size; outColor = transition(uv); }