// Hexagonalize crossfade, from gl-transitions.com // Author: Fernando Kuteken (MIT) // Description: both images turn into hexagons, crossfade, then sharpen again. // Hexagonal math from http://www.redblobgames.com/grids/hexagons/ // // Ported to ZShell's GLSL ABI (see wallpaper_trans_bowtie.frag). The // gl-transitions `ratio` contextual value is derived from `size`. Optional // params are fixed here: steps = 50, horizontalHexagons = 20. 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; const int steps = 50; const float horizontalHexagons = 20.0; float ratio; 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); } struct Hexagon { float q; float r; float s; }; Hexagon createHexagon(float q, float r) { Hexagon hex; hex.q = q; hex.r = r; hex.s = -q - r; return hex; } Hexagon roundHexagon(Hexagon hex) { float q = floor(hex.q + 0.5); float r = floor(hex.r + 0.5); float s = floor(hex.s + 0.5); float deltaQ = abs(q - hex.q); float deltaR = abs(r - hex.r); float deltaS = abs(s - hex.s); if (deltaQ > deltaR && deltaQ > deltaS) q = -r - s; else if (deltaR > deltaS) r = -q - s; else s = -q - r; return createHexagon(q, r); } Hexagon hexagonFromPoint(vec2 point, float size) { point.y /= ratio; point = (point - 0.5) / size; float q = (sqrt(3.0) / 3.0) * point.x + (-1.0 / 3.0) * point.y; float r = 0.0 * point.x + 2.0 / 3.0 * point.y; Hexagon hex = createHexagon(q, r); return roundHexagon(hex); } vec2 pointFromHexagon(Hexagon hex, float size) { float x = (sqrt(3.0) * hex.q + (sqrt(3.0) / 2.0) * hex.r) * size + 0.5; float y = (0.0 * hex.q + (3.0 / 2.0) * hex.r) * size + 0.5; return vec2(x, y * ratio); } vec4 transition(vec2 uv) { float dist = 2.0 * min(progress, 1.0 - progress); dist = steps > 0 ? ceil(dist * float(steps)) / float(steps) : dist; float size = (sqrt(3.0) / 3.0) * dist / horizontalHexagons; vec2 point = dist > 0.0 ? pointFromHexagon(hexagonFromPoint(uv, size), size) : uv; return mix(getFromColor(point), getToColor(point), progress); } void main() { vec2 uv = gl_FragCoord.xy / size; ratio = size.x / size.y; outColor = transition(uv); }