gl-transitions 1.73.0 → 1.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/gl-transitions.js CHANGED
@@ -1,2 +1,2 @@
1
1
  window.GLTransitions=
2
- [{"name":"AdvancedMosaic","paramsTypes":{"pixelSize":"float"},"defaultParams":{"pixelSize":50},"glsl":"// Author: Sergey Kosarevsky\n// License: MIT\n// Description: Both images break into large blocks that blend, then sharpen into the incoming image\n// Tags: pixelate, mosaic, blend\n// Ported from https://gist.github.com/corporateshark/21d2fdd24c706952dc8c\n\nuniform float pixelSize; // = 50.0\n\nvec4 transition(vec2 uv) {\n float T = progress;\n float half_ = 0.5;\n float size = (T < half_) ? mix(1.0, pixelSize, T / half_) : mix(pixelSize, 1.0, (T - half_) / half_);\n float D = size * 0.005;\n // Remap UV to center the mosaic pattern\n vec2 UV = (uv - 0.5) / D;\n vec2 coord = clamp(D * (ceil(UV - 0.5)) + 0.5, 0.0, 1.0);\n vec4 C0 = getFromColor(coord);\n vec4 C1 = getToColor(coord);\n return mix(C0, C1, T);\n}\n","author":"Sergey Kosarevsky","license":"MIT","description":"Both images break into large blocks that blend, then sharpen into the incoming image","tags":["pixelate","mosaic","blend"],"params":{"pixelSize":{"type":"float","default":50}},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"BlockDissolve","paramsTypes":{"blocksize":"float"},"defaultParams":{"blocksize":0.02},"glsl":"// Author: nwoeanhinnogaehr\n// License: MIT\n// Description: The incoming image appears in small random blocks\n// Tags: dissolve, blocks, noise\n// Ported from https://gist.github.com/nwoeanhinnogaehr/b93818de23d4511fde10\n\nuniform float blocksize; // = 0.02\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvec4 transition(vec2 uv) {\n return mix(getFromColor(uv), getToColor(uv), step(rand(floor(uv / blocksize)), progress));\n}\n","author":"nwoeanhinnogaehr","license":"MIT","description":"The incoming image appears in small random blocks","tags":["dissolve","blocks","noise"],"params":{"blocksize":{"type":"float","default":0.02}},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"BookFlip","paramsTypes":{},"defaultParams":{},"glsl":"// Author: hong\n// License: MIT\n// Description: The outgoing image turns like a book page from right to left, revealing the incoming one\n// Tags: page, flip, 3d\n\n// Avoids dividing by zero when the page is edge-on (progress = 0.5).\nfloat nonZero(float x) {\n return abs(x) < 1e-4 ? (x < 0.0 ? -1e-4 : 1e-4) : x;\n}\n\nvec2 skewRight(vec2 p) {\n float skewX = (p.x - progress)/nonZero(0.5 - progress) * 0.5;\n float skewY = (p.y - 0.5)/(0.5 + progress * (p.x - 0.5) / 0.5)* 0.5 + 0.5;\n return vec2(skewX, skewY);\n}\n\nvec2 skewLeft(vec2 p) {\n float skewX = (p.x - 0.5)/nonZero(progress - 0.5) * 0.5 + 0.5;\n float skewY = (p.y - 0.5) / (0.5 + (1.0 - progress ) * (0.5 - p.x) / 0.5) * 0.5 + 0.5;\n return vec2(skewX, skewY);\n}\n\nvec4 addShade() {\n float shadeVal = max(0.7, abs(progress - 0.5) * 2.0);\n return vec4(vec3(shadeVal ), 1.0);\n}\n\nvec4 transition (vec2 p) {\n float pr = step(1.0 - progress, p.x);\n\n if (p.x < 0.5) {\n return mix(getFromColor(p), getToColor(skewLeft(p)) * addShade(), pr);\n } else {\n return mix(getFromColor(skewRight(p)) * addShade(), getToColor(p), pr);\n }\n}\n","author":"hong","license":"MIT","description":"The outgoing image turns like a book page from right to left, revealing the incoming one","tags":["page","flip","3d"],"params":{},"textures":[],"createdAt":"Fri, 27 May 2022 19:13:57 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Bounce","paramsTypes":{"shadow_colour":"vec4","shadow_height":"float","bounces":"float"},"defaultParams":{"shadow_colour":[0,0,0,0.6],"shadow_height":0.075,"bounces":3},"glsl":"// Author: Adrian Purser\n// License: MIT\n// Description: The outgoing image drops out of the frame with a few bounces, revealing the incoming one\n// Tags: bounce, slide, vertical, shadow\n\n// @color Color of the shadow cast on the incoming image\nuniform vec4 shadow_colour; // = vec4(0.,0.,0.,.6)\n// @range(0.01, 0.5) Height of the shadow, relative to the image height\nuniform float shadow_height; // = 0.075\n// @range(1, 10, 1) Number of bounces before settling\nuniform float bounces; // = 3.0\n\nconst float PI = 3.14159265358;\n\nvec4 transition (vec2 uv) {\n float time = progress;\n float stime = sin(time * PI / 2.);\n float phase = time * PI * bounces;\n float y = (abs(cos(phase))) * (1.0 - stime);\n float d = uv.y - y;\n return mix(\n mix(\n getToColor(uv),\n shadow_colour,\n step(d, shadow_height) * (1. - mix(\n ((d / shadow_height) * shadow_colour.a) + (1.0 - shadow_colour.a),\n 1.0,\n smoothstep(0.95, 1., progress) // fade-out the shadow at the end\n ))\n ),\n getFromColor(vec2(uv.x, uv.y + (1.0 - y))),\n step(d, 0.0)\n );\n}\n","author":"Adrian Purser","license":"MIT","description":"The outgoing image drops out of the frame with a few bounces, revealing the incoming one","tags":["bounce","slide","vertical","shadow"],"params":{"shadow_colour":{"type":"vec4","default":[0,0,0,0.6],"color":true,"description":"Color of the shadow cast on the incoming image"},"shadow_height":{"type":"float","default":0.075,"min":0.01,"max":0.5,"description":"Height of the shadow, relative to the image height"},"bounces":{"type":"float","default":3,"min":1,"max":10,"step":1,"description":"Number of bounces before settling"}},"textures":[],"createdAt":"Fri, 10 Nov 2017 17:01:45 +0000","updatedAt":"Fri, 9 Oct 2026 23:18:05 +0200"},{"name":"BowTieHorizontal","paramsTypes":{},"defaultParams":{},"glsl":"// Author: huynx\n// License: MIT\n// Description: Two triangles grow from the left and right edges into a bow tie that reveals the incoming image\n// Tags: wipe, shape, horizontal\n\nconst vec2 bottom_left = vec2(0.0, 1.0);\nconst vec2 bottom_right = vec2(1.0, 1.0);\nconst vec2 top_left = vec2(0.0, 0.0);\nconst vec2 top_right = vec2(1.0, 0.0);\nconst vec2 center = vec2(0.5, 0.5);\n\nfloat check(vec2 p1, vec2 p2, vec2 p3)\n{\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\n}\n\nbool PointInTriangle (vec2 pt, vec2 p1, vec2 p2, vec2 p3)\n{\n bool b1, b2, b3;\n b1 = check(pt, p1, p2) < 0.0;\n b2 = check(pt, p2, p3) < 0.0;\n b3 = check(pt, p3, p1) < 0.0;\n return ((b1 == b2) && (b2 == b3));\n}\n\nbool in_left_triangle(vec2 p){\n vec2 vertex1, vertex2, vertex3;\n vertex1 = vec2(progress, 0.5);\n vertex2 = vec2(0.0, 0.5-progress);\n vertex3 = vec2(0.0, 0.5+progress);\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\n {\n return true;\n }\n return false;\n}\n\nbool in_right_triangle(vec2 p){\n vec2 vertex1, vertex2, vertex3;\n vertex1 = vec2(1.0-progress, 0.5);\n vertex2 = vec2(1.0, 0.5-progress);\n vertex3 = vec2(1.0, 0.5+progress);\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\n {\n return true;\n }\n return false;\n}\n\nfloat blur_edge(vec2 bot1, vec2 bot2, vec2 top, vec2 testPt)\n{\n vec2 lineDir = bot1 - top;\n vec2 perpDir = vec2(lineDir.y, -lineDir.x);\n vec2 dirToPt1 = bot1 - testPt;\n float dist1 = abs(dot(normalize(perpDir), dirToPt1));\n \n lineDir = bot2 - top;\n perpDir = vec2(lineDir.y, -lineDir.x);\n dirToPt1 = bot2 - testPt;\n float min_dist = min(abs(dot(normalize(perpDir), dirToPt1)), dist1);\n \n if (min_dist < 0.005) {\n return min_dist / 0.005;\n }\n else {\n return 1.0;\n };\n}\n\n\nvec4 transition (vec2 uv) {\n if (in_left_triangle(uv))\n {\n if (progress < 0.1)\n {\n return getFromColor(uv);\n }\n if (uv.x < 0.5)\n {\n vec2 vertex1 = vec2(progress, 0.5);\n vec2 vertex2 = vec2(0.0, 0.5-progress);\n vec2 vertex3 = vec2(0.0, 0.5+progress);\n return mix(\n getFromColor(uv),\n getToColor(uv),\n blur_edge(vertex2, vertex3, vertex1, uv)\n );\n }\n else\n {\n if (progress > 0.0)\n {\n return getToColor(uv);\n }\n else\n {\n return getFromColor(uv);\n }\n } \n }\n else if (in_right_triangle(uv))\n {\n if (uv.x >= 0.5)\n {\n vec2 vertex1 = vec2(1.0-progress, 0.5);\n vec2 vertex2 = vec2(1.0, 0.5-progress);\n vec2 vertex3 = vec2(1.0, 0.5+progress);\n return mix(\n getFromColor(uv),\n getToColor(uv),\n blur_edge(vertex2, vertex3, vertex1, uv)\n ); \n }\n else\n {\n return getFromColor(uv);\n }\n }\n else {\n return getFromColor(uv);\n }\n}","author":"huynx","license":"MIT","description":"Two triangles grow from the left and right edges into a bow tie that reveals the incoming image","tags":["wipe","shape","horizontal"],"params":{},"textures":[],"createdAt":"Sat, 24 Mar 2018 12:54:26 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"BowTieVertical","paramsTypes":{},"defaultParams":{},"glsl":"// Author: huynx\n// License: MIT\n// Description: Two triangles grow from the top and bottom edges into a bow tie that reveals the incoming image\n// Tags: wipe, shape, vertical\n\nfloat check(vec2 p1, vec2 p2, vec2 p3)\n{\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\n}\n\nbool PointInTriangle (vec2 pt, vec2 p1, vec2 p2, vec2 p3)\n{\n bool b1, b2, b3;\n b1 = check(pt, p1, p2) < 0.0;\n b2 = check(pt, p2, p3) < 0.0;\n b3 = check(pt, p3, p1) < 0.0;\n return ((b1 == b2) && (b2 == b3));\n}\n\nbool in_top_triangle(vec2 p){\n vec2 vertex1, vertex2, vertex3;\n vertex1 = vec2(0.5, progress);\n vertex2 = vec2(0.5-progress, 0.0);\n vertex3 = vec2(0.5+progress, 0.0);\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\n {\n return true;\n }\n return false;\n}\n\nbool in_bottom_triangle(vec2 p){\n vec2 vertex1, vertex2, vertex3;\n vertex1 = vec2(0.5, 1.0 - progress);\n vertex2 = vec2(0.5-progress, 1.0);\n vertex3 = vec2(0.5+progress, 1.0);\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\n {\n return true;\n }\n return false;\n}\n\nfloat blur_edge(vec2 bot1, vec2 bot2, vec2 top, vec2 testPt)\n{\n vec2 lineDir = bot1 - top;\n vec2 perpDir = vec2(lineDir.y, -lineDir.x);\n vec2 dirToPt1 = bot1 - testPt;\n float dist1 = abs(dot(normalize(perpDir), dirToPt1));\n \n lineDir = bot2 - top;\n perpDir = vec2(lineDir.y, -lineDir.x);\n dirToPt1 = bot2 - testPt;\n float min_dist = min(abs(dot(normalize(perpDir), dirToPt1)), dist1);\n \n if (min_dist < 0.005) {\n return min_dist / 0.005;\n }\n else {\n return 1.0;\n };\n}\n\n\nvec4 transition (vec2 uv) {\n if (in_top_triangle(uv))\n {\n if (progress < 0.1)\n {\n return getFromColor(uv);\n }\n if (uv.y < 0.5)\n {\n vec2 vertex1 = vec2(0.5, progress);\n vec2 vertex2 = vec2(0.5-progress, 0.0);\n vec2 vertex3 = vec2(0.5+progress, 0.0);\n return mix(\n getFromColor(uv),\n getToColor(uv),\n blur_edge(vertex2, vertex3, vertex1, uv)\n );\n }\n else\n {\n if (progress > 0.0)\n {\n return getToColor(uv);\n }\n else\n {\n return getFromColor(uv);\n }\n } \n }\n else if (in_bottom_triangle(uv))\n {\n if (uv.y >= 0.5)\n {\n vec2 vertex1 = vec2(0.5, 1.0-progress);\n vec2 vertex2 = vec2(0.5-progress, 1.0);\n vec2 vertex3 = vec2(0.5+progress, 1.0);\n return mix(\n getFromColor(uv),\n getToColor(uv),\n blur_edge(vertex2, vertex3, vertex1, uv)\n ); \n }\n else\n {\n return getFromColor(uv);\n }\n }\n else {\n return getFromColor(uv);\n }\n}","author":"huynx","license":"MIT","description":"Two triangles grow from the top and bottom edges into a bow tie that reveals the incoming image","tags":["wipe","shape","vertical"],"params":{},"textures":[],"createdAt":"Tue, 27 Mar 2018 10:07:54 +0700","updatedAt":"Fri, 9 Oct 2026 23:12:22 +0200"},{"name":"BowTieWithParameter","paramsTypes":{"adjust":"float","reverse":"bool"},"defaultParams":{"adjust":0.5,"reverse":false},"glsl":"// Author: KMojek\n// License: MIT\n// Description: A bow-tie wipe with an adjustable shape that can run in reverse\n// Tags: wipe, shape\n\nuniform float adjust; // = 0.5\n// @param Run the wipe in reverse\nuniform bool reverse; // = false\n\nfloat check(vec2 p1, vec2 p2, vec2 p3)\n{\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\n}\n\nbool pointInTriangle(vec2 pt, vec2 p1, vec2 p2, vec2 p3)\n{\n\n bool b1 = check(pt, p1, p2) < 0.0;\n bool b2 = check(pt, p2, p3) < 0.0;\n bool b3 = check(pt, p3, p1) < 0.0;\n return b1 == b2 && b2 == b3;\n}\n\nconst float height = 0.5;\n\nvec4 transition_firstHalf( vec2 uv, float prog )\n{\n if ( uv.y < 0.5 )\n {\n vec2 botLeft = vec2( -0., prog-height );\n vec2 botRight = vec2( 1., prog-height );\n vec2 tip = vec2( adjust, prog );\n if ( pointInTriangle( uv, botLeft, botRight, tip ) )\n return getToColor(uv);\n }\n else\n {\n vec2 topLeft = vec2( -0., 1.-prog+height );\n vec2 topRight = vec2( 1., 1.-prog+height );\n vec2 tip = vec2( adjust, 1.-prog );\n if ( pointInTriangle( uv, topLeft, topRight, tip ) )\n return getToColor( uv );\n }\n return getFromColor( uv );\n}\n\nvec4 transition_secondHalf( vec2 uv, float prog )\n{\n if ( uv.x > adjust )\n {\n vec2 top = vec2( prog + height, 1. );\n vec2 bot = vec2( prog + height, -0. );\n vec2 tip = vec2( mix( adjust, 1.0, 2.0 * (prog - 0.5) ), 0.5 );\n if ( pointInTriangle( uv, top, bot, tip) )\n return getFromColor( uv );\n }\n else\n {\n vec2 top = vec2( 1.0-prog - height, 1. );\n vec2 bot = vec2( 1.0-prog - height, -0. );\n vec2 tip = vec2( mix( adjust, 0.0, 2.0 * (prog - 0.5) ), 0.5 );\n if ( pointInTriangle( uv, top, bot, tip) )\n return getFromColor( uv );\n }\n return getToColor( uv );\n}\n\nvec4 transition (vec2 uv) {\n if ( reverse )\n return ( progress < 0.5 ) ? transition_secondHalf( uv, 1.-progress ) : transition_firstHalf( uv, 1.-progress );\n else\n return ( progress < 0.5 ) ? transition_firstHalf( uv, progress ) : transition_secondHalf( uv, progress );\n}","author":"KMojek","license":"MIT","description":"A bow-tie wipe with an adjustable shape that can run in reverse","tags":["wipe","shape"],"params":{"adjust":{"type":"float","default":0.5},"reverse":{"type":"bool","default":false,"description":"Run the wipe in reverse"}},"textures":[],"createdAt":"Thu, 19 Mar 2020 21:36:12 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Box","paramsTypes":{"rectIn":"int","location":"int"},"defaultParams":{"rectIn":1,"location":0},"glsl":"// Author: lql\n// License: MIT\n// Description: The outgoing image shrinks into a box, toward the center or a corner, revealing the incoming one\n// Tags: box, zoom, shape\nuniform int rectIn; // =1\n// center:0, left_top:1, left_bottom:2, right_top:3, right_bottom:4\n// @range(0, 4, 1) Where the box goes: 0 center, 1 left top, 2 left bottom, 3 right top, 4 right bottom\nuniform int location; // =0\n\nvec4 transition(vec2 uv) {\n float p = rectIn == 1 ? 1.0 - progress : progress;\n float x1, y1, x2, y2;\n\n // Determine rectangle coordinates based on location\n if (location == 0) {\n x1 = y1 = 0.5 * (1.0 - p);\n x2 = y2 = 1.0 - x1;\n } else {\n // Calculate the x and y coordinates based on the location\n x1 = (location == 1 || location == 2) ? 0.0 : 1.0 - p;\n y1 = (location == 1 || location == 3) ? 1.0 - p : 0.0;\n x2 = (location == 1 || location == 2) ? p : 1.0;\n y2 = (location == 1 || location == 3) ? 1.0 : p;\n }\n\n // Determine if the point is inside the rectangle\n float in_rect = step(x1, uv.x) * step(uv.x, x2) * step(y1, uv.y) * step(uv.y, y2);\n in_rect = rectIn == 1 ? 1.0 - in_rect : in_rect;\n\n // Mix colors based on the in_rect value\n return mix(getFromColor(uv), getToColor(uv), in_rect);\n}\n","author":"lql","license":"MIT","description":"The outgoing image shrinks into a box, toward the center or a corner, revealing the incoming one","tags":["box","zoom","shape"],"params":{"rectIn":{"type":"int","default":1},"location":{"type":"int","default":0,"min":0,"max":4,"step":1,"description":"Where the box goes: 0 center, 1 left top, 2 left bottom, 3 right top, 4 right bottom"}},"textures":[],"createdAt":"Tue, 23 Jan 2024 23:06:37 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"ButterflyWaveScrawler","paramsTypes":{"amplitude":"float","waves":"float","colorSeparation":"float"},"defaultParams":{"amplitude":1,"waves":30,"colorSeparation":0.3},"glsl":"// Author: mandubian\n// License: MIT\n// Description: Wavy, color-separated ripples scramble the outgoing image into the incoming one\n// Tags: wave, distort, chromatic\nuniform float amplitude; // = 1.0\nuniform float waves; // = 30.0\nuniform float colorSeparation; // = 0.3\nconst float PI = 3.14159265358979323846264;\nfloat compute(vec2 p, float progress, vec2 center) {\nvec2 o = p*sin(progress * amplitude)-center;\n// horizontal vector\nvec2 h = vec2(1., 0.);\n// butterfly polar function (don't ask me why this one :))\nfloat theta = acos(dot(o, h)) * waves;\nfloat s = sin((2.*theta - PI) / 24.);\nfloat s2 = s * s;\nreturn (exp(cos(theta)) - 2.*cos(4.*theta) + s2 * s2 * s) / 10.;\n}\nvec4 transition(vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n vec2 p = uv;\n float inv = 1. - progress;\n float disp = compute(p, progress, vec2(0.5, 0.5));\n vec4 texTo = getToColor(p + inv*disp);\n vec4 texFrom = vec4(\n getFromColor(p + progress*disp*(1.0 - colorSeparation)).r,\n getFromColor(p + progress*disp).g,\n getFromColor(p + progress*disp*(1.0 + colorSeparation)).b,\n 1.0);\n return texTo*progress + texFrom*inv;\n}\n","author":"mandubian","license":"MIT","description":"Wavy, color-separated ripples scramble the outgoing image into the incoming one","tags":["wave","distort","chromatic"],"params":{"amplitude":{"type":"float","default":1},"waves":{"type":"float","default":30},"colorSeparation":{"type":"float","default":0.3}},"textures":[],"createdAt":"Thu, 1 Jun 2017 11:47:17 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"CircleCrop","paramsTypes":{"bgcolor":"vec4"},"defaultParams":{"bgcolor":[0,0,0,1]},"glsl":"// License: MIT\n// Author: fkuteken\n// Description: The outgoing image closes into a circle over a background color, then the incoming one opens from it\n// Tags: circle, iris, shape\n// ported by gre from https://gist.github.com/fkuteken/f63e3009c1143950dee9063c3b83fb88\n\n// @color Background color\nuniform vec4 bgcolor; // = vec4(0.0, 0.0, 0.0, 1.0)\n\nvec4 transition(vec2 p) {\n vec2 ratio2 = vec2(1.0, 1.0 / ratio);\n float s = pow(2.0 * abs(progress - 0.5), 3.0);\n float dist = length((vec2(p) - 0.5) * ratio2);\n return mix(\n progress < 0.5 ? getFromColor(p) : getToColor(p), // branching is ok here as we statically depend on progress uniform (branching won't change over pixels)\n bgcolor,\n step(s, dist)\n );\n}\n","author":"fkuteken","license":"MIT","description":"The outgoing image closes into a circle over a background color, then the incoming one opens from it","tags":["circle","iris","shape"],"params":{"bgcolor":{"type":"vec4","default":[0,0,0,1],"color":true,"description":"Background color"}},"textures":[],"createdAt":"Mon, 12 Jun 2017 12:52:34 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"ColourDistance","paramsTypes":{"power":"float"},"defaultParams":{"power":5},"glsl":"// License: MIT\n// Author: P-Seebauer\n// Description: Pixels switch to the incoming image in order of how close their colors are\n// Tags: blend, color\n// ported by gre from https://gist.github.com/P-Seebauer/2a5fa2f77c883dd661f9\n\nuniform float power; // = 5.0\n\nvec4 transition(vec2 p) {\n vec4 fTex = getFromColor(p);\n vec4 tTex = getToColor(p);\n float m = step(distance(fTex, tTex), progress);\n return mix(\n mix(fTex, tTex, m),\n tTex,\n pow(progress, power)\n );\n}\n","author":"P-Seebauer","license":"MIT","description":"Pixels switch to the incoming image in order of how close their colors are","tags":["blend","color"],"params":{"power":{"type":"float","default":5}},"textures":[],"createdAt":"Mon, 12 Jun 2017 12:57:42 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"CrazyParametricFun","paramsTypes":{"a":"float","b":"float","amplitude":"float","smoothness":"float"},"defaultParams":{"a":4,"b":1,"amplitude":120,"smoothness":0.1},"glsl":"// Author: mandubian\n// License: MIT\n// Description: The outgoing image is pulled along a parametric curve into a psychedelic swirl\n// Tags: distort, psychedelic\n\nuniform float a; // = 4\nuniform float b; // = 1\nuniform float amplitude; // = 120\nuniform float smoothness; // = 0.1\n\nvec4 transition(vec2 uv) {\n vec2 p = uv.xy / vec2(1.0).xy;\n vec2 dir = p - vec2(.5);\n float dist = length(dir);\n float x = (a - b) * cos(progress) + b * cos(progress * ((a / b) - 1.) );\n float y = (a - b) * sin(progress) - b * sin(progress * ((a / b) - 1.));\n vec2 offset = dir * vec2(sin(progress * dist * amplitude * x), sin(progress * dist * amplitude * y)) / smoothness;\n return mix(getFromColor(p + offset), getToColor(p), smoothstep(0.2, 1.0, progress));\n}\n","author":"mandubian","license":"MIT","description":"The outgoing image is pulled along a parametric curve into a psychedelic swirl","tags":["distort","psychedelic"],"params":{"a":{"type":"float","default":4},"b":{"type":"float","default":1},"amplitude":{"type":"float","default":120},"smoothness":{"type":"float","default":0.1}},"textures":[],"createdAt":"Thu, 1 Jun 2017 13:03:12 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"CrossZoom","paramsTypes":{"strength":"float"},"defaultParams":{"strength":0.4},"glsl":"// License: MIT\n// Author: rectalogic\n// Description: A crossfade through a strong zoom blur\n// Tags: zoom, blur, blend\n// ported by gre from https://gist.github.com/rectalogic/b86b90161503a0023231\n\n// Converted from https://github.com/rectalogic/rendermix-basic-effects/blob/master/assets/com/rendermix/CrossZoom/CrossZoom.frag\n// Which is based on https://github.com/evanw/glfx.js/blob/master/src/filters/blur/zoomblur.js\n// With additional easing functions from https://github.com/rectalogic/rendermix-basic-effects/blob/master/assets/com/rendermix/Easing/Easing.glsllib\n\n// @range(0, 1) Blur strength\nuniform float strength; // = 0.4\n\nconst float PI = 3.141592653589793;\n\nfloat Linear_ease(in float begin, in float change, in float duration, in float time) {\n return change * time / duration + begin;\n}\n\nfloat Exponential_easeInOut(in float begin, in float change, in float duration, in float time) {\n if (time == 0.0)\n return begin;\n else if (time == duration)\n return begin + change;\n time = time / (duration / 2.0);\n if (time < 1.0)\n return change / 2.0 * pow(2.0, 10.0 * (time - 1.0)) + begin;\n return change / 2.0 * (-pow(2.0, -10.0 * (time - 1.0)) + 2.0) + begin;\n}\n\nfloat Sinusoidal_easeInOut(in float begin, in float change, in float duration, in float time) {\n return -change / 2.0 * (cos(PI * time / duration) - 1.0) + begin;\n}\n\nfloat rand (vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nvec4 crossFade(in vec2 uv, in float dissolve) {\n return mix(getFromColor(uv), getToColor(uv), dissolve);\n}\n\nvec4 transition(vec2 uv) {\n vec2 texCoord = uv.xy / vec2(1.0).xy;\n\n // Linear interpolate center across center half of the image\n vec2 center = vec2(Linear_ease(0.25, 0.5, 1.0, progress), 0.5);\n float dissolve = Exponential_easeInOut(0.0, 1.0, 1.0, progress);\n\n // Mirrored sinusoidal loop. 0->strength then strength->0\n float strength = Sinusoidal_easeInOut(0.0, strength, 0.5, progress);\n\n vec4 color = vec4(0.0);\n float total = 0.0;\n vec2 toCenter = center - texCoord;\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = rand(uv);\n\n for (float t = 0.0; t <= 40.0; t++) {\n float percent = (t + offset) / 40.0;\n float weight = 4.0 * (percent - percent * percent);\n color += crossFade(texCoord + toCenter * percent * strength, dissolve) * weight;\n total += weight;\n }\n return color / total;\n}\n","author":"rectalogic","license":"MIT","description":"A crossfade through a strong zoom blur","tags":["zoom","blur","blend"],"params":{"strength":{"type":"float","default":0.4,"min":0,"max":1,"description":"Blur strength"}},"textures":[],"createdAt":"Mon, 12 Jun 2017 12:33:07 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"DefocusBlur","paramsTypes":{"blurSize":"float"},"defaultParams":{"blurSize":0.02},"glsl":"// Author: Sergey Kosarevsky\n// License: MIT\n// Description: A crossfade through an out-of-focus blur\n// Tags: blur, blend\n// Ported from https://gist.github.com/corporateshark/b9f8e5675c647e615419\n\n// @param Amount of blur\nuniform float blurSize; // = 0.02\n\n// 12-tap Poisson disk\n// https://github.com/spite/Wagner/blob/master/fragment-shaders/poisson-disc-blur-fs.glsl\n\nvec4 transition(vec2 uv) {\n float T = progress;\n float half_ = 0.5;\n float D = (T < half_) ? mix(0.0, blurSize, T / half_) : mix(blurSize, 0.0, (T - half_) / half_);\n vec4 C0 = getFromColor(uv);\n vec4 C1 = getToColor(uv);\n C0 += getFromColor(vec2(-0.326, -0.406) * D + uv);\n C1 += getToColor(vec2(-0.326, -0.406) * D + uv);\n C0 += getFromColor(vec2(-0.840, -0.074) * D + uv);\n C1 += getToColor(vec2(-0.840, -0.074) * D + uv);\n C0 += getFromColor(vec2(-0.696, 0.457) * D + uv);\n C1 += getToColor(vec2(-0.696, 0.457) * D + uv);\n C0 += getFromColor(vec2(-0.203, 0.621) * D + uv);\n C1 += getToColor(vec2(-0.203, 0.621) * D + uv);\n C0 += getFromColor(vec2( 0.962, -0.195) * D + uv);\n C1 += getToColor(vec2( 0.962, -0.195) * D + uv);\n C0 += getFromColor(vec2( 0.473, -0.480) * D + uv);\n C1 += getToColor(vec2( 0.473, -0.480) * D + uv);\n C0 += getFromColor(vec2( 0.519, 0.767) * D + uv);\n C1 += getToColor(vec2( 0.519, 0.767) * D + uv);\n C0 += getFromColor(vec2( 0.185, -0.893) * D + uv);\n C1 += getToColor(vec2( 0.185, -0.893) * D + uv);\n C0 += getFromColor(vec2( 0.507, 0.064) * D + uv);\n C1 += getToColor(vec2( 0.507, 0.064) * D + uv);\n C0 += getFromColor(vec2( 0.896, 0.412) * D + uv);\n C1 += getToColor(vec2( 0.896, 0.412) * D + uv);\n C0 += getFromColor(vec2(-0.322, -0.933) * D + uv);\n C1 += getToColor(vec2(-0.322, -0.933) * D + uv);\n C0 += getFromColor(vec2(-0.792, -0.598) * D + uv);\n C1 += getToColor(vec2(-0.792, -0.598) * D + uv);\n C0 /= 13.0;\n C1 /= 13.0;\n return mix(C0, C1, T);\n}\n","author":"Sergey Kosarevsky","license":"MIT","description":"A crossfade through an out-of-focus blur","tags":["blur","blend"],"params":{"blurSize":{"type":"float","default":0.02,"description":"Amount of blur"}},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Directional","paramsTypes":{"direction":"vec2"},"defaultParams":{"direction":[0,1]},"glsl":"// Author: Gaëtan Renaudeau\n// License: MIT\n// Description: The incoming image pushes the outgoing one out in a given direction\n// Tags: slide, push, directional\n\n// @param Direction of the movement\nuniform vec2 direction; // = vec2(0.0, 1.0)\n\nvec4 transition (vec2 uv) {\n vec2 p = uv + progress * sign(direction);\n vec2 f = fract(p);\n return mix(\n getToColor(f),\n getFromColor(f),\n step(0.0, p.y) * step(p.y, 1.0) * step(0.0, p.x) * step(p.x, 1.0)\n );\n}\n","author":"Gaëtan Renaudeau","license":"MIT","description":"The incoming image pushes the outgoing one out in a given direction","tags":["slide","push","directional"],"params":{"direction":{"type":"vec2","default":[0,1],"description":"Direction of the movement"}},"textures":[],"createdAt":"Thu, 19 Apr 2018 12:20:29 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"DirectionalScaled","paramsTypes":{"direction":"vec2","scale":"float"},"defaultParams":{"direction":[0,1],"scale":0.7},"glsl":"// Author: Thibaut Foussard\n// based on Directional transition by Gaëtan Renaudeau\n// https://gl-transitions.com/editor/Directional\n// License: MIT\n// Description: Like Directional, with both images scaled down while they slide\n// Tags: slide, push, zoom, directional\n\n#define PI acos(-1.0)\n\n// @param Direction of the movement\nuniform vec2 direction; // = vec2(0.0, 1.0)\nuniform float scale; // = .7\n\nfloat parabola(float x) {\n float y = pow(sin(x * PI), 1.);\n return y;\n}\n\nvec4 transition (vec2 uv) {\n float easedProgress = pow(sin(progress * PI / 2.), 3.);\n vec2 p = uv + easedProgress * sign(direction);\n vec2 f = fract(p);\n \n float s = 1. - (1. - (1. / scale)) * parabola(progress);\n f = (f - 0.5) * s + 0.5;\n \n float mixer = step(0.0, p.y) * step(p.y, 1.0) * step(0.0, p.x) * step(p.x, 1.0);\n vec4 col = mix(getToColor(f), getFromColor(f), mixer);\n \n float border = step(0., f.x) * step(0., (1. - f.x)) * step(0., f.y) * step(0., 1. - f.y);\n col *= border;\n \n return col;\n}\n","author":"Thibaut Foussard","license":"MIT","description":"Like Directional, with both images scaled down while they slide","tags":["slide","push","zoom","directional"],"params":{"direction":{"type":"vec2","default":[0,1],"description":"Direction of the movement"},"scale":{"type":"float","default":0.7}},"textures":[],"createdAt":"Tue, 4 Apr 2023 03:29:34 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"DoomScreenTransition","paramsTypes":{"bars":"int","amplitude":"float","noise":"float","frequency":"float","dripScale":"float"},"defaultParams":{"bars":30,"amplitude":2,"noise":0.1,"frequency":0.5,"dripScale":0.5},"glsl":"// Author: Zeh Fernando\n// License: MIT\n// Description: The outgoing image melts down in uneven columns, like the Doom screen wipe\n// Tags: melt, columns, retro\n\n\n// Transition parameters --------\n\n// Number of total bars/columns\nuniform int bars; // = 30\n\n// Multiplier for speed ratio. 0 = no variation when going down, higher = some elements go much faster\nuniform float amplitude; // = 2\n\n// Further variations in speed. 0 = no noise, 1 = super noisy (ignore frequency)\nuniform float noise; // = 0.1\n\n// Speed variation horizontally. the bigger the value, the shorter the waves\nuniform float frequency; // = 0.5\n\n// How much the bars seem to \"run\" from the middle of the screen first (sticking to the sides). 0 = no drip, 1 = curved drip\nuniform float dripScale; // = 0.5\n\n\n// The code proper --------\n\nfloat rand(int num) {\n return fract(mod(float(num) * 67123.313, 12.0) * sin(float(num) * 10.3) * cos(float(num)));\n}\n\nfloat wave(int num) {\n float fn = float(num) * frequency * 0.1 * float(bars);\n return cos(fn * 0.5) * cos(fn * 0.13) * sin((fn+10.0) * 0.3) / 2.0 + 0.5;\n}\n\nfloat drip(int num) {\n return sin(float(num) / float(bars - 1) * 3.141592) * dripScale;\n}\n\nfloat pos(int num) {\n return (noise == 0.0 ? wave(num) : mix(wave(num), rand(num), noise)) + (dripScale == 0.0 ? 0.0 : drip(num));\n}\n\nvec4 transition(vec2 uv) {\n int bar = int(uv.x * (float(bars)));\n float scale = 1.0 + pos(bar) * amplitude;\n float phase = progress * scale;\n float posY = uv.y / vec2(1.0).y;\n vec2 p;\n vec4 c;\n if (phase + posY < 1.0) {\n p = vec2(uv.x, uv.y + mix(0.0, vec2(1.0).y, phase)) / vec2(1.0).xy;\n c = getFromColor(p);\n } else {\n p = uv.xy / vec2(1.0).xy;\n c = getToColor(p);\n }\n\n // Finally, apply the color\n return c;\n}\n","author":"Zeh Fernando","license":"MIT","description":"The outgoing image melts down in uneven columns, like the Doom screen wipe","tags":["melt","columns","retro"],"params":{"bars":{"type":"int","default":30},"amplitude":{"type":"float","default":2},"noise":{"type":"float","default":0.1},"frequency":{"type":"float","default":0.5},"dripScale":{"type":"float","default":0.5}},"textures":[],"createdAt":"Tue, 30 May 2017 09:39:09 -0700","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Dreamy","paramsTypes":{},"defaultParams":{},"glsl":"// Author: mikolalysenko\n// License: MIT\n// Description: A crossfade with a gentle wavy distortion\n// Tags: wave, blend\n\nvec2 offset(float progress, float x, float theta) {\n float phase = progress*progress + progress + theta;\n float shifty = 0.03*progress*cos(10.0*(progress+x));\n return vec2(0, shifty);\n}\nvec4 transition(vec2 p) {\n return mix(getFromColor(p + offset(progress, p.x, 0.0)), getToColor(p + offset(1.0-progress, p.x, 3.14)), progress);\n}\n","author":"mikolalysenko","license":"MIT","description":"A crossfade with a gentle wavy distortion","tags":["wave","blend"],"params":{},"textures":[],"createdAt":"Mon, 12 Jun 2017 12:27:38 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"DreamyZoom","paramsTypes":{"rotation":"float","scale":"float"},"defaultParams":{"rotation":6,"scale":1.2},"glsl":"// Author: Zeh Fernando\n// License: MIT\n// Description: Zooms and rotates into a bright flash, then out to the incoming image\n// Tags: zoom, rotate, flash\n\n// Definitions --------\n#define DEG2RAD 0.03926990816987241548078304229099 // 1/180*PI\n\n\n// Transition parameters --------\n\n// In degrees\nuniform float rotation; // = 6\n\n// Multiplier\nuniform float scale; // = 1.2\n\n\n// The code proper --------\n\nvec4 transition(vec2 uv) {\n // Massage parameters\n float phase = progress < 0.5 ? progress * 2.0 : (progress - 0.5) * 2.0;\n float angleOffset = progress < 0.5 ? mix(0.0, rotation * DEG2RAD, phase) : mix(-rotation * DEG2RAD, 0.0, phase);\n float newScale = progress < 0.5 ? mix(1.0, scale, phase) : mix(scale, 1.0, phase);\n \n vec2 center = vec2(0, 0);\n\n // Calculate the source point\n vec2 assumedCenter = vec2(0.5, 0.5);\n vec2 p = (uv.xy - vec2(0.5, 0.5)) / newScale * vec2(ratio, 1.0);\n\n // This can probably be optimized (with distance())\n float angle = atan(p.y, p.x) + angleOffset;\n float dist = distance(center, p);\n p.x = cos(angle) * dist / ratio + 0.5;\n p.y = sin(angle) * dist + 0.5;\n vec4 c = progress < 0.5 ? getFromColor(p) : getToColor(p);\n\n // Finally, apply the color\n return c + (progress < 0.5 ? mix(0.0, 1.0, phase) : mix(1.0, 0.0, phase));\n}\n","author":"Zeh Fernando","license":"MIT","description":"Zooms and rotates into a bright flash, then out to the incoming image","tags":["zoom","rotate","flash"],"params":{"rotation":{"type":"float","default":6},"scale":{"type":"float","default":1.2}},"textures":[],"createdAt":"Tue, 30 May 2017 10:44:06 -0700","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Drop_Zone_Flicker","paramsTypes":{"frameRate":"float","rgbOffset":"float","blockAmount":"float","ghostAmount":"float","redCyan":"float","scanline":"float"},"defaultParams":{"frameRate":24,"rgbOffset":0.014,"blockAmount":0.72,"ghostAmount":0.62,"redCyan":0.58,"scanline":0.075},"glsl":"// Author: bread\n// License: MIT\n// Description: A flickering glitch with RGB offset, ghosting and scanlines that flashes back to the outgoing image\n// Tags: glitch, flicker, chromatic, scanlines\n// Drop_Zone_Flicker.glsl\n// gl-transitions compatible: progress, ratio, getFromColor, getToColor\nuniform float frameRate; // = 24.0\nuniform float rgbOffset; // = 0.014\nuniform float blockAmount; // = 0.72\nuniform float ghostAmount; // = 0.62\nuniform float redCyan; // = 0.58\nuniform float scanline; // = 0.075\n\nfloat sat(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nfloat hash12(vec2 p) {\n p = fract(p * vec2(443.8975, 397.2973));\n p += dot(p, p.yx + 19.19);\n return fract(p.x * p.y);\n}\n\nvec2 safeUv(vec2 uv) {\n return clamp(uv, vec2(0.001), vec2(0.999));\n}\n\n// 24fps reference-matched reveal curve.\n// Non-monotonic on purpose: the reference flashes back to the old clip.\nfloat frameReveal(float f) {\n if (f < 0.5) return 0.00;\n if (f < 1.5) return 0.28;\n if (f < 2.5) return 0.43;\n if (f < 3.5) return 0.46;\n if (f < 4.5) return 0.38;\n if (f < 5.5) return 0.48;\n if (f < 6.5) return 0.26;\n if (f < 7.5) return 0.10;\n if (f < 8.5) return 0.00;\n if (f < 9.5) return 0.00;\n if (f < 10.5) return 0.30;\n if (f < 11.5) return 0.58;\n if (f < 12.5) return 1.00;\n if (f < 13.5) return 0.70;\n if (f < 14.5) return 0.42;\n if (f < 15.5) return 0.55;\n if (f < 16.5) return 0.72;\n if (f < 17.5) return 0.88;\n if (f < 18.5) return 0.34;\n if (f < 19.5) return 0.48;\n if (f < 20.5) return 0.56;\n if (f < 21.5) return 0.76;\n if (f < 22.5) return 0.93;\n return 1.00;\n}\n\nfloat frameGlitch(float f) {\n if (f < 0.5) return 0.00;\n if (f < 6.5) return 0.92;\n if (f < 10.5) return 0.38;\n if (f < 11.5) return 0.78;\n if (f < 12.5) return 0.12;\n if (f < 17.5) return 0.74;\n if (f < 22.5) return 0.88;\n if (f < 23.5) return 0.28;\n return 0.00;\n}\n\nvec4 chromaFrom(vec2 uv, float amt) {\n vec2 o = vec2(amt, 0.0);\n return vec4(\n getFromColor(safeUv(uv + o)).r,\n getFromColor(safeUv(uv)).g,\n getFromColor(safeUv(uv - o)).b,\n 1.0\n );\n}\n\nvec4 chromaTo(vec2 uv, float amt) {\n vec2 o = vec2(amt, 0.0);\n return vec4(\n getToColor(safeUv(uv - o)).r,\n getToColor(safeUv(uv)).g,\n getToColor(safeUv(uv + o)).b,\n 1.0\n );\n}\n\nfloat blockMask(vec2 uv, float f) {\n vec2 big = floor(uv * vec2(4.0, 2.0));\n vec2 small = floor(uv * vec2(8.0, 4.0));\n\n float wide = step(0.48, hash12(vec2(big.x, f * 1.37)));\n float chunks = step(0.56, hash12(small + vec2(f * 2.11, f * 0.73)));\n\n float verticalCut = smoothstep(\n -0.035,\n 0.035,\n uv.x - mix(0.18, 0.78, hash12(vec2(f, 4.7)))\n );\n\n return sat(mix(wide, chunks, 0.38) * 0.72 + verticalCut * 0.28);\n}\n\nvec4 transition(vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n\n float f = floor(progress * frameRate);\n float reveal = frameReveal(f);\n float glitch = frameGlitch(f);\n\n float rnd = hash12(vec2(f, 9.13));\n vec2 jitter = vec2(\n (rnd - 0.5) * 0.042,\n (hash12(vec2(f, 2.71)) - 0.5) * 0.010\n ) * glitch;\n\n vec2 fromUv = safeUv(uv + jitter);\n vec2 toUv = safeUv(uv - jitter * 0.55);\n\n float block = blockMask(uv, f);\n float localReveal = sat(\n reveal +\n (block - 0.5) * blockAmount * glitch +\n (hash12(vec2(f, floor(uv.y * 9.0))) - 0.5) * 0.18 * glitch\n );\n\n localReveal = smoothstep(0.22, 0.78, localReveal);\n\n vec4 oldClip = chromaFrom(fromUv, rgbOffset * glitch);\n vec4 newClip = chromaTo(toUv, rgbOffset * glitch);\n\n vec4 color = mix(oldClip, newClip, localReveal);\n\n float leftWash = (1.0 - smoothstep(0.10, 0.78, uv.x)) * glitch;\n float cyanWash = smoothstep(0.08, 0.62, uv.x) * (1.0 - smoothstep(0.86, 1.0, uv.x)) * glitch;\n\n vec3 redGhost = oldClip.rgb * vec3(1.34, 0.42, 0.38);\n vec3 cyanGhost = newClip.rgb * vec3(0.48, 1.12, 1.24);\n\n color.rgb = mix(color.rgb, redGhost, leftWash * redCyan * 0.42);\n color.rgb = mix(color.rgb, cyanGhost, cyanWash * redCyan * 0.30);\n\n // Keeps the old circular \"drop zone\" visible as a translucent flash,\n // especially after the first full new-frame hit.\n float oldReturn = glitch * (1.0 - smoothstep(0.94, 1.0, reveal));\n oldReturn *= 0.18 + 0.52 * (1.0 - abs(localReveal - 0.5) * 2.0);\n color.rgb = mix(color.rgb, oldClip.rgb, oldReturn * ghostAmount);\n\n float lines = sin((uv.y + f * 0.017) * 1080.0);\n color.rgb += lines * scanline * glitch;\n\n float exposurePulse = (hash12(vec2(f, 12.4)) - 0.35) * 0.10 * glitch;\n color.rgb += exposurePulse;\n\n return vec4(sat(color.r), sat(color.g), sat(color.b), 1.0);\n}\n","author":"bread","license":"MIT","description":"A flickering glitch with RGB offset, ghosting and scanlines that flashes back to the outgoing image","tags":["glitch","flicker","chromatic","scanlines"],"params":{"frameRate":{"type":"float","default":24},"rgbOffset":{"type":"float","default":0.014},"blockAmount":{"type":"float","default":0.72},"ghostAmount":{"type":"float","default":0.62},"redCyan":{"type":"float","default":0.58},"scanline":{"type":"float","default":0.075}},"textures":[],"createdAt":"Wed, 10 Jun 2026 11:41:33 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"EdgeTransition","paramsTypes":{"edge_thickness":"float","edge_brightness":"float"},"defaultParams":{"edge_thickness":0.001,"edge_brightness":8},"glsl":"// Author: Woohyun Kim\n// License: MIT\n// Description: Both images fade through black with their edges glowing\n// Tags: edges, fade\n\nuniform float edge_thickness; // = 0.001\nuniform float edge_brightness; // = 8.0\n\nvec4 detectEdgeColor(vec3[9] c) {\n /* adjacent texel array for texel c[4]\n 036\n 147\n 258\n */\n vec3 dx = 2.0 * abs(c[7]-c[1]) + abs(c[2] - c[6]) + abs(c[8] - c[0]);\n\tvec3 dy = 2.0 * abs(c[3]-c[5]) + abs(c[6] - c[8]) + abs(c[0] - c[2]);\n float delta = length(0.25 * (dx + dy) * 0.5);\n\treturn vec4(clamp(edge_brightness * delta, 0.0, 1.0) * c[4], 1.0);\n}\n\nvec4 getFromEdgeColor(vec2 uv) {\n\tvec3 c[9];\n\tfor (int i=0; i < 3; ++i) for (int j=0; j < 3; ++j)\n\t{\n\t vec4 color = getFromColor(uv + edge_thickness * vec2(i-1,j-1));\n c[3*i + j] = color.rgb;\n\t}\n\treturn detectEdgeColor(c);\n}\n\nvec4 getToEdgeColor(vec2 uv) {\n\tvec3 c[9];\n\tfor (int i=0; i < 3; ++i) for (int j=0; j < 3; ++j)\n\t{\n\t vec4 color = getToColor(uv + edge_thickness * vec2(i-1,j-1));\n c[3*i + j] = color.rgb;\n\t}\n\treturn detectEdgeColor(c);\n}\n\nvec4 transition (vec2 uv) {\n vec4 start = mix(getFromColor(uv), getFromEdgeColor(uv), clamp(2.0 * progress, 0.0, 1.0));\n vec4 end = mix(getToEdgeColor(uv), getToColor(uv), clamp(2.0 * (progress - 0.5), 0.0, 1.0));\n return mix(\n start,\n end,\n progress\n );\n}\n","author":"Woohyun Kim","license":"MIT","description":"Both images fade through black with their edges glowing","tags":["edges","fade"],"params":{"edge_thickness":{"type":"float","default":0.001},"edge_brightness":{"type":"float","default":8}},"textures":[],"createdAt":"Tue, 4 Apr 2023 16:28:18 +0900","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"FilmBurn","paramsTypes":{"Seed":"float"},"defaultParams":{"Seed":2.31},"glsl":"// Author: Anastasia Dunbar\n// License: MIT\n// Description: Glowing film-burn light leaks wash over the image and reveal the incoming one\n// Tags: burn, film, light-leak\n// @param Random seed\nuniform float Seed; // = 2.31\nfloat sigmoid(float x, float a) {\n float b = pow(x*2.,a)/2.;\n if (x > .5) {\n b = 1.-pow(2.-(x*2.),a)/2.;\n }\n\treturn b;\n}\nfloat rand(float co){\n return fract(sin((co*24.9898)+Seed)*43758.5453);\n}\nfloat rand(vec2 co){\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\nfloat apow(float a,float b) { return pow(abs(a),b)*sign(b); }\nvec3 pow3(vec3 a,vec3 b) { return vec3(apow(a.r,b.r),apow(a.g,b.g),apow(a.b,b.b)); }\nfloat smooth_mix(float a,float b,float c) { return mix(a,b,sigmoid(c,2.)); }\nfloat random(vec2 co, float shft){\n co += 10.;\n return smooth_mix(fract(sin(dot(co.xy ,vec2(12.9898+(floor(shft)*.5),78.233+Seed))) * 43758.5453),fract(sin(dot(co.xy ,vec2(12.9898+(floor(shft+1.)*.5),78.233+Seed))) * 43758.5453),fract(shft));\n}\nfloat smooth_random(vec2 co, float shft) {\n\treturn smooth_mix(smooth_mix(random(floor(co),shft),random(floor(co+vec2(1.,0.)),shft),fract(co.x)),smooth_mix(random(floor(co+vec2(0.,1.)),shft),random(floor(co+vec2(1.,1.)),shft),fract(co.x)),fract(co.y));\n}\nvec4 blendedColor(vec2 p) {\n return mix(getFromColor(p), getToColor(p), sigmoid(progress,10.));\n}\n#define pi 3.14159265358979323\n#define clamps(x) clamp(x,0.,1.)\n\nvec4 transition(vec2 p) {\n vec3 f = vec3(0.);\n for (float i = 0.; i < 13.; i++) {\n f += sin(((p.x*rand(i)*6.)+(progress*8.))+rand(i+1.43))*sin(((p.y*rand(i+4.4)*6.)+(progress*6.))+rand(i+2.4));\n f += 1.-clamps(length(p-vec2(smooth_random(vec2(progress*1.3),i+1.),smooth_random(vec2(progress*.5),i+6.25)))*mix(20.,70.,rand(i)));\n }\n f += 4.;\n f /= 11.;\n f = pow3(f*vec3(1.,0.7,0.6),vec3(1.,2.-sin(progress*pi),1.3));\n f *= sin(progress*pi);\n \n p -= .5;\n p *= 1.+(smooth_random(vec2(progress*5.),6.3)*sin(progress*pi)*.05);\n p += .5;\n \n vec4 blurred_image = vec4(0.);\n float bluramount = sin(progress*pi)*.03;\n #define repeats 50.\n for (float i = 0.; i < repeats; i++) { \n vec2 q = vec2(cos(degrees((i/repeats)*360.)),sin(degrees((i/repeats)*360.))) * (rand(vec2(i,p.x+p.y))+bluramount); \n vec2 uv2 = p+(q*bluramount);\n blurred_image += blendedColor(uv2);\n }\n blurred_image /= repeats;\n \n return blurred_image+vec4(f,0.);\n}\n","author":"Anastasia Dunbar","license":"MIT","description":"Glowing film-burn light leaks wash over the image and reveal the incoming one","tags":["burn","film","light-leak"],"params":{"Seed":{"type":"float","default":2.31,"description":"Random seed"}},"textures":[],"createdAt":"Wed, 21 Feb 2018 20:52:13 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Fold","paramsTypes":{},"defaultParams":{},"glsl":"// Author: nwoeanhinnogaehr\n// License: MIT\n// Description: The incoming image unfolds from the left while the outgoing one folds away to the right\n// Tags: fold, slide, horizontal\n// Ported from https://gist.github.com/nwoeanhinnogaehr/f6fc39f4cfcbb97f96a6\n\nvec4 transition(vec2 uv) {\n vec4 a = getFromColor((uv - vec2(progress, 0.0)) / vec2(1.0 - progress, 1.0));\n vec4 b = getToColor(uv / vec2(progress, 1.0));\n return mix(a, b, step(uv.x, progress));\n}\n","author":"nwoeanhinnogaehr","license":"MIT","description":"The incoming image unfolds from the left while the outgoing one folds away to the right","tags":["fold","slide","horizontal"],"params":{},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"GlitchDisplace","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Matt DesLauriers\n// License: MIT\n// Description: Blocks of the image are displaced in a glitch that flashes into the incoming image\n// Tags: glitch, displace\n\nfloat random(vec2 co)\n{\n float a = 12.9898;\n float b = 78.233;\n float c = 43758.5453;\n float dt= dot(co.xy ,vec2(a,b));\n float sn= mod(dt,3.14);\n return fract(sin(sn) * c);\n}\nfloat voronoi( in vec2 x ) {\n vec2 p = floor( x );\n vec2 f = fract( x );\n float res = 8.0;\n for( float j=-1.; j<=1.; j++ )\n for( float i=-1.; i<=1.; i++ ) {\n vec2 b = vec2( i, j );\n vec2 r = b - f + random( p + b );\n float d = dot( r, r );\n res = min( res, d );\n }\n return sqrt( res );\n}\n\nvec2 displace(vec4 tex, vec2 texCoord, float dotDepth, float textureDepth, float strength) {\n float b = voronoi(.003 * texCoord + 2.0);\n float g = voronoi(0.2 * texCoord);\n float r = voronoi(texCoord - 1.0);\n vec4 dt = tex * 1.0;\n vec4 dis = dt * dotDepth + 1.0 - tex * textureDepth;\n\n dis.x = dis.x - 1.0 + textureDepth*dotDepth;\n dis.y = dis.y - 1.0 + textureDepth*dotDepth;\n dis.x *= strength;\n dis.y *= strength;\n vec2 res_uv = texCoord ;\n res_uv.x = res_uv.x + dis.x - 0.0;\n res_uv.y = res_uv.y + dis.y;\n return res_uv;\n}\n\nfloat ease1(float t) {\n return t == 0.0 || t == 1.0\n ? t\n : t < 0.5\n ? +0.5 * pow(2.0, (20.0 * t) - 10.0)\n : -0.5 * pow(2.0, 10.0 - (t * 20.0)) + 1.0;\n}\nfloat ease2(float t) {\n return t == 1.0 ? t : 1.0 - pow(2.0, -10.0 * t);\n}\n\n\n\nvec4 transition(vec2 uv) {\n vec2 p = uv.xy / vec2(1.0).xy;\n vec4 color1 = getFromColor(p);\n vec4 color2 = getToColor(p);\n vec2 disp = displace(color1, p, 0.33, 0.7, 1.0-ease1(progress));\n vec2 disp2 = displace(color2, p, 0.33, 0.5, ease2(progress));\n vec4 dColor1 = getToColor(disp);\n vec4 dColor2 = getFromColor(disp2);\n float val = ease1(progress);\n vec3 gray = vec3(dot(min(dColor2, dColor1).rgb, vec3(0.299, 0.587, 0.114)));\n dColor2 = vec4(gray, 1.0);\n dColor2 *= 2.0;\n color1 = mix(color1, dColor2, smoothstep(0.0, 0.5, progress));\n color2 = mix(color2, dColor1, smoothstep(1.0, 0.5, progress));\n return mix(color1, color2, val);\n //gl_FragColor = mix(gl_FragColor, dColor, smoothstep(0.0, 0.5, progress));\n\n //gl_FragColor = mix(texture2D(from, p), texture2D(to, p), progress);\n}\n","author":"Matt DesLauriers","license":"MIT","description":"Blocks of the image are displaced in a glitch that flashes into the incoming image","tags":["glitch","displace"],"params":{},"textures":[],"createdAt":"Tue, 30 May 2017 14:53:04 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"GlitchMemories","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Gunnar Roth\n// based on work from natewave\n// License: MIT\n// Description: A crossfade with glitchy, color-shifted blocks\n// Tags: glitch, chromatic, blend\nvec4 transition(vec2 p) {\n vec2 block = floor(p.xy / vec2(16));\n vec2 uv_noise = block / vec2(64);\n uv_noise += floor(vec2(progress) * vec2(1200.0, 3500.0)) / vec2(64);\n vec2 dist = progress > 0.0 ? (fract(uv_noise) - 0.5) * 0.3 *(1.0 -progress) : vec2(0.0);\n vec2 red = p + dist * 0.2;\n vec2 green = p + dist * .3;\n vec2 blue = p + dist * .5;\n\n return vec4(mix(getFromColor(red), getToColor(red), progress).r,mix(getFromColor(green), getToColor(green), progress).g,mix(getFromColor(blue), getToColor(blue), progress).b,1.0);\n}\n\n","author":"Gunnar Roth","license":"MIT","description":"A crossfade with glitchy, color-shifted blocks","tags":["glitch","chromatic","blend"],"params":{},"textures":[],"createdAt":"Wed, 21 Feb 2018 00:52:15 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"GridFlip","paramsTypes":{"size":"ivec2","pause":"float","dividerWidth":"float","bgcolor":"vec4","randomness":"float"},"defaultParams":{"size":[4,4],"pause":0.1,"dividerWidth":0.05,"bgcolor":[0,0,0,1],"randomness":0.1},"glsl":"// License: MIT\n// Author: TimDonselaar\n// Description: The image splits into a grid of tiles that flip one by one to the incoming image\n// Tags: grid, tiles, flip\n// ported by gre from https://gist.github.com/TimDonselaar/9bcd1c4b5934ba60087bdb55c2ea92e5\n\n// @param Number of tiles (columns, rows)\nuniform ivec2 size; // = ivec2(4)\nuniform float pause; // = 0.1\nuniform float dividerWidth; // = 0.05\n// @color Color behind the tiles\nuniform vec4 bgcolor; // = vec4(0.0, 0.0, 0.0, 1.0)\nuniform float randomness; // = 0.1\n \nfloat rand (vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nfloat getDelta(vec2 p) {\n vec2 rectanglePos = floor(vec2(size) * p);\n vec2 rectangleSize = vec2(1.0 / vec2(size).x, 1.0 / vec2(size).y);\n float top = rectangleSize.y * (rectanglePos.y + 1.0);\n float bottom = rectangleSize.y * rectanglePos.y;\n float left = rectangleSize.x * rectanglePos.x;\n float right = rectangleSize.x * (rectanglePos.x + 1.0);\n float minX = min(abs(p.x - left), abs(p.x - right));\n float minY = min(abs(p.y - top), abs(p.y - bottom));\n return min(minX, minY);\n}\n\nfloat getDividerSize() {\n vec2 rectangleSize = vec2(1.0 / vec2(size).x, 1.0 / vec2(size).y);\n return min(rectangleSize.x, rectangleSize.y) * dividerWidth;\n}\n\nvec4 transition(vec2 p) {\n if(progress < pause) {\n float currentProg = progress / pause;\n float a = 1.0;\n if(getDelta(p) < getDividerSize()) {\n a = 1.0 - currentProg;\n }\n return mix(bgcolor, getFromColor(p), a);\n }\n else if(progress < 1.0 - pause){\n if(getDelta(p) < getDividerSize()) {\n return bgcolor;\n } else {\n float currentProg = (progress - pause) / (1.0 - pause * 2.0);\n vec2 q = p;\n vec2 rectanglePos = floor(vec2(size) * q);\n \n float r = rand(rectanglePos) - randomness;\n float cp = smoothstep(0.0, 1.0 - r, currentProg);\n \n float rectangleSize = 1.0 / vec2(size).x;\n float delta = rectanglePos.x * rectangleSize;\n float offset = rectangleSize / 2.0 + delta;\n \n p.x = (p.x - offset)/abs(cp - 0.5)*0.5 + offset;\n vec4 a = getFromColor(p);\n vec4 b = getToColor(p);\n \n float s = step(abs(vec2(size).x * (q.x - delta) - 0.5), abs(cp - 0.5));\n return mix(bgcolor, mix(b, a, step(cp, 0.5)), s);\n }\n }\n else {\n float currentProg = (progress - 1.0 + pause) / pause;\n float a = 1.0;\n if(getDelta(p) < getDividerSize()) {\n a = currentProg;\n }\n return mix(bgcolor, getToColor(p), a);\n }\n}\n","author":"TimDonselaar","license":"MIT","description":"The image splits into a grid of tiles that flip one by one to the incoming image","tags":["grid","tiles","flip"],"params":{"size":{"type":"ivec2","default":[4,4],"description":"Number of tiles (columns, rows)"},"pause":{"type":"float","default":0.1},"dividerWidth":{"type":"float","default":0.05},"bgcolor":{"type":"vec4","default":[0,0,0,1],"color":true,"description":"Color behind the tiles"},"randomness":{"type":"float","default":0.1}},"textures":[],"createdAt":"Mon, 12 Jun 2017 11:32:51 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"HSVfade","paramsTypes":{},"defaultParams":{},"glsl":"// Author: nwoeanhinnogaehr\n// License: MIT\n// Description: A crossfade through the HSV color space that cycles through hues\n// Tags: fade, color, hue\n// Ported from https://gist.github.com/nwoeanhinnogaehr/b185145363d65751009b\n\n// HSV functions from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl\n\nvec3 hsv2rgb(vec3 c) {\n const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\nvec3 rgb2hsv(vec3 c) {\n const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n float d = q.x - min(q.w, q.y);\n return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + 0.001)), d / (q.x + 0.001), q.x);\n}\n\nvec4 transition(vec2 uv) {\n vec3 a = rgb2hsv(getFromColor(uv).rgb);\n vec3 b = rgb2hsv(getToColor(uv).rgb);\n vec3 m = mix(a, b, progress);\n return vec4(hsv2rgb(m), 1.0);\n}\n","author":"nwoeanhinnogaehr","license":"MIT","description":"A crossfade through the HSV color space that cycles through hues","tags":["fade","color","hue"],"params":{},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"HorizontalClose","paramsTypes":{},"defaultParams":{},"glsl":"// Author: martiniti\n// License: MIT\n// Description: The incoming image closes in from the top and bottom edges toward the middle\n// Tags: wipe, split\n\nvec4 transition (vec2 uv) {\n\n float s = 2.0 - abs((uv.y - 0.5) / (progress - 1.0)) - 2.0 * progress;\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n smoothstep(0.5, 0.0, s)\n ); \n}\n","author":"martiniti","license":"MIT","description":"The incoming image closes in from the top and bottom edges toward the middle","tags":["wipe","split"],"params":{},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:35:23 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"HorizontalOpen","paramsTypes":{},"defaultParams":{},"glsl":"// Author: martiniti\n// License: MIT\n// Description: The incoming image opens from a line in the middle toward the top and bottom edges\n// Tags: wipe, split\n\nvec4 transition (vec2 uv) {\n \n float regress = 1.0 - progress;\n\n float s = 2.0 - abs((uv.y - 0.5) / (regress - 1.0)) - 2.0 * regress;\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n smoothstep(0.0, 0.5, s)\n );\n}\n","author":"martiniti","license":"MIT","description":"The incoming image opens from a line in the middle toward the top and bottom edges","tags":["wipe","split"],"params":{},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:35:30 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"InvertedPageCurl","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Hewlett-Packard\n// License: BSD 3 Clause\n// Description: The outgoing image curls away like a page, revealing the incoming one\n// Tags: page, curl, 3d\n// Adapted by Sergey Kosarevsky from:\n// http://rectalogic.github.io/webvfx/examples_2transition-shader-pagecurl_8html-example.html\n\n/*\nCopyright (c) 2010 Hewlett-Packard Development Company, L.P. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\n copyright notice, this list of conditions and the following disclaimer\n in the documentation and/or other materials provided with the\n distribution.\n * Neither the name of Hewlett-Packard nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\nin vec2 texCoord;\n*/\n\nconst float MIN_AMOUNT = -0.16;\nconst float MAX_AMOUNT = 1.5;\n\nconst float PI = 3.141592653589793;\n\nconst float scale = 512.0;\nconst float sharpness = 3.0;\n\nconst float cylinderRadius = 1.0 / PI / 2.0;\n\n// These depend on the progress uniform and must be computed per-fragment.\n// Global initializers with uniforms are invalid in GLSL ES and fail on Mesa.\nfloat amount;\nfloat cylinderCenter;\nfloat cylinderAngle;\n\nvec3 hitPoint(float hitAngle, float yc, vec3 point, mat3 rrotation)\n{\n float hitPoint = hitAngle / (2.0 * PI);\n point.y = hitPoint;\n return rrotation * point;\n}\n\nvec4 antiAlias(vec4 color1, vec4 color2, float distanc)\n{\n distanc *= scale;\n if (distanc < 0.0) return color2;\n if (distanc > 2.0) return color1;\n float dd = pow(1.0 - distanc / 2.0, sharpness);\n return ((color2 - color1) * dd) + color1;\n}\n\nfloat distanceToEdge(vec3 point)\n{\n float dx = abs(point.x > 0.5 ? 1.0 - point.x : point.x);\n float dy = abs(point.y > 0.5 ? 1.0 - point.y : point.y);\n if (point.x < 0.0) dx = -point.x;\n if (point.x > 1.0) dx = point.x - 1.0;\n if (point.y < 0.0) dy = -point.y;\n if (point.y > 1.0) dy = point.y - 1.0;\n if ((point.x < 0.0 || point.x > 1.0) && (point.y < 0.0 || point.y > 1.0)) return sqrt(dx * dx + dy * dy);\n return min(dx, dy);\n}\n\nvec4 seeThrough(float yc, vec2 p, mat3 rotation, mat3 rrotation)\n{\n float hitAngle = PI - (acos(clamp(yc / cylinderRadius, -1.0, 1.0)) - cylinderAngle);\n vec3 point = hitPoint(hitAngle, yc, rotation * vec3(p, 1.0), rrotation);\n if (yc <= 0.0 && (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0))\n {\n return getToColor(p);\n }\n\n if (yc > 0.0) return getFromColor(p);\n\n vec4 color = getFromColor(point.xy);\n vec4 tcolor = vec4(0.0);\n\n return antiAlias(color, tcolor, distanceToEdge(point));\n}\n\nvec4 seeThroughWithShadow(float yc, vec2 p, vec3 point, mat3 rotation, mat3 rrotation)\n{\n float shadow = distanceToEdge(point) * 30.0;\n shadow = (1.0 - shadow) / 3.0;\n\n if (shadow < 0.0) shadow = 0.0; else shadow *= amount;\n\n vec4 shadowColor = seeThrough(yc, p, rotation, rrotation);\n shadowColor.r -= shadow;\n shadowColor.g -= shadow;\n shadowColor.b -= shadow;\n\n return shadowColor;\n}\n\nvec4 backside(float yc, vec3 point)\n{\n vec4 color = getFromColor(point.xy);\n float gray = (color.r + color.b + color.g) / 15.0;\n gray += (8.0 / 10.0) * (pow(max(0.0, 1.0 - abs(yc / cylinderRadius)), 2.0 / 10.0) / 2.0 + (5.0 / 10.0));\n color.rgb = vec3(gray);\n return color;\n}\n\nvec4 behindSurface(vec2 p, float yc, vec3 point, mat3 rrotation)\n{\n float safeAmount = amount >= 0.0 ? max(amount, 1e-4) : min(amount, -1e-4);\n float shado = (1.0 - ((-cylinderRadius - yc) / safeAmount * 7.0)) / 6.0;\n shado *= 1.0 - abs(point.x - 0.5);\n\n yc = (-cylinderRadius - cylinderRadius - yc);\n\n float hitAngle = (acos(clamp(yc / cylinderRadius, -1.0, 1.0)) + cylinderAngle) - PI;\n point = hitPoint(hitAngle, yc, point, rrotation);\n\n if (yc < 0.0 && point.x >= 0.0 && point.y >= 0.0 && point.x <= 1.0 && point.y <= 1.0 && (hitAngle < PI || amount > 0.5))\n {\n float dx = point.x - 0.5;\n float dy = point.y - 0.5;\n shado = 1.0 - (sqrt(dx * dx + dy * dy) / (71.0 / 100.0));\n float nyc = -yc / cylinderRadius;\n shado *= nyc * nyc * nyc;\n shado *= 0.5;\n }\n else\n {\n shado = 0.0;\n }\n return vec4(getToColor(p).rgb - shado, 1.0);\n}\n\nvec4 transition(vec2 p) {\n amount = progress * (MAX_AMOUNT - MIN_AMOUNT) + MIN_AMOUNT;\n cylinderCenter = amount;\n cylinderAngle = 2.0 * PI * amount;\n\n const float angle = 100.0 * PI / 180.0;\n float c = cos(-angle);\n float s = sin(-angle);\n\n mat3 rotation = mat3( c, s, 0,\n -s, c, 0,\n -0.801, 0.8900, 1\n );\n c = cos(angle);\n s = sin(angle);\n\n mat3 rrotation = mat3(\tc, s, 0,\n -s, c, 0,\n 0.98500, 0.985, 1\n );\n\n vec3 point = rotation * vec3(p, 1.0);\n\n float yc = point.y - cylinderCenter;\n\n if (yc < -cylinderRadius)\n {\n // Behind surface\n return behindSurface(p,yc, point, rrotation);\n }\n\n if (yc > cylinderRadius)\n {\n // Flat surface\n return getFromColor(p);\n }\n\n float hitAngle = (acos(clamp(yc / cylinderRadius, -1.0, 1.0)) + cylinderAngle) - PI;\n\n float hitAngleMod = mod(hitAngle, 2.0 * PI);\n if ((hitAngleMod > PI && amount < 0.5) || (hitAngleMod > PI/2.0 && amount < 0.0))\n {\n return seeThrough(yc, p, rotation, rrotation);\n }\n\n point = hitPoint(hitAngle, yc, point, rrotation);\n\n if (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0)\n {\n return seeThroughWithShadow(yc, p, point, rotation, rrotation);\n }\n\n vec4 color = backside(yc, point);\n\n vec4 otherColor;\n if (yc < 0.0)\n {\n float dx2 = point.x - 0.5;\n float dy2 = point.y - 0.5;\n float shado = 1.0 - (sqrt(dx2 * dx2 + dy2 * dy2) / 0.71);\n float nyc2 = -yc / cylinderRadius;\n shado *= nyc2 * nyc2 * nyc2;\n shado *= 0.5;\n otherColor = vec4(0.0, 0.0, 0.0, shado);\n }\n else\n {\n otherColor = getFromColor(p);\n }\n\n color = antiAlias(color, otherColor, cylinderRadius - abs(yc));\n\n vec4 cl = seeThroughWithShadow(yc, p, point, rotation, rrotation);\n float dist = distanceToEdge(point);\n\n return antiAlias(color, cl, dist);\n}\n","author":"Hewlett-Packard","license":"BSD 3 Clause","description":"The outgoing image curls away like a page, revealing the incoming one","tags":["page","curl","3d"],"params":{},"textures":[],"createdAt":"Wed, 21 Feb 2018 01:13:49 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"LeftRight","paramsTypes":{},"defaultParams":{},"glsl":"// Author: zhmy\n// License: MIT\n// Description: The outgoing image shrinks away to the left while the incoming one slides in from the right\n// Tags: slide, zoom, horizontal\n\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n vec2 spfr,spto = vec2(-1.);\n\n float size = mix(1.0, 3.0, progress*0.2);\n spto = (uv + vec2(-0.5,-0.5))*vec2(size,size)+vec2(0.5,0.5);\n spfr = (uv - vec2(1.-progress, 0.0));\n if(inBounds(spfr)){\n return getToColor(spfr);\n }else if(inBounds(spto)){\n return getFromColor(spto) * (1.0 - progress);\n } else{\n return black;\n }\n}","author":"zhmy","license":"MIT","description":"The outgoing image shrinks away to the left while the incoming one slides in from the right","tags":["slide","zoom","horizontal"],"params":{},"textures":[],"createdAt":"Thu, 17 Dec 2020 11:50:34 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"LinearBlur","paramsTypes":{"intensity":"float"},"defaultParams":{"intensity":0.1},"glsl":"// Author: gre\n// License: MIT\n// Description: A crossfade through a blur\n// Tags: blur, blend\n// @param Amount of blur\nuniform float intensity; // = 0.1\nconst int passes = 6;\n\nvec4 transition(vec2 uv) {\n vec4 c1 = vec4(0.0);\n vec4 c2 = vec4(0.0);\n\n float disp = intensity*(0.5-distance(0.5, progress));\n for (int xi=0; xi<passes; xi++)\n {\n float x = float(xi) / float(passes) - 0.5;\n for (int yi=0; yi<passes; yi++)\n {\n float y = float(yi) / float(passes) - 0.5;\n vec2 v = vec2(x,y);\n float d = disp;\n c1 += getFromColor( uv + d*v);\n c2 += getToColor( uv + d*v);\n }\n }\n c1 /= float(passes*passes);\n c2 /= float(passes*passes);\n return mix(c1, c2, progress);\n}\n","author":"gre","license":"MIT","description":"A crossfade through a blur","tags":["blur","blend"],"params":{"intensity":{"type":"float","default":0.1,"description":"Amount of blur"}},"textures":[],"createdAt":"Fri, 23 Feb 2018 15:18:22 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Mosaic","paramsTypes":{"endx":"int","endy":"int"},"defaultParams":{"endx":2,"endy":-1},"glsl":"// License: MIT\n// Author: Xaychru\n// Description: The view pans across a mosaic of rotated tiles from both images and settles on the incoming one\n// Tags: mosaic, tiles, zoom\n// ported by gre from https://gist.github.com/Xaychru/130bb7b7affedbda9df5\n\n#define PI 3.14159265358979323\n#define POW2(X) X*X\n#define POW3(X) X*X*X\nuniform int endx; // = 2\nuniform int endy; // = -1\n\nfloat Rand(vec2 v) {\n return fract(sin(dot(v.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\nvec2 Rotate(vec2 v, float a) {\n mat2 rm = mat2(cos(a), -sin(a),\n sin(a), cos(a));\n return rm*v;\n}\nfloat CosInterpolation(float x) {\n return -cos(x*PI)/2.+.5;\n}\nvec4 transition(vec2 uv) {\n vec2 p = uv.xy / vec2(1.0).xy - .5;\n vec2 rp = p;\n float rpr = (progress*2.-1.);\n float z = -(rpr*rpr*2.) + 3.;\n float az = abs(z);\n rp *= az;\n rp += mix(vec2(.5, .5), vec2(float(endx) + .5, float(endy) + .5), POW2(CosInterpolation(progress)));\n vec2 mrp = mod(rp, 1.);\n vec2 crp = rp;\n bool onEnd = int(floor(crp.x))==endx&&int(floor(crp.y))==endy;\n if(!onEnd) {\n float ang = float(int(Rand(floor(crp))*4.))*.5*PI;\n mrp = vec2(.5) + Rotate(mrp-vec2(.5), ang);\n }\n if(onEnd || Rand(floor(crp))>.5) {\n return getToColor(mrp);\n } else {\n return getFromColor(mrp);\n }\n}\n","author":"Xaychru","license":"MIT","description":"The view pans across a mosaic of rotated tiles from both images and settles on the incoming one","tags":["mosaic","tiles","zoom"],"params":{"endx":{"type":"int","default":2},"endy":{"type":"int","default":-1}},"textures":[],"createdAt":"Mon, 12 Jun 2017 10:26:51 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Overexposure","paramsTypes":{"strength":"float"},"defaultParams":{"strength":0.6},"glsl":"// Author: Ben Zhang\n// License: MIT\n// Description: A crossfade through a washed-out, overexposed white\n// Tags: flash, light, fade\n\n// @param Amount of overexposure\nuniform float strength; // = 0.6\nconst float PI = 3.141592653589793;\n\nvec4 transition (vec2 uv) {\n vec4 from = getFromColor(uv);\n vec4 to = getToColor(uv);\n\n // Multipliers\n float from_m = 1.0 - progress + sin(PI * progress) * strength;\n float to_m = progress + sin(PI * progress) * strength;\n \n return vec4(\n from.r * from.a * from_m + to.r * to.a * to_m,\n from.g * from.a * from_m + to.g * to.a * to_m,\n from.b * from.a * from_m + to.b * to.a * to_m,\n mix(from.a, to.a, progress)\n );\n}\n","author":"Ben Zhang","license":"MIT","description":"A crossfade through a washed-out, overexposed white","tags":["flash","light","fade"],"params":{"strength":{"type":"float","default":0.6,"description":"Amount of overexposure"}},"textures":[],"createdAt":"Tue, 15 Mar 2022 20:21:15 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"PolkaDotsCurtain","paramsTypes":{"dots":"float","center":"vec2"},"defaultParams":{"dots":20,"center":[0,0]},"glsl":"// Author: bobylito\n// License: MIT\n// Description: The incoming image appears through growing polka dots\n// Tags: dots, pattern\nconst float SQRT_2 = 1.414213562373;\n// @param Number of dots across the image\nuniform float dots; // = 20.0\nuniform vec2 center; // = vec2(0, 0)\n\nvec4 transition(vec2 uv) {\n bool nextImage = distance(fract(uv * dots), vec2(0.5, 0.5)) < ( progress / distance(uv, center));\n return nextImage ? getToColor(uv) : getFromColor(uv);\n}\n","author":"bobylito","license":"MIT","description":"The incoming image appears through growing polka dots","tags":["dots","pattern"],"params":{"dots":{"type":"float","default":20,"description":"Number of dots across the image"},"center":{"type":"vec2","default":[0,0]}},"textures":[],"createdAt":"Tue, 20 Feb 2018 23:41:45 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"PuzzleRight","paramsTypes":{"size":"ivec2","pause":"float","dividerWidth":"float"},"defaultParams":{"size":[4,4],"pause":0.1,"dividerWidth":0.005},"glsl":"// Author: JustKirillS\n// License: MIT\n// Description: The image splits into a grid of tiles that flip one by one to the incoming image\n// Tags: grid, tiles, flip\n// Ported from https://gist.github.com/JustKirillS/714f095318834f4d2375de872c53af1e\n\nuniform ivec2 size; // = ivec2(4, 4)\nuniform float pause; // = 0.1\nuniform float dividerWidth; // = 0.005\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nfloat getDelta(vec2 p) {\n vec2 rectangleSize = 1.0 / vec2(size);\n vec2 rectanglePos = floor(vec2(size) * p);\n float top = rectangleSize.y * (rectanglePos.y + 1.0);\n float bottom = rectangleSize.y * rectanglePos.y;\n float left = rectangleSize.x * rectanglePos.x;\n float right = rectangleSize.x * (rectanglePos.x + 1.0);\n float minX = min(abs(p.x - left), abs(p.x - right));\n float minY = min(abs(p.y - top), abs(p.y - bottom));\n return min(minX, minY);\n}\n\nvec4 transition(vec2 uv) {\n if (progress < pause) {\n float currentProg = progress / pause;\n float a = 1.0;\n if (getDelta(uv) < dividerWidth) { a = 1.0 - currentProg; }\n return mix(vec4(0.0, 0.0, 0.0, 1.0), getFromColor(uv), a);\n } else if (progress < 1.0 - pause) {\n if (getDelta(uv) < dividerWidth) {\n return vec4(0.0, 0.0, 0.0, 1.0);\n }\n float currentProg = (progress - pause) / (1.0 - pause * 2.0);\n vec2 rectanglePos = floor(vec2(size) * uv);\n float r = rand(rectanglePos) - 0.1;\n float cp = smoothstep(0.0, 1.0 - r, currentProg);\n float rectangleSize = 1.0 / float(size.x);\n float delta = rectanglePos.x * rectangleSize;\n float offset = rectangleSize / 2.0 + delta;\n vec2 p = uv;\n p.x = (p.x - offset) / abs(cp - 0.5) * 0.5 + offset;\n vec4 a = getFromColor(p);\n vec4 b = getToColor(p);\n float s = step(abs(float(size.x) * (uv.x - delta) - 0.5), abs(cp - 0.5));\n return vec4(mix(b, a, step(cp, 0.5)).rgb * s, 1.0);\n } else {\n float currentProg = (progress - 1.0 + pause) / pause;\n float a = 1.0;\n if (getDelta(uv) < dividerWidth) { a = currentProg; }\n return mix(vec4(0.0, 0.0, 0.0, 1.0), getToColor(uv), a);\n }\n}\n","author":"JustKirillS","license":"MIT","description":"The image splits into a grid of tiles that flip one by one to the incoming image","tags":["grid","tiles","flip"],"params":{"size":{"type":"ivec2","default":[4,4]},"pause":{"type":"float","default":0.1},"dividerWidth":{"type":"float","default":0.005}},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"Radial","paramsTypes":{"smoothness":"float"},"defaultParams":{"smoothness":1},"glsl":"// License: MIT\n// Author: Xaychru\n// Description: A radial wipe that sweeps around the center like a clock hand\n// Tags: wipe, radial, clock\n// ported by gre from https://gist.github.com/Xaychru/ce1d48f0ce00bb379750\n\nuniform float smoothness; // = 1.0\n\nconst float PI = 3.141592653589;\n\nvec4 transition(vec2 p) {\n vec2 rp = p*2.-1.;\n return mix(\n getToColor(p),\n getFromColor(p),\n smoothstep(0., smoothness, atan(rp.y,rp.x) - (progress-.5) * PI * 2.5)\n );\n}\n","author":"Xaychru","license":"MIT","description":"A radial wipe that sweeps around the center like a clock hand","tags":["wipe","radial","clock"],"params":{"smoothness":{"type":"float","default":1}},"textures":[],"createdAt":"Mon, 12 Jun 2017 10:36:24 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Rectangle","paramsTypes":{"bgcolor":"vec4"},"defaultParams":{"bgcolor":[0,0,0,1]},"glsl":"// Author: martiniti\n// License: MIT\n// Description: A rectangle grows from the center to cover the outgoing image, then shrinks to reveal the incoming one\n// Tags: box, shape, iris\n\n// @color Color of the rectangle\nuniform vec4 bgcolor; // = vec4(0.0, 0.0, 0.0, 1.0)\n\nvec4 transition(vec2 p) {\n float s = pow(2.0 * abs(progress - 0.5), 3.0);\n \n vec2 sq = p.xy / vec2(1.0).xy;\n \n // bottom-left\n vec2 bl = step(vec2(abs(1. - 2.*progress)), sq + .25);\n float dist = bl.x * bl.y;\n\n // top-right\n vec2 tr = step(vec2(abs(1. - 2.*progress)), 1.25-sq);\n dist *= 1. * tr.x * tr.y;\n \n return mix(\n progress < 0.5 ? getFromColor(p) : getToColor(p),\n bgcolor,\n step(s, dist)\n );\n \n}\n","author":"martiniti","license":"MIT","description":"A rectangle grows from the center to cover the outgoing image, then shrinks to reveal the incoming one","tags":["box","shape","iris"],"params":{"bgcolor":{"type":"vec4","default":[0,0,0,1],"color":true,"description":"Color of the rectangle"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:29:59 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"RectangleCrop","paramsTypes":{"bgcolor":"vec4"},"defaultParams":{"bgcolor":[0,0,0,1]},"glsl":"// License: MIT\n// Author: martiniti\n// Description: The outgoing image shrinks into a small rectangle over a background color, then the incoming one grows from it\n// Tags: box, iris, zoom\n\n// @color Background color\nuniform vec4 bgcolor; // = vec4(0.0, 0.0, 0.0, 1.0)\n\nvec4 transition(vec2 uv) {\n \n float s = pow(2.0 * abs(progress - 0.5), 3.0);\n \n vec2 q = uv.xy / vec2(1.0).xy;\n \n // bottom-left\n vec2 bl = step(vec2(1.0 - 2.0*abs(progress - 0.5)), q + 0.25);\n \n // top-right\n vec2 tr = step(vec2(1.0 - 2.0*abs(progress - 0.5)), 1.25 - q);\n \n float dist = length(1.0 - bl.x * bl.y * tr.x * tr.y);\n \n return mix(\n progress < 0.5 ? getFromColor(uv) : getToColor(uv),\n bgcolor,\n step(s, dist)\n );\n \n}\n","author":"martiniti","license":"MIT","description":"The outgoing image shrinks into a small rectangle over a background color, then the incoming one grows from it","tags":["box","iris","zoom"],"params":{"bgcolor":{"type":"vec4","default":[0,0,0,1],"color":true,"description":"Background color"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:30:36 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Revolve_Left","paramsTypes":{"center":"vec2","direction":"float","maxRotation":"float","peakZoom":"float","swirl":"float","barrel":"float","motionBlur":"float","switchStart":"float","switchEnd":"float","shadow":"float"},"defaultParams":{"center":[0.46,0.52],"direction":-1,"maxRotation":1.95,"peakZoom":2.22,"swirl":2.85,"barrel":0.38,"motionBlur":1,"switchStart":0.3,"switchEnd":0.5,"shadow":0.16},"glsl":"// Author: bread\n// License: MIT\n// Description: The outgoing image swirls and zooms with motion blur into the incoming one\n// Tags: swirl, zoom, rotate, blur\n// gl-transitions v1 compatible\n\n// @param Center of the swirl\nuniform vec2 center; // = vec2(0.46, 0.52)\nuniform float direction; // = -1.0\nuniform float maxRotation; // = 1.95\nuniform float peakZoom; // = 2.22\nuniform float swirl; // = 2.85\nuniform float barrel; // = 0.38\nuniform float motionBlur; // = 1.0\nuniform float switchStart; // = 0.30\nuniform float switchEnd; // = 0.50\nuniform float shadow; // = 0.16\n\nfloat sat(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nfloat ease(float x) {\n x = sat(x);\n return x * x * (3.0 - 2.0 * x);\n}\n\nfloat revolveEnvelope(float t) {\n float rise = ease((t - 0.10) / 0.33);\n float fall = 1.0 - ease((t - 0.43) / 0.29);\n return rise * fall;\n}\n\nvec2 rotate2(vec2 p, float a) {\n float s = sin(a);\n float c = cos(a);\n return vec2(c * p.x - s * p.y, s * p.x + c * p.y);\n}\n\nvec2 warpUv(vec2 uv, float t) {\n float e = revolveEnvelope(t);\n\n vec2 p = uv - center;\n p.x *= ratio;\n\n float r = length(p);\n float edgeSpin = maxRotation * e;\n float coreSpin = swirl * e * pow(1.0 - sat(r / 0.96), 1.55);\n float visibleAngle = direction * (edgeSpin + coreSpin);\n\n p = rotate2(p, -visibleAngle);\n\n float sc = 1.0 + (peakZoom - 1.0) * pow(e, 0.85);\n p /= sc;\n\n float rr = length(p);\n p *= 1.0 + barrel * e * rr * rr * 2.8;\n\n p.x /= ratio;\n return clamp(p + center, vec2(0.001), vec2(0.999));\n}\n\nvec4 sampleRevolve(vec2 uv, float t) {\n vec2 p = warpUv(uv, t);\n float reveal = smoothstep(switchStart, switchEnd, t);\n return mix(getFromColor(p), getToColor(p), reveal);\n}\n\nvec4 transition(vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n\n float e = revolveEnvelope(progress);\n float span = 0.060 * motionBlur * e;\n\n vec4 color = vec4(0.0);\n float total = 0.0;\n\n for (int i = -8; i <= 8; i++) {\n float x = float(i) / 8.0;\n float w = 1.0 - abs(x);\n w = w * w + 0.01;\n\n float t = sat(progress + x * span);\n color += sampleRevolve(uv, t) * w;\n total += w;\n }\n\n color /= total;\n\n vec2 q = uv - vec2(0.5);\n q.x *= ratio;\n float vignette = 1.0 - shadow * e * smoothstep(0.35, 0.95, length(q));\n color.rgb *= vignette;\n\n return color;\n}\n","author":"bread","license":"MIT","description":"The outgoing image swirls and zooms with motion blur into the incoming one","tags":["swirl","zoom","rotate","blur"],"params":{"center":{"type":"vec2","default":[0.46,0.52],"description":"Center of the swirl"},"direction":{"type":"float","default":-1},"maxRotation":{"type":"float","default":1.95},"peakZoom":{"type":"float","default":2.22},"swirl":{"type":"float","default":2.85},"barrel":{"type":"float","default":0.38},"motionBlur":{"type":"float","default":1},"switchStart":{"type":"float","default":0.3},"switchEnd":{"type":"float","default":0.5},"shadow":{"type":"float","default":0.16}},"textures":[],"createdAt":"Wed, 10 Jun 2026 09:26:47 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Rolls","paramsTypes":{"type":"int","RotDown":"bool"},"defaultParams":{"type":0,"RotDown":false},"glsl":"// Author: Mark Craig\n// mrmcsoftware on github and youtube ( http://www.youtube.com/MrMcSoftware )\n// License: MIT\n// Description: The outgoing image rolls away around a corner, revealing the incoming one\n// Tags: rotate, roll\n\n// Rolls Transition by Mark Craig (Copyright © 2022)\n\n// @range(0, 3, 1) Corner to roll around\nuniform int type; // = 0\n// @param Roll the outgoing image down instead of up\nuniform bool RotDown; // = false\n// type (0-3): Rotate/Roll from which corner\n// RotDown: if true rotate old image down, otherwise rotate old image up\n\n#define M_PI 3.14159265358979323846\n\nvec4 transition(vec2 uv)\n{\nfloat theta, c1, s1;\nvec2 iResolution = vec2(ratio, 1.0);\nvec2 uvi;\n// I used if/else instead of switch in case it's an old GPU\nif (type == 0) { theta = (RotDown ? M_PI : -M_PI) / 2.0 * progress; uvi.x = 1.0 - uv.x; uvi.y = uv.y; }\nelse if (type == 1) { theta = (RotDown ? M_PI : -M_PI) / 2.0 * progress; uvi = uv; }\nelse if (type == 2) { theta = (RotDown ? -M_PI : M_PI) / 2.0 * progress; uvi.x = uv.x; uvi.y = 1.0 - uv.y; }\nelse if (type == 3) { theta = (RotDown ? -M_PI : M_PI) / 2.0 * progress; uvi = 1.0 - uv; }\nc1 = cos(theta); s1 = sin(theta);\nvec2 uv2;\nuv2.x = (uvi.x * iResolution.x * c1 - uvi.y * iResolution.y * s1);\nuv2.y = (uvi.x * iResolution.x * s1 + uvi.y * iResolution.y * c1);\nif ((uv2.x >= 0.0) && (uv2.x <= iResolution.x) && (uv2.y >= 0.0) && (uv2.y <= iResolution.y))\n\t{\n\tuv2 /= iResolution;\n\tif (type == 0) { uv2.x = 1.0 - uv2.x; }\n\telse if (type == 2) { uv2.y = 1.0 - uv2.y; }\n\telse if (type == 3) { uv2 = 1.0 - uv2; }\n\treturn(getFromColor(uv2));\n\t}\nreturn(getToColor(uv));\n}\n","author":"Mark Craig","license":"MIT","description":"The outgoing image rolls away around a corner, revealing the incoming one","tags":["rotate","roll"],"params":{"type":{"type":"int","default":0,"min":0,"max":3,"step":1,"description":"Corner to roll around"},"RotDown":{"type":"bool","default":false,"description":"Roll the outgoing image down instead of up"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 03:31:55 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"RotateScaleVanish","paramsTypes":{"FadeInSecond":"bool","ReverseEffect":"bool","ReverseRotation":"bool"},"defaultParams":{"FadeInSecond":true,"ReverseEffect":false,"ReverseRotation":false},"glsl":"// Author: Mark Craig\n// mrmcsoftware on github and youtube ( http://www.youtube.com/MrMcSoftware )\n// License: MIT\n// Description: The outgoing image spins and shrinks away over the incoming one\n// Tags: rotate, zoom, spin\n\n// RotateScaleVanish Transition by Mark Craig (Copyright © 2022)\n\n// @param Fade in the incoming image\nuniform bool FadeInSecond; // = true\n// @param Run the effect in reverse\nuniform bool ReverseEffect; // = false\n// @param Rotate the other way\nuniform bool ReverseRotation; // = false\n\n#define M_PI 3.14159265358979323846\n#define _TWOPI 6.283185307179586476925286766559\n\nvec4 transition(vec2 uv)\n{\nvec2 iResolution = vec2(ratio, 1.0);\nfloat t = ReverseEffect ? 1.0 - progress : progress;\nfloat theta = ReverseRotation ? _TWOPI * t : -_TWOPI * t;\nfloat c1 = cos(theta);\nfloat s1 = sin(theta);\nfloat rad = max(0.00001, 1.0 - t);\nfloat xc1 = (uv.x - 0.5) * iResolution.x;\nfloat yc1 = (uv.y - 0.5) * iResolution.y;\nfloat xc2 = (xc1 * c1 - yc1 * s1) / rad;\nfloat yc2 = (xc1 * s1 + yc1 * c1) / rad;\nvec2 uv2 = vec2(xc2 + iResolution.x / 2.0, yc2 + iResolution.y / 2.0);\nvec4 col3;\nvec4 ColorTo = ReverseEffect ? getFromColor(uv) : getToColor(uv);\nif ((uv2.x >= 0.0) && (uv2.x <= iResolution.x) && (uv2.y >= 0.0) && (uv2.y <= iResolution.y))\n\t{\n\tuv2 /= iResolution;\n\tcol3 = ReverseEffect ? getToColor(uv2) : getFromColor(uv2);\n\t}\nelse { col3 = FadeInSecond ? vec4(0.0, 0.0, 0.0, 1.0) : ColorTo; }\nreturn((1.0 - t) * col3 + t * ColorTo); // could have used mix\n}\n","author":"Mark Craig","license":"MIT","description":"The outgoing image spins and shrinks away over the incoming one","tags":["rotate","zoom","spin"],"params":{"FadeInSecond":{"type":"bool","default":true,"description":"Fade in the incoming image"},"ReverseEffect":{"type":"bool","default":false,"description":"Run the effect in reverse"},"ReverseRotation":{"type":"bool","default":false,"description":"Rotate the other way"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 03:31:48 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"SimpleFlip","paramsTypes":{},"defaultParams":{},"glsl":"// Author: nwoeanhinnogaehr\n// License: MIT\n// Description: The outgoing image flips around the vertical axis into the incoming one\n// Tags: flip, horizontal\n// Ported from https://gist.github.com/nwoeanhinnogaehr/408045772d255df97520\n\nvec4 transition(vec2 uv) {\n vec2 q = uv;\n uv.x = (uv.x - 0.5) / abs(progress - 0.5) * 0.5 + 0.5;\n vec4 a = getFromColor(uv);\n vec4 b = getToColor(uv);\n return vec4(mix(a, b, step(0.5, progress)).rgb * step(abs(q.x - 0.5), abs(progress - 0.5)), 1.0);\n}\n","author":"nwoeanhinnogaehr","license":"MIT","description":"The outgoing image flips around the vertical axis into the incoming one","tags":["flip","horizontal"],"params":{},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"SimpleZoom","paramsTypes":{"zoom_quickness":"float"},"defaultParams":{"zoom_quickness":0.8},"glsl":"// Author: 0gust1\n// License: MIT\n// Description: Zooms into the outgoing image, then fades to the incoming one\n// Tags: zoom, fade\n\n// @range(0.2, 1) Part of the transition spent zooming\nuniform float zoom_quickness; // = 0.8\nvec2 zoom(vec2 uv, float amount) {\n return 0.5 + ((uv - 0.5) * (1.0-amount));\t\n}\n\nvec4 transition (vec2 uv) {\n float nQuick = clamp(zoom_quickness,0.2,1.0);\n return mix(\n getFromColor(zoom(uv, smoothstep(0.0, nQuick, progress))),\n getToColor(uv),\n smoothstep(nQuick-0.2, 1.0, progress)\n );\n}","author":"0gust1","license":"MIT","description":"Zooms into the outgoing image, then fades to the incoming one","tags":["zoom","fade"],"params":{"zoom_quickness":{"type":"float","default":0.8,"min":0.2,"max":1,"description":"Part of the transition spent zooming"}},"textures":[],"createdAt":"Tue, 6 Mar 2018 00:43:47 +0100","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"SimpleZoomOut","paramsTypes":{"zoom_quickness":"float","fade":"bool"},"defaultParams":{"zoom_quickness":0.8,"fade":true},"glsl":"// Author: Tianshuo\n// License: MIT\n// Description: The incoming image zooms out into place while fading in\n// Tags: zoom, fade\n\n\n// @range(0.2, 1) Part of the transition spent zooming\nuniform float zoom_quickness; // = 0.8\n// @param Fade instead of cutting to the incoming image\nuniform bool fade; // = true\nvec2 zoom(vec2 uv, float amount) {\n return 0.5 + ((uv - 0.5) * (1.0-amount));\t\n}\n\nvec4 transition (vec2 uv) {\n float nQuick = clamp(zoom_quickness,0.2,1.0);\n return mix(\n getFromColor(uv),\n getToColor(zoom(uv,1.-smoothstep(1.-nQuick, 1., progress))),\n fade?smoothstep(1.0-nQuick, 1., progress):(progress<1.0-nQuick?0.0:1.0)\n );\n}\n","author":"Tianshuo","license":"MIT","description":"The incoming image zooms out into place while fading in","tags":["zoom","fade"],"params":{"zoom_quickness":{"type":"float","default":0.8,"min":0.2,"max":1,"description":"Part of the transition spent zooming"},"fade":{"type":"bool","default":true,"description":"Fade instead of cutting to the incoming image"}},"textures":[],"createdAt":"Sun, 29 Mar 2026 19:32:53 +0200","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"Slides","paramsTypes":{"type":"int","In":"bool"},"defaultParams":{"type":0,"In":false},"glsl":"// Author: Mark Craig\n// mrmcsoftware on github and youtube ( http://www.youtube.com/MrMcSoftware )\n// License: MIT\n// Description: The outgoing image slides out, or the incoming one slides in, toward an edge, a corner or the center\n// Tags: slide, directional\n\n// Slides Transition by Mark Craig (Copyright © 2022)\n\nuniform int type; // = 0\n// @param Slide the incoming image in instead of the outgoing one out\nuniform bool In; // = false\n// type: slide to/from which edge, which corner, or center\n// In: if true slide new image in, otherwise slide old image out\n\n#define rad2 rad / 2.0\n\nvec4 transition(vec2 uv)\n{\nvec2 uv0 = uv;\nfloat rad = In ? progress : 1.0 - progress;\nfloat xc1, yc1;\n// I used if/else instead of switch in case it's an old GPU\nif (type == 0) { xc1 = .5 - rad2; yc1 = 0.0; }\nelse if (type == 1) { xc1 = 1.0 - rad; yc1 = .5 - rad2; }\nelse if (type == 2) { xc1 = .5 - rad2; yc1 = 1.0 - rad; }\nelse if (type == 3) { xc1 = 0.0; yc1 = .5 - rad2; }\nelse if (type == 4) { xc1 = 1.0 - rad; yc1 = 0.0; }\nelse if (type == 5) { xc1 = 1.0 - rad; yc1 = 1.0 - rad; }\nelse if (type == 6) { xc1 = 0.0; yc1 = 1.0 - rad; }\nelse if (type == 7) { xc1 = 0.0; yc1 = 0.0; }\nelse if (type == 8) { xc1 = .5 - rad2; yc1 = .5 - rad2; }\nuv.y = 1.0 - uv.y;\nvec2 uv2;\nif ((uv.x >= xc1) && (uv.x <= xc1 + rad) && (uv.y >= yc1) && (uv.y <= yc1 + rad))\n\t{\n\tuv2 = vec2((uv.x - xc1) / rad, 1.0 - (uv.y - yc1) / rad);\n\treturn(In ? getToColor(uv2) : getFromColor(uv2));\n\t}\nreturn(In ? getFromColor(uv0) : getToColor(uv0));\n}\n","author":"Mark Craig","license":"MIT","description":"The outgoing image slides out, or the incoming one slides in, toward an edge, a corner or the center","tags":["slide","directional"],"params":{"type":{"type":"int","default":0},"In":{"type":"bool","default":false,"description":"Slide the incoming image in instead of the outgoing one out"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 03:32:13 -0400","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"StarWipe","paramsTypes":{"border_thickness":"float","star_rotation":"float","border_color":"vec4","star_center":"vec2"},"defaultParams":{"border_thickness":0.01,"star_rotation":0.75,"border_color":[1,1,1,1],"star_center":[0.5,0.5]},"glsl":"// Author: Ben Lucas\n// License: MIT\n// Description: A growing star reveals the incoming image\n// Tags: wipe, shape, star\n#define PI 3.141592653589793\n#define STAR_ANGLE 1.2566370614359172\n\n// @param Thickness of the star's border\nuniform float border_thickness;// = 0.01\nuniform float star_rotation;// = 0.75\n// @color Color of the star's border\nuniform vec4 border_color; // = vec4(1.0)\n// @param Center of the star\nuniform vec2 star_center;// = vec2(0.5)\n\nvec2 rotate(vec2 v, float theta) {\n float cosTheta = cos(theta);\n float sinTheta = sin(theta);\n\n return vec2(\n cosTheta * v.x - sinTheta * v.y,\n sinTheta * v.x + cosTheta * v.y\n );\n}\n\nbool inStar(vec2 uv, vec2 center, float radius){\n vec2 uv_centered = uv - center;\n uv_centered = rotate(uv_centered, star_rotation * STAR_ANGLE);\n float theta = atan(uv_centered.y, uv_centered.x) + PI;\n\n vec2 uv_rotated = rotate(uv_centered, -STAR_ANGLE * (floor(theta / STAR_ANGLE) + 0.5));\n\n float slope = 0.3;\n if(uv_rotated.y > 0.0){\n return (radius + uv_rotated.x * slope > uv_rotated.y);\n } else {\n return (-radius - uv_rotated.x * slope < uv_rotated.y);\n }\n}\n\nvec4 transition (vec2 uv) {\n float progressScaled = (2.0 * border_thickness + 1.0) * progress - border_thickness;\n if(inStar(uv, star_center, progressScaled)){\n return getToColor(uv);\n } else if(inStar(uv, star_center, progressScaled+border_thickness)){\n return border_color;\n } else {\n return getFromColor(uv);\n }\n}\n","author":"Ben Lucas","license":"MIT","description":"A growing star reveals the incoming image","tags":["wipe","shape","star"],"params":{"border_thickness":{"type":"float","default":0.01,"description":"Thickness of the star's border"},"star_rotation":{"type":"float","default":0.75},"border_color":{"type":"vec4","default":[1,1,1,1],"color":true,"description":"Color of the star's border"},"star_center":{"type":"vec2","default":[0.5,0.5],"description":"Center of the star"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 10:31:54 -0700","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"StaticFade","paramsTypes":{"n_noise_pixels":"float","static_luminosity":"float"},"defaultParams":{"n_noise_pixels":200,"static_luminosity":0.8},"glsl":"// Author: Ben Lucas\n// License: MIT\n// Description: Cuts to the incoming image halfway, hidden behind a burst of TV static\n// Tags: static, noise, retro\n\nuniform float n_noise_pixels ; // = 200.0\nuniform float static_luminosity ; // = 0.8\n\nfloat rnd (vec2 st) {\n return fract(sin(dot(st.xy,\n vec2(10.5302340293,70.23492931)))*\n 12345.5453123);\n}\n\nvec4 staticNoise (vec2 st, float offset, float luminosity) {\n float staticR = luminosity * rnd(st * vec2(offset * 2.0, offset * 3.0));\n float staticG = luminosity * rnd(st * vec2(offset * 3.0, offset * 5.0));\n float staticB = luminosity * rnd(st * vec2(offset * 5.0, offset * 7.0));\n return vec4(staticR, staticG, staticB, 1.0);\n}\n\nfloat staticIntensity(float t)\n{\n float transitionProgress = abs(2.0*(t-0.5));\n float transformedThreshold =1.2*(1.0 - transitionProgress)-0.1;\n return min(1.0, transformedThreshold);\n}\n \nvec4 transition (vec2 uv) {\n\n float baseMix = step(0.5, progress);\n vec4 transitionMix = mix(\n getFromColor(uv),\n getToColor(uv),\n baseMix\n );\n \n vec2 uvStatic = floor(uv * n_noise_pixels)/n_noise_pixels;\n \n vec4 staticColor = staticNoise(uvStatic, progress, static_luminosity);\n\n float staticThresh = staticIntensity(progress);\n float staticMix = step(rnd(uvStatic), staticThresh);\n\n return mix(transitionMix, staticColor, staticMix);\n}\n","author":"Ben Lucas","license":"MIT","description":"Cuts to the incoming image halfway, hidden behind a burst of TV static","tags":["static","noise","retro"],"params":{"n_noise_pixels":{"type":"float","default":200},"static_luminosity":{"type":"float","default":0.8}},"textures":[],"createdAt":"Fri, 2 Jun 2023 04:27:43 -0400","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"StereoViewer","paramsTypes":{"zoom":"float","corner_radius":"float"},"defaultParams":{"zoom":0.88,"corner_radius":0.22},"glsl":"// Tunable parameters\n// How much to zoom (out) for the effect ~ 0.5 - 1.0\n// @range(0.5, 1) How much the images zoom out\nuniform float zoom; // = 0.88\n// Corner radius as a fraction of the image height\nuniform float corner_radius; // = 0.22\n\n// Author: Ted Schundler\n// License: BSD 2 Clause\n// Description: Both images shrink into rounded cards that swap, like a stereo viewer toy\n// Tags: cards, zoom, retro\n// Free for use and modification by anyone with credit\n\n// Copyright (c) 2016, Theodore K Schundler\n// All rights reserved.\n\n// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\n// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n///////////////////////////////////////////////////////////////////////////////\n// Stereo Viewer Toy Transition //\n// //\n// Inspired by ViewMaster / Image3D image viewer devices. //\n// This effect is similar to what you see when you press the device's lever. //\n// There is a quick zoom in / out to make the transition 'valid' for GLSL.io //\n///////////////////////////////////////////////////////////////////////////////\n\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\nconst vec2 c00 = vec2(0.0, 0.0); // the four corner points\nconst vec2 c01 = vec2(0.0, 1.0);\nconst vec2 c11 = vec2(1.0, 1.0);\nconst vec2 c10 = vec2(1.0, 0.0);\n\n// Check if a point is within a given corner\nbool in_corner(vec2 p, vec2 corner, vec2 radius) {\n // determine the direction we want to be filled\n vec2 axis = (c11 - corner) - corner;\n\n // warp the point so we are always testing the bottom left point with the\n // circle centered on the origin\n p = p - (corner + axis * radius);\n p *= axis / radius;\n return (p.x > 0.0 && p.y > -1.0) || (p.y > 0.0 && p.x > -1.0) || dot(p, p) < 1.0;\n}\n\n// Check all four corners\n// return a float for v2 for anti-aliasing?\nbool test_rounded_mask(vec2 p, vec2 corner_size) {\n return\n in_corner(p, c00, corner_size) &&\n in_corner(p, c01, corner_size) &&\n in_corner(p, c10, corner_size) &&\n in_corner(p, c11, corner_size);\n}\n\n// Screen blend mode - https://en.wikipedia.org/wiki/Blend_modes\n// This more closely approximates what you see than linear blending\nvec4 screen(vec4 a, vec4 b) {\n return 1.0 - (1.0 - a) * (1.0 -b);\n}\n\n// Given RGBA, find a value that when screened with itself\n// will yield the original value.\nvec4 unscreen(vec4 c) {\n return 1.0 - sqrt(1.0 - c);\n}\n\n// Grab a pixel, only if it isn't masked out by the rounded corners\nvec4 sample_with_corners_from(vec2 p, vec2 corner_size) {\n p = (p - 0.5) / zoom + 0.5;\n if (!test_rounded_mask(p, corner_size)) {\n return black;\n }\n return unscreen(getFromColor(p));\n}\n\nvec4 sample_with_corners_to(vec2 p, vec2 corner_size) {\n p = (p - 0.5) / zoom + 0.5;\n if (!test_rounded_mask(p, corner_size)) {\n return black;\n }\n return unscreen(getToColor(p));\n}\n\n// special sampling used when zooming - extra zoom parameter and don't unscreen\nvec4 simple_sample_with_corners_from(vec2 p, vec2 corner_size, float zoom_amt) {\n p = (p - 0.5) / (1.0 - zoom_amt + zoom * zoom_amt) + 0.5;\n if (!test_rounded_mask(p, corner_size)) {\n return black;\n }\n return getFromColor(p);\n}\n\nvec4 simple_sample_with_corners_to(vec2 p, vec2 corner_size, float zoom_amt) {\n p = (p - 0.5) / (1.0 - zoom_amt + zoom * zoom_amt) + 0.5;\n if (!test_rounded_mask(p, corner_size)) {\n return black;\n }\n return getToColor(p);\n}\n\n// Basic 2D affine transform matrix helpers\n// These really shouldn't be used in a fragment shader - I should work out the\n// the math for a translate & rotate function as a pair of dot products instead\n\nmat3 rotate2d(float angle, float ratio) {\n float s = sin(angle);\n float c = cos(angle);\n return mat3(\n c, s ,0.0,\n -s, c, 0.0,\n 0.0, 0.0, 1.0);\n}\n\nmat3 translate2d(float x, float y) {\n return mat3(\n 1.0, 0.0, 0,\n 0.0, 1.0, 0,\n -x, -y, 1.0);\n}\n\nmat3 scale2d(float x, float y) {\n return mat3(\n x, 0.0, 0,\n 0.0, y, 0,\n 0, 0, 1.0);\n}\n\n// Split an image and rotate one up and one down along off screen pivot points\nvec4 get_cross_rotated(vec3 p3, float angle, vec2 corner_size, float ratio) {\n angle = angle * angle; // easing\n angle /= 2.4; // works out to be a good number of radians\n\n mat3 center_and_scale = translate2d(-0.5, -0.5) * scale2d(1.0, ratio);\n mat3 unscale_and_uncenter = scale2d(1.0, 1.0/ratio) * translate2d(0.5,0.5);\n mat3 slide_left = translate2d(-2.0,0.0);\n mat3 slide_right = translate2d(2.0,0.0);\n mat3 rotate = rotate2d(angle, ratio);\n\n mat3 op_a = center_and_scale * slide_right * rotate * slide_left * unscale_and_uncenter;\n mat3 op_b = center_and_scale * slide_left * rotate * slide_right * unscale_and_uncenter;\n\n vec4 a = sample_with_corners_from((op_a * p3).xy, corner_size);\n vec4 b = sample_with_corners_from((op_b * p3).xy, corner_size);\n\n return screen(a, b);\n}\n\n// Image stays put, but this time move two masks\nvec4 get_cross_masked(vec3 p3, float angle, vec2 corner_size, float ratio) {\n angle = 1.0 - angle;\n angle = angle * angle; // easing\n angle /= 2.4;\n\n vec4 img;\n\n mat3 center_and_scale = translate2d(-0.5, -0.5) * scale2d(1.0, ratio);\n mat3 unscale_and_uncenter = scale2d(1.0 / zoom, 1.0 / (zoom * ratio)) * translate2d(0.5,0.5);\n mat3 slide_left = translate2d(-2.0,0.0);\n mat3 slide_right = translate2d(2.0,0.0);\n mat3 rotate = rotate2d(angle, ratio);\n\n mat3 op_a = center_and_scale * slide_right * rotate * slide_left * unscale_and_uncenter;\n mat3 op_b = center_and_scale * slide_left * rotate * slide_right * unscale_and_uncenter;\n\n bool mask_a = test_rounded_mask((op_a * p3).xy, corner_size);\n bool mask_b = test_rounded_mask((op_b * p3).xy, corner_size);\n\n if (mask_a || mask_b) {\n img = sample_with_corners_to(p3.xy, corner_size);\n return screen(mask_a ? img : black, mask_b ? img : black);\n } else {\n return black;\n }\n}\n\nvec4 transition(vec2 uv) {\n float a;\n vec2 p=uv.xy/vec2(1.0).xy;\n vec3 p3 = vec3(p.xy, 1.0); // for 2D matrix transforms\n\n // corner is warped to represent to size after mapping to 1.0, 1.0\n vec2 corner_size = vec2(corner_radius / ratio, corner_radius);\n\n if (progress <= 0.0) {\n // 0.0: start with the base frame always\n return getFromColor(p);\n } else if (progress < 0.1) {\n // 0.0-0.1: zoom out and add rounded corners\n a = progress / 0.1;\n return simple_sample_with_corners_from(p, corner_size * a, a);\n } else if (progress < 0.48) {\n // 0.1-0.48: Split original image apart\n a = (progress - 0.1)/0.38;\n return get_cross_rotated(p3, a, corner_size, ratio);\n } else if (progress < 0.9) {\n // 0.48-0.52: black\n // 0.52 - 0.9: unmask new image\n return get_cross_masked(p3, (progress - 0.52)/0.38, corner_size, ratio);\n } else if (progress < 1.0) {\n // zoom out and add rounded corners\n a = (1.0 - progress) / 0.1;\n return simple_sample_with_corners_to(p, corner_size * a, a);\n } else {\n // 1.0 end with base frame\n return getToColor(p);\n }\n}\n","author":"Ted Schundler","license":"BSD 2 Clause","description":"Both images shrink into rounded cards that swap, like a stereo viewer toy","tags":["cards","zoom","retro"],"params":{"zoom":{"type":"float","default":0.88,"min":0.5,"max":1,"description":"How much the images zoom out"},"corner_radius":{"type":"float","default":0.22}},"textures":[],"createdAt":"Tue, 20 Feb 2018 23:20:29 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"StripDatamoshGlitch","paramsTypes":{"strength":"float","horizontalBars":"float","verticalSlits":"float","tear":"float","chroma":"float","residue":"float","noiseAmount":"float","scanAmount":"float","flashAmount":"float"},"defaultParams":{"strength":1,"horizontalBars":42,"verticalSlits":18,"tear":0.18,"chroma":0.032,"residue":0.62,"noiseAmount":0.16,"scanAmount":0.13,"flashAmount":0.2},"glsl":"// Author: bread\n// License: MIT\n// Description: A datamosh glitch: torn strips, chroma shifts and scan noise drag the outgoing image into the incoming one\n// Tags: glitch, datamosh, chromatic\n\nuniform float strength; // = 1.0\nuniform float horizontalBars; // = 42.0\nuniform float verticalSlits; // = 18.0\nuniform float tear; // = 0.18\nuniform float chroma; // = 0.032\nuniform float residue; // = 0.62\nuniform float noiseAmount; // = 0.16\nuniform float scanAmount; // = 0.13\nuniform float flashAmount; // = 0.20\n\nconst float PI = 3.141592653589793;\n\nfloat hash(float n) {\n return fract(sin(n) * 43758.5453123);\n}\n\nfloat hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);\n}\n\nfloat sat(float v) {\n return clamp(v, 0.0, 1.0);\n}\n\nfloat burst() {\n return pow(max(0.0, sin(progress * PI)), 0.42) * strength;\n}\n\nvec2 safeUv(vec2 uv) {\n return clamp(uv, vec2(0.0), vec2(1.0));\n}\n\nfloat stripeY(vec2 uv, float density, float seed, float minWidth, float maxWidth) {\n float y = uv.y * density + seed * 0.137;\n float id = floor(y);\n float f = fract(y);\n float c = hash(vec2(id, seed));\n float w = mix(minWidth, maxWidth, hash(vec2(id + 9.17, seed + 2.31)));\n return 1.0 - smoothstep(w, w + 0.018, abs(f - c));\n}\n\nfloat stripeX(vec2 uv, float density, float seed, float minWidth, float maxWidth) {\n float x = uv.x * density + seed * 0.091;\n float id = floor(x);\n float f = fract(x);\n float c = hash(vec2(id, seed + 41.0));\n float w = mix(minWidth, maxWidth, hash(vec2(id + 4.7, seed + 8.9)));\n return 1.0 - smoothstep(w, w + 0.012, abs(f - c));\n}\n\nfloat brokenGate(vec2 uv, float row, float rnd, float frame) {\n float segs = mix(1.0, 9.0, hash(vec2(row, frame + 44.0)));\n float seg = floor(uv.x * segs);\n return step(0.16, hash(vec2(seg, row + frame * 3.0 + rnd)));\n}\n\nfloat horizontalMask(vec2 uv, float frame) {\n float r1 = floor((uv.y + hash(frame) * 0.031) * horizontalBars * 0.38);\n float r2 = floor((uv.y + hash(frame + 2.0) * 0.013) * horizontalBars);\n float r3 = floor((uv.y + hash(frame + 7.0) * 0.006) * horizontalBars * 3.4);\n\n float thick = stripeY(uv, horizontalBars * 0.38, frame + 1.0, 0.035, 0.22);\n float mid = stripeY(uv, horizontalBars, frame + 4.0, 0.014, 0.11);\n float hair = stripeY(uv, horizontalBars * 3.4, frame + 9.0, 0.004, 0.035);\n\n thick *= step(0.42, hash(vec2(r1, frame + 10.0)));\n mid *= step(0.48, hash(vec2(r2, frame + 20.0)));\n hair *= step(0.62, hash(vec2(r3, frame + 30.0)));\n\n thick *= brokenGate(uv, r1, hash(vec2(r1, frame)), frame);\n mid *= brokenGate(uv, r2, hash(vec2(r2, frame)), frame + 3.0);\n\n return sat(max(thick, max(mid, hair)));\n}\n\nfloat verticalMask(vec2 uv, float frame) {\n float col = floor((uv.x + hash(frame + 12.0) * 0.017) * verticalSlits);\n float slit = stripeX(uv, verticalSlits, frame + 13.0, 0.01, 0.075);\n slit *= step(0.66, hash(vec2(col, frame + 19.0)));\n return sat(slit);\n}\n\nvec4 chromaFrom(vec2 uv, vec2 s) {\n uv = safeUv(uv);\n return vec4(\n getFromColor(safeUv(uv + s)).r,\n getFromColor(uv).g,\n getFromColor(safeUv(uv - s)).b,\n 1.0\n );\n}\n\nvec4 chromaTo(vec2 uv, vec2 s) {\n uv = safeUv(uv);\n return vec4(\n getToColor(safeUv(uv - s)).r,\n getToColor(uv).g,\n getToColor(safeUv(uv + s)).b,\n 1.0\n );\n}\n\nvec2 distortUv(vec2 uv, float dir, float b, float h, float v, float frame) {\n float row = floor(uv.y * horizontalBars);\n float col = floor(uv.x * verticalSlits);\n\n float rowRnd = hash(vec2(row, frame));\n float colRnd = hash(vec2(col, frame + 27.0));\n\n float xTear = (rowRnd - 0.5) * 2.0 * tear * b * h;\n xTear += sin(uv.y * 120.0 + progress * 95.0) * 0.006 * b;\n\n float yDrag = (colRnd - 0.5) * 0.13 * b * v;\n float micro = (hash(vec2(row, col + frame)) - 0.5) * 0.018 * b * max(h, v);\n\n return uv + vec2(xTear * dir + micro, yDrag);\n}\n\nvec4 transition(vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n\n float b = burst();\n float frame = floor(progress * 30.0);\n\n float h = horizontalMask(uv, frame);\n float v = verticalMask(uv, frame);\n float glitch = sat(max(h, v * 0.75));\n\n float row = floor(uv.y * horizontalBars);\n float rowRnd = hash(vec2(row, frame + 5.0));\n\n float bandDelay = (rowRnd - 0.5) * 0.30 * h;\n float reveal = smoothstep(0.18, 0.84, progress + bandDelay);\n\n vec2 split = vec2(chroma * b * (1.0 + 1.7 * glitch), chroma * 0.22 * b * v);\n\n vec2 fromUv = distortUv(uv, 1.0, b, h, v, frame);\n vec2 toUv = distortUv(uv, -1.0, b, h, v, frame);\n\n vec4 color = mix(\n chromaFrom(fromUv, split),\n chromaTo(toUv, split),\n reveal\n );\n\n // Horizontal time-slice residue: old/new frames dragged through uneven scan bands.\n vec2 smearUv = uv;\n smearUv.x += (rowRnd - 0.5) * 0.46 * b * h;\n smearUv.y += (hash(vec2(row, frame + 31.0)) - 0.5) * 0.045 * b * h;\n\n float sliceReveal = smoothstep(0.28, 0.78, progress + (rowRnd - 0.5) * 0.22);\n vec4 sliceColor = mix(\n chromaFrom(smearUv, split * 1.65),\n chromaTo(smearUv - vec2((rowRnd - 0.5) * 0.18 * b, 0.0), split * 1.65),\n sliceReveal\n );\n\n color = mix(color, sliceColor, h * b * residue);\n\n // Thin scan sparks and broken white lines, like the reference clip's bright horizontal noise.\n float hairLine = stripeY(uv, 190.0, frame + 55.0, 0.002, 0.012);\n hairLine *= step(0.70, hash(vec2(floor(uv.y * 190.0), frame + 56.0)));\n color.rgb += vec3(0.72, 0.90, 1.0) * hairLine * b * 0.28;\n\n float scan = 0.5 + 0.5 * sin(uv.y * 980.0 + progress * 130.0);\n color.rgb *= 1.0 - scanAmount * b * scan;\n\n vec2 nCell = floor(uv * vec2(360.0 * ratio, 210.0));\n float n = hash(nCell + vec2(frame * 7.0, frame * 13.0));\n color.rgb += (n - 0.5) * noiseAmount * b * (0.55 + glitch);\n\n // Slight desaturation during the damage peak makes it feel more like broadcast/video signal corruption.\n float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));\n color.rgb = mix(color.rgb, vec3(luma), 0.18 * b * glitch);\n\n float strobe = step(0.78, hash(vec2(frame, 3.14))) * pow(b, 1.65);\n color.rgb += vec3(strobe * flashAmount);\n\n return vec4(clamp(color.rgb, vec3(0.0), vec3(1.0)), 1.0);\n}\n","author":"bread","license":"MIT","description":"A datamosh glitch: torn strips, chroma shifts and scan noise drag the outgoing image into the incoming one","tags":["glitch","datamosh","chromatic"],"params":{"strength":{"type":"float","default":1},"horizontalBars":{"type":"float","default":42},"verticalSlits":{"type":"float","default":18},"tear":{"type":"float","default":0.18},"chroma":{"type":"float","default":0.032},"residue":{"type":"float","default":0.62},"noiseAmount":{"type":"float","default":0.16},"scanAmount":{"type":"float","default":0.13},"flashAmount":{"type":"float","default":0.2}},"textures":[],"createdAt":"Fri, 12 Jun 2026 15:15:42 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Swirl","paramsTypes":{},"defaultParams":{},"glsl":"// License: MIT\n// Author: Sergey Kosarevsky\n// Description: Both images swirl around the center while crossfading\n// Tags: swirl, rotate, blend\n// ( http://www.linderdaum.com )\n// ported by gre from https://gist.github.com/corporateshark/cacfedb8cca0f5ce3f7c\n\nvec4 transition(vec2 UV)\n{\n\tfloat Radius = 1.0;\n\n\tfloat T = progress;\n\n\tUV -= vec2( 0.5, 0.5 );\n\n\tfloat Dist = length(UV);\n\n\tif ( Dist < Radius )\n\t{\n\t\tfloat Percent = (Radius - Dist) / Radius;\n\t\tfloat A = ( T <= 0.5 ) ? mix( 0.0, 1.0, T/0.5 ) : mix( 1.0, 0.0, (T-0.5)/0.5 );\n\t\tfloat Theta = Percent * Percent * A * 8.0 * 3.14159;\n\t\tfloat S = sin( Theta );\n\t\tfloat C = cos( Theta );\n\t\tUV = vec2( dot(UV, vec2(C, -S)), dot(UV, vec2(S, C)) );\n\t}\n\tUV += vec2( 0.5, 0.5 );\n\n\tvec4 C0 = getFromColor(UV);\n\tvec4 C1 = getToColor(UV);\n\n\treturn mix( C0, C1, T );\n}\n","author":"Sergey Kosarevsky","license":"MIT","description":"Both images swirl around the center while crossfading","tags":["swirl","rotate","blend"],"params":{},"textures":[],"createdAt":"Mon, 12 Jun 2017 12:38:27 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"TVStatic","paramsTypes":{"offset":"float"},"defaultParams":{"offset":0.05},"glsl":"// Author: Brandon Anzaldi\n// License: MIT\n// Description: Cuts to full-screen TV static, then to the incoming image\n// Tags: static, noise, retro\n// @param Part of the transition, at each end, that shows the images instead of static\nuniform float offset; // = 0.05\n\n// Pseudo-random noise function\n// http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/\nhighp float noise(vec2 co)\n{\n highp float a = 12.9898;\n highp float b = 78.233;\n highp float c = 43758.5453;\n highp float dt= dot(co.xy * progress, vec2(a, b));\n highp float sn= mod(dt,3.14);\n return fract(sin(sn) * c);\n}\n\nvec4 transition(vec2 p) {\n if (progress < offset) {\n return getFromColor(p);\n } else if (progress > (1.0 - offset)) {\n return getToColor(p);\n } else {\n return vec4(vec3(noise(p)), 1.0);\n }\n}\n","author":"Brandon Anzaldi","license":"MIT","description":"Cuts to full-screen TV static, then to the incoming image","tags":["static","noise","retro"],"params":{"offset":{"type":"float","default":0.05,"description":"Part of the transition, at each end, that shows the images instead of static"}},"textures":[],"createdAt":"Fri, 22 Mar 2019 11:53:09 -0700","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"TilesWave","paramsTypes":{"tileCount":"ivec2","flipX":"bool","flipY":"bool"},"defaultParams":{"tileCount":[8,8],"flipX":true,"flipY":false},"glsl":"// Author: numb3r23\n// License: MIT\n// Description: The incoming image is revealed tile by tile in a diagonal wave\n// Tags: tiles, wave, wipe\n// Ported from https://gist.github.com/numb3r23/169781bb76f310e2bfde\n\n// @param Number of tiles (columns, rows)\nuniform ivec2 tileCount; // = ivec2(8, 8)\nuniform bool flipX; // = true\nuniform bool flipY; // = false\n\nvec4 transition(vec2 uv) {\n vec2 tileSize = 1.0 / vec2(tileCount);\n vec2 posInTile = fract(uv * vec2(tileCount));\n vec2 tileNum = floor(uv * vec2(tileCount));\n float countTiles = float(tileCount.x * tileCount.y);\n\n // Diagonal wave from bottom-left to top-right\n float offset = (tileNum.y + tileNum.x * float(tileCount.y)) / countTiles;\n float timeOffset = clamp((progress - offset) * countTiles, 0.0, 0.5);\n float sinTime = 1.0 - abs(cos(fract(timeOffset) * 3.1415926));\n\n vec2 texC = posInTile;\n\n if (sinTime <= 0.5) {\n if (flipX) {\n if (texC.x < sinTime || texC.x > 1.0 - sinTime)\n return getFromColor(uv);\n texC.x = texC.x < 0.5\n ? (texC.x - sinTime) * 0.5 / (0.5 - sinTime)\n : (texC.x - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;\n }\n if (flipY) {\n if (texC.y < sinTime || texC.y > 1.0 - sinTime)\n return getFromColor(uv);\n texC.y = texC.y < 0.5\n ? (texC.y - sinTime) * 0.5 / (0.5 - sinTime)\n : (texC.y - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;\n }\n vec2 globalUV = tileNum * tileSize + texC * tileSize;\n return getFromColor(globalUV);\n } else {\n if (flipX) {\n if (texC.x > sinTime || texC.x < 1.0 - sinTime)\n return getToColor(uv);\n texC.x = texC.x < 0.5\n ? (texC.x - sinTime) * 0.5 / (0.5 - sinTime)\n : (texC.x - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;\n texC.x = 1.0 - texC.x;\n }\n if (flipY) {\n if (texC.y > sinTime || texC.y < 1.0 - sinTime)\n return getToColor(uv);\n texC.y = texC.y < 0.5\n ? (texC.y - sinTime) * 0.5 / (0.5 - sinTime)\n : (texC.y - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;\n texC.y = 1.0 - texC.y;\n }\n vec2 globalUV = tileNum * tileSize + texC * tileSize;\n return getToColor(globalUV);\n }\n}\n","author":"numb3r23","license":"MIT","description":"The incoming image is revealed tile by tile in a diagonal wave","tags":["tiles","wave","wipe"],"params":{"tileCount":{"type":"ivec2","default":[8,8],"description":"Number of tiles (columns, rows)"},"flipX":{"type":"bool","default":true},"flipY":{"type":"bool","default":false}},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"TopBottom","paramsTypes":{},"defaultParams":{},"glsl":"// Author: zhmy\n// License: MIT\n// Description: The outgoing image shrinks away upward while the incoming one slides in from the bottom\n// Tags: slide, zoom, vertical\n\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n vec2 spfr,spto = vec2(-1.);\n float size = mix(1.0, 3.0, progress*0.2);\n spto = (uv + vec2(-0.5,-0.5))*vec2(size,size)+vec2(0.5,0.5);\n spfr = (uv + vec2(0.0, 1.0 - progress));\n if(inBounds(spfr)){\n return getToColor(spfr);\n } else if(inBounds(spto)){\n return getFromColor(spto) * (1.0 - progress);\n } else{\n return black;\n }\n}","author":"zhmy","license":"MIT","description":"The outgoing image shrinks away upward while the incoming one slides in from the bottom","tags":["slide","zoom","vertical"],"params":{},"textures":[],"createdAt":"Thu, 17 Dec 2020 11:50:34 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"VerticalClose","paramsTypes":{},"defaultParams":{},"glsl":"// Author: martiniti\n// License: MIT\n// Description: The incoming image closes in from the left and right edges toward the middle\n// Tags: wipe, split\n\nvec4 transition (vec2 uv) {\n\n float s = 2.0 - abs((uv.x - 0.5) / (progress - 1.0)) - 2.0 * progress;\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n smoothstep(0.5, 0.0, s)\n );\n}\n","author":"martiniti","license":"MIT","description":"The incoming image closes in from the left and right edges toward the middle","tags":["wipe","split"],"params":{},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:35:17 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"VerticalOpen","paramsTypes":{},"defaultParams":{},"glsl":"// Author: martiniti\n// License: MIT\n// Description: The incoming image opens from a line in the middle toward the left and right edges\n// Tags: wipe, split\n\nvec4 transition (vec2 uv) {\n\n float regress = 1.0 - progress;\n float s = 2.0 - abs((uv.x - 0.5) / (regress - 1.0)) - 2.0 * regress;\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n smoothstep(0.0, 0.5, s)\n );\n}\n","author":"martiniti","license":"MIT","description":"The incoming image opens from a line in the middle toward the left and right edges","tags":["wipe","split"],"params":{},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:35:12 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"WaterDrop","paramsTypes":{"amplitude":"float","speed":"float"},"defaultParams":{"amplitude":30,"speed":30},"glsl":"// Author: Paweł Płóciennik\n// License: MIT\n// Description: Ripples spread from the center like a drop falling into water, crossfading to the incoming image\n// Tags: ripple, water, blend\n// @param Frequency of the ripples\nuniform float amplitude; // = 30\n// @param Speed of the ripples\nuniform float speed; // = 30\n\nvec4 transition(vec2 p) {\n vec2 dir = p - vec2(.5);\n float dist = length(dir);\n\n if (dist > progress) {\n return mix(getFromColor( p), getToColor( p), progress);\n } else {\n vec2 offset = dir * sin(dist * amplitude - progress * speed);\n return mix(getFromColor( p + offset), getToColor( p), progress);\n }\n}\n","author":"Paweł Płóciennik","license":"MIT","description":"Ripples spread from the center like a drop falling into water, crossfading to the incoming image","tags":["ripple","water","blend"],"params":{"amplitude":{"type":"float","default":30,"description":"Frequency of the ripples"},"speed":{"type":"float","default":30,"description":"Speed of the ripples"}},"textures":[],"createdAt":"Wed, 21 Feb 2018 19:37:15 +0100","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"ZoomInCircles","paramsTypes":{},"defaultParams":{},"glsl":"// License: MIT\n// Author: dycm8009\n// Description: Concentric rings of the outgoing image zoom at different speeds before revealing the incoming one\n// Tags: zoom, circle\n// ported by gre from https://gist.github.com/dycm8009/948e99b1800e81ad909a\n\nvec2 zoom(vec2 uv, float amount) {\n return 0.5 + ((uv - 0.5) * amount);\t\n}\n\nvec4 transition(vec2 uv) {\n vec2 ratio2 = vec2(1.0, 1.0 / ratio);\n // TODO: some timing are hardcoded but should be one or many parameters\n // TODO: should also be able to configure how much circles\n // TODO: if() branching should be avoided when possible, prefer use of step() & other functions\n vec2 r = 2.0 * ((vec2(uv.xy) - 0.5) * ratio2);\n float pro = progress / 0.8;\n float z = pro * 0.2;\n float t = 0.0;\n if (pro > 1.0) {\n z = 0.2 + (pro - 1.0) * 5.;\n t = clamp((progress - 0.8) / 0.07, 0.0, 1.0);\n }\n if (length(r) < 0.5+z) {\n // uv = zoom(uv, 0.9 - 0.1 * pro);\n }\n else if (length(r) < 0.8+z*1.5) {\n uv = zoom(uv, 1.0 - 0.15 * pro);\n t = t * 0.5;\n }\n else if (length(r) < 1.2+z*2.5) {\n uv = zoom(uv, 1.0 - 0.2 * pro);\n t = t * 0.2;\n }\n else {\n uv = zoom(uv, 1.0 - 0.25 * pro);\n }\n return mix(getFromColor(uv), getToColor(uv), t);\n}\n","author":"dycm8009","license":"MIT","description":"Concentric rings of the outgoing image zoom at different speeds before revealing the incoming one","tags":["zoom","circle"],"params":{},"textures":[],"createdAt":"Mon, 12 Jun 2017 11:24:34 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"ZoomLeftWipe","paramsTypes":{"zoom_quickness":"float"},"defaultParams":{"zoom_quickness":0.8},"glsl":"// Author: Handk\n// License: MIT\n// Description: Zooms into the outgoing image, then the incoming one wipes in from right to left\n// Tags: zoom, wipe, horizontal\n\n// @param Part of the first half spent zooming (capped at 0.5)\nuniform float zoom_quickness; // = 0.8\nvec2 zoom(vec2 uv, float amount) {\n if(amount<0.5)\n return 0.5 + ((uv - 0.5) * (1.0-amount));\n else\n return 0.5 + ((uv - 0.5) * (amount));\n \n}\n\nvec4 transition (vec2 uv) {\n float nQuick = clamp(zoom_quickness,0.0,0.5);\n if(progress<0.5){\n vec4 c= mix(\n getFromColor(zoom(uv, smoothstep(0.0, nQuick, progress))),\n getToColor(uv),\n step(0.5, progress)\n );\n \n return c;\n }\n else{\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 d=getFromColor(p);\n vec4 e=getToColor(p);\n vec4 f= mix(d, e, step(1.0-p.x,(progress-0.5)*2.0));\n \n return f;\n }\n}\n","author":"Handk","license":"MIT","description":"Zooms into the outgoing image, then the incoming one wipes in from right to left","tags":["zoom","wipe","horizontal"],"params":{"zoom_quickness":{"type":"float","default":0.8,"description":"Part of the first half spent zooming (capped at 0.5)"}},"textures":[],"createdAt":"Tue, 15 Mar 2022 21:20:28 +0900","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"ZoomRigthWipe","paramsTypes":{"zoom_quickness":"float"},"defaultParams":{"zoom_quickness":0.8},"glsl":"// Author: Handk\n// License: MIT\n// Description: Zooms into the outgoing image, then the incoming one wipes in from left to right\n// Tags: zoom, wipe, horizontal\n\n// @param Part of the first half spent zooming (capped at 0.5)\nuniform float zoom_quickness; // = 0.8\nvec2 zoom(vec2 uv, float amount) {\n if(amount<0.5)\n return 0.5 + ((uv - 0.5) * (1.0-amount));\n else\n return 0.5 + ((uv - 0.5) * (amount));\n \n}\n\nvec4 transition (vec2 uv) {\n float nQuick = clamp(zoom_quickness,0.0,0.5);\n if(progress<0.5){\n vec4 c= mix(\n getFromColor(zoom(uv, smoothstep(0.0, nQuick, progress))),\n getToColor(uv),\n step(0.5, progress)\n );\n \n return c;\n }\n else{\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 d=getFromColor(p);\n vec4 e=getToColor(p);\n vec4 f= mix(d, e, step(0.0+p.x,(progress-0.5)*2.0));\n \n return f;\n }\n}\n","author":"Handk","license":"MIT","description":"Zooms into the outgoing image, then the incoming one wipes in from left to right","tags":["zoom","wipe","horizontal"],"params":{"zoom_quickness":{"type":"float","default":0.8,"description":"Part of the first half spent zooming (capped at 0.5)"}},"textures":[],"createdAt":"Tue, 15 Mar 2022 21:20:28 +0900","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"angular","paramsTypes":{"startingAngle":"float"},"defaultParams":{"startingAngle":90},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: A wipe that sweeps around the center from a starting angle\n// Tags: wipe, radial, clock\n\n#define PI 3.141592653589\n\n// @range(0, 360) Angle where the wipe starts, in degrees\nuniform float startingAngle; // = 90\n\nvec4 transition (vec2 uv) {\n \n float offset = startingAngle * PI / 180.0;\n float angle = atan(uv.y - 0.5, uv.x - 0.5) + offset;\n float normalizedAngle = (angle + PI) / (2.0 * PI);\n \n normalizedAngle = normalizedAngle - floor(normalizedAngle);\n\n return mix(\n getFromColor(uv),\n getToColor(uv),\n step(normalizedAngle, progress)\n );\n}\n","author":"Fernando Kuteken","license":"MIT","description":"A wipe that sweeps around the center from a starting angle","tags":["wipe","radial","clock"],"params":{"startingAngle":{"type":"float","default":90,"min":0,"max":360,"description":"Angle where the wipe starts, in degrees"}},"textures":[],"createdAt":"Sun, 28 May 2017 18:30:24 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"burn","paramsTypes":{"color":"vec3"},"defaultParams":{"color":[0.9,0.4,0.2]},"glsl":"// Author: gre\n// License: MIT\n// Description: A crossfade that brightens toward a color in the middle\n// Tags: fade, color, flash\n// @color Color the images brighten toward\nuniform vec3 color /* = vec3(0.9, 0.4, 0.2) */;\nvec4 transition (vec2 uv) {\n return mix(\n getFromColor(uv) + vec4(progress*color, 1.0),\n getToColor(uv) + vec4((1.0-progress)*color, 1.0),\n progress\n );\n}\n","author":"gre","license":"MIT","description":"A crossfade that brightens toward a color in the middle","tags":["fade","color","flash"],"params":{"color":{"type":"vec3","default":[0.9,0.4,0.2],"color":true,"description":"Color the images brighten toward"}},"textures":[],"createdAt":"Sat, 20 May 2017 19:28:26 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"burn0","paramsTypes":{"burnColor":"vec3"},"defaultParams":{"burnColor":[1,0.5,0]},"glsl":"// Author: liubailin2020@gmail.com\n// License: MIT\n// Description: The outgoing image burns away in noisy, glowing patches\n// Tags: burn, fire, noise\n\n// @color Color of the burning edges\nuniform vec3 burnColor; // = vec3(1.0, 0.5, 0.0)\n\nfloat random (in vec2 st) {\n return fract(sin(dot(st.xy,\n vec2(12.9898,78.233)))*\n 43758.5453123);\n}\n\n// Based on Morgan McGuire @morgan3d\n// https://www.shadertoy.com/view/4dS3Wd\nfloat noise (in vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n\n float a = random(i);\n float b = random(i + vec2(1.0, 0.0));\n float c = random(i + vec2(0.0, 1.0));\n float d = random(i + vec2(1.0, 1.0));\n\n vec2 u = f * f * (3.0 - 2.0 * f);\n\n return mix(a, b, u.x) +\n (c - a)* u.y * (1.0 - u.x) +\n (d - b) * u.x * u.y;\n}\n\n#define OCTAVES 4\nfloat fbm (in vec2 st) {\n float value = 0.0;\n float amplitude = .5;\n for (int i = 0; i < OCTAVES; i++) {\n value += amplitude * noise(st);\n st *= 2.;\n amplitude *= .5;\n }\n return value;\n}\n\nvec4 transition (vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n vec4 from = getFromColor(uv);\n vec4 to = getToColor(uv);\n float n = fbm(uv * 4.);\n float l = smoothstep(progress, progress + 0.05, n);\n float edge = (1.0 - l) * l * 5.0;\n return mix(to, from, l) + vec4(burnColor, 0.0) * edge;\n}\n","author":"liubailin2020@gmail.com","license":"MIT","description":"The outgoing image burns away in noisy, glowing patches","tags":["burn","fire","noise"],"params":{"burnColor":{"type":"vec3","default":[1,0.5,0],"color":true,"description":"Color of the burning edges"}},"textures":[],"createdAt":"Thu, 4 Jul 2024 14:49:27 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"cannabisleaf","paramsTypes":{},"defaultParams":{},"glsl":"// Author: @Flexi23\n// License: MIT\n// Description: A cannabis-leaf shape grows from the center to reveal the incoming image\n// Tags: shape, wipe\n\n// inspired by http://www.wolframalpha.com/input/?i=cannabis+curve\n\nvec4 transition (vec2 uv) {\n if(progress == 0.0){\n return getFromColor(uv);\n }\n vec2 leaf_uv = (uv - vec2(0.5))/10./pow(progress,3.5);\n\tleaf_uv.y += 0.35;\n\tfloat r = 0.18;\n\tfloat o = atan(leaf_uv.y, leaf_uv.x);\n return mix(getFromColor(uv), getToColor(uv), 1.-step(1. - length(leaf_uv)+r*(1.+sin(o))*(1.+0.9 * cos(8.*o))*(1.+0.1*cos(24.*o))*(0.9+0.05*cos(200.*o)), 1.));\n}\n","author":"@Flexi23","license":"MIT","description":"A cannabis-leaf shape grows from the center to reveal the incoming image","tags":["shape","wipe"],"params":{},"textures":[],"createdAt":"Thu, 1 Jun 2017 15:58:58 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"chessboard","paramsTypes":{"grid_num":"float"},"defaultParams":{"grid_num":10},"glsl":"// Author: lql\n// License: MIT\n// Description: A chessboard pattern of squares reveals the incoming image\n// Tags: grid, squares, pattern\n\n// @param Number of squares per row\nuniform float grid_num; // = 10.0\n\nvec4 transition(vec2 uv) {\n vec2 st = uv * grid_num;\n vec2 idx = floor(st);\n vec2 grid = fract(st);\n\n vec4 a = getFromColor(uv);\n vec4 b = getToColor(uv);\n\n float checker = mod(idx.x + idx.y, 2.0);\n float mixFactor;\n\n if (progress <= 0.5) {\n mixFactor = (checker > 0.5) ? step(grid.x, progress * 2.0) : 0.0;\n } else {\n mixFactor = (checker < 0.5) ? step(grid.x, (progress - 0.5) * 2.0) : 1.0;\n }\n\n return mix(a, b, mixFactor);\n}\n","author":"lql","license":"MIT","description":"A chessboard pattern of squares reveals the incoming image","tags":["grid","squares","pattern"],"params":{"grid_num":{"type":"float","default":10,"description":"Number of squares per row"}},"textures":[],"createdAt":"Mon, 22 Jan 2024 22:35:57 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"circle","paramsTypes":{"center":"vec2","backColor":"vec3"},"defaultParams":{"center":[0.5,0.5],"backColor":[0.1,0.1,0.1]},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: The outgoing image closes into a circle over a background color, then the incoming one opens from it\n// Tags: circle, iris, shape\n\n// @param Center of the circle\nuniform vec2 center; // = vec2(0.5, 0.5)\n// @color Background color\nuniform vec3 backColor; // = vec3(0.1, 0.1, 0.1)\n\nvec4 transition (vec2 uv) {\n \n float distance = length(uv - center);\n float radius = sqrt(8.0) * abs(progress - 0.5);\n \n if (distance > radius) {\n return vec4(backColor, 1.0);\n }\n else {\n if (progress < 0.5) return getFromColor(uv);\n else return getToColor(uv);\n }\n}\n","author":"Fernando Kuteken","license":"MIT","description":"The outgoing image closes into a circle over a background color, then the incoming one opens from it","tags":["circle","iris","shape"],"params":{"center":{"type":"vec2","default":[0.5,0.5],"description":"Center of the circle"},"backColor":{"type":"vec3","default":[0.1,0.1,0.1],"color":true,"description":"Background color"}},"textures":[],"createdAt":"Sun, 28 May 2017 18:00:31 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"circleopen","paramsTypes":{"smoothness":"float","opening":"bool"},"defaultParams":{"smoothness":0.3,"opening":true},"glsl":"// Author: gre\n// License: MIT\n// Description: A soft-edged circle opens from the center to reveal the incoming image\n// Tags: circle, iris, wipe\n// @param Softness of the circle's edge\nuniform float smoothness; // = 0.3\n// @param Open the circle; false closes it instead\nuniform bool opening; // = true\n\nconst vec2 center = vec2(0.5, 0.5);\nconst float SQRT_2 = 1.414213562373;\n\nvec4 transition (vec2 uv) {\n float x = opening ? progress : 1.-progress;\n float m = smoothstep(-smoothness, 0.0, SQRT_2*distance(center, uv) - x*(1.+smoothness));\n return mix(getFromColor(uv), getToColor(uv), opening ? 1.-m : m);\n}\n","author":"gre","license":"MIT","description":"A soft-edged circle opens from the center to reveal the incoming image","tags":["circle","iris","wipe"],"params":{"smoothness":{"type":"float","default":0.3,"description":"Softness of the circle's edge"},"opening":{"type":"bool","default":true,"description":"Open the circle; false closes it instead"}},"textures":[],"createdAt":"Sat, 20 May 2017 19:28:26 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"colorphase","paramsTypes":{"fromStep":"vec4","toStep":"vec4"},"defaultParams":{"fromStep":[0,0.2,0.4,0],"toStep":[0.6,0.8,1,1]},"glsl":"// Author: gre\n// License: MIT\n// Description: A crossfade in which each color channel changes at a different time\n// Tags: fade, color\n\n// Usage: fromStep and toStep must be in [0.0, 1.0] range \n// and all(fromStep) must be < all(toStep)\n\n// @range(0, 1) When each channel (r, g, b, a) starts changing\nuniform vec4 fromStep; // = vec4(0.0, 0.2, 0.4, 0.0)\n// @range(0, 1) When each channel (r, g, b, a) finishes changing\nuniform vec4 toStep; // = vec4(0.6, 0.8, 1.0, 1.0)\n\nvec4 transition (vec2 uv) {\n vec4 a = getFromColor(uv);\n vec4 b = getToColor(uv);\n return mix(a, b, smoothstep(fromStep, toStep, vec4(progress)));\n}\n","author":"gre","license":"MIT","description":"A crossfade in which each color channel changes at a different time","tags":["fade","color"],"params":{"fromStep":{"type":"vec4","default":[0,0.2,0.4,0],"min":0,"max":1,"description":"When each channel (r, g, b, a) starts changing"},"toStep":{"type":"vec4","default":[0.6,0.8,1,1],"min":0,"max":1,"description":"When each channel (r, g, b, a) finishes changing"}},"textures":[],"createdAt":"Sat, 27 May 2017 14:09:58 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"coord-from-in","paramsTypes":{},"defaultParams":{},"glsl":"// Author: haiyoucuv\n// License: MIT\n// Description: A crossfade in which the colors of one image displace the other\n// Tags: displace, distort, blend\n\nvec4 transition (vec2 uv) {\n\n vec4 coordTo = getToColor(uv);\n vec4 coordFrom = getFromColor(uv);\n\n return mix(\n getFromColor(mix(uv, coordTo.rg, progress)),\n getToColor(mix(coordFrom.rg, uv, progress)),\n progress\n );\n\n}\n","author":"haiyoucuv","license":"MIT","description":"A crossfade in which the colors of one image displace the other","tags":["displace","distort","blend"],"params":{},"textures":[],"createdAt":"Tue, 15 Mar 2022 20:22:47 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"crosshatch","paramsTypes":{"center":"vec2","threshold":"float","fadeEdge":"float"},"defaultParams":{"center":[0.5,0.5],"threshold":3,"fadeEdge":0.1},"glsl":"// License: MIT\n// Author: pthrasher\n// Description: The incoming image appears through a crosshatch of lines spreading from the center\n// Tags: pattern, lines, noise\n// adapted by gre from https://gist.github.com/pthrasher/04fd9a7de4012cbb03f6\n\n// @param Point the lines spread from\nuniform vec2 center; // = vec2(0.5)\nuniform float threshold; // = 3.0\nuniform float fadeEdge; // = 0.1\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\nvec4 transition(vec2 p) {\n float dist = distance(center, p) / threshold;\n float r = progress - min(rand(vec2(p.y, 0.0)), rand(vec2(0.0, p.x)));\n return mix(getFromColor(p), getToColor(p), mix(0.0, mix(step(dist, r), 1.0, smoothstep(1.0-fadeEdge, 1.0, progress)), smoothstep(0.0, fadeEdge, progress))); \n}\n","author":"pthrasher","license":"MIT","description":"The incoming image appears through a crosshatch of lines spreading from the center","tags":["pattern","lines","noise"],"params":{"center":{"type":"vec2","default":[0.5,0.5],"description":"Point the lines spread from"},"threshold":{"type":"float","default":3},"fadeEdge":{"type":"float","default":0.1}},"textures":[],"createdAt":"Mon, 12 Jun 2017 10:02:12 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"crosswarp","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Eke Péter <peterekepeter@gmail.com>\n// License: MIT\n// Description: The outgoing image zooms in while the incoming one zooms out into place, sweeping from right to left\n// Tags: warp, zoom, horizontal\nvec4 transition(vec2 p) {\n float x = progress;\n x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));\n return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);\n}\n","author":"Eke Péter <peterekepeter@gmail.com>","license":"MIT","description":"The outgoing image zooms in while the incoming one zooms out into place, sweeping from right to left","tags":["warp","zoom","horizontal"],"params":{},"textures":[],"createdAt":"Sat, 27 May 2017 00:19:45 +0300","updatedAt":"Fri, 9 Oct 2026 22:46:55 +0200"},{"name":"cube","paramsTypes":{"persp":"float","unzoom":"float","reflection":"float","floating":"float"},"defaultParams":{"persp":0.7,"unzoom":0.3,"reflection":0.4,"floating":3},"glsl":"// Author: gre\n// License: MIT\n// Description: The two images are faces of a rotating 3D cube, with a floor reflection\n// Tags: 3d, cube, rotate, reflection\n// @range(0, 1) Amount of perspective\nuniform float persp; // = 0.7\nuniform float unzoom; // = 0.3\n// @range(0, 1) Strength of the reflection\nuniform float reflection; // = 0.4\nuniform float floating; // = 3.0\n\nvec2 project (vec2 p) {\n return p * vec2(1.0, -1.2) + vec2(0.0, -floating/100.);\n}\n\nbool inBounds (vec2 p) {\n return all(lessThan(vec2(0.0), p)) && all(lessThan(p, vec2(1.0)));\n}\n\nvec4 bgColor (vec2 p, vec2 pfr, vec2 pto) {\n vec4 c = vec4(0.0, 0.0, 0.0, 1.0);\n pfr = project(pfr);\n // FIXME avoid branching might help perf!\n if (inBounds(pfr)) {\n c += mix(vec4(0.0), getFromColor(pfr), reflection * mix(1.0, 0.0, pfr.y));\n }\n pto = project(pto);\n if (inBounds(pto)) {\n c += mix(vec4(0.0), getToColor(pto), reflection * mix(1.0, 0.0, pto.y));\n }\n return c;\n}\n\n// p : the position\n// persp : the perspective in [ 0, 1 ]\n// center : the xcenter in [0, 1] \\ 0.5 excluded\nvec2 xskew (vec2 p, float persp, float center) {\n float x = mix(p.x, 1.0-p.x, center);\n return (\n (\n vec2( x, (p.y - 0.5*(1.0-persp) * x) / (1.0+(persp-1.0)*x) )\n - vec2(0.5-distance(center, 0.5), 0.0)\n )\n * vec2(0.5 / distance(center, 0.5) * (center<0.5 ? 1.0 : -1.0), 1.0)\n + vec2(center<0.5 ? 0.0 : 1.0, 0.0)\n );\n}\n\nvec4 transition(vec2 op) {\n float uz = unzoom * 2.0*(0.5-distance(0.5, progress));\n vec2 p = -uz*0.5+(1.0+uz) * op;\n vec2 fromP = xskew(\n (p - vec2(progress, 0.0)) / vec2(1.0-progress, 1.0),\n 1.0-mix(progress, 0.0, persp),\n 0.0\n );\n vec2 toP = xskew(\n p / vec2(progress, 1.0),\n mix(pow(progress, 2.0), 1.0, persp),\n 1.0\n );\n // FIXME avoid branching might help perf!\n if (inBounds(fromP)) {\n return getFromColor(fromP);\n }\n else if (inBounds(toP)) {\n return getToColor(toP);\n }\n return bgColor(op, fromP, toP);\n}\n","author":"gre","license":"MIT","description":"The two images are faces of a rotating 3D cube, with a floor reflection","tags":["3d","cube","rotate","reflection"],"params":{"persp":{"type":"float","default":0.7,"min":0,"max":1,"description":"Amount of perspective"},"unzoom":{"type":"float","default":0.3},"reflection":{"type":"float","default":0.4,"min":0,"max":1,"description":"Strength of the reflection"},"floating":{"type":"float","default":3}},"textures":[],"createdAt":"Sat, 27 May 2017 11:39:22 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"directional-easing","paramsTypes":{"direction":"vec2"},"defaultParams":{"direction":[0,1]},"glsl":"// Author: Max Plotnikov\n// License: MIT\n// Description: Like Directional, with an eased movement\n// Tags: slide, push, directional\n\n// @param Direction of the movement\nuniform vec2 direction; // = vec2(0.0, 1.0)\n\nvec4 transition (vec2 uv) {\n float easing = sqrt((2.0 - progress) * progress);\n vec2 p = uv + easing * sign(direction);\n vec2 f = fract(p);\n return mix(\n getToColor(f),\n getFromColor(f),\n step(0.0, p.y) * step(p.y, 1.0) * step(0.0, p.x) * step(p.x, 1.0)\n );\n}\n","author":"Max Plotnikov","license":"MIT","description":"Like Directional, with an eased movement","tags":["slide","push","directional"],"params":{"direction":{"type":"vec2","default":[0,1],"description":"Direction of the movement"}},"textures":[],"createdAt":"Wed, 23 Sep 2020 22:54:49 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"directionalwarp","paramsTypes":{"smoothness":"float","direction":"vec2"},"defaultParams":{"smoothness":0.1,"direction":[-1,1]},"glsl":"// Author: pschroen\n// License: MIT\n// Description: A diagonal wipe with a warped, smeared edge\n// Tags: wipe, warp, directional\n\n// @param Softness of the edge\nuniform float smoothness; // = 0.1\n// @param Direction of the wipe\nuniform vec2 direction; // = vec2(-1.0, 1.0)\n\nconst vec2 center = vec2(0.5, 0.5);\n\nvec4 transition (vec2 uv) {\n vec2 v = normalize(direction);\n v /= abs(v.x) + abs(v.y);\n float d = v.x * center.x + v.y * center.y;\n float m = 1.0 - smoothstep(-smoothness, 0.0, v.x * uv.x + v.y * uv.y - (d - 0.5 + progress * (1.0 + smoothness)));\n return mix(getFromColor((uv - 0.5) * (1.0 - m) + 0.5), getToColor((uv - 0.5) * m + 0.5), m);\n}\n","author":"pschroen","license":"MIT","description":"A diagonal wipe with a warped, smeared edge","tags":["wipe","warp","directional"],"params":{"smoothness":{"type":"float","default":0.1,"description":"Softness of the edge"},"direction":{"type":"vec2","default":[-1,1],"description":"Direction of the wipe"}},"textures":[],"createdAt":"Wed, 13 Dec 2017 12:08:49 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"directionalwipe","paramsTypes":{"direction":"vec2","smoothness":"float"},"defaultParams":{"direction":[1,-1],"smoothness":0.5},"glsl":"// Author: gre\n// License: MIT\n// Description: A soft-edged diagonal wipe\n// Tags: wipe, directional\n\n// @param Direction of the wipe\nuniform vec2 direction; // = vec2(1.0, -1.0)\n// @param Softness of the edge\nuniform float smoothness; // = 0.5\n \nconst vec2 center = vec2(0.5, 0.5);\n \nvec4 transition (vec2 uv) {\n vec2 v = normalize(direction);\n v /= abs(v.x)+abs(v.y);\n float d = v.x * center.x + v.y * center.y;\n float m =\n (1.0-step(progress, 0.0)) * // there is something wrong with our formula that makes m not equals 0.0 with progress is 0.0\n (1.0 - smoothstep(-smoothness, 0.0, v.x * uv.x + v.y * uv.y - (d-0.5+progress*(1.+smoothness))));\n return mix(getFromColor(uv), getToColor(uv), m);\n}\n","author":"gre","license":"MIT","description":"A soft-edged diagonal wipe","tags":["wipe","directional"],"params":{"direction":{"type":"vec2","default":[1,-1],"description":"Direction of the wipe"},"smoothness":{"type":"float","default":0.5,"description":"Softness of the edge"}},"textures":[],"createdAt":"Fri, 26 May 2017 10:41:57 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"displacement","paramsTypes":{"strength":"float"},"defaultParams":{"strength":0.5},"glsl":"// Author: Travis Fischer\n// License: MIT\n// Description: A crossfade in which a displacement map (an extra grayscale texture) warps both images\n// Tags: displace, distort, blend\n//\n// Adapted from a Codrops article by Robin Delaporte\n// https://tympanus.net/Development/DistortionHoverEffect\n\nuniform sampler2D displacementMap;\n\n// @param Strength of the displacement\nuniform float strength; // = 0.5\n\nvec4 transition (vec2 uv) {\n float displacement = texture2D(displacementMap, uv).r * strength;\n\n vec2 uvFrom = vec2(uv.x + progress * displacement, uv.y);\n vec2 uvTo = vec2(uv.x - (1.0 - progress) * displacement, uv.y);\n\n return mix(\n getFromColor(uvFrom),\n getToColor(uvTo),\n progress\n );\n}\n","author":"Travis Fischer","license":"MIT","description":"A crossfade in which a displacement map (an extra grayscale texture) warps both images","tags":["displace","distort","blend"],"params":{"strength":{"type":"float","default":0.5,"description":"Strength of the displacement"}},"textures":["displacementMap"],"createdAt":"Tue, 10 Apr 2018 23:03:38 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"dissolve","paramsTypes":{"uLineWidth":"float","uSpreadClr":"vec3","uHotClr":"vec3","uPow":"float","uIntensity":"float"},"defaultParams":{"uLineWidth":0.1,"uSpreadClr":[1,0,0],"uHotClr":[0.9,0.9,0.2],"uPow":5,"uIntensity":1},"glsl":"// Author: hjm1fb\n// License: MIT\n// Description: The incoming image spreads over the outgoing one with a hot, glowing edge\n// Tags: dissolve, burn, glow\n\nuniform float uLineWidth; // = 0.1\n// @color Color of the spreading edge\nuniform vec3 uSpreadClr; // = vec3(1.0, 0.0, 0.0)\n// @color Color of the hottest part of the edge\nuniform vec3 uHotClr; // = vec3(0.9, 0.9, 0.2)\nuniform float uPow; // = 5.0\nuniform float uIntensity; // = 1.0\n\nvec2 hash(vec2 p) // replace this by something better\n{\n p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)));\n return -1.0 + 2.0 * fract(sin(p) * 43758.5453123);\n}\n\nfloat noise(in vec2 p) {\n const float K1 = 0.366025404; // (sqrt(3)-1)/2;\n const float K2 = 0.211324865; // (3-sqrt(3))/6;\n\n vec2 i = floor(p + (p.x + p.y) * K1);\n vec2 a = p - i + (i.x + i.y) * K2;\n float m = step(a.y, a.x);\n vec2 o = vec2(m, 1.0 - m);\n vec2 b = a - o + K2;\n vec2 c = a - 1.0 + 2.0 * K2;\n vec3 h = max(0.5 - vec3(dot(a, a), dot(b, b), dot(c, c)), 0.0);\n vec3 n = h * h * h * h * vec3(dot(a, hash(i + 0.0)), dot(b, hash(i + o)), dot(c, hash(i + 1.0)));\n return dot(n, vec3(70.0));\n}\n\nvec4 transition(vec2 uv) {\n vec4 from = getFromColor(uv);\n vec4 to = getToColor(uv);\n vec4 outColor;\n float burn;\n burn = 0.5 + 0.5 * (0.299 * from.r + 0.587 * from.g + 0.114 * from.b);\n\n float show = burn - progress;\n if (show < 0.001) {\n outColor = to;\n } else {\n float factor = 1.0 - smoothstep(0.0, uLineWidth, show);\n vec3 burnColor = mix(uSpreadClr, uHotClr, factor);\n burnColor = pow(burnColor, vec3(uPow)) * uIntensity;\n vec3 finalRGB = mix(from.rgb, burnColor, factor * step(0.0001, progress));\n outColor = vec4(finalRGB * from.a, from.a);\n }\n return outColor;\n}\n","author":"hjm1fb","license":"MIT","description":"The incoming image spreads over the outgoing one with a hot, glowing edge","tags":["dissolve","burn","glow"],"params":{"uLineWidth":{"type":"float","default":0.1},"uSpreadClr":{"type":"vec3","default":[1,0,0],"color":true,"description":"Color of the spreading edge"},"uHotClr":{"type":"vec3","default":[0.9,0.9,0.2],"color":true,"description":"Color of the hottest part of the edge"},"uPow":{"type":"float","default":5},"uIntensity":{"type":"float","default":1}},"textures":[],"createdAt":"Fri, 2 Jun 2023 16:25:50 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"doorway","paramsTypes":{"reflection":"float","perspective":"float","depth":"float"},"defaultParams":{"reflection":0.4,"perspective":0.4,"depth":3},"glsl":"// Author: gre\n// License: MIT\n// Description: The outgoing image opens like double doors as the incoming one comes forward, with a floor reflection\n// Tags: doors, 3d, reflection\n// @param Strength of the reflection\nuniform float reflection; // = 0.4\n// @param Amount of perspective\nuniform float perspective; // = 0.4\nuniform float depth; // = 3\n\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec2 project (vec2 p) {\n return p * vec2(1.0, -1.2) + vec2(0.0, -0.02);\n}\n\nvec4 bgColor (vec2 p, vec2 pto) {\n vec4 c = black;\n pto = project(pto);\n if (inBounds(pto)) {\n c += mix(black, getToColor(pto), reflection * mix(1.0, 0.0, pto.y));\n }\n return c;\n}\n\n\nvec4 transition (vec2 p) {\n vec2 pfr = vec2(-1.), pto = vec2(-1.);\n float middleSlit = 2.0 * abs(p.x-0.5) - progress;\n if (middleSlit > 0.0) {\n pfr = p + (p.x > 0.5 ? -1.0 : 1.0) * vec2(0.5*progress, 0.0);\n float d = 1.0/(1.0+perspective*progress*(1.0-middleSlit));\n pfr.y -= d/2.;\n pfr.y *= d;\n pfr.y += d/2.;\n }\n float size = mix(1.0, depth, 1.-progress);\n pto = (p + vec2(-0.5, -0.5)) * vec2(size, size) + vec2(0.5, 0.5);\n if (inBounds(pfr)) {\n return getFromColor(pfr);\n }\n else if (inBounds(pto)) {\n return getToColor(pto);\n }\n else {\n return bgColor(p, pto);\n }\n}\n","author":"gre","license":"MIT","description":"The outgoing image opens like double doors as the incoming one comes forward, with a floor reflection","tags":["doors","3d","reflection"],"params":{"reflection":{"type":"float","default":0.4,"description":"Strength of the reflection"},"perspective":{"type":"float","default":0.4,"description":"Amount of perspective"},"depth":{"type":"float","default":3}},"textures":[],"createdAt":"Sat, 20 May 2017 19:28:26 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"fade","paramsTypes":{},"defaultParams":{},"glsl":"// Author: gre\n// License: MIT\n// Description: A linear crossfade between the two images\n// Tags: fade, blend\n\nvec4 transition (vec2 uv) {\n return mix(\n getFromColor(uv),\n getToColor(uv),\n progress\n );\n}\n","author":"gre","license":"MIT","description":"A linear crossfade between the two images","tags":["fade","blend"],"params":{},"textures":[],"createdAt":"Sat, 20 May 2017 19:28:26 +0200","updatedAt":"Fri, 9 Oct 2026 22:46:55 +0200"},{"name":"fadecolor","paramsTypes":{"color":"vec3","colorPhase":"float"},"defaultParams":{"color":[0,0,0],"colorPhase":0.4},"glsl":"// Author: gre\n// License: MIT\n// Description: A fade through a solid color, black by default\n// Tags: fade, color\n// @color Color to fade through\nuniform vec3 color;// = vec3(0.0)\n// @range(0, 1) How long the color shows in the middle\nuniform float colorPhase; // = 0.4 ; // if 0.0, there is no black phase, if 0.9, the black phase is very important\nvec4 transition (vec2 uv) {\n return mix(\n mix(vec4(color, 1.0), getFromColor(uv), smoothstep(1.0-colorPhase, 0.0, progress)),\n mix(vec4(color, 1.0), getToColor(uv), smoothstep( colorPhase, 1.0, progress)),\n progress);\n}\n","author":"gre","license":"MIT","description":"A fade through a solid color, black by default","tags":["fade","color"],"params":{"color":{"type":"vec3","default":[0,0,0],"color":true,"description":"Color to fade through"},"colorPhase":{"type":"float","default":0.4,"min":0,"max":1,"description":"How long the color shows in the middle"}},"textures":[],"createdAt":"Sat, 20 May 2017 19:28:26 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"fadegrayscale","paramsTypes":{"intensity":"float"},"defaultParams":{"intensity":0.3},"glsl":"// Author: gre\n// License: MIT\n// Description: A crossfade through grayscale\n// Tags: fade, grayscale, color\n\n// @range(0, 1) How long the grayscale phase lasts\nuniform float intensity; // = 0.3; // if 0.0, the image directly turn grayscale, if 0.9, the grayscale transition phase is very important\n \nvec3 grayscale (vec3 color) {\n return vec3(0.2126*color.r + 0.7152*color.g + 0.0722*color.b);\n}\n \nvec4 transition (vec2 uv) {\n vec4 fc = getFromColor(uv);\n vec4 tc = getToColor(uv);\n return mix(\n mix(vec4(grayscale(fc.rgb), 1.0), fc, smoothstep(1.0-intensity, 0.0, progress)),\n mix(vec4(grayscale(tc.rgb), 1.0), tc, smoothstep( intensity, 1.0, progress)),\n progress);\n}\n","author":"gre","license":"MIT","description":"A crossfade through grayscale","tags":["fade","grayscale","color"],"params":{"intensity":{"type":"float","default":0.3,"min":0,"max":1,"description":"How long the grayscale phase lasts"}},"textures":[],"createdAt":"Fri, 26 May 2017 09:52:33 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"flyeye","paramsTypes":{"size":"float","zoom":"float","colorSeparation":"float"},"defaultParams":{"size":0.04,"zoom":50,"colorSeparation":0.3},"glsl":"// Author: gre\n// License: MIT\n// Description: The image breaks into a fly's-eye grid of lenses with color separation\n// Tags: lens, distort, chromatic\nuniform float size; // = 0.04\nuniform float zoom; // = 50.0\nuniform float colorSeparation; // = 0.3\n\nvec4 transition(vec2 p) {\n float inv = 1. - progress;\n vec2 disp = size*vec2(cos(zoom*p.x), sin(zoom*p.y));\n vec4 texTo = getToColor(p + inv*disp);\n vec4 texFrom = vec4(\n getFromColor(p + progress*disp*(1.0 - colorSeparation)).r,\n getFromColor(p + progress*disp).g,\n getFromColor(p + progress*disp*(1.0 + colorSeparation)).b,\n 1.0);\n return texTo*progress + texFrom*inv;\n}\n","author":"gre","license":"MIT","description":"The image breaks into a fly's-eye grid of lenses with color separation","tags":["lens","distort","chromatic"],"params":{"size":{"type":"float","default":0.04},"zoom":{"type":"float","default":50},"colorSeparation":{"type":"float","default":0.3}},"textures":[],"createdAt":"Sat, 27 May 2017 11:34:46 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"fragment","paramsTypes":{},"defaultParams":{},"glsl":"// Author: lbl\n// License: MIT\n// Description: The outgoing image shatters into fragments that fly away\n// Tags: shatter, fragments\n\n#define POINTS 10\n\nfloat random(vec2 par) {\n return fract(sin(dot(par.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvec2 random2(vec2 par) {\n float rand = random(par);\n return vec2(rand, random(par + rand));\n}\n\nvec4 transition (vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n\n const float duration = 8.0;\n float time = progress * duration;\n vec2 point[POINTS];\n for (int i = 0; i < POINTS; i++) {\n point[i] = random2(vec2(float(i)));\n }\n\n vec4 col = getToColor(uv);\n\n for (int i = 0; i < POINTS; i++) {\n vec2 dir = normalize(random2(vec2(float(i), float(i) + 11.)));\n float v = (1.0 + random(dir) * 0.5) * 0.2;\n vec2 ofst = dir * clamp(time - 0.5, 0.0, duration) * v;\n vec2 U = uv - ofst;\n\n if (U.x < 0.0 || U.x > 1.0 || U.y < 0.0 || U.y > 1.0) continue;\n\n float dist_i = distance(U, point[i]);\n bool closest = true;\n for (int j = 0; j < POINTS; j++) {\n if (distance(U, point[j]) < dist_i) {\n closest = false;\n break;\n }\n }\n\n if (closest) {\n col = getFromColor(U);\n break;\n }\n }\n return col;\n}\n","author":"lbl","license":"MIT","description":"The outgoing image shatters into fragments that fly away","tags":["shatter","fragments"],"params":{},"textures":[],"createdAt":"Thu, 4 Jul 2024 15:10:28 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"heart","paramsTypes":{},"defaultParams":{},"glsl":"// Author: gre\n// License: MIT\n// Description: A heart shape grows from the center to reveal the incoming image\n// Tags: shape, wipe, heart\n\nfloat inHeart (vec2 p, vec2 center, float size) {\n if (size==0.0) return 0.0;\n vec2 o = (p-center)/(1.6*size);\n float a = o.x*o.x+o.y*o.y-0.3;\n return step(a*a*a, o.x*o.x*o.y*o.y*o.y);\n}\nvec4 transition (vec2 uv) {\n return mix(\n getFromColor(uv),\n getToColor(uv),\n inHeart(uv, vec2(0.5, 0.4), progress)\n );\n}\n","author":"gre","license":"MIT","description":"A heart shape grows from the center to reveal the incoming image","tags":["shape","wipe","heart"],"params":{},"textures":[],"createdAt":"Fri, 26 May 2017 12:22:53 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"hexagonalize","paramsTypes":{"steps":"int","horizontalHexagons":"float"},"defaultParams":{"steps":50,"horizontalHexagons":20},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: Both images turn into hexagons, crossfade, then sharpen again\n// Tags: pixelate, hexagon, blend\n// Hexagonal math from: http://www.redblobgames.com/grids/hexagons/\n\nuniform int steps; // = 50\n// @param Number of hexagons across\nuniform float horizontalHexagons; // = 20\n\nstruct Hexagon {\n float q;\n float r;\n float s;\n};\n\nHexagon createHexagon(float q, float r){\n Hexagon hex;\n hex.q = q;\n hex.r = r;\n hex.s = -q - r;\n return hex;\n}\n\nHexagon roundHexagon(Hexagon hex){\n \n float q = floor(hex.q + 0.5);\n float r = floor(hex.r + 0.5);\n float s = floor(hex.s + 0.5);\n\n float deltaQ = abs(q - hex.q);\n float deltaR = abs(r - hex.r);\n float deltaS = abs(s - hex.s);\n\n if (deltaQ > deltaR && deltaQ > deltaS)\n q = -r - s;\n else if (deltaR > deltaS)\n r = -q - s;\n else\n s = -q - r;\n\n return createHexagon(q, r);\n}\n\nHexagon hexagonFromPoint(vec2 point, float size) {\n \n point.y /= ratio;\n point = (point - 0.5) / size;\n \n float q = (sqrt(3.0) / 3.0) * point.x + (-1.0 / 3.0) * point.y;\n float r = 0.0 * point.x + 2.0 / 3.0 * point.y;\n\n Hexagon hex = createHexagon(q, r);\n return roundHexagon(hex);\n \n}\n\nvec2 pointFromHexagon(Hexagon hex, float size) {\n \n float x = (sqrt(3.0) * hex.q + (sqrt(3.0) / 2.0) * hex.r) * size + 0.5;\n float y = (0.0 * hex.q + (3.0 / 2.0) * hex.r) * size + 0.5;\n \n return vec2(x, y * ratio);\n}\n\nvec4 transition (vec2 uv) {\n \n float dist = 2.0 * min(progress, 1.0 - progress);\n dist = steps > 0 ? ceil(dist * float(steps)) / float(steps) : dist;\n \n float size = (sqrt(3.0) / 3.0) * dist / horizontalHexagons;\n \n vec2 point = dist > 0.0 ? pointFromHexagon(hexagonFromPoint(uv, size), size) : uv;\n\n return mix(getFromColor(point), getToColor(point), progress);\n \n}\n","author":"Fernando Kuteken","license":"MIT","description":"Both images turn into hexagons, crossfade, then sharpen again","tags":["pixelate","hexagon","blend"],"params":{"steps":{"type":"int","default":50},"horizontalHexagons":{"type":"float","default":20,"description":"Number of hexagons across"}},"textures":[],"createdAt":"Tue, 30 May 2017 21:55:47 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"kaleidoscope","paramsTypes":{"speed":"float","angle":"float","power":"float"},"defaultParams":{"speed":1,"angle":1,"power":1.5},"glsl":"// Author: nwoeanhinnogaehr\n// License: MIT\n// Description: A crossfade through a spinning kaleidoscope\n// Tags: kaleidoscope, distort, blend\n\nuniform float speed; // = 1.0\nuniform float angle; // = 1.0\nuniform float power; // = 1.5\n\nvec4 transition(vec2 uv) {\n vec2 p = uv.xy / vec2(1.0).xy;\n vec2 q = p;\n float t = pow(progress, power)*speed;\n p = p -0.5;\n for (int i = 0; i < 7; i++) {\n p = vec2(sin(t)*p.x + cos(t)*p.y, sin(t)*p.y - cos(t)*p.x);\n t += angle;\n p = abs(mod(p, 2.0) - 1.0);\n }\n abs(mod(p, 1.0));\n return mix(\n mix(getFromColor(q), getToColor(q), progress),\n mix(getFromColor(p), getToColor(p), progress), 1.0 - 2.0*abs(progress - 0.5));\n}\n","author":"nwoeanhinnogaehr","license":"MIT","description":"A crossfade through a spinning kaleidoscope","tags":["kaleidoscope","distort","blend"],"params":{"speed":{"type":"float","default":1},"angle":{"type":"float","default":1},"power":{"type":"float","default":1.5}},"textures":[],"createdAt":"Wed, 31 May 2017 21:48:26 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"luma","paramsTypes":{},"defaultParams":{},"glsl":"// Author: gre\n// License: MIT\n// Description: A wipe that follows the brightness of a grayscale mask (the luma texture)\n// Tags: wipe, luma, mask\n\nuniform sampler2D luma;\n\nvec4 transition(vec2 uv) {\n return mix(\n getToColor(uv),\n getFromColor(uv),\n step(progress, texture2D(luma, uv).r)\n );\n}\n","author":"gre","license":"MIT","description":"A wipe that follows the brightness of a grayscale mask (the luma texture)","tags":["wipe","luma","mask"],"params":{},"textures":["luma"],"createdAt":"Fri, 26 May 2017 21:30:20 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"luminance_melt","paramsTypes":{"direction":"bool","l_threshold":"float","above":"bool"},"defaultParams":{"direction":false,"l_threshold":0.8,"above":false},"glsl":"// Author: 0gust1\n// License: MIT\n// Description: The outgoing image melts away in noisy vertical streaks, depending on its brightness\n// Tags: melt, noise, luma\n//My own first transition — based on crosshatch code (from pthrasher), using simplex noise formula (copied and pasted)\n//-> cooler with high contrasted images (isolated dark subject on light background f.e.)\n//TODO : try to rebase it on DoomTransition (from zeh)?\n//optimizations :\n//luminance (see http://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color#answer-596241)\n// Y = (R+R+B+G+G+G)/6\n//or Y = (R+R+R+B+G+G+G+G)>>3 \n\n\n//direction of movement : 0 : up, 1, down\n// @param Direction of the melt (false: up, true: down)\nuniform bool direction; // = 1 \n//luminance threshold\n// @range(0, 1) Luminance threshold\nuniform float l_threshold; // = 0.8 \n//does the movement takes effect above or below luminance threshold ?\n// @param Melt the parts above the threshold instead of below\nuniform bool above; // = false \n\n\n//Random function borrowed from everywhere\nfloat rand(vec2 co){\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\n\n// Simplex noise :\n// Description : Array and textureless GLSL 2D simplex noise function.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : ijm\n// Lastmod : 20110822 (ijm)\n// License : MIT \n// 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// \n\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec3 permute(vec3 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat snoise(vec2 v)\n {\n const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0\n 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)\n -0.577350269189626, // -1.0 + 2.0 * C.x\n 0.024390243902439); // 1.0 / 41.0\n// First corner\n vec2 i = floor(v + dot(v, C.yy) );\n vec2 x0 = v - i + dot(i, C.xx);\n\n// Other corners\n vec2 i1;\n //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0\n //i1.y = 1.0 - i1.x;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n // x0 = x0 - 0.0 + 0.0 * C.xx ;\n // x1 = x0 - i1 + 1.0 * C.xx ;\n // x2 = x0 - 1.0 + 2.0 * C.xx ;\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n\n// Permutations\n i = mod289(i); // Avoid truncation effects in permutation\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))\n\t\t+ i.x + vec3(0.0, i1.x, 1.0 ));\n\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n m = m*m ;\n m = m*m ;\n\n// Gradients: 41 points uniformly over a line, mapped onto a diamond.\n// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n\n// Normalise gradients implicitly by scaling m\n// Approximation of: m *= inversesqrt( a0*a0 + h*h );\n m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );\n\n// Compute final noise value at P\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\n// Simplex noise -- end\n\nfloat luminance(vec4 color){\n //(0.299*R + 0.587*G + 0.114*B)\n return color.r*0.299+color.g*0.587+color.b*0.114;\n}\n\nvec4 transition(vec2 uv) {\n vec2 center = vec2(1.0, direction);\n vec2 p = uv.xy / vec2(1.0).xy;\n if (progress == 0.0) {\n return getFromColor(p);\n } else if (progress == 1.0) {\n return getToColor(p);\n } else {\n float x = progress;\n float dist = distance(center, p)- progress*exp(snoise(vec2(p.x, 0.0)));\n float r = x - rand(vec2(p.x, 0.1));\n float m;\n if(above){\n m = dist <= r && luminance(getFromColor(p))>l_threshold ? 1.0 : (progress*progress*progress);\n }\n else{\n m = dist <= r && luminance(getFromColor(p))<l_threshold ? 1.0 : (progress*progress*progress); \n }\n return mix(getFromColor(p), getToColor(p), m); \n }\n}\n","author":"0gust1","license":"MIT","description":"The outgoing image melts away in noisy vertical streaks, depending on its brightness","tags":["melt","noise","luma"],"params":{"direction":{"type":"bool","default":false,"description":"Direction of the melt (false: up, true: down)"},"l_threshold":{"type":"float","default":0.8,"min":0,"max":1,"description":"Luminance threshold"},"above":{"type":"bool","default":false,"description":"Melt the parts above the threshold instead of below"}},"textures":[],"createdAt":"Wed, 24 Jan 2018 19:02:32 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"morph","paramsTypes":{"strength":"float"},"defaultParams":{"strength":0.1},"glsl":"// Author: paniq\n// License: MIT\n// Description: A crossfade in which each image is displaced by the other's colors, like a morph\n// Tags: morph, distort, blend\n// @param Strength of the displacement\nuniform float strength; // = 0.1\n\nvec4 transition(vec2 p) {\n vec4 ca = getFromColor(p);\n vec4 cb = getToColor(p);\n \n vec2 oa = (((ca.rg+ca.b)*0.5)*2.0-1.0);\n vec2 ob = (((cb.rg+cb.b)*0.5)*2.0-1.0);\n vec2 oc = mix(oa,ob,0.5)*strength;\n \n float w0 = progress;\n float w1 = 1.0-w0;\n return mix(getFromColor(p+oc*w0), getToColor(p-oc*w1), progress);\n}\n","author":"paniq","license":"MIT","description":"A crossfade in which each image is displaced by the other's colors, like a morph","tags":["morph","distort","blend"],"params":{"strength":{"type":"float","default":0.1,"description":"Strength of the displacement"}},"textures":[],"createdAt":"Thu, 10 Aug 2017 00:27:36 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"mosaic_transition","paramsTypes":{"mosaicNum":"float"},"defaultParams":{"mosaicNum":10},"glsl":"// Author: YueDev\n// License: MIT\n// Description: Both images break into mosaic blocks that blend, then sharpen into the incoming image\n// Tags: mosaic, pixelate, blend\n\n// @param Number of mosaic blocks\nuniform float mosaicNum;// = 10.0\n\nvec2 getMosaicUV(vec2 uv) {\n float mosaicWidth = 2.0 / mosaicNum * min(progress, 1.0 - progress);\n float mX = floor(uv.x / mosaicWidth) + 0.5;\n float mY = floor(uv.y / mosaicWidth) + 0.5;\n return vec2(mX * mosaicWidth, mY * mosaicWidth);\n}\n\nvec4 transition (vec2 uv) {\n vec2 mosaicUV = min(progress, 1.0 - progress) == 0.0 ? uv : getMosaicUV(uv);\n return mix(getFromColor(mosaicUV), getToColor(mosaicUV), progress * progress);\n}\n","author":"YueDev","license":"MIT","description":"Both images break into mosaic blocks that blend, then sharpen into the incoming image","tags":["mosaic","pixelate","blend"],"params":{"mosaicNum":{"type":"float","default":10,"description":"Number of mosaic blocks"}},"textures":[],"createdAt":"Fri, 27 May 2022 19:14:24 +0800","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"multiply_blend","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: A crossfade through the multiplied blend of both images\n// Tags: blend, fade\n\nvec4 blend(vec4 a, vec4 b) {\n return a * b;\n}\n\nvec4 transition (vec2 uv) {\n \n vec4 blended = blend(getFromColor(uv), getToColor(uv));\n \n if (progress < 0.5)\n return mix(getFromColor(uv), blended, 2.0 * progress);\n else\n return mix(blended, getToColor(uv), 2.0 * progress - 1.0);\n}\n\n","author":"Fernando Kuteken","license":"MIT","description":"A crossfade through the multiplied blend of both images","tags":["blend","fade"],"params":{},"textures":[],"createdAt":"Mon, 29 May 2017 17:13:58 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"old_tv_lost_signal","paramsTypes":{},"defaultParams":{},"glsl":"// Author: mernking gitlab: Godswork\n// License: MIT\n// Description: A crossfade with drifting tracking lines and tearing, like a TV losing its signal\n// Tags: retro, glitch, scanlines\n\nfloat hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n}\n\nvec4 transition(vec2 uv) {\n\n float p = progress;\n float strength = sin(p * 3.14159265);\n\n vec2 tv = uv;\n\n vec4 fromColor = getFromColor(tv);\n vec4 toColor = getToColor(tv);\n\n vec4 color = mix(fromColor, toColor, p);\n\n // horizontal tracking lines (key effect)\n float lineY = floor(tv.y * 120.0);\n\n float noise = hash(vec2(lineY, p * 20.0));\n\n float line = step(0.92, noise);\n\n // make lines drift during transition\n float drift =\n sin(tv.y * 30.0 + p * 10.0)\n * 0.02\n * strength;\n\n vec4 shiftedFrom = getFromColor(tv + vec2(drift, 0.0));\n vec4 shiftedTo = getToColor(tv + vec2(drift, 0.0));\n\n vec4 lineColor = mix(shiftedFrom, shiftedTo, p);\n\n // apply tearing only on selected scanlines\n color = mix(color, lineColor, line * strength);\n\n // mild scanline darkening (CRT feel)\n float scan =\n sin(tv.y * 900.0) * 0.03;\n\n color.rgb -= scan * strength;\n\n return color;\n}\n","author":"mernking gitlab: Godswork","license":"MIT","description":"A crossfade with drifting tracking lines and tearing, like a TV losing its signal","tags":["retro","glitch","scanlines"],"params":{},"textures":[],"createdAt":"Mon, 22 Jun 2026 00:33:17 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"parametric_glitch","paramsTypes":{"ampx":"float","ampy":"float"},"defaultParams":{"ampx":1,"ampy":1},"glsl":"// Author: Yoni Maltsman @friendlyspinach\n// License: MIT\n// Description: A crossfade with glitchy horizontal bands and color shifts\n// Tags: glitch, blend\n\n\n\n// @param Horizontal amplitude of the glitch\nuniform float ampx; // =1.0\n// @param Vertical amplitude of the glitch\nuniform float ampy; //=1.0\n\nvec4 transition (vec2 uv) {\n vec4 from = getFromColor(uv);\n vec4 to = getToColor(uv);\n float r = from.r;\n float g = from.g;\n float b = from.b;\n float sphere = r*r + g*g + b*b - 1.0; //3 to 1\n float spiralX = cos(sphere - uv.x/(progress + .01));\n float spiralY = sin(sphere - uv.y/(progress+.01));\n vec2 st = uv;\n st.x = fract(ampx*st.x*spiralX); //1 to 2\n st.y = fract(ampy*st.y*spiralY);\n vec2 diff = uv - st;\n from = getFromColor(uv + progress*diff);\n return mix(from, to, progress);\n}\n","author":"Yoni Maltsman @friendlyspinach","license":"MIT","description":"A crossfade with glitchy horizontal bands and color shifts","tags":["glitch","blend"],"params":{"ampx":{"type":"float","default":1,"description":"Horizontal amplitude of the glitch"},"ampy":{"type":"float","default":1,"description":"Vertical amplitude of the glitch"}},"textures":[],"createdAt":"Sat, 22 Jun 2024 13:22:34 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"perlin","paramsTypes":{"scale":"float","smoothness":"float","seed":"float"},"defaultParams":{"scale":4,"smoothness":0.01,"seed":12.9898},"glsl":"// Author: Rich Harris\n// License: MIT\n// Description: The incoming image appears through blobs of Perlin noise\n// Tags: noise, dissolve\n\n// @param Scale of the noise; higher values make smaller blobs\nuniform float scale; // = 4.0\n// @param Softness of the blob edges\nuniform float smoothness; // = 0.01\n\n// @param Random seed\nuniform float seed; // = 12.9898\n\n// http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/\nfloat random(vec2 co)\n{\n float a = seed;\n float b = 78.233;\n float c = 43758.5453;\n float dt= dot(co.xy ,vec2(a,b));\n float sn= mod(dt,3.14);\n return fract(sin(sn) * c);\n}\n\n// 2D Noise based on Morgan McGuire @morgan3d\n// https://www.shadertoy.com/view/4dS3Wd\nfloat noise (in vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n\n // Four corners in 2D of a tile\n float a = random(i);\n float b = random(i + vec2(1.0, 0.0));\n float c = random(i + vec2(0.0, 1.0));\n float d = random(i + vec2(1.0, 1.0));\n\n // Smooth Interpolation\n\n // Cubic Hermine Curve. Same as SmoothStep()\n vec2 u = f*f*(3.0-2.0*f);\n // u = smoothstep(0.,1.,f);\n\n // Mix 4 coorners porcentages\n return mix(a, b, u.x) +\n (c - a)* u.y * (1.0 - u.x) +\n (d - b) * u.x * u.y;\n}\n\nvec4 transition (vec2 uv) {\n vec4 from = getFromColor(uv);\n vec4 to = getToColor(uv);\n float n = noise(uv * scale);\n\n float p = mix(-smoothness, 1.0 + smoothness, progress);\n float lower = p - smoothness;\n float higher = p + smoothness;\n\n float q = smoothstep(lower, higher, n);\n\n return mix(\n from,\n to,\n 1.0 - q\n );\n}\n","author":"Rich Harris","license":"MIT","description":"The incoming image appears through blobs of Perlin noise","tags":["noise","dissolve"],"params":{"scale":{"type":"float","default":4,"description":"Scale of the noise; higher values make smaller blobs"},"smoothness":{"type":"float","default":0.01,"description":"Softness of the blob edges"},"seed":{"type":"float","default":12.9898,"description":"Random seed"}},"textures":[],"createdAt":"Tue, 23 Jan 2018 21:35:10 -0500","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"pinwheel","paramsTypes":{"speed":"float"},"defaultParams":{"speed":2},"glsl":"// Author: Mr Speaker\n// License: MIT\n// Description: A spinning pinwheel reveals the incoming image\n// Tags: pinwheel, radial, rotate\n\n// @param Rotation speed\nuniform float speed; // = 2.0\n\nvec4 transition(vec2 uv) {\n \n vec2 p = uv.xy / vec2(1.0).xy;\n \n float circPos = atan(p.y - 0.5, p.x - 0.5) + progress * speed;\n float modPos = mod(circPos, 3.1415 / 4.);\n float signed = sign(progress - modPos);\n \n return mix(getToColor(p), getFromColor(p), step(signed, 0.5));\n \n}\n","author":"Mr Speaker","license":"MIT","description":"A spinning pinwheel reveals the incoming image","tags":["pinwheel","radial","rotate"],"params":{"speed":{"type":"float","default":2,"description":"Rotation speed"}},"textures":[],"createdAt":"Tue, 30 May 2017 09:04:31 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"pixelize","paramsTypes":{"squaresMin":"ivec2","steps":"int"},"defaultParams":{"squaresMin":[20,20],"steps":50},"glsl":"// Author: gre\n// License: MIT\n// Description: Both images pixelate, crossfade, then sharpen again\n// Tags: pixelate, blend\n// forked from https://gist.github.com/benraziel/c528607361d90a072e98\n\n// minimum number of squares (when the effect is at its higher level)\n// @param Number of squares at the strongest pixelation\nuniform ivec2 squaresMin; // = ivec2(20)\n// zero disable the stepping\n// @param Number of pixelation steps; 0 for a continuous effect\nuniform int steps; // = 50\n\nvec4 transition(vec2 uv) {\n float d = min(progress, 1.0 - progress);\n float dist = steps>0 ? ceil(d * float(steps)) / float(steps) : d;\n vec2 squareSize = 2.0 * dist / vec2(squaresMin);\n vec2 p = dist>0.0 ? (floor(uv / squareSize) + 0.5) * squareSize : uv;\n return mix(getFromColor(p), getToColor(p), progress);\n}\n","author":"gre","license":"MIT","description":"Both images pixelate, crossfade, then sharpen again","tags":["pixelate","blend"],"params":{"squaresMin":{"type":"ivec2","default":[20,20],"description":"Number of squares at the strongest pixelation"},"steps":{"type":"int","default":50,"description":"Number of pixelation steps; 0 for a continuous effect"}},"textures":[],"createdAt":"Mon, 29 May 2017 11:16:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"polar_function","paramsTypes":{"segments":"int"},"defaultParams":{"segments":5},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: A flower shape with several petals grows to reveal the incoming image\n// Tags: shape, wipe, polar\n\n#define PI 3.14159265359\n\n// @param Number of petals\nuniform int segments; // = 5\n\nvec4 transition (vec2 uv) {\n \n float angle = atan(uv.y - 0.5, uv.x - 0.5) - 0.5 * PI;\n float normalized = (angle + 1.5 * PI) * (2.0 * PI);\n \n float radius = (cos(float(segments) * angle) + 4.0) / 4.0;\n float difference = length(uv - vec2(0.5, 0.5));\n \n if (difference > radius * progress)\n return getFromColor(uv);\n else\n return getToColor(uv);\n}\n","author":"Fernando Kuteken","license":"MIT","description":"A flower shape with several petals grows to reveal the incoming image","tags":["shape","wipe","polar"],"params":{"segments":{"type":"int","default":5,"description":"Number of petals"}},"textures":[],"createdAt":"Sun, 28 May 2017 18:53:12 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"powerKaleido","paramsTypes":{"scale":"float","z":"float","speed":"float"},"defaultParams":{"scale":2,"z":1.5,"speed":5},"glsl":"// Name: Power Kaleido\n// Author: Boundless\n// License: MIT\n// Description: The image folds into an animated kaleidoscope before revealing the incoming one\n// Tags: kaleidoscope, distort\n#define PI 3.14159265358979\nconst float rad = 120.; // change this value to get different mirror effects\nconst float deg = rad / 180. * PI;\nuniform float scale; // = 2.0\nuniform float z; // = 1.5\nuniform float speed; // = 5.\nvec2 refl(vec2 p,vec2 o,vec2 n)\n{\n\treturn 2.0*o+2.0*n*dot(p-o,n)-p;\n}\n\nvec2 rot(vec2 p, vec2 o, float a)\n{\n float s = sin(a);\n float c = cos(a);\n\treturn o + mat2(c, -s, s, c) * (p - o);\n}\n\nvec4 mainImage(vec2 uv)\n{\n float dist = scale / 10.;\n vec2 uv0 = uv;\n\tuv -= 0.5;\n uv.x *= ratio;\n uv *= z;\n uv = rot(uv, vec2(0.0), progress*speed);\n // uv.x = fract(uv.x/l/3.0)*l*3.0;\n\tfloat theta = progress*6.+PI/.5;\n\tfor(int iter = 0; iter < 10; iter++) {\n for(float i = 0.; i < 2. * PI; i+=deg) {\n\t float ts = sign(asin(cos(i))) == 1.0 ? 1.0 : 0.0;\n if(((ts == 1.0) && (uv.y-dist*cos(i) > tan(i)*(uv.x+dist*+sin(i)))) || ((ts == 0.0) && (uv.y-dist*cos(i) < tan(i)*(uv.x+dist*+sin(i))))) {\n uv = refl(vec2(uv.x+sin(i)*dist*2.,uv.y-cos(i)*dist*2.), vec2(0.,0.), vec2(cos(i),sin(i)));\n }\n }\n }\n uv += 0.5;\n uv = rot(uv, vec2(0.5), progress*-speed);\n uv -= 0.5;\n uv.x /= ratio;\n uv += 0.5;\n uv = 2.*abs(uv/2.-floor(uv/2.+0.5));\n vec2 uvMix = mix(uv,uv0,cos(progress*PI*2.)/2.+0.5);\n vec4 color = mix(getFromColor(uvMix),getToColor(uvMix),cos((progress-1.)*PI)/2.+0.5);\n\treturn color;\n \n}\nvec4 transition (vec2 uv) {\n vec4 color = mainImage(uv);\n return color;\n}\n","author":"Boundless","license":"MIT","description":"The image folds into an animated kaleidoscope before revealing the incoming one","tags":["kaleidoscope","distort"],"params":{"scale":{"type":"float","default":2},"z":{"type":"float","default":1.5},"speed":{"type":"float","default":5}},"textures":[],"createdAt":"Tue, 15 Mar 2022 07:18:34 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"randomNoisex","paramsTypes":{},"defaultParams":{},"glsl":"// Author: towrabbit\n// License: MIT\n// Description: The incoming image appears pixel by pixel in random noise\n// Tags: dissolve, noise\n\nfloat random (vec2 st) {\n return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123);\n}\nvec4 transition (vec2 uv) {\n vec4 leftSide = getFromColor(uv);\n vec4 rightSide = getToColor(uv);\n float uvz = floor(random(uv)+progress);\n return mix(leftSide,rightSide,uvz);\n}\n","author":"towrabbit","license":"MIT","description":"The incoming image appears pixel by pixel in random noise","tags":["dissolve","noise"],"params":{},"textures":[],"createdAt":"Wed, 28 Oct 2020 15:02:19 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"randomsquares","paramsTypes":{"size":"ivec2","smoothness":"float"},"defaultParams":{"size":[10,10],"smoothness":0.5},"glsl":"// Author: gre\n// License: MIT\n// Description: The incoming image appears in random squares\n// Tags: squares, grid, dissolve\n\n// @param Number of squares (columns, rows)\nuniform ivec2 size; // = ivec2(10, 10)\n// @param Softness of each square's switch\nuniform float smoothness; // = 0.5\n \nfloat rand (vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nvec4 transition(vec2 p) {\n float r = rand(floor(vec2(size) * p));\n float m = smoothstep(0.0, -smoothness, r - (progress * (1.0 + smoothness)));\n return mix(getFromColor(p), getToColor(p), m);\n}\n","author":"gre","license":"MIT","description":"The incoming image appears in random squares","tags":["squares","grid","dissolve"],"params":{"size":{"type":"ivec2","default":[10,10],"description":"Number of squares (columns, rows)"},"smoothness":{"type":"float","default":0.5,"description":"Softness of each square's switch"}},"textures":[],"createdAt":"Sat, 27 May 2017 11:31:45 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"ripple","paramsTypes":{"amplitude":"float","speed":"float"},"defaultParams":{"amplitude":100,"speed":50},"glsl":"// Author: gre\n// License: MIT\n// Description: Ripples spread from the center while crossfading\n// Tags: ripple, wave, blend\n// @param Frequency of the ripples\nuniform float amplitude; // = 100.0\n// @param Speed of the ripples\nuniform float speed; // = 50.0\n\nvec4 transition (vec2 uv) {\n vec2 dir = uv - vec2(.5);\n float dist = length(dir);\n vec2 offset = dir * (sin(progress * dist * amplitude - progress * speed) + .5) / 30. * progress;\n return mix(\n getFromColor(uv + offset),\n getToColor(uv),\n smoothstep(0.2, 1.0, progress)\n );\n}\n","author":"gre","license":"MIT","description":"Ripples spread from the center while crossfading","tags":["ripple","wave","blend"],"params":{"amplitude":{"type":"float","default":100,"description":"Frequency of the ripples"},"speed":{"type":"float","default":50,"description":"Speed of the ripples"}},"textures":[],"createdAt":"Fri, 26 May 2017 12:25:18 +0200","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"rotateTransition","paramsTypes":{},"defaultParams":{},"glsl":"// Author: haiyoucuv\n// License: MIT\n// Description: The images spin around the center while crossfading\n// Tags: rotate, spin, blend\n\n#define PI 3.1415926\n\nvec2 rotate2D(in vec2 uv, in float angle){\n \n return uv * mat2(cos(angle), -sin(angle), sin(angle), cos(angle));\n}\nvec4 transition (vec2 uv) {\n \n vec2 p = fract(rotate2D(uv - 0.5, progress * PI * 2.0) + 0.5);\n\n return mix(\n getFromColor(p),\n getToColor(p),\n progress\n );\n}\n","author":"haiyoucuv","license":"MIT","description":"The images spin around the center while crossfading","tags":["rotate","spin","blend"],"params":{},"textures":[],"createdAt":"Thu, 25 Mar 2021 16:48:22 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"rotate_scale_fade","paramsTypes":{"center":"vec2","rotations":"float","scale":"float","backColor":"vec4"},"defaultParams":{"center":[0.5,0.5],"rotations":1,"scale":8,"backColor":[0.15,0.15,0.15,1]},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: The outgoing image spins and zooms while fading to the incoming one, over a background color\n// Tags: rotate, zoom, fade\n\n#define PI 3.14159265359\n\n// @param Center of the rotation\nuniform vec2 center; // = vec2(0.5, 0.5)\n// @param Number of turns\nuniform float rotations; // = 1\n// @param Maximum zoom\nuniform float scale; // = 8\n// @color Background color\nuniform vec4 backColor; // = vec4(0.15, 0.15, 0.15, 1.0)\n\nvec4 transition (vec2 uv) {\n \n vec2 difference = uv - center;\n vec2 dir = normalize(difference);\n float dist = length(difference);\n \n float angle = 2.0 * PI * rotations * progress;\n \n float c = cos(angle);\n float s = sin(angle);\n \n float currentScale = mix(scale, 1.0, 2.0 * abs(progress - 0.5));\n \n vec2 rotatedDir = vec2(dir.x * c - dir.y * s, dir.x * s + dir.y * c);\n vec2 rotatedUv = center + rotatedDir * dist / currentScale;\n \n if (rotatedUv.x < 0.0 || rotatedUv.x > 1.0 ||\n rotatedUv.y < 0.0 || rotatedUv.y > 1.0)\n return backColor;\n \n return mix(getFromColor(rotatedUv), getToColor(rotatedUv), progress);\n}\n","author":"Fernando Kuteken","license":"MIT","description":"The outgoing image spins and zooms while fading to the incoming one, over a background color","tags":["rotate","zoom","fade"],"params":{"center":{"type":"vec2","default":[0.5,0.5],"description":"Center of the rotation"},"rotations":{"type":"float","default":1,"description":"Number of turns"},"scale":{"type":"float","default":8,"description":"Maximum zoom"},"backColor":{"type":"vec4","default":[0.15,0.15,0.15,1],"color":true,"description":"Background color"}},"textures":[],"createdAt":"Mon, 29 May 2017 18:25:00 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"scale-in","paramsTypes":{},"defaultParams":{},"glsl":"// Author: haiyoucuv\n// License: MIT\n// Description: The incoming image scales in from the center while fading in\n// Tags: zoom, fade\n\nvec4 scale(in vec2 uv){\n uv = 0.5 + (uv - 0.5) * progress;\n return getToColor(uv);\n}\n\nvec4 transition (vec2 uv) {\n return mix(\n getFromColor(uv),\n scale(uv),\n progress\n );\n}\n","author":"haiyoucuv","license":"MIT","description":"The incoming image scales in from the center while fading in","tags":["zoom","fade"],"params":{},"textures":[],"createdAt":"Tue, 15 Mar 2022 20:21:46 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideInHorizontal","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The incoming image slides in as two halves moving horizontally in opposite directions\n// Tags: slide, split, horizontal\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = reverse ? -1.0 : 1.0;\n vec2 toP = (uv.y > 0.5) ?\n vec2((uv.x - (progress * modifier)) + modifier, uv.y) :\n vec2((uv.x + (progress * modifier)) - modifier, uv.y);\n\n vec2 fromP = uv;\n\n return inBounds(toP) ? getToColor(toP) : getFromColor(fromP);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The incoming image slides in as two halves moving horizontally in opposite directions","tags":["slide","split","horizontal"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideInOutHorizontal","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The halves of both images slide horizontally in opposite directions, out and in at once\n// Tags: slide, split, horizontal\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = (uv.y > 0.5 ? 1.0 : -1.0) * (reverse ? -1.0 : 1.0) ;\n vec2 fromP = vec2(uv.x + (progress * modifier), uv.y);\n vec2 toP = vec2((uv.x + (progress * modifier)) - modifier, uv.y);\n\n return inBounds(fromP) ? getFromColor(fromP) : getToColor(toP);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The halves of both images slide horizontally in opposite directions, out and in at once","tags":["slide","split","horizontal"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideInOutVertical","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The halves of both images slide vertically in opposite directions, out and in at once\n// Tags: slide, split, vertical\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = (uv.x > 0.5 ? 1.0 : -1.0) * (reverse ? -1.0 : 1.0) ;\n vec2 fromP = vec2(uv.x, uv.y + (progress * modifier));\n vec2 toP = vec2(uv.x, (uv.y + (progress * modifier)) - modifier);\n\n return inBounds(fromP) ? getFromColor(fromP) : getToColor(toP);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The halves of both images slide vertically in opposite directions, out and in at once","tags":["slide","split","vertical"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideInVertical","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The incoming image slides in as two halves moving vertically in opposite directions\n// Tags: slide, split, vertical\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = reverse ? -1.0 : 1.0;\n vec2 p = (uv.x > 0.5) ?\n vec2(uv.x, (uv.y - (progress * modifier)) + modifier) :\n vec2(uv.x, (uv.y + (progress * modifier)) - modifier);\n\n return inBounds(p) ? getToColor(p) : getFromColor(uv);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The incoming image slides in as two halves moving vertically in opposite directions","tags":["slide","split","vertical"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideOutHorizontal","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The outgoing image slides out as two halves moving horizontally in opposite directions\n// Tags: slide, split, horizontal\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = (uv.y > 0.5 ? 1.0 : -1.0) * (reverse ? -1.0 : 1.0) ;\n vec2 p = vec2(uv.x + (progress * modifier), uv.y);\n\n return inBounds(p) ? getFromColor(p) : getToColor(uv);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The outgoing image slides out as two halves moving horizontally in opposite directions","tags":["slide","split","horizontal"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideOutVertical","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The outgoing image slides out as two halves moving vertically in opposite directions\n// Tags: slide, split, vertical\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = (uv.x > 0.5 ? 1.0 : -1.0) * (reverse ? -1.0 : 1.0) ;\n vec2 p = vec2(uv.x, uv.y + (progress * modifier));\n\n return inBounds(p) ? getFromColor(p) : getToColor(uv);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The outgoing image slides out as two halves moving vertically in opposite directions","tags":["slide","split","vertical"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"squareswire","paramsTypes":{"squares":"ivec2","direction":"vec2","smoothness":"float"},"defaultParams":{"squares":[10,10],"direction":[1,-0.5],"smoothness":1.6},"glsl":"// Author: gre\n// License: MIT\n// Description: Squares grow along a diagonal sweep to reveal the incoming image\n// Tags: squares, grid, wipe, directional\n \n// @param Number of squares (columns, rows)\nuniform ivec2 squares;// = ivec2(10,10)\n// @param Direction of the sweep\nuniform vec2 direction;// = vec2(1.0, -0.5)\n// @param Softness of the sweep\nuniform float smoothness; // = 1.6\n\nconst vec2 center = vec2(0.5, 0.5);\nvec4 transition (vec2 p) {\n vec2 v = normalize(direction);\n v /= abs(v.x)+abs(v.y);\n float d = v.x * center.x + v.y * center.y;\n float offset = smoothness;\n float pr = smoothstep(-offset, 0.0, v.x * p.x + v.y * p.y - (d-0.5+progress*(1.+offset)));\n vec2 squarep = fract(p*vec2(squares));\n vec2 squaremin = vec2(pr/2.0);\n vec2 squaremax = vec2(1.0 - pr/2.0);\n float a = (1.0 - step(progress, 0.0)) * step(squaremin.x, squarep.x) * step(squaremin.y, squarep.y) * step(squarep.x, squaremax.x) * step(squarep.y, squaremax.y);\n return mix(getFromColor(p), getToColor(p), a);\n}\n","author":"gre","license":"MIT","description":"Squares grow along a diagonal sweep to reveal the incoming image","tags":["squares","grid","wipe","directional"],"params":{"squares":{"type":"ivec2","default":[10,10],"description":"Number of squares (columns, rows)"},"direction":{"type":"vec2","default":[1,-0.5],"description":"Direction of the sweep"},"smoothness":{"type":"float","default":1.6,"description":"Softness of the sweep"}},"textures":[],"createdAt":"Fri, 26 May 2017 12:48:21 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"squeeze","paramsTypes":{"colorSeparation":"float"},"defaultParams":{"colorSeparation":0.04},"glsl":"// Author: gre\n// License: MIT\n// Description: The outgoing image is squeezed into a line with color separation, revealing the incoming one\n// Tags: squeeze, chromatic, vertical\n \n// @param Amount of color separation\nuniform float colorSeparation; // = 0.04\n \nvec4 transition (vec2 uv) {\n float y = 0.5 + (uv.y-0.5) / (1.0-progress);\n if (y < 0.0 || y > 1.0) {\n return getToColor(uv);\n }\n else {\n vec2 fp = vec2(uv.x, y);\n vec2 off = progress * vec2(0.0, colorSeparation);\n vec4 c = getFromColor(fp);\n vec4 cn = getFromColor(fp - off);\n vec4 cp = getFromColor(fp + off);\n return vec4(cn.r, c.g, cp.b, c.a);\n }\n}\n","author":"gre","license":"MIT","description":"The outgoing image is squeezed into a line with color separation, revealing the incoming one","tags":["squeeze","chromatic","vertical"],"params":{"colorSeparation":{"type":"float","default":0.04,"description":"Amount of color separation"}},"textures":[],"createdAt":"Fri, 26 May 2017 12:34:44 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"static_wipe","paramsTypes":{"u_transitionUpToDown":"bool","u_max_static_span":"float"},"defaultParams":{"u_transitionUpToDown":true,"u_max_static_span":0.5},"glsl":"// Author: Ben Lucas\n// License: MIT\n// Description: A wipe from top to bottom with a band of TV static at its edge\n// Tags: wipe, static, noise, vertical\n\n#define PI 3.14159265359\n\nfloat rnd (vec2 st) {\n return fract(sin(dot(st.xy,\n vec2(10,70)))*\n 12345.5453123);\n}\n\n// @param Wipe from top to bottom; false wipes from bottom to top\nuniform bool u_transitionUpToDown; // = true\n// @param Maximum height of the static band\nuniform float u_max_static_span; // = 0.5\n\nvec4 transition (vec2 uv) {\n \n\n float span = u_max_static_span*pow(sin(PI*progress),0.5);\n \n float transitionEdge = u_transitionUpToDown ? 1.0-uv.y : uv.y;\n float mixRatio = 1.0 - step(progress, transitionEdge);\n\n vec4 transitionMix = mix(\n getFromColor(uv),\n getToColor(uv),\n mixRatio\n );\n \n float noiseEnvelope = smoothstep(progress-span, progress, transitionEdge) * (1.0 - smoothstep(progress, progress + span, transitionEdge));\n vec4 noise = vec4(vec3(rnd(uv*(1.0+progress))), 1.0);\n \n\n return mix(transitionMix, noise, noiseEnvelope);\n}\n","author":"Ben Lucas","license":"MIT","description":"A wipe from top to bottom with a band of TV static at its edge","tags":["wipe","static","noise","vertical"],"params":{"u_transitionUpToDown":{"type":"bool","default":true,"description":"Wipe from top to bottom; false wipes from bottom to top"},"u_max_static_span":{"type":"float","default":0.5,"description":"Maximum height of the static band"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 03:29:01 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"swap","paramsTypes":{"reflection":"float","perspective":"float","depth":"float"},"defaultParams":{"reflection":0.4,"perspective":0.2,"depth":3},"glsl":"// Author: gre\n// License: MIT\n// Description: The two images swap places in 3D, with a floor reflection\n// Tags: 3d, swap, reflection\n// General parameters\n// @param Strength of the reflection\nuniform float reflection; // = 0.4\n// @param Amount of perspective\nuniform float perspective; // = 0.2\nuniform float depth; // = 3.0\n \nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n \nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n \nvec2 project (vec2 p) {\n return p * vec2(1.0, -1.2) + vec2(0.0, -0.02);\n}\n \nvec4 bgColor (vec2 p, vec2 pfr, vec2 pto) {\n vec4 c = black;\n pfr = project(pfr);\n if (inBounds(pfr)) {\n c += mix(black, getFromColor(pfr), reflection * mix(1.0, 0.0, pfr.y));\n }\n pto = project(pto);\n if (inBounds(pto)) {\n c += mix(black, getToColor(pto), reflection * mix(1.0, 0.0, pto.y));\n }\n return c;\n}\n \nvec4 transition(vec2 p) {\n vec2 pfr, pto = vec2(-1.);\n \n float size = mix(1.0, depth, progress);\n float persp = perspective * progress;\n pfr = (p + vec2(-0.0, -0.5)) * vec2(size/(1.0-perspective*progress), size/(1.0-size*persp*p.x)) + vec2(0.0, 0.5);\n \n size = mix(1.0, depth, 1.-progress);\n persp = perspective * (1.-progress);\n pto = (p + vec2(-1.0, -0.5)) * vec2(size/(1.0-perspective*(1.0-progress)), size/(1.0-size*persp*(0.5-p.x))) + vec2(1.0, 0.5);\n\n if (progress < 0.5) {\n if (inBounds(pfr)) {\n return getFromColor(pfr);\n }\n if (inBounds(pto)) {\n return getToColor(pto);\n } \n }\n if (inBounds(pto)) {\n return getToColor(pto);\n }\n if (inBounds(pfr)) {\n return getFromColor(pfr);\n }\n return bgColor(p, pfr, pto);\n}\n","author":"gre","license":"MIT","description":"The two images swap places in 3D, with a floor reflection","tags":["3d","swap","reflection"],"params":{"reflection":{"type":"float","default":0.4,"description":"Strength of the reflection"},"perspective":{"type":"float","default":0.2,"description":"Amount of perspective"},"depth":{"type":"float","default":3}},"textures":[],"createdAt":"Sat, 27 May 2017 11:36:00 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"tangentMotionBlur","paramsTypes":{},"defaultParams":{},"glsl":"\n// License: MIT\n// Author: chenkai\n// Description: The outgoing image is flung away along a curve with motion blur\n// Tags: motion-blur, rotate, slide\n// ported from https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/671116/\n\nfloat rand (vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n \n// motion blur for texture from\nvec4 motionBlurFrom(vec2 _st, vec2 speed) {\n vec2 texCoord = _st.xy / vec2(1.0).xy;\n vec3 color = vec3(0.0);\n float total = 0.0;\n float offset = rand(_st);\n for (float t = 0.0; t <= 20.0; t++) {\n float percent = (t + offset) / 20.0;\n float weight = 4.0 * (percent - percent * percent);\n vec2 newuv = texCoord + speed * percent;\n newuv = fract(newuv);\n color += getFromColor(newuv).rgb * weight;\n total += weight;\n }\n return vec4(color / total, 1.0);\n}\n\n// motion blur for texture to\nvec4 motionBlurTo(vec2 _st, vec2 speed) {\n vec2 texCoord = _st.xy / vec2(1.0).xy;\n vec3 color = vec3(0.0);\n float total = 0.0;\n float offset = rand(_st);\n for (float t = 0.0; t <= 20.0; t++) {\n float percent = (t + offset) / 20.0;\n float weight = 4.0 * (percent - percent * percent);\n vec2 newuv = texCoord + speed * percent;\n newuv = fract(newuv);\n color += getToColor(newuv).rgb * weight;\n total += weight;\n }\n return vec4(color / total, 1.0);\n}\n\n\n// bezier in gpu\nfloat A(float aA1, float aA2) {\n return 1.0 - 3.0 * aA2 + 3.0 * aA1;\n}\nfloat B(float aA1, float aA2) {\n return 3.0 * aA2 - 6.0 * aA1;\n}\nfloat C(float aA1) {\n return 3.0 * aA1;\n}\nfloat GetSlope(float aT, float aA1, float aA2) {\n return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1);\n}\nfloat CalcBezier(float aT, float aA1, float aA2) {\n return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT;\n}\nfloat GetTForX(float aX, float mX1, float mX2) {\n // iteration to solve\n float aGuessT = aX;\n for (int i = 0; i < 4; ++i) {\n float currentSlope = GetSlope(aGuessT, mX1, mX2);\n if (currentSlope == 0.0) return aGuessT;\n float currentX = CalcBezier(aGuessT, mX1, mX2) - aX;\n aGuessT -= currentX / currentSlope;\n }\n return aGuessT;\n}\nfloat KeySpline(float aX, float mX1, float mY1, float mX2, float mY2) {\n if (mX1 == mY1 && mX2 == mY2) return aX; // linear\n return CalcBezier(GetTForX(aX, mX1, mX2), mY1, mY2); // x to t, t to y\n}\n\n// norm distribution\nfloat normpdf(float x) {\n float d = x - .5;\n return exp(-20.*d*d);\n}\n\nvec2 rotateUv(vec2 uv, float angle, vec2 anchor, float zDirection) {\n uv = uv - anchor; // anchor to origin\n float s = sin(angle);\n\tfloat c = cos(angle);\n\tmat2 m = mat2(c, -s, s, c);\n uv = m * uv;\n uv += anchor; // anchor back\n return uv;\n}\n\n\n\nvec4 transition (vec2 uv) {\n \n vec2 myst = uv;\n float animationTime = progress; //getAnimationTime();\n float easingTime = KeySpline(animationTime, .68,.01,.17,.98);\n float blur = normpdf(easingTime);\n float r = 0.;\n float rotation = 180./180.*3.14159;\n if (easingTime <= .5) {\n r = rotation * easingTime;\n } else {\n r = -rotation + rotation * easingTime;\n }\n\n // rotation for current frame\n vec2 mystCurrent = myst;\n mystCurrent.y *= 1./ratio;\n mystCurrent = rotateUv(mystCurrent, r, vec2(1., 0.), -1.);\n mystCurrent.y *= ratio;\n \n // frame timeInterval by fps=30\n float timeInterval = 0.0167*2.0;\n if (easingTime <= .5) {\n r = rotation * (easingTime+timeInterval);\n } else {\n r = -rotation + rotation * (easingTime+timeInterval);\n }\n \n // rotation for next frame\n vec2 mystNext = myst;\n mystNext.y *= 1./ratio;\n mystNext = rotateUv(mystNext, r, vec2(1., 0.), -1.);\n mystNext.y *= ratio;\n \n // get speed at tagent direction\n vec2 speed = (mystNext - mystCurrent) / timeInterval * blur * 0.5;\n if (easingTime <= .5) {\n return motionBlurFrom(mystCurrent, speed);\n } else {\n return motionBlurTo(mystCurrent, speed);\n }\n}\n\n","author":"chenkai","license":"MIT","description":"The outgoing image is flung away along a curve with motion blur","tags":["motion-blur","rotate","slide"],"params":{},"textures":[],"createdAt":"Wed, 25 Mar 2020 10:46:29 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"undulatingBurnOut","paramsTypes":{"smoothness":"float","center":"vec2","color":"vec3"},"defaultParams":{"smoothness":0.03,"center":[0.5,0.5],"color":[0,0,0]},"glsl":"// License: MIT\n// Author: pthrasher\n// Description: A circle with a wavy edge burns out from the center to reveal the incoming image\n// Tags: circle, burn, wipe\n// adapted by gre from https://gist.github.com/pthrasher/8e6226b215548ba12734\n\n// @param Softness of the edge\nuniform float smoothness; // = 0.03\n// @param Center of the circle\nuniform vec2 center; // = vec2(0.5)\n// @color Color of the burning edge\nuniform vec3 color; // = vec3(0.0)\n\nconst float M_PI = 3.14159265358979323846;\n\nfloat quadraticInOut(float t) {\n float p = 2.0 * t * t;\n return t < 0.5 ? p : -p + (4.0 * t) - 1.0;\n}\n\nfloat getGradient(float r, float dist) {\n float d = r - dist;\n return mix(\n smoothstep(-smoothness, 0.0, r - dist * (1.0 + smoothness)),\n -1.0 - step(0.005, d),\n step(-0.005, d) * step(d, 0.01)\n );\n}\n\nfloat getWave(vec2 p){\n vec2 _p = p - center; // offset from center\n float rads = atan(_p.y, _p.x);\n float degs = degrees(rads) + 180.0;\n vec2 range = vec2(0.0, M_PI * 30.0);\n vec2 domain = vec2(0.0, 360.0);\n float ratio = (M_PI * 30.0) / 360.0;\n degs = degs * ratio;\n float x = progress;\n float magnitude = mix(0.02, 0.09, smoothstep(0.0, 1.0, x));\n float offset = mix(40.0, 30.0, smoothstep(0.0, 1.0, x));\n float ease_degs = quadraticInOut(sin(degs));\n float deg_wave_pos = (ease_degs * magnitude) * sin(x * offset);\n return x + deg_wave_pos;\n}\n\nvec4 transition(vec2 p) {\n float dist = distance(center, p);\n float m = getGradient(getWave(p), dist);\n vec4 cfrom = getFromColor(p);\n vec4 cto = getToColor(p);\n return mix(mix(cfrom, cto, m), mix(cfrom, vec4(color, 1.0), 0.75), step(m, -2.0));\n}\n","author":"pthrasher","license":"MIT","description":"A circle with a wavy edge burns out from the center to reveal the incoming image","tags":["circle","burn","wipe"],"params":{"smoothness":{"type":"float","default":0.03,"description":"Softness of the edge"},"center":{"type":"vec2","default":[0.5,0.5],"description":"Center of the circle"},"color":{"type":"vec3","default":[0,0,0],"color":true,"description":"Color of the burning edge"}},"textures":[],"createdAt":"Mon, 12 Jun 2017 10:23:37 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"wind","paramsTypes":{"size":"float","reversed":"bool"},"defaultParams":{"size":0.2,"reversed":false},"glsl":"// Author: gre\n// License: MIT\n// Description: A ragged left-to-right wipe, as if the image was blown away by the wind\n// Tags: wipe, horizontal, noise\n\n// @range(0, 1) Width of the ragged edge\nuniform float size; // = 0.2\n// @param Wipe from right to left instead\nuniform bool reversed; // = false\n\nfloat rand (vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nvec4 transition (vec2 uv) {\n float x = reversed ? 1. - uv.x : uv.x;\n float r = rand(vec2(0, uv.y));\n float m = smoothstep(0.0, -size, x*(1.0-size) + size*r - (progress * (1.0 + size)));\n return mix(\n getFromColor(uv),\n getToColor(uv),\n m\n );\n}\n","author":"gre","license":"MIT","description":"A ragged left-to-right wipe, as if the image was blown away by the wind","tags":["wipe","horizontal","noise"],"params":{"size":{"type":"float","default":0.2,"min":0,"max":1,"description":"Width of the ragged edge"},"reversed":{"type":"bool","default":false,"description":"Wipe from right to left instead"}},"textures":[],"createdAt":"Fri, 26 May 2017 09:55:44 +0200","updatedAt":"Fri, 9 Oct 2026 22:46:55 +0200"},{"name":"windowblinds","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Fabien Benetou\n// License: MIT\n// Description: A crossfade through horizontal window blinds\n// Tags: blinds, stripes, blend\n\nvec4 transition (vec2 uv) {\n float t = progress;\n \n if (mod(floor(uv.y*100.*progress),2.)==0.)\n t*=2.-.5;\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n mix(t, progress, smoothstep(0.8, 1.0, progress))\n );\n}\n","author":"Fabien Benetou","license":"MIT","description":"A crossfade through horizontal window blinds","tags":["blinds","stripes","blend"],"params":{},"textures":[],"createdAt":"Wed, 31 May 2017 14:11:48 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"windowslice","paramsTypes":{"count":"float","smoothness":"float"},"defaultParams":{"count":10,"smoothness":0.5},"glsl":"// Author: gre\n// License: MIT\n// Description: The incoming image appears through vertical slices that widen\n// Tags: slices, stripes, wipe\n\n// @param Number of slices\nuniform float count; // = 10.0\n// @param Softness of the slices' edges\nuniform float smoothness; // = 0.5\n\nvec4 transition (vec2 p) {\n float pr = smoothstep(-smoothness, 0.0, p.x - progress * (1.0 + smoothness));\n float s = step(pr, fract(count * p.x));\n return mix(getFromColor(p), getToColor(p), s);\n}\n","author":"gre","license":"MIT","description":"The incoming image appears through vertical slices that widen","tags":["slices","stripes","wipe"],"params":{"count":{"type":"float","default":10,"description":"Number of slices"},"smoothness":{"type":"float","default":0.5,"description":"Softness of the slices' edges"}},"textures":[],"createdAt":"Wed, 28 Mar 2018 17:23:26 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"wipeDown","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Jake Nelson\n// License: MIT\n// Description: A hard-edged wipe from top to bottom\n// Tags: wipe, vertical\n\nvec4 transition(vec2 uv) {\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 a=getFromColor(p);\n vec4 b=getToColor(p);\n return mix(a, b, step(1.0-p.y,progress));\n}\n","author":"Jake Nelson","license":"MIT","description":"A hard-edged wipe from top to bottom","tags":["wipe","vertical"],"params":{},"textures":[],"createdAt":"Wed, 1 Nov 2017 15:26:01 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"wipeLeft","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Jake Nelson\n// License: MIT\n// Description: A hard-edged wipe from right to left\n// Tags: wipe, horizontal\n\nvec4 transition(vec2 uv) {\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 a=getFromColor(p);\n vec4 b=getToColor(p);\n return mix(a, b, step(1.0-p.x,progress));\n}\n","author":"Jake Nelson","license":"MIT","description":"A hard-edged wipe from right to left","tags":["wipe","horizontal"],"params":{},"textures":[],"createdAt":"Wed, 1 Nov 2017 15:26:28 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"wipeRight","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Jake Nelson\n// License: MIT\n// Description: A hard-edged wipe from left to right\n// Tags: wipe, horizontal\n\nvec4 transition(vec2 uv) {\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 a=getFromColor(p);\n vec4 b=getToColor(p);\n return mix(a, b, step(0.0+p.x,progress));\n}\n","author":"Jake Nelson","license":"MIT","description":"A hard-edged wipe from left to right","tags":["wipe","horizontal"],"params":{},"textures":[],"createdAt":"Wed, 1 Nov 2017 15:27:02 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"wipeUp","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Jake Nelson\n// License: MIT\n// Description: A hard-edged wipe from bottom to top\n// Tags: wipe, vertical\n\nvec4 transition(vec2 uv) {\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 a=getFromColor(p);\n vec4 b=getToColor(p);\n return mix(a, b, step(0.0+p.y,progress));\n}\n","author":"Jake Nelson","license":"MIT","description":"A hard-edged wipe from bottom to top","tags":["wipe","vertical"],"params":{},"textures":[],"createdAt":"Wed, 1 Nov 2017 15:24:36 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"x_axis_translation","paramsTypes":{},"defaultParams":{},"glsl":"// Author: lizhongjian\n// License: MIT\n// Description: The outgoing image slides to the right, uncovering a crossfade to the incoming one\n// Tags: slide, horizontal, blend\n\nvec4 transition (vec2 uv) {\n vec2 newUV = uv;\n newUV.x -= progress;\n if(uv.x >= progress)\n {\n return getFromColor(newUV);\n }\n\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n progress\n );\n}\n","author":"lizhongjian","license":"MIT","description":"The outgoing image slides to the right, uncovering a crossfade to the incoming one","tags":["slide","horizontal","blend"],"params":{},"textures":[],"createdAt":"Tue, 4 Apr 2023 15:34:35 +0800","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"zoomInOut","paramsTypes":{},"defaultParams":{},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: Zooms into the outgoing image until it blurs into a flat color, then out to the incoming one\n// Tags: zoom, blur\n\nvec2 zoom(vec2 uv, float amount) {\n return 0.5 + ((uv - 0.5) * (1.0 - amount));\n}\n\nvec4 transition (vec2 uv) {\n float zoomFrom = smoothstep(0.0, 1.0, progress * 2.0);\n float zoomTo = smoothstep(0.0, 1.0, (1.0 - progress) * 2.0);\n float crossfade = smoothstep(0.4, 0.6, progress);\n return mix(\n getFromColor(zoom(uv, zoomFrom)),\n getToColor(zoom(uv, zoomTo)),\n crossfade\n );\n}\n","author":"OllyOllyOlly","license":"MIT","description":"Zooms into the outgoing image until it blurs into a flat color, then out to the incoming one","tags":["zoom","blur"],"params":{},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"}]
2
+ [{"name":"AdvancedMosaic","paramsTypes":{"pixelSize":"float"},"defaultParams":{"pixelSize":50},"glsl":"// Author: Sergey Kosarevsky\n// License: MIT\n// Description: Both images break into large blocks that blend, then sharpen into the incoming image\n// Tags: pixelate, mosaic, blend\n// Ported from https://gist.github.com/corporateshark/21d2fdd24c706952dc8c\n\nuniform float pixelSize; // = 50.0\n\nvec4 transition(vec2 uv) {\n float T = progress;\n float half_ = 0.5;\n float size = (T < half_) ? mix(1.0, pixelSize, T / half_) : mix(pixelSize, 1.0, (T - half_) / half_);\n float D = size * 0.005;\n // Remap UV to center the mosaic pattern\n vec2 UV = (uv - 0.5) / D;\n vec2 coord = clamp(D * (ceil(UV - 0.5)) + 0.5, 0.0, 1.0);\n vec4 C0 = getFromColor(coord);\n vec4 C1 = getToColor(coord);\n return mix(C0, C1, T);\n}\n","author":"Sergey Kosarevsky","license":"MIT","description":"Both images break into large blocks that blend, then sharpen into the incoming image","tags":["pixelate","mosaic","blend"],"params":{"pixelSize":{"type":"float","default":50}},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"BlockDissolve","paramsTypes":{"blocksize":"float"},"defaultParams":{"blocksize":0.02},"glsl":"// Author: nwoeanhinnogaehr\n// License: MIT\n// Description: The incoming image appears in small random blocks\n// Tags: dissolve, blocks, noise\n// Ported from https://gist.github.com/nwoeanhinnogaehr/b93818de23d4511fde10\n\nuniform float blocksize; // = 0.02\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvec4 transition(vec2 uv) {\n return mix(getFromColor(uv), getToColor(uv), step(rand(floor(uv / blocksize)), progress));\n}\n","author":"nwoeanhinnogaehr","license":"MIT","description":"The incoming image appears in small random blocks","tags":["dissolve","blocks","noise"],"params":{"blocksize":{"type":"float","default":0.02}},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"BookFlip","paramsTypes":{},"defaultParams":{},"glsl":"// Author: hong\n// License: MIT\n// Description: The outgoing image turns like a book page from right to left, revealing the incoming one\n// Tags: page, flip, 3d\n\n// Avoids dividing by zero when the page is edge-on (progress = 0.5).\nfloat nonZero(float x) {\n return abs(x) < 1e-4 ? (x < 0.0 ? -1e-4 : 1e-4) : x;\n}\n\nvec2 skewRight(vec2 p) {\n float skewX = (p.x - progress)/nonZero(0.5 - progress) * 0.5;\n float skewY = (p.y - 0.5)/(0.5 + progress * (p.x - 0.5) / 0.5)* 0.5 + 0.5;\n return vec2(skewX, skewY);\n}\n\nvec2 skewLeft(vec2 p) {\n float skewX = (p.x - 0.5)/nonZero(progress - 0.5) * 0.5 + 0.5;\n float skewY = (p.y - 0.5) / (0.5 + (1.0 - progress ) * (0.5 - p.x) / 0.5) * 0.5 + 0.5;\n return vec2(skewX, skewY);\n}\n\nvec4 addShade() {\n float shadeVal = max(0.7, abs(progress - 0.5) * 2.0);\n return vec4(vec3(shadeVal ), 1.0);\n}\n\nvec4 transition (vec2 p) {\n float pr = step(1.0 - progress, p.x);\n\n if (p.x < 0.5) {\n return mix(getFromColor(p), getToColor(skewLeft(p)) * addShade(), pr);\n } else {\n return mix(getFromColor(skewRight(p)) * addShade(), getToColor(p), pr);\n }\n}\n","author":"hong","license":"MIT","description":"The outgoing image turns like a book page from right to left, revealing the incoming one","tags":["page","flip","3d"],"params":{},"textures":[],"createdAt":"Fri, 27 May 2022 19:13:57 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Bounce","paramsTypes":{"shadow_colour":"vec4","shadow_height":"float","bounces":"float"},"defaultParams":{"shadow_colour":[0,0,0,0.6],"shadow_height":0.075,"bounces":3},"glsl":"// Author: Adrian Purser\n// License: MIT\n// Description: The outgoing image drops out of the frame with a few bounces, revealing the incoming one\n// Tags: bounce, slide, vertical, shadow\n\n// @color Color of the shadow cast on the incoming image\nuniform vec4 shadow_colour; // = vec4(0.,0.,0.,.6)\n// @range(0.01, 0.5) Height of the shadow, relative to the image height\nuniform float shadow_height; // = 0.075\n// @range(1, 10, 1) Number of bounces before settling\nuniform float bounces; // = 3.0\n\nconst float PI = 3.14159265358;\n\nvec4 transition (vec2 uv) {\n float time = progress;\n float stime = sin(time * PI / 2.);\n float phase = time * PI * bounces;\n float y = (abs(cos(phase))) * (1.0 - stime);\n float d = uv.y - y;\n return mix(\n mix(\n getToColor(uv),\n shadow_colour,\n step(d, shadow_height) * (1. - mix(\n ((d / shadow_height) * shadow_colour.a) + (1.0 - shadow_colour.a),\n 1.0,\n smoothstep(0.95, 1., progress) // fade-out the shadow at the end\n ))\n ),\n getFromColor(vec2(uv.x, uv.y + (1.0 - y))),\n step(d, 0.0)\n );\n}\n","author":"Adrian Purser","license":"MIT","description":"The outgoing image drops out of the frame with a few bounces, revealing the incoming one","tags":["bounce","slide","vertical","shadow"],"params":{"shadow_colour":{"type":"vec4","default":[0,0,0,0.6],"color":true,"description":"Color of the shadow cast on the incoming image"},"shadow_height":{"type":"float","default":0.075,"min":0.01,"max":0.5,"description":"Height of the shadow, relative to the image height"},"bounces":{"type":"float","default":3,"min":1,"max":10,"step":1,"description":"Number of bounces before settling"}},"textures":[],"createdAt":"Fri, 10 Nov 2017 17:01:45 +0000","updatedAt":"Fri, 9 Oct 2026 23:18:05 +0200"},{"name":"BowTieHorizontal","paramsTypes":{},"defaultParams":{},"glsl":"// Author: huynx\n// License: MIT\n// Description: Two triangles grow from the left and right edges into a bow tie that reveals the incoming image\n// Tags: wipe, shape, horizontal\n\nconst vec2 bottom_left = vec2(0.0, 1.0);\nconst vec2 bottom_right = vec2(1.0, 1.0);\nconst vec2 top_left = vec2(0.0, 0.0);\nconst vec2 top_right = vec2(1.0, 0.0);\nconst vec2 center = vec2(0.5, 0.5);\n\nfloat check(vec2 p1, vec2 p2, vec2 p3)\n{\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\n}\n\nbool PointInTriangle (vec2 pt, vec2 p1, vec2 p2, vec2 p3)\n{\n bool b1, b2, b3;\n b1 = check(pt, p1, p2) < 0.0;\n b2 = check(pt, p2, p3) < 0.0;\n b3 = check(pt, p3, p1) < 0.0;\n return ((b1 == b2) && (b2 == b3));\n}\n\nbool in_left_triangle(vec2 p){\n vec2 vertex1, vertex2, vertex3;\n vertex1 = vec2(progress, 0.5);\n vertex2 = vec2(0.0, 0.5-progress);\n vertex3 = vec2(0.0, 0.5+progress);\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\n {\n return true;\n }\n return false;\n}\n\nbool in_right_triangle(vec2 p){\n vec2 vertex1, vertex2, vertex3;\n vertex1 = vec2(1.0-progress, 0.5);\n vertex2 = vec2(1.0, 0.5-progress);\n vertex3 = vec2(1.0, 0.5+progress);\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\n {\n return true;\n }\n return false;\n}\n\nfloat blur_edge(vec2 bot1, vec2 bot2, vec2 top, vec2 testPt)\n{\n vec2 lineDir = bot1 - top;\n vec2 perpDir = vec2(lineDir.y, -lineDir.x);\n vec2 dirToPt1 = bot1 - testPt;\n float dist1 = abs(dot(normalize(perpDir), dirToPt1));\n \n lineDir = bot2 - top;\n perpDir = vec2(lineDir.y, -lineDir.x);\n dirToPt1 = bot2 - testPt;\n float min_dist = min(abs(dot(normalize(perpDir), dirToPt1)), dist1);\n \n if (min_dist < 0.005) {\n return min_dist / 0.005;\n }\n else {\n return 1.0;\n };\n}\n\n\nvec4 transition (vec2 uv) {\n if (in_left_triangle(uv))\n {\n if (progress < 0.1)\n {\n return getFromColor(uv);\n }\n if (uv.x < 0.5)\n {\n vec2 vertex1 = vec2(progress, 0.5);\n vec2 vertex2 = vec2(0.0, 0.5-progress);\n vec2 vertex3 = vec2(0.0, 0.5+progress);\n return mix(\n getFromColor(uv),\n getToColor(uv),\n blur_edge(vertex2, vertex3, vertex1, uv)\n );\n }\n else\n {\n if (progress > 0.0)\n {\n return getToColor(uv);\n }\n else\n {\n return getFromColor(uv);\n }\n } \n }\n else if (in_right_triangle(uv))\n {\n if (uv.x >= 0.5)\n {\n vec2 vertex1 = vec2(1.0-progress, 0.5);\n vec2 vertex2 = vec2(1.0, 0.5-progress);\n vec2 vertex3 = vec2(1.0, 0.5+progress);\n return mix(\n getFromColor(uv),\n getToColor(uv),\n blur_edge(vertex2, vertex3, vertex1, uv)\n ); \n }\n else\n {\n return getFromColor(uv);\n }\n }\n else {\n return getFromColor(uv);\n }\n}","author":"huynx","license":"MIT","description":"Two triangles grow from the left and right edges into a bow tie that reveals the incoming image","tags":["wipe","shape","horizontal"],"params":{},"textures":[],"createdAt":"Sat, 24 Mar 2018 12:54:26 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"BowTieVertical","paramsTypes":{},"defaultParams":{},"glsl":"// Author: huynx\n// License: MIT\n// Description: Two triangles grow from the top and bottom edges into a bow tie that reveals the incoming image\n// Tags: wipe, shape, vertical\n\nfloat check(vec2 p1, vec2 p2, vec2 p3)\n{\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\n}\n\nbool PointInTriangle (vec2 pt, vec2 p1, vec2 p2, vec2 p3)\n{\n bool b1, b2, b3;\n b1 = check(pt, p1, p2) < 0.0;\n b2 = check(pt, p2, p3) < 0.0;\n b3 = check(pt, p3, p1) < 0.0;\n return ((b1 == b2) && (b2 == b3));\n}\n\nbool in_top_triangle(vec2 p){\n vec2 vertex1, vertex2, vertex3;\n vertex1 = vec2(0.5, progress);\n vertex2 = vec2(0.5-progress, 0.0);\n vertex3 = vec2(0.5+progress, 0.0);\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\n {\n return true;\n }\n return false;\n}\n\nbool in_bottom_triangle(vec2 p){\n vec2 vertex1, vertex2, vertex3;\n vertex1 = vec2(0.5, 1.0 - progress);\n vertex2 = vec2(0.5-progress, 1.0);\n vertex3 = vec2(0.5+progress, 1.0);\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\n {\n return true;\n }\n return false;\n}\n\nfloat blur_edge(vec2 bot1, vec2 bot2, vec2 top, vec2 testPt)\n{\n vec2 lineDir = bot1 - top;\n vec2 perpDir = vec2(lineDir.y, -lineDir.x);\n vec2 dirToPt1 = bot1 - testPt;\n float dist1 = abs(dot(normalize(perpDir), dirToPt1));\n \n lineDir = bot2 - top;\n perpDir = vec2(lineDir.y, -lineDir.x);\n dirToPt1 = bot2 - testPt;\n float min_dist = min(abs(dot(normalize(perpDir), dirToPt1)), dist1);\n \n if (min_dist < 0.005) {\n return min_dist / 0.005;\n }\n else {\n return 1.0;\n };\n}\n\n\nvec4 transition (vec2 uv) {\n if (in_top_triangle(uv))\n {\n if (progress < 0.1)\n {\n return getFromColor(uv);\n }\n if (uv.y < 0.5)\n {\n vec2 vertex1 = vec2(0.5, progress);\n vec2 vertex2 = vec2(0.5-progress, 0.0);\n vec2 vertex3 = vec2(0.5+progress, 0.0);\n return mix(\n getFromColor(uv),\n getToColor(uv),\n blur_edge(vertex2, vertex3, vertex1, uv)\n );\n }\n else\n {\n if (progress > 0.0)\n {\n return getToColor(uv);\n }\n else\n {\n return getFromColor(uv);\n }\n } \n }\n else if (in_bottom_triangle(uv))\n {\n if (uv.y >= 0.5)\n {\n vec2 vertex1 = vec2(0.5, 1.0-progress);\n vec2 vertex2 = vec2(0.5-progress, 1.0);\n vec2 vertex3 = vec2(0.5+progress, 1.0);\n return mix(\n getFromColor(uv),\n getToColor(uv),\n blur_edge(vertex2, vertex3, vertex1, uv)\n ); \n }\n else\n {\n return getFromColor(uv);\n }\n }\n else {\n return getFromColor(uv);\n }\n}","author":"huynx","license":"MIT","description":"Two triangles grow from the top and bottom edges into a bow tie that reveals the incoming image","tags":["wipe","shape","vertical"],"params":{},"textures":[],"createdAt":"Tue, 27 Mar 2018 10:07:54 +0700","updatedAt":"Fri, 9 Oct 2026 23:12:22 +0200"},{"name":"BowTieWithParameter","paramsTypes":{"adjust":"float","reverse":"bool"},"defaultParams":{"adjust":0.5,"reverse":false},"glsl":"// Author: KMojek\n// License: MIT\n// Description: A bow-tie wipe with an adjustable shape that can run in reverse\n// Tags: wipe, shape\n\nuniform float adjust; // = 0.5\n// @param Run the wipe in reverse\nuniform bool reverse; // = false\n\nfloat check(vec2 p1, vec2 p2, vec2 p3)\n{\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\n}\n\nbool pointInTriangle(vec2 pt, vec2 p1, vec2 p2, vec2 p3)\n{\n\n bool b1 = check(pt, p1, p2) < 0.0;\n bool b2 = check(pt, p2, p3) < 0.0;\n bool b3 = check(pt, p3, p1) < 0.0;\n return b1 == b2 && b2 == b3;\n}\n\nconst float height = 0.5;\n\nvec4 transition_firstHalf( vec2 uv, float prog )\n{\n if ( uv.y < 0.5 )\n {\n vec2 botLeft = vec2( -0., prog-height );\n vec2 botRight = vec2( 1., prog-height );\n vec2 tip = vec2( adjust, prog );\n if ( pointInTriangle( uv, botLeft, botRight, tip ) )\n return getToColor(uv);\n }\n else\n {\n vec2 topLeft = vec2( -0., 1.-prog+height );\n vec2 topRight = vec2( 1., 1.-prog+height );\n vec2 tip = vec2( adjust, 1.-prog );\n if ( pointInTriangle( uv, topLeft, topRight, tip ) )\n return getToColor( uv );\n }\n return getFromColor( uv );\n}\n\nvec4 transition_secondHalf( vec2 uv, float prog )\n{\n if ( uv.x > adjust )\n {\n vec2 top = vec2( prog + height, 1. );\n vec2 bot = vec2( prog + height, -0. );\n vec2 tip = vec2( mix( adjust, 1.0, 2.0 * (prog - 0.5) ), 0.5 );\n if ( pointInTriangle( uv, top, bot, tip) )\n return getFromColor( uv );\n }\n else\n {\n vec2 top = vec2( 1.0-prog - height, 1. );\n vec2 bot = vec2( 1.0-prog - height, -0. );\n vec2 tip = vec2( mix( adjust, 0.0, 2.0 * (prog - 0.5) ), 0.5 );\n if ( pointInTriangle( uv, top, bot, tip) )\n return getFromColor( uv );\n }\n return getToColor( uv );\n}\n\nvec4 transition (vec2 uv) {\n if ( reverse )\n return ( progress < 0.5 ) ? transition_secondHalf( uv, 1.-progress ) : transition_firstHalf( uv, 1.-progress );\n else\n return ( progress < 0.5 ) ? transition_firstHalf( uv, progress ) : transition_secondHalf( uv, progress );\n}","author":"KMojek","license":"MIT","description":"A bow-tie wipe with an adjustable shape that can run in reverse","tags":["wipe","shape"],"params":{"adjust":{"type":"float","default":0.5},"reverse":{"type":"bool","default":false,"description":"Run the wipe in reverse"}},"textures":[],"createdAt":"Thu, 19 Mar 2020 21:36:12 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Box","paramsTypes":{"rectIn":"int","location":"int"},"defaultParams":{"rectIn":1,"location":0},"glsl":"// Author: lql\n// License: MIT\n// Description: The outgoing image shrinks into a box, toward the center or a corner, revealing the incoming one\n// Tags: box, zoom, shape\nuniform int rectIn; // =1\n// center:0, left_top:1, left_bottom:2, right_top:3, right_bottom:4\n// @range(0, 4, 1) Where the box goes: 0 center, 1 left top, 2 left bottom, 3 right top, 4 right bottom\nuniform int location; // =0\n\nvec4 transition(vec2 uv) {\n float p = rectIn == 1 ? 1.0 - progress : progress;\n float x1, y1, x2, y2;\n\n // Determine rectangle coordinates based on location\n if (location == 0) {\n x1 = y1 = 0.5 * (1.0 - p);\n x2 = y2 = 1.0 - x1;\n } else {\n // Calculate the x and y coordinates based on the location\n x1 = (location == 1 || location == 2) ? 0.0 : 1.0 - p;\n y1 = (location == 1 || location == 3) ? 1.0 - p : 0.0;\n x2 = (location == 1 || location == 2) ? p : 1.0;\n y2 = (location == 1 || location == 3) ? 1.0 : p;\n }\n\n // Determine if the point is inside the rectangle\n float in_rect = step(x1, uv.x) * step(uv.x, x2) * step(y1, uv.y) * step(uv.y, y2);\n in_rect = rectIn == 1 ? 1.0 - in_rect : in_rect;\n\n // Mix colors based on the in_rect value\n return mix(getFromColor(uv), getToColor(uv), in_rect);\n}\n","author":"lql","license":"MIT","description":"The outgoing image shrinks into a box, toward the center or a corner, revealing the incoming one","tags":["box","zoom","shape"],"params":{"rectIn":{"type":"int","default":1},"location":{"type":"int","default":0,"min":0,"max":4,"step":1,"description":"Where the box goes: 0 center, 1 left top, 2 left bottom, 3 right top, 4 right bottom"}},"textures":[],"createdAt":"Tue, 23 Jan 2024 23:06:37 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"ButterflyWaveScrawler","paramsTypes":{"amplitude":"float","waves":"float","colorSeparation":"float"},"defaultParams":{"amplitude":1,"waves":30,"colorSeparation":0.3},"glsl":"// Author: mandubian\n// License: MIT\n// Description: Wavy, color-separated ripples scramble the outgoing image into the incoming one\n// Tags: wave, distort, chromatic\nuniform float amplitude; // = 1.0\nuniform float waves; // = 30.0\nuniform float colorSeparation; // = 0.3\nconst float PI = 3.14159265358979323846264;\nfloat compute(vec2 p, float progress, vec2 center) {\nvec2 o = p*sin(progress * amplitude)-center;\n// horizontal vector\nvec2 h = vec2(1., 0.);\n// butterfly polar function (don't ask me why this one :))\nfloat theta = acos(dot(o, h)) * waves;\nfloat s = sin((2.*theta - PI) / 24.);\nfloat s2 = s * s;\nreturn (exp(cos(theta)) - 2.*cos(4.*theta) + s2 * s2 * s) / 10.;\n}\nvec4 transition(vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n vec2 p = uv;\n float inv = 1. - progress;\n float disp = compute(p, progress, vec2(0.5, 0.5));\n vec4 texTo = getToColor(p + inv*disp);\n vec4 texFrom = vec4(\n getFromColor(p + progress*disp*(1.0 - colorSeparation)).r,\n getFromColor(p + progress*disp).g,\n getFromColor(p + progress*disp*(1.0 + colorSeparation)).b,\n 1.0);\n return texTo*progress + texFrom*inv;\n}\n","author":"mandubian","license":"MIT","description":"Wavy, color-separated ripples scramble the outgoing image into the incoming one","tags":["wave","distort","chromatic"],"params":{"amplitude":{"type":"float","default":1},"waves":{"type":"float","default":30},"colorSeparation":{"type":"float","default":0.3}},"textures":[],"createdAt":"Thu, 1 Jun 2017 11:47:17 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"CircleCrop","paramsTypes":{"bgcolor":"vec4"},"defaultParams":{"bgcolor":[0,0,0,1]},"glsl":"// License: MIT\n// Author: fkuteken\n// Description: The outgoing image closes into a circle over a background color, then the incoming one opens from it\n// Tags: circle, iris, shape\n// ported by gre from https://gist.github.com/fkuteken/f63e3009c1143950dee9063c3b83fb88\n\n// @color Background color\nuniform vec4 bgcolor; // = vec4(0.0, 0.0, 0.0, 1.0)\n\nvec4 transition(vec2 p) {\n vec2 ratio2 = vec2(1.0, 1.0 / ratio);\n float s = pow(2.0 * abs(progress - 0.5), 3.0);\n float dist = length((vec2(p) - 0.5) * ratio2);\n return mix(\n progress < 0.5 ? getFromColor(p) : getToColor(p), // branching is ok here as we statically depend on progress uniform (branching won't change over pixels)\n bgcolor,\n step(s, dist)\n );\n}\n","author":"fkuteken","license":"MIT","description":"The outgoing image closes into a circle over a background color, then the incoming one opens from it","tags":["circle","iris","shape"],"params":{"bgcolor":{"type":"vec4","default":[0,0,0,1],"color":true,"description":"Background color"}},"textures":[],"createdAt":"Mon, 12 Jun 2017 12:52:34 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"ColourDistance","paramsTypes":{"power":"float"},"defaultParams":{"power":5},"glsl":"// License: MIT\n// Author: P-Seebauer\n// Description: Pixels switch to the incoming image in order of how close their colors are\n// Tags: blend, color\n// ported by gre from https://gist.github.com/P-Seebauer/2a5fa2f77c883dd661f9\n\nuniform float power; // = 5.0\n\nvec4 transition(vec2 p) {\n vec4 fTex = getFromColor(p);\n vec4 tTex = getToColor(p);\n float m = step(distance(fTex, tTex), progress);\n return mix(\n mix(fTex, tTex, m),\n tTex,\n pow(progress, power)\n );\n}\n","author":"P-Seebauer","license":"MIT","description":"Pixels switch to the incoming image in order of how close their colors are","tags":["blend","color"],"params":{"power":{"type":"float","default":5}},"textures":[],"createdAt":"Mon, 12 Jun 2017 12:57:42 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"CrazyParametricFun","paramsTypes":{"a":"float","b":"float","amplitude":"float","smoothness":"float"},"defaultParams":{"a":4,"b":1,"amplitude":120,"smoothness":0.1},"glsl":"// Author: mandubian\n// License: MIT\n// Description: The outgoing image is pulled along a parametric curve into a psychedelic swirl\n// Tags: distort, psychedelic\n\nuniform float a; // = 4\nuniform float b; // = 1\nuniform float amplitude; // = 120\nuniform float smoothness; // = 0.1\n\nvec4 transition(vec2 uv) {\n vec2 p = uv.xy / vec2(1.0).xy;\n vec2 dir = p - vec2(.5);\n float dist = length(dir);\n float x = (a - b) * cos(progress) + b * cos(progress * ((a / b) - 1.) );\n float y = (a - b) * sin(progress) - b * sin(progress * ((a / b) - 1.));\n vec2 offset = dir * vec2(sin(progress * dist * amplitude * x), sin(progress * dist * amplitude * y)) / smoothness;\n return mix(getFromColor(p + offset), getToColor(p), smoothstep(0.2, 1.0, progress));\n}\n","author":"mandubian","license":"MIT","description":"The outgoing image is pulled along a parametric curve into a psychedelic swirl","tags":["distort","psychedelic"],"params":{"a":{"type":"float","default":4},"b":{"type":"float","default":1},"amplitude":{"type":"float","default":120},"smoothness":{"type":"float","default":0.1}},"textures":[],"createdAt":"Thu, 1 Jun 2017 13:03:12 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"CrossZoom","paramsTypes":{"strength":"float"},"defaultParams":{"strength":0.4},"glsl":"// License: MIT\n// Author: rectalogic\n// Description: A crossfade through a strong zoom blur\n// Tags: zoom, blur, blend\n// ported by gre from https://gist.github.com/rectalogic/b86b90161503a0023231\n\n// Converted from https://github.com/rectalogic/rendermix-basic-effects/blob/master/assets/com/rendermix/CrossZoom/CrossZoom.frag\n// Which is based on https://github.com/evanw/glfx.js/blob/master/src/filters/blur/zoomblur.js\n// With additional easing functions from https://github.com/rectalogic/rendermix-basic-effects/blob/master/assets/com/rendermix/Easing/Easing.glsllib\n\n// @range(0, 1) Blur strength\nuniform float strength; // = 0.4\n\nconst float PI = 3.141592653589793;\n\nfloat Linear_ease(in float begin, in float change, in float duration, in float time) {\n return change * time / duration + begin;\n}\n\nfloat Exponential_easeInOut(in float begin, in float change, in float duration, in float time) {\n if (time == 0.0)\n return begin;\n else if (time == duration)\n return begin + change;\n time = time / (duration / 2.0);\n if (time < 1.0)\n return change / 2.0 * pow(2.0, 10.0 * (time - 1.0)) + begin;\n return change / 2.0 * (-pow(2.0, -10.0 * (time - 1.0)) + 2.0) + begin;\n}\n\nfloat Sinusoidal_easeInOut(in float begin, in float change, in float duration, in float time) {\n return -change / 2.0 * (cos(PI * time / duration) - 1.0) + begin;\n}\n\nfloat rand (vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nvec4 crossFade(in vec2 uv, in float dissolve) {\n return mix(getFromColor(uv), getToColor(uv), dissolve);\n}\n\nvec4 transition(vec2 uv) {\n vec2 texCoord = uv.xy / vec2(1.0).xy;\n\n // Linear interpolate center across center half of the image\n vec2 center = vec2(Linear_ease(0.25, 0.5, 1.0, progress), 0.5);\n float dissolve = Exponential_easeInOut(0.0, 1.0, 1.0, progress);\n\n // Mirrored sinusoidal loop. 0->strength then strength->0\n float strength = Sinusoidal_easeInOut(0.0, strength, 0.5, progress);\n\n vec4 color = vec4(0.0);\n float total = 0.0;\n vec2 toCenter = center - texCoord;\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = rand(uv);\n\n for (float t = 0.0; t <= 40.0; t++) {\n float percent = (t + offset) / 40.0;\n float weight = 4.0 * (percent - percent * percent);\n color += crossFade(texCoord + toCenter * percent * strength, dissolve) * weight;\n total += weight;\n }\n return color / total;\n}\n","author":"rectalogic","license":"MIT","description":"A crossfade through a strong zoom blur","tags":["zoom","blur","blend"],"params":{"strength":{"type":"float","default":0.4,"min":0,"max":1,"description":"Blur strength"}},"textures":[],"createdAt":"Mon, 12 Jun 2017 12:33:07 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"DefocusBlur","paramsTypes":{"blurSize":"float"},"defaultParams":{"blurSize":0.02},"glsl":"// Author: Sergey Kosarevsky\n// License: MIT\n// Description: A crossfade through an out-of-focus blur\n// Tags: blur, blend\n// Ported from https://gist.github.com/corporateshark/b9f8e5675c647e615419\n\n// @param Amount of blur\nuniform float blurSize; // = 0.02\n\n// 12-tap Poisson disk\n// https://github.com/spite/Wagner/blob/master/fragment-shaders/poisson-disc-blur-fs.glsl\n\nvec4 transition(vec2 uv) {\n float T = progress;\n float half_ = 0.5;\n float D = (T < half_) ? mix(0.0, blurSize, T / half_) : mix(blurSize, 0.0, (T - half_) / half_);\n vec4 C0 = getFromColor(uv);\n vec4 C1 = getToColor(uv);\n C0 += getFromColor(vec2(-0.326, -0.406) * D + uv);\n C1 += getToColor(vec2(-0.326, -0.406) * D + uv);\n C0 += getFromColor(vec2(-0.840, -0.074) * D + uv);\n C1 += getToColor(vec2(-0.840, -0.074) * D + uv);\n C0 += getFromColor(vec2(-0.696, 0.457) * D + uv);\n C1 += getToColor(vec2(-0.696, 0.457) * D + uv);\n C0 += getFromColor(vec2(-0.203, 0.621) * D + uv);\n C1 += getToColor(vec2(-0.203, 0.621) * D + uv);\n C0 += getFromColor(vec2( 0.962, -0.195) * D + uv);\n C1 += getToColor(vec2( 0.962, -0.195) * D + uv);\n C0 += getFromColor(vec2( 0.473, -0.480) * D + uv);\n C1 += getToColor(vec2( 0.473, -0.480) * D + uv);\n C0 += getFromColor(vec2( 0.519, 0.767) * D + uv);\n C1 += getToColor(vec2( 0.519, 0.767) * D + uv);\n C0 += getFromColor(vec2( 0.185, -0.893) * D + uv);\n C1 += getToColor(vec2( 0.185, -0.893) * D + uv);\n C0 += getFromColor(vec2( 0.507, 0.064) * D + uv);\n C1 += getToColor(vec2( 0.507, 0.064) * D + uv);\n C0 += getFromColor(vec2( 0.896, 0.412) * D + uv);\n C1 += getToColor(vec2( 0.896, 0.412) * D + uv);\n C0 += getFromColor(vec2(-0.322, -0.933) * D + uv);\n C1 += getToColor(vec2(-0.322, -0.933) * D + uv);\n C0 += getFromColor(vec2(-0.792, -0.598) * D + uv);\n C1 += getToColor(vec2(-0.792, -0.598) * D + uv);\n C0 /= 13.0;\n C1 /= 13.0;\n return mix(C0, C1, T);\n}\n","author":"Sergey Kosarevsky","license":"MIT","description":"A crossfade through an out-of-focus blur","tags":["blur","blend"],"params":{"blurSize":{"type":"float","default":0.02,"description":"Amount of blur"}},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Directional","paramsTypes":{"direction":"vec2"},"defaultParams":{"direction":[0,1]},"glsl":"// Author: Gaëtan Renaudeau\n// License: MIT\n// Description: The incoming image pushes the outgoing one out in a given direction\n// Tags: slide, push, directional\n\n// @param Direction of the movement\nuniform vec2 direction; // = vec2(0.0, 1.0)\n\nvec4 transition (vec2 uv) {\n vec2 p = uv + progress * sign(direction);\n vec2 f = fract(p);\n return mix(\n getToColor(f),\n getFromColor(f),\n step(0.0, p.y) * step(p.y, 1.0) * step(0.0, p.x) * step(p.x, 1.0)\n );\n}\n","author":"Gaëtan Renaudeau","license":"MIT","description":"The incoming image pushes the outgoing one out in a given direction","tags":["slide","push","directional"],"params":{"direction":{"type":"vec2","default":[0,1],"description":"Direction of the movement"}},"textures":[],"createdAt":"Thu, 19 Apr 2018 12:20:29 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"DirectionalScaled","paramsTypes":{"direction":"vec2","scale":"float"},"defaultParams":{"direction":[0,1],"scale":0.7},"glsl":"// Author: Thibaut Foussard\n// based on Directional transition by Gaëtan Renaudeau\n// https://gl-transitions.com/editor/Directional\n// License: MIT\n// Description: Like Directional, with both images scaled down while they slide\n// Tags: slide, push, zoom, directional\n\n#define PI acos(-1.0)\n\n// @param Direction of the movement\nuniform vec2 direction; // = vec2(0.0, 1.0)\nuniform float scale; // = .7\n\nfloat parabola(float x) {\n float y = pow(sin(x * PI), 1.);\n return y;\n}\n\nvec4 transition (vec2 uv) {\n float easedProgress = pow(sin(progress * PI / 2.), 3.);\n vec2 p = uv + easedProgress * sign(direction);\n vec2 f = fract(p);\n \n float s = 1. - (1. - (1. / scale)) * parabola(progress);\n f = (f - 0.5) * s + 0.5;\n \n float mixer = step(0.0, p.y) * step(p.y, 1.0) * step(0.0, p.x) * step(p.x, 1.0);\n vec4 col = mix(getToColor(f), getFromColor(f), mixer);\n \n float border = step(0., f.x) * step(0., (1. - f.x)) * step(0., f.y) * step(0., 1. - f.y);\n col *= border;\n \n return col;\n}\n","author":"Thibaut Foussard","license":"MIT","description":"Like Directional, with both images scaled down while they slide","tags":["slide","push","zoom","directional"],"params":{"direction":{"type":"vec2","default":[0,1],"description":"Direction of the movement"},"scale":{"type":"float","default":0.7}},"textures":[],"createdAt":"Tue, 4 Apr 2023 03:29:34 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"DoomScreenTransition","paramsTypes":{"bars":"int","amplitude":"float","noise":"float","frequency":"float","dripScale":"float"},"defaultParams":{"bars":30,"amplitude":2,"noise":0.1,"frequency":0.5,"dripScale":0.5},"glsl":"// Author: Zeh Fernando\n// License: MIT\n// Description: The outgoing image melts down in uneven columns, like the Doom screen wipe\n// Tags: melt, columns, retro\n\n\n// Transition parameters --------\n\n// Number of total bars/columns\nuniform int bars; // = 30\n\n// Multiplier for speed ratio. 0 = no variation when going down, higher = some elements go much faster\nuniform float amplitude; // = 2\n\n// Further variations in speed. 0 = no noise, 1 = super noisy (ignore frequency)\nuniform float noise; // = 0.1\n\n// Speed variation horizontally. the bigger the value, the shorter the waves\nuniform float frequency; // = 0.5\n\n// How much the bars seem to \"run\" from the middle of the screen first (sticking to the sides). 0 = no drip, 1 = curved drip\nuniform float dripScale; // = 0.5\n\n\n// The code proper --------\n\nfloat rand(int num) {\n return fract(mod(float(num) * 67123.313, 12.0) * sin(float(num) * 10.3) * cos(float(num)));\n}\n\nfloat wave(int num) {\n float fn = float(num) * frequency * 0.1 * float(bars);\n return cos(fn * 0.5) * cos(fn * 0.13) * sin((fn+10.0) * 0.3) / 2.0 + 0.5;\n}\n\nfloat drip(int num) {\n return sin(float(num) / float(bars - 1) * 3.141592) * dripScale;\n}\n\nfloat pos(int num) {\n return (noise == 0.0 ? wave(num) : mix(wave(num), rand(num), noise)) + (dripScale == 0.0 ? 0.0 : drip(num));\n}\n\nvec4 transition(vec2 uv) {\n int bar = int(uv.x * (float(bars)));\n float scale = 1.0 + pos(bar) * amplitude;\n float phase = progress * scale;\n float posY = uv.y / vec2(1.0).y;\n vec2 p;\n vec4 c;\n if (phase + posY < 1.0) {\n p = vec2(uv.x, uv.y + mix(0.0, vec2(1.0).y, phase)) / vec2(1.0).xy;\n c = getFromColor(p);\n } else {\n p = uv.xy / vec2(1.0).xy;\n c = getToColor(p);\n }\n\n // Finally, apply the color\n return c;\n}\n","author":"Zeh Fernando","license":"MIT","description":"The outgoing image melts down in uneven columns, like the Doom screen wipe","tags":["melt","columns","retro"],"params":{"bars":{"type":"int","default":30},"amplitude":{"type":"float","default":2},"noise":{"type":"float","default":0.1},"frequency":{"type":"float","default":0.5},"dripScale":{"type":"float","default":0.5}},"textures":[],"createdAt":"Tue, 30 May 2017 09:39:09 -0700","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Dreamy","paramsTypes":{},"defaultParams":{},"glsl":"// Author: mikolalysenko\n// License: MIT\n// Description: A crossfade with a gentle wavy distortion\n// Tags: wave, blend\n\nvec2 offset(float progress, float x, float theta) {\n float phase = progress*progress + progress + theta;\n float shifty = 0.03*progress*cos(10.0*(progress+x));\n return vec2(0, shifty);\n}\nvec4 transition(vec2 p) {\n return mix(getFromColor(p + offset(progress, p.x, 0.0)), getToColor(p + offset(1.0-progress, p.x, 3.14)), progress);\n}\n","author":"mikolalysenko","license":"MIT","description":"A crossfade with a gentle wavy distortion","tags":["wave","blend"],"params":{},"textures":[],"createdAt":"Mon, 12 Jun 2017 12:27:38 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"DreamyZoom","paramsTypes":{"rotation":"float","scale":"float"},"defaultParams":{"rotation":6,"scale":1.2},"glsl":"// Author: Zeh Fernando\n// License: MIT\n// Description: Zooms and rotates into a bright flash, then out to the incoming image\n// Tags: zoom, rotate, flash\n\n// Definitions --------\n#define DEG2RAD 0.03926990816987241548078304229099 // 1/180*PI\n\n\n// Transition parameters --------\n\n// In degrees\nuniform float rotation; // = 6\n\n// Multiplier\nuniform float scale; // = 1.2\n\n\n// The code proper --------\n\nvec4 transition(vec2 uv) {\n // Massage parameters\n float phase = progress < 0.5 ? progress * 2.0 : (progress - 0.5) * 2.0;\n float angleOffset = progress < 0.5 ? mix(0.0, rotation * DEG2RAD, phase) : mix(-rotation * DEG2RAD, 0.0, phase);\n float newScale = progress < 0.5 ? mix(1.0, scale, phase) : mix(scale, 1.0, phase);\n \n vec2 center = vec2(0, 0);\n\n // Calculate the source point\n vec2 assumedCenter = vec2(0.5, 0.5);\n vec2 p = (uv.xy - vec2(0.5, 0.5)) / newScale * vec2(ratio, 1.0);\n\n // This can probably be optimized (with distance())\n float angle = atan(p.y, p.x) + angleOffset;\n float dist = distance(center, p);\n p.x = cos(angle) * dist / ratio + 0.5;\n p.y = sin(angle) * dist + 0.5;\n vec4 c = progress < 0.5 ? getFromColor(p) : getToColor(p);\n\n // Finally, apply the color\n return c + (progress < 0.5 ? mix(0.0, 1.0, phase) : mix(1.0, 0.0, phase));\n}\n","author":"Zeh Fernando","license":"MIT","description":"Zooms and rotates into a bright flash, then out to the incoming image","tags":["zoom","rotate","flash"],"params":{"rotation":{"type":"float","default":6},"scale":{"type":"float","default":1.2}},"textures":[],"createdAt":"Tue, 30 May 2017 10:44:06 -0700","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Drop_Zone_Flicker","paramsTypes":{"frameRate":"float","rgbOffset":"float","blockAmount":"float","ghostAmount":"float","redCyan":"float","scanline":"float"},"defaultParams":{"frameRate":24,"rgbOffset":0.014,"blockAmount":0.72,"ghostAmount":0.62,"redCyan":0.58,"scanline":0.075},"glsl":"// Author: bread\n// License: MIT\n// Description: A flickering glitch with RGB offset, ghosting and scanlines that flashes back to the outgoing image\n// Tags: glitch, flicker, chromatic, scanlines\n// Drop_Zone_Flicker.glsl\n// gl-transitions compatible: progress, ratio, getFromColor, getToColor\nuniform float frameRate; // = 24.0\nuniform float rgbOffset; // = 0.014\nuniform float blockAmount; // = 0.72\nuniform float ghostAmount; // = 0.62\nuniform float redCyan; // = 0.58\nuniform float scanline; // = 0.075\n\nfloat sat(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nfloat hash12(vec2 p) {\n p = fract(p * vec2(443.8975, 397.2973));\n p += dot(p, p.yx + 19.19);\n return fract(p.x * p.y);\n}\n\nvec2 safeUv(vec2 uv) {\n return clamp(uv, vec2(0.001), vec2(0.999));\n}\n\n// 24fps reference-matched reveal curve.\n// Non-monotonic on purpose: the reference flashes back to the old clip.\nfloat frameReveal(float f) {\n if (f < 0.5) return 0.00;\n if (f < 1.5) return 0.28;\n if (f < 2.5) return 0.43;\n if (f < 3.5) return 0.46;\n if (f < 4.5) return 0.38;\n if (f < 5.5) return 0.48;\n if (f < 6.5) return 0.26;\n if (f < 7.5) return 0.10;\n if (f < 8.5) return 0.00;\n if (f < 9.5) return 0.00;\n if (f < 10.5) return 0.30;\n if (f < 11.5) return 0.58;\n if (f < 12.5) return 1.00;\n if (f < 13.5) return 0.70;\n if (f < 14.5) return 0.42;\n if (f < 15.5) return 0.55;\n if (f < 16.5) return 0.72;\n if (f < 17.5) return 0.88;\n if (f < 18.5) return 0.34;\n if (f < 19.5) return 0.48;\n if (f < 20.5) return 0.56;\n if (f < 21.5) return 0.76;\n if (f < 22.5) return 0.93;\n return 1.00;\n}\n\nfloat frameGlitch(float f) {\n if (f < 0.5) return 0.00;\n if (f < 6.5) return 0.92;\n if (f < 10.5) return 0.38;\n if (f < 11.5) return 0.78;\n if (f < 12.5) return 0.12;\n if (f < 17.5) return 0.74;\n if (f < 22.5) return 0.88;\n if (f < 23.5) return 0.28;\n return 0.00;\n}\n\nvec4 chromaFrom(vec2 uv, float amt) {\n vec2 o = vec2(amt, 0.0);\n return vec4(\n getFromColor(safeUv(uv + o)).r,\n getFromColor(safeUv(uv)).g,\n getFromColor(safeUv(uv - o)).b,\n 1.0\n );\n}\n\nvec4 chromaTo(vec2 uv, float amt) {\n vec2 o = vec2(amt, 0.0);\n return vec4(\n getToColor(safeUv(uv - o)).r,\n getToColor(safeUv(uv)).g,\n getToColor(safeUv(uv + o)).b,\n 1.0\n );\n}\n\nfloat blockMask(vec2 uv, float f) {\n vec2 big = floor(uv * vec2(4.0, 2.0));\n vec2 small = floor(uv * vec2(8.0, 4.0));\n\n float wide = step(0.48, hash12(vec2(big.x, f * 1.37)));\n float chunks = step(0.56, hash12(small + vec2(f * 2.11, f * 0.73)));\n\n float verticalCut = smoothstep(\n -0.035,\n 0.035,\n uv.x - mix(0.18, 0.78, hash12(vec2(f, 4.7)))\n );\n\n return sat(mix(wide, chunks, 0.38) * 0.72 + verticalCut * 0.28);\n}\n\nvec4 transition(vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n\n float f = floor(progress * frameRate);\n float reveal = frameReveal(f);\n float glitch = frameGlitch(f);\n\n float rnd = hash12(vec2(f, 9.13));\n vec2 jitter = vec2(\n (rnd - 0.5) * 0.042,\n (hash12(vec2(f, 2.71)) - 0.5) * 0.010\n ) * glitch;\n\n vec2 fromUv = safeUv(uv + jitter);\n vec2 toUv = safeUv(uv - jitter * 0.55);\n\n float block = blockMask(uv, f);\n float localReveal = sat(\n reveal +\n (block - 0.5) * blockAmount * glitch +\n (hash12(vec2(f, floor(uv.y * 9.0))) - 0.5) * 0.18 * glitch\n );\n\n localReveal = smoothstep(0.22, 0.78, localReveal);\n\n vec4 oldClip = chromaFrom(fromUv, rgbOffset * glitch);\n vec4 newClip = chromaTo(toUv, rgbOffset * glitch);\n\n vec4 color = mix(oldClip, newClip, localReveal);\n\n float leftWash = (1.0 - smoothstep(0.10, 0.78, uv.x)) * glitch;\n float cyanWash = smoothstep(0.08, 0.62, uv.x) * (1.0 - smoothstep(0.86, 1.0, uv.x)) * glitch;\n\n vec3 redGhost = oldClip.rgb * vec3(1.34, 0.42, 0.38);\n vec3 cyanGhost = newClip.rgb * vec3(0.48, 1.12, 1.24);\n\n color.rgb = mix(color.rgb, redGhost, leftWash * redCyan * 0.42);\n color.rgb = mix(color.rgb, cyanGhost, cyanWash * redCyan * 0.30);\n\n // Keeps the old circular \"drop zone\" visible as a translucent flash,\n // especially after the first full new-frame hit.\n float oldReturn = glitch * (1.0 - smoothstep(0.94, 1.0, reveal));\n oldReturn *= 0.18 + 0.52 * (1.0 - abs(localReveal - 0.5) * 2.0);\n color.rgb = mix(color.rgb, oldClip.rgb, oldReturn * ghostAmount);\n\n float lines = sin((uv.y + f * 0.017) * 1080.0);\n color.rgb += lines * scanline * glitch;\n\n float exposurePulse = (hash12(vec2(f, 12.4)) - 0.35) * 0.10 * glitch;\n color.rgb += exposurePulse;\n\n return vec4(sat(color.r), sat(color.g), sat(color.b), 1.0);\n}\n","author":"bread","license":"MIT","description":"A flickering glitch with RGB offset, ghosting and scanlines that flashes back to the outgoing image","tags":["glitch","flicker","chromatic","scanlines"],"params":{"frameRate":{"type":"float","default":24},"rgbOffset":{"type":"float","default":0.014},"blockAmount":{"type":"float","default":0.72},"ghostAmount":{"type":"float","default":0.62},"redCyan":{"type":"float","default":0.58},"scanline":{"type":"float","default":0.075}},"textures":[],"createdAt":"Wed, 10 Jun 2026 11:41:33 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"EdgeTransition","paramsTypes":{"edge_thickness":"float","edge_brightness":"float"},"defaultParams":{"edge_thickness":0.001,"edge_brightness":8},"glsl":"// Author: Woohyun Kim\n// License: MIT\n// Description: Both images fade through black with their edges glowing\n// Tags: edges, fade\n\nuniform float edge_thickness; // = 0.001\nuniform float edge_brightness; // = 8.0\n\nvec4 detectEdgeColor(vec3[9] c) {\n /* adjacent texel array for texel c[4]\n 036\n 147\n 258\n */\n vec3 dx = 2.0 * abs(c[7]-c[1]) + abs(c[2] - c[6]) + abs(c[8] - c[0]);\n\tvec3 dy = 2.0 * abs(c[3]-c[5]) + abs(c[6] - c[8]) + abs(c[0] - c[2]);\n float delta = length(0.25 * (dx + dy) * 0.5);\n\treturn vec4(clamp(edge_brightness * delta, 0.0, 1.0) * c[4], 1.0);\n}\n\nvec4 getFromEdgeColor(vec2 uv) {\n\tvec3 c[9];\n\tfor (int i=0; i < 3; ++i) for (int j=0; j < 3; ++j)\n\t{\n\t vec4 color = getFromColor(uv + edge_thickness * vec2(i-1,j-1));\n c[3*i + j] = color.rgb;\n\t}\n\treturn detectEdgeColor(c);\n}\n\nvec4 getToEdgeColor(vec2 uv) {\n\tvec3 c[9];\n\tfor (int i=0; i < 3; ++i) for (int j=0; j < 3; ++j)\n\t{\n\t vec4 color = getToColor(uv + edge_thickness * vec2(i-1,j-1));\n c[3*i + j] = color.rgb;\n\t}\n\treturn detectEdgeColor(c);\n}\n\nvec4 transition (vec2 uv) {\n vec4 start = mix(getFromColor(uv), getFromEdgeColor(uv), clamp(2.0 * progress, 0.0, 1.0));\n vec4 end = mix(getToEdgeColor(uv), getToColor(uv), clamp(2.0 * (progress - 0.5), 0.0, 1.0));\n return mix(\n start,\n end,\n progress\n );\n}\n","author":"Woohyun Kim","license":"MIT","description":"Both images fade through black with their edges glowing","tags":["edges","fade"],"params":{"edge_thickness":{"type":"float","default":0.001},"edge_brightness":{"type":"float","default":8}},"textures":[],"createdAt":"Tue, 4 Apr 2023 16:28:18 +0900","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"FilmBurn","paramsTypes":{"Seed":"float"},"defaultParams":{"Seed":2.31},"glsl":"// Author: Anastasia Dunbar\n// License: MIT\n// Description: Glowing film-burn light leaks wash over the image and reveal the incoming one\n// Tags: burn, film, light-leak\n// @param Random seed\nuniform float Seed; // = 2.31\nfloat sigmoid(float x, float a) {\n float b = pow(x*2.,a)/2.;\n if (x > .5) {\n b = 1.-pow(2.-(x*2.),a)/2.;\n }\n\treturn b;\n}\nfloat rand(float co){\n return fract(sin((co*24.9898)+Seed)*43758.5453);\n}\nfloat rand(vec2 co){\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\nfloat apow(float a,float b) { return pow(abs(a),b)*sign(b); }\nvec3 pow3(vec3 a,vec3 b) { return vec3(apow(a.r,b.r),apow(a.g,b.g),apow(a.b,b.b)); }\nfloat smooth_mix(float a,float b,float c) { return mix(a,b,sigmoid(c,2.)); }\nfloat random(vec2 co, float shft){\n co += 10.;\n return smooth_mix(fract(sin(dot(co.xy ,vec2(12.9898+(floor(shft)*.5),78.233+Seed))) * 43758.5453),fract(sin(dot(co.xy ,vec2(12.9898+(floor(shft+1.)*.5),78.233+Seed))) * 43758.5453),fract(shft));\n}\nfloat smooth_random(vec2 co, float shft) {\n\treturn smooth_mix(smooth_mix(random(floor(co),shft),random(floor(co+vec2(1.,0.)),shft),fract(co.x)),smooth_mix(random(floor(co+vec2(0.,1.)),shft),random(floor(co+vec2(1.,1.)),shft),fract(co.x)),fract(co.y));\n}\nvec4 blendedColor(vec2 p) {\n return mix(getFromColor(p), getToColor(p), sigmoid(progress,10.));\n}\n#define pi 3.14159265358979323\n#define clamps(x) clamp(x,0.,1.)\n\nvec4 transition(vec2 p) {\n vec3 f = vec3(0.);\n for (float i = 0.; i < 13.; i++) {\n f += sin(((p.x*rand(i)*6.)+(progress*8.))+rand(i+1.43))*sin(((p.y*rand(i+4.4)*6.)+(progress*6.))+rand(i+2.4));\n f += 1.-clamps(length(p-vec2(smooth_random(vec2(progress*1.3),i+1.),smooth_random(vec2(progress*.5),i+6.25)))*mix(20.,70.,rand(i)));\n }\n f += 4.;\n f /= 11.;\n f = pow3(f*vec3(1.,0.7,0.6),vec3(1.,2.-sin(progress*pi),1.3));\n f *= sin(progress*pi);\n \n p -= .5;\n p *= 1.+(smooth_random(vec2(progress*5.),6.3)*sin(progress*pi)*.05);\n p += .5;\n \n vec4 blurred_image = vec4(0.);\n float bluramount = sin(progress*pi)*.03;\n #define repeats 50.\n for (float i = 0.; i < repeats; i++) { \n vec2 q = vec2(cos(degrees((i/repeats)*360.)),sin(degrees((i/repeats)*360.))) * (rand(vec2(i,p.x+p.y))+bluramount); \n vec2 uv2 = p+(q*bluramount);\n blurred_image += blendedColor(uv2);\n }\n blurred_image /= repeats;\n \n return blurred_image+vec4(f,0.);\n}\n","author":"Anastasia Dunbar","license":"MIT","description":"Glowing film-burn light leaks wash over the image and reveal the incoming one","tags":["burn","film","light-leak"],"params":{"Seed":{"type":"float","default":2.31,"description":"Random seed"}},"textures":[],"createdAt":"Wed, 21 Feb 2018 20:52:13 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Fold","paramsTypes":{},"defaultParams":{},"glsl":"// Author: nwoeanhinnogaehr\n// License: MIT\n// Description: The incoming image unfolds from the left while the outgoing one folds away to the right\n// Tags: fold, slide, horizontal\n// Ported from https://gist.github.com/nwoeanhinnogaehr/f6fc39f4cfcbb97f96a6\n\nvec4 transition(vec2 uv) {\n // Only sample the visible side: the other one divides by zero at progress 0 and 1.\n if (progress == 0.0 || uv.x > progress) return getFromColor((uv - vec2(progress, 0.0)) / vec2(1.0 - progress, 1.0));\n return getToColor(uv / vec2(progress, 1.0));\n}\n","author":"nwoeanhinnogaehr","license":"MIT","description":"The incoming image unfolds from the left while the outgoing one folds away to the right","tags":["fold","slide","horizontal"],"params":{},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Sat, 10 Oct 2026 11:26:01 +0200"},{"name":"GlitchDisplace","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Matt DesLauriers\n// License: MIT\n// Description: Blocks of the image are displaced in a glitch that flashes into the incoming image\n// Tags: glitch, displace\n\nfloat random(vec2 co)\n{\n float a = 12.9898;\n float b = 78.233;\n float c = 43758.5453;\n float dt= dot(co.xy ,vec2(a,b));\n float sn= mod(dt,3.14);\n return fract(sin(sn) * c);\n}\nfloat voronoi( in vec2 x ) {\n vec2 p = floor( x );\n vec2 f = fract( x );\n float res = 8.0;\n for( float j=-1.; j<=1.; j++ )\n for( float i=-1.; i<=1.; i++ ) {\n vec2 b = vec2( i, j );\n vec2 r = b - f + random( p + b );\n float d = dot( r, r );\n res = min( res, d );\n }\n return sqrt( res );\n}\n\nvec2 displace(vec4 tex, vec2 texCoord, float dotDepth, float textureDepth, float strength) {\n float b = voronoi(.003 * texCoord + 2.0);\n float g = voronoi(0.2 * texCoord);\n float r = voronoi(texCoord - 1.0);\n vec4 dt = tex * 1.0;\n vec4 dis = dt * dotDepth + 1.0 - tex * textureDepth;\n\n dis.x = dis.x - 1.0 + textureDepth*dotDepth;\n dis.y = dis.y - 1.0 + textureDepth*dotDepth;\n dis.x *= strength;\n dis.y *= strength;\n vec2 res_uv = texCoord ;\n res_uv.x = res_uv.x + dis.x - 0.0;\n res_uv.y = res_uv.y + dis.y;\n return res_uv;\n}\n\nfloat ease1(float t) {\n return t == 0.0 || t == 1.0\n ? t\n : t < 0.5\n ? +0.5 * pow(2.0, (20.0 * t) - 10.0)\n : -0.5 * pow(2.0, 10.0 - (t * 20.0)) + 1.0;\n}\nfloat ease2(float t) {\n return t == 1.0 ? t : 1.0 - pow(2.0, -10.0 * t);\n}\n\n\n\nvec4 transition(vec2 uv) {\n vec2 p = uv.xy / vec2(1.0).xy;\n vec4 color1 = getFromColor(p);\n vec4 color2 = getToColor(p);\n vec2 disp = displace(color1, p, 0.33, 0.7, 1.0-ease1(progress));\n vec2 disp2 = displace(color2, p, 0.33, 0.5, ease2(progress));\n vec4 dColor1 = getToColor(disp);\n vec4 dColor2 = getFromColor(disp2);\n float val = ease1(progress);\n vec3 gray = vec3(dot(min(dColor2, dColor1).rgb, vec3(0.299, 0.587, 0.114)));\n dColor2 = vec4(gray, 1.0);\n dColor2 *= 2.0;\n color1 = mix(color1, dColor2, smoothstep(0.0, 0.5, progress));\n color2 = mix(color2, dColor1, smoothstep(1.0, 0.5, progress));\n return mix(color1, color2, val);\n //gl_FragColor = mix(gl_FragColor, dColor, smoothstep(0.0, 0.5, progress));\n\n //gl_FragColor = mix(texture2D(from, p), texture2D(to, p), progress);\n}\n","author":"Matt DesLauriers","license":"MIT","description":"Blocks of the image are displaced in a glitch that flashes into the incoming image","tags":["glitch","displace"],"params":{},"textures":[],"createdAt":"Tue, 30 May 2017 14:53:04 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"GlitchMemories","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Gunnar Roth\n// based on work from natewave\n// License: MIT\n// Description: A crossfade with glitchy, color-shifted blocks\n// Tags: glitch, chromatic, blend\nvec4 transition(vec2 p) {\n vec2 block = floor(p.xy / vec2(16));\n vec2 uv_noise = block / vec2(64);\n uv_noise += floor(vec2(progress) * vec2(1200.0, 3500.0)) / vec2(64);\n vec2 dist = progress > 0.0 ? (fract(uv_noise) - 0.5) * 0.3 *(1.0 -progress) : vec2(0.0);\n vec2 red = p + dist * 0.2;\n vec2 green = p + dist * .3;\n vec2 blue = p + dist * .5;\n\n return vec4(mix(getFromColor(red), getToColor(red), progress).r,mix(getFromColor(green), getToColor(green), progress).g,mix(getFromColor(blue), getToColor(blue), progress).b,1.0);\n}\n\n","author":"Gunnar Roth","license":"MIT","description":"A crossfade with glitchy, color-shifted blocks","tags":["glitch","chromatic","blend"],"params":{},"textures":[],"createdAt":"Wed, 21 Feb 2018 00:52:15 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"GridFlip","paramsTypes":{"size":"ivec2","pause":"float","dividerWidth":"float","bgcolor":"vec4","randomness":"float"},"defaultParams":{"size":[4,4],"pause":0.1,"dividerWidth":0.05,"bgcolor":[0,0,0,1],"randomness":0.1},"glsl":"// License: MIT\n// Author: TimDonselaar\n// Description: The image splits into a grid of tiles that flip one by one to the incoming image\n// Tags: grid, tiles, flip\n// ported by gre from https://gist.github.com/TimDonselaar/9bcd1c4b5934ba60087bdb55c2ea92e5\n\n// @param Number of tiles (columns, rows)\nuniform ivec2 size; // = ivec2(4)\nuniform float pause; // = 0.1\nuniform float dividerWidth; // = 0.05\n// @color Color behind the tiles\nuniform vec4 bgcolor; // = vec4(0.0, 0.0, 0.0, 1.0)\nuniform float randomness; // = 0.1\n \nfloat rand (vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nfloat getDelta(vec2 p) {\n vec2 rectanglePos = floor(vec2(size) * p);\n vec2 rectangleSize = vec2(1.0 / vec2(size).x, 1.0 / vec2(size).y);\n float top = rectangleSize.y * (rectanglePos.y + 1.0);\n float bottom = rectangleSize.y * rectanglePos.y;\n float left = rectangleSize.x * rectanglePos.x;\n float right = rectangleSize.x * (rectanglePos.x + 1.0);\n float minX = min(abs(p.x - left), abs(p.x - right));\n float minY = min(abs(p.y - top), abs(p.y - bottom));\n return min(minX, minY);\n}\n\nfloat getDividerSize() {\n vec2 rectangleSize = vec2(1.0 / vec2(size).x, 1.0 / vec2(size).y);\n return min(rectangleSize.x, rectangleSize.y) * dividerWidth;\n}\n\nvec4 transition(vec2 p) {\n if(progress < pause) {\n float currentProg = progress / pause;\n float a = 1.0;\n if(getDelta(p) < getDividerSize()) {\n a = 1.0 - currentProg;\n }\n return mix(bgcolor, getFromColor(p), a);\n }\n else if(progress < 1.0 - pause){\n if(getDelta(p) < getDividerSize()) {\n return bgcolor;\n } else {\n float currentProg = (progress - pause) / (1.0 - pause * 2.0);\n vec2 q = p;\n vec2 rectanglePos = floor(vec2(size) * q);\n \n float r = rand(rectanglePos) - randomness;\n float cp = smoothstep(0.0, 1.0 - r, currentProg);\n \n float rectangleSize = 1.0 / vec2(size).x;\n float delta = rectanglePos.x * rectangleSize;\n float offset = rectangleSize / 2.0 + delta;\n \n p.x = (p.x - offset)/abs(cp - 0.5)*0.5 + offset;\n vec4 a = getFromColor(p);\n vec4 b = getToColor(p);\n \n float s = step(abs(vec2(size).x * (q.x - delta) - 0.5), abs(cp - 0.5));\n return mix(bgcolor, mix(b, a, step(cp, 0.5)), s);\n }\n }\n else {\n float currentProg = (progress - 1.0 + pause) / pause;\n float a = 1.0;\n if(getDelta(p) < getDividerSize()) {\n a = currentProg;\n }\n return mix(bgcolor, getToColor(p), a);\n }\n}\n","author":"TimDonselaar","license":"MIT","description":"The image splits into a grid of tiles that flip one by one to the incoming image","tags":["grid","tiles","flip"],"params":{"size":{"type":"ivec2","default":[4,4],"description":"Number of tiles (columns, rows)"},"pause":{"type":"float","default":0.1},"dividerWidth":{"type":"float","default":0.05},"bgcolor":{"type":"vec4","default":[0,0,0,1],"color":true,"description":"Color behind the tiles"},"randomness":{"type":"float","default":0.1}},"textures":[],"createdAt":"Mon, 12 Jun 2017 11:32:51 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"HSVfade","paramsTypes":{},"defaultParams":{},"glsl":"// Author: nwoeanhinnogaehr\n// License: MIT\n// Description: A crossfade through the HSV color space that cycles through hues\n// Tags: fade, color, hue\n// Ported from https://gist.github.com/nwoeanhinnogaehr/b185145363d65751009b\n\n// HSV functions from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl\n\nvec3 hsv2rgb(vec3 c) {\n const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\nvec3 rgb2hsv(vec3 c) {\n const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n float d = q.x - min(q.w, q.y);\n return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + 0.001)), d / (q.x + 0.001), q.x);\n}\n\nvec4 transition(vec2 uv) {\n vec3 a = rgb2hsv(getFromColor(uv).rgb);\n vec3 b = rgb2hsv(getToColor(uv).rgb);\n vec3 m = mix(a, b, progress);\n return vec4(hsv2rgb(m), 1.0);\n}\n","author":"nwoeanhinnogaehr","license":"MIT","description":"A crossfade through the HSV color space that cycles through hues","tags":["fade","color","hue"],"params":{},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"HorizontalClose","paramsTypes":{},"defaultParams":{},"glsl":"// Author: martiniti\n// License: MIT\n// Description: The incoming image closes in from the top and bottom edges toward the middle\n// Tags: wipe, split\n\nvec4 transition (vec2 uv) {\n\n float s = 2.0 - abs((uv.y - 0.5) / (progress - 1.0)) - 2.0 * progress;\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n smoothstep(0.5, 0.0, s)\n ); \n}\n","author":"martiniti","license":"MIT","description":"The incoming image closes in from the top and bottom edges toward the middle","tags":["wipe","split"],"params":{},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:35:23 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"HorizontalOpen","paramsTypes":{},"defaultParams":{},"glsl":"// Author: martiniti\n// License: MIT\n// Description: The incoming image opens from a line in the middle toward the top and bottom edges\n// Tags: wipe, split\n\nvec4 transition (vec2 uv) {\n \n float regress = 1.0 - progress;\n\n float s = 2.0 - abs((uv.y - 0.5) / (regress - 1.0)) - 2.0 * regress;\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n smoothstep(0.0, 0.5, s)\n );\n}\n","author":"martiniti","license":"MIT","description":"The incoming image opens from a line in the middle toward the top and bottom edges","tags":["wipe","split"],"params":{},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:35:30 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"InvertedPageCurl","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Hewlett-Packard\n// License: BSD 3 Clause\n// Description: The outgoing image curls away like a page, revealing the incoming one\n// Tags: page, curl, 3d\n// Adapted by Sergey Kosarevsky from:\n// http://rectalogic.github.io/webvfx/examples_2transition-shader-pagecurl_8html-example.html\n\n/*\nCopyright (c) 2010 Hewlett-Packard Development Company, L.P. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\n copyright notice, this list of conditions and the following disclaimer\n in the documentation and/or other materials provided with the\n distribution.\n * Neither the name of Hewlett-Packard nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\nin vec2 texCoord;\n*/\n\nconst float MIN_AMOUNT = -0.16;\nconst float MAX_AMOUNT = 1.5;\n\nconst float PI = 3.141592653589793;\n\nconst float scale = 512.0;\nconst float sharpness = 3.0;\n\nconst float cylinderRadius = 1.0 / PI / 2.0;\n\n// These depend on the progress uniform and must be computed per-fragment.\n// Global initializers with uniforms are invalid in GLSL ES and fail on Mesa.\nfloat amount;\nfloat cylinderCenter;\nfloat cylinderAngle;\n\nvec3 hitPoint(float hitAngle, float yc, vec3 point, mat3 rrotation)\n{\n float hitPoint = hitAngle / (2.0 * PI);\n point.y = hitPoint;\n return rrotation * point;\n}\n\nvec4 antiAlias(vec4 color1, vec4 color2, float distanc)\n{\n distanc *= scale;\n if (distanc < 0.0) return color2;\n if (distanc > 2.0) return color1;\n float dd = pow(1.0 - distanc / 2.0, sharpness);\n return ((color2 - color1) * dd) + color1;\n}\n\nfloat distanceToEdge(vec3 point)\n{\n float dx = abs(point.x > 0.5 ? 1.0 - point.x : point.x);\n float dy = abs(point.y > 0.5 ? 1.0 - point.y : point.y);\n if (point.x < 0.0) dx = -point.x;\n if (point.x > 1.0) dx = point.x - 1.0;\n if (point.y < 0.0) dy = -point.y;\n if (point.y > 1.0) dy = point.y - 1.0;\n if ((point.x < 0.0 || point.x > 1.0) && (point.y < 0.0 || point.y > 1.0)) return sqrt(dx * dx + dy * dy);\n return min(dx, dy);\n}\n\nvec4 seeThrough(float yc, vec2 p, mat3 rotation, mat3 rrotation)\n{\n float hitAngle = PI - (acos(clamp(yc / cylinderRadius, -1.0, 1.0)) - cylinderAngle);\n vec3 point = hitPoint(hitAngle, yc, rotation * vec3(p, 1.0), rrotation);\n if (yc <= 0.0 && (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0))\n {\n return getToColor(p);\n }\n\n if (yc > 0.0) return getFromColor(p);\n\n vec4 color = getFromColor(point.xy);\n vec4 tcolor = vec4(0.0);\n\n return antiAlias(color, tcolor, distanceToEdge(point));\n}\n\nvec4 seeThroughWithShadow(float yc, vec2 p, vec3 point, mat3 rotation, mat3 rrotation)\n{\n float shadow = distanceToEdge(point) * 30.0;\n shadow = (1.0 - shadow) / 3.0;\n\n if (shadow < 0.0) shadow = 0.0; else shadow *= amount;\n\n vec4 shadowColor = seeThrough(yc, p, rotation, rrotation);\n shadowColor.r -= shadow;\n shadowColor.g -= shadow;\n shadowColor.b -= shadow;\n\n return shadowColor;\n}\n\nvec4 backside(float yc, vec3 point)\n{\n vec4 color = getFromColor(point.xy);\n float gray = (color.r + color.b + color.g) / 15.0;\n gray += (8.0 / 10.0) * (pow(max(0.0, 1.0 - abs(yc / cylinderRadius)), 2.0 / 10.0) / 2.0 + (5.0 / 10.0));\n color.rgb = vec3(gray);\n return color;\n}\n\nvec4 behindSurface(vec2 p, float yc, vec3 point, mat3 rrotation)\n{\n float safeAmount = amount >= 0.0 ? max(amount, 1e-4) : min(amount, -1e-4);\n float shado = (1.0 - ((-cylinderRadius - yc) / safeAmount * 7.0)) / 6.0;\n shado *= 1.0 - abs(point.x - 0.5);\n\n yc = (-cylinderRadius - cylinderRadius - yc);\n\n float hitAngle = (acos(clamp(yc / cylinderRadius, -1.0, 1.0)) + cylinderAngle) - PI;\n point = hitPoint(hitAngle, yc, point, rrotation);\n\n if (yc < 0.0 && point.x >= 0.0 && point.y >= 0.0 && point.x <= 1.0 && point.y <= 1.0 && (hitAngle < PI || amount > 0.5))\n {\n float dx = point.x - 0.5;\n float dy = point.y - 0.5;\n shado = 1.0 - (sqrt(dx * dx + dy * dy) / (71.0 / 100.0));\n float nyc = -yc / cylinderRadius;\n shado *= nyc * nyc * nyc;\n shado *= 0.5;\n }\n else\n {\n shado = 0.0;\n }\n return vec4(getToColor(p).rgb - shado, 1.0);\n}\n\nvec4 transition(vec2 p) {\n amount = progress * (MAX_AMOUNT - MIN_AMOUNT) + MIN_AMOUNT;\n cylinderCenter = amount;\n cylinderAngle = 2.0 * PI * amount;\n\n const float angle = 100.0 * PI / 180.0;\n float c = cos(-angle);\n float s = sin(-angle);\n\n mat3 rotation = mat3( c, s, 0,\n -s, c, 0,\n -0.801, 0.8900, 1\n );\n c = cos(angle);\n s = sin(angle);\n\n mat3 rrotation = mat3(\tc, s, 0,\n -s, c, 0,\n 0.98500, 0.985, 1\n );\n\n vec3 point = rotation * vec3(p, 1.0);\n\n float yc = point.y - cylinderCenter;\n\n if (yc < -cylinderRadius)\n {\n // Behind surface\n return behindSurface(p,yc, point, rrotation);\n }\n\n if (yc > cylinderRadius)\n {\n // Flat surface\n return getFromColor(p);\n }\n\n float hitAngle = (acos(clamp(yc / cylinderRadius, -1.0, 1.0)) + cylinderAngle) - PI;\n\n float hitAngleMod = mod(hitAngle, 2.0 * PI);\n if ((hitAngleMod > PI && amount < 0.5) || (hitAngleMod > PI/2.0 && amount < 0.0))\n {\n return seeThrough(yc, p, rotation, rrotation);\n }\n\n point = hitPoint(hitAngle, yc, point, rrotation);\n\n if (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0)\n {\n return seeThroughWithShadow(yc, p, point, rotation, rrotation);\n }\n\n vec4 color = backside(yc, point);\n\n vec4 otherColor;\n if (yc < 0.0)\n {\n float dx2 = point.x - 0.5;\n float dy2 = point.y - 0.5;\n float shado = 1.0 - (sqrt(dx2 * dx2 + dy2 * dy2) / 0.71);\n float nyc2 = -yc / cylinderRadius;\n shado *= nyc2 * nyc2 * nyc2;\n shado *= 0.5;\n otherColor = vec4(0.0, 0.0, 0.0, shado);\n }\n else\n {\n otherColor = getFromColor(p);\n }\n\n color = antiAlias(color, otherColor, cylinderRadius - abs(yc));\n\n vec4 cl = seeThroughWithShadow(yc, p, point, rotation, rrotation);\n float dist = distanceToEdge(point);\n\n return antiAlias(color, cl, dist);\n}\n","author":"Hewlett-Packard","license":"BSD 3 Clause","description":"The outgoing image curls away like a page, revealing the incoming one","tags":["page","curl","3d"],"params":{},"textures":[],"createdAt":"Wed, 21 Feb 2018 01:13:49 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"LeftRight","paramsTypes":{},"defaultParams":{},"glsl":"// Author: zhmy\n// License: MIT\n// Description: The outgoing image shrinks away to the left while the incoming one slides in from the right\n// Tags: slide, zoom, horizontal\n\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n vec2 spfr,spto = vec2(-1.);\n\n float size = mix(1.0, 3.0, progress*0.2);\n spto = (uv + vec2(-0.5,-0.5))*vec2(size,size)+vec2(0.5,0.5);\n spfr = (uv - vec2(1.-progress, 0.0));\n if(inBounds(spfr)){\n return getToColor(spfr);\n }else if(inBounds(spto)){\n return getFromColor(spto) * (1.0 - progress);\n } else{\n return black;\n }\n}","author":"zhmy","license":"MIT","description":"The outgoing image shrinks away to the left while the incoming one slides in from the right","tags":["slide","zoom","horizontal"],"params":{},"textures":[],"createdAt":"Thu, 17 Dec 2020 11:50:34 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"LinearBlur","paramsTypes":{"intensity":"float"},"defaultParams":{"intensity":0.1},"glsl":"// Author: gre\n// License: MIT\n// Description: A crossfade through a blur\n// Tags: blur, blend\n// @param Amount of blur\nuniform float intensity; // = 0.1\nconst int passes = 6;\n\nvec4 transition(vec2 uv) {\n vec4 c1 = vec4(0.0);\n vec4 c2 = vec4(0.0);\n\n float disp = intensity*(0.5-distance(0.5, progress));\n for (int xi=0; xi<passes; xi++)\n {\n float x = float(xi) / float(passes) - 0.5;\n for (int yi=0; yi<passes; yi++)\n {\n float y = float(yi) / float(passes) - 0.5;\n vec2 v = vec2(x,y);\n float d = disp;\n c1 += getFromColor( uv + d*v);\n c2 += getToColor( uv + d*v);\n }\n }\n c1 /= float(passes*passes);\n c2 /= float(passes*passes);\n return mix(c1, c2, progress);\n}\n","author":"gre","license":"MIT","description":"A crossfade through a blur","tags":["blur","blend"],"params":{"intensity":{"type":"float","default":0.1,"description":"Amount of blur"}},"textures":[],"createdAt":"Fri, 23 Feb 2018 15:18:22 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Mosaic","paramsTypes":{"endx":"int","endy":"int"},"defaultParams":{"endx":2,"endy":-1},"glsl":"// License: MIT\n// Author: Xaychru\n// Description: The view pans across a mosaic of rotated tiles from both images and settles on the incoming one\n// Tags: mosaic, tiles, zoom\n// ported by gre from https://gist.github.com/Xaychru/130bb7b7affedbda9df5\n\n#define PI 3.14159265358979323\n#define POW2(X) X*X\n#define POW3(X) X*X*X\nuniform int endx; // = 2\nuniform int endy; // = -1\n\nfloat Rand(vec2 v) {\n return fract(sin(dot(v.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\nvec2 Rotate(vec2 v, float a) {\n mat2 rm = mat2(cos(a), -sin(a),\n sin(a), cos(a));\n return rm*v;\n}\nfloat CosInterpolation(float x) {\n return -cos(x*PI)/2.+.5;\n}\nvec4 transition(vec2 uv) {\n vec2 p = uv.xy / vec2(1.0).xy - .5;\n vec2 rp = p;\n float rpr = (progress*2.-1.);\n float z = -(rpr*rpr*2.) + 3.;\n float az = abs(z);\n rp *= az;\n rp += mix(vec2(.5, .5), vec2(float(endx) + .5, float(endy) + .5), POW2(CosInterpolation(progress)));\n vec2 mrp = mod(rp, 1.);\n vec2 crp = rp;\n bool onEnd = int(floor(crp.x))==endx&&int(floor(crp.y))==endy;\n if(!onEnd) {\n float ang = float(int(Rand(floor(crp))*4.))*.5*PI;\n mrp = vec2(.5) + Rotate(mrp-vec2(.5), ang);\n }\n if(onEnd || Rand(floor(crp))>.5) {\n return getToColor(mrp);\n } else {\n return getFromColor(mrp);\n }\n}\n","author":"Xaychru","license":"MIT","description":"The view pans across a mosaic of rotated tiles from both images and settles on the incoming one","tags":["mosaic","tiles","zoom"],"params":{"endx":{"type":"int","default":2},"endy":{"type":"int","default":-1}},"textures":[],"createdAt":"Mon, 12 Jun 2017 10:26:51 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Overexposure","paramsTypes":{"strength":"float"},"defaultParams":{"strength":0.6},"glsl":"// Author: Ben Zhang\n// License: MIT\n// Description: A crossfade through a washed-out, overexposed white\n// Tags: flash, light, fade\n\n// @param Amount of overexposure\nuniform float strength; // = 0.6\nconst float PI = 3.141592653589793;\n\nvec4 transition (vec2 uv) {\n vec4 from = getFromColor(uv);\n vec4 to = getToColor(uv);\n\n // Multipliers\n float from_m = 1.0 - progress + sin(PI * progress) * strength;\n float to_m = progress + sin(PI * progress) * strength;\n \n return vec4(\n from.r * from.a * from_m + to.r * to.a * to_m,\n from.g * from.a * from_m + to.g * to.a * to_m,\n from.b * from.a * from_m + to.b * to.a * to_m,\n mix(from.a, to.a, progress)\n );\n}\n","author":"Ben Zhang","license":"MIT","description":"A crossfade through a washed-out, overexposed white","tags":["flash","light","fade"],"params":{"strength":{"type":"float","default":0.6,"description":"Amount of overexposure"}},"textures":[],"createdAt":"Tue, 15 Mar 2022 20:21:15 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"PolkaDotsCurtain","paramsTypes":{"dots":"float","center":"vec2"},"defaultParams":{"dots":20,"center":[0,0]},"glsl":"// Author: bobylito\n// License: MIT\n// Description: The incoming image appears through growing polka dots\n// Tags: dots, pattern\nconst float SQRT_2 = 1.414213562373;\n// @param Number of dots across the image\nuniform float dots; // = 20.0\nuniform vec2 center; // = vec2(0, 0)\n\nvec4 transition(vec2 uv) {\n bool nextImage = distance(fract(uv * dots), vec2(0.5, 0.5)) < ( progress / distance(uv, center));\n return nextImage ? getToColor(uv) : getFromColor(uv);\n}\n","author":"bobylito","license":"MIT","description":"The incoming image appears through growing polka dots","tags":["dots","pattern"],"params":{"dots":{"type":"float","default":20,"description":"Number of dots across the image"},"center":{"type":"vec2","default":[0,0]}},"textures":[],"createdAt":"Tue, 20 Feb 2018 23:41:45 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"PuzzleRight","paramsTypes":{"size":"ivec2","pause":"float","dividerWidth":"float"},"defaultParams":{"size":[4,4],"pause":0.1,"dividerWidth":0.005},"glsl":"// Author: JustKirillS\n// License: MIT\n// Description: The image splits into a grid of tiles that flip one by one to the incoming image\n// Tags: grid, tiles, flip\n// Ported from https://gist.github.com/JustKirillS/714f095318834f4d2375de872c53af1e\n\nuniform ivec2 size; // = ivec2(4, 4)\nuniform float pause; // = 0.1\nuniform float dividerWidth; // = 0.005\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nfloat getDelta(vec2 p) {\n vec2 rectangleSize = 1.0 / vec2(size);\n vec2 rectanglePos = floor(vec2(size) * p);\n float top = rectangleSize.y * (rectanglePos.y + 1.0);\n float bottom = rectangleSize.y * rectanglePos.y;\n float left = rectangleSize.x * rectanglePos.x;\n float right = rectangleSize.x * (rectanglePos.x + 1.0);\n float minX = min(abs(p.x - left), abs(p.x - right));\n float minY = min(abs(p.y - top), abs(p.y - bottom));\n return min(minX, minY);\n}\n\nvec4 transition(vec2 uv) {\n if (progress < pause) {\n float currentProg = progress / pause;\n float a = 1.0;\n if (getDelta(uv) < dividerWidth) { a = 1.0 - currentProg; }\n return mix(vec4(0.0, 0.0, 0.0, 1.0), getFromColor(uv), a);\n } else if (progress < 1.0 - pause) {\n if (getDelta(uv) < dividerWidth) {\n return vec4(0.0, 0.0, 0.0, 1.0);\n }\n float currentProg = (progress - pause) / (1.0 - pause * 2.0);\n vec2 rectanglePos = floor(vec2(size) * uv);\n float r = rand(rectanglePos) - 0.1;\n float cp = smoothstep(0.0, 1.0 - r, currentProg);\n float rectangleSize = 1.0 / float(size.x);\n float delta = rectanglePos.x * rectangleSize;\n float offset = rectangleSize / 2.0 + delta;\n vec2 p = uv;\n p.x = (p.x - offset) / abs(cp - 0.5) * 0.5 + offset;\n vec4 a = getFromColor(p);\n vec4 b = getToColor(p);\n float s = step(abs(float(size.x) * (uv.x - delta) - 0.5), abs(cp - 0.5));\n return vec4(mix(b, a, step(cp, 0.5)).rgb * s, 1.0);\n } else {\n float currentProg = (progress - 1.0 + pause) / pause;\n float a = 1.0;\n if (getDelta(uv) < dividerWidth) { a = currentProg; }\n return mix(vec4(0.0, 0.0, 0.0, 1.0), getToColor(uv), a);\n }\n}\n","author":"JustKirillS","license":"MIT","description":"The image splits into a grid of tiles that flip one by one to the incoming image","tags":["grid","tiles","flip"],"params":{"size":{"type":"ivec2","default":[4,4]},"pause":{"type":"float","default":0.1},"dividerWidth":{"type":"float","default":0.005}},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"Radial","paramsTypes":{"smoothness":"float"},"defaultParams":{"smoothness":1},"glsl":"// License: MIT\n// Author: Xaychru\n// Description: A radial wipe that sweeps around the center like a clock hand\n// Tags: wipe, radial, clock\n// ported by gre from https://gist.github.com/Xaychru/ce1d48f0ce00bb379750\n\nuniform float smoothness; // = 1.0\n\nconst float PI = 3.141592653589;\n\nvec4 transition(vec2 p) {\n vec2 rp = p*2.-1.;\n return mix(\n getToColor(p),\n getFromColor(p),\n smoothstep(0., smoothness, atan(rp.y,rp.x) - (progress-.5) * PI * 2.5)\n );\n}\n","author":"Xaychru","license":"MIT","description":"A radial wipe that sweeps around the center like a clock hand","tags":["wipe","radial","clock"],"params":{"smoothness":{"type":"float","default":1}},"textures":[],"createdAt":"Mon, 12 Jun 2017 10:36:24 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Rectangle","paramsTypes":{"bgcolor":"vec4"},"defaultParams":{"bgcolor":[0,0,0,1]},"glsl":"// Author: martiniti\n// License: MIT\n// Description: A rectangle grows from the center to cover the outgoing image, then shrinks to reveal the incoming one\n// Tags: box, shape, iris\n\n// @color Color of the rectangle\nuniform vec4 bgcolor; // = vec4(0.0, 0.0, 0.0, 1.0)\n\nvec4 transition(vec2 p) {\n float s = pow(2.0 * abs(progress - 0.5), 3.0);\n \n vec2 sq = p.xy / vec2(1.0).xy;\n \n // bottom-left\n vec2 bl = step(vec2(abs(1. - 2.*progress)), sq + .25);\n float dist = bl.x * bl.y;\n\n // top-right\n vec2 tr = step(vec2(abs(1. - 2.*progress)), 1.25-sq);\n dist *= 1. * tr.x * tr.y;\n \n return mix(\n progress < 0.5 ? getFromColor(p) : getToColor(p),\n bgcolor,\n step(s, dist)\n );\n \n}\n","author":"martiniti","license":"MIT","description":"A rectangle grows from the center to cover the outgoing image, then shrinks to reveal the incoming one","tags":["box","shape","iris"],"params":{"bgcolor":{"type":"vec4","default":[0,0,0,1],"color":true,"description":"Color of the rectangle"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:29:59 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"RectangleCrop","paramsTypes":{"bgcolor":"vec4"},"defaultParams":{"bgcolor":[0,0,0,1]},"glsl":"// License: MIT\n// Author: martiniti\n// Description: The outgoing image shrinks into a small rectangle over a background color, then the incoming one grows from it\n// Tags: box, iris, zoom\n\n// @color Background color\nuniform vec4 bgcolor; // = vec4(0.0, 0.0, 0.0, 1.0)\n\nvec4 transition(vec2 uv) {\n \n float s = pow(2.0 * abs(progress - 0.5), 3.0);\n \n vec2 q = uv.xy / vec2(1.0).xy;\n \n // bottom-left\n vec2 bl = step(vec2(1.0 - 2.0*abs(progress - 0.5)), q + 0.25);\n \n // top-right\n vec2 tr = step(vec2(1.0 - 2.0*abs(progress - 0.5)), 1.25 - q);\n \n float dist = length(1.0 - bl.x * bl.y * tr.x * tr.y);\n \n return mix(\n progress < 0.5 ? getFromColor(uv) : getToColor(uv),\n bgcolor,\n step(s, dist)\n );\n \n}\n","author":"martiniti","license":"MIT","description":"The outgoing image shrinks into a small rectangle over a background color, then the incoming one grows from it","tags":["box","iris","zoom"],"params":{"bgcolor":{"type":"vec4","default":[0,0,0,1],"color":true,"description":"Background color"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:30:36 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Revolve_Left","paramsTypes":{"center":"vec2","direction":"float","maxRotation":"float","peakZoom":"float","swirl":"float","barrel":"float","motionBlur":"float","switchStart":"float","switchEnd":"float","shadow":"float"},"defaultParams":{"center":[0.46,0.52],"direction":-1,"maxRotation":1.95,"peakZoom":2.22,"swirl":2.85,"barrel":0.38,"motionBlur":1,"switchStart":0.3,"switchEnd":0.5,"shadow":0.16},"glsl":"// Author: bread\n// License: MIT\n// Description: The outgoing image swirls and zooms with motion blur into the incoming one\n// Tags: swirl, zoom, rotate, blur\n// gl-transitions v1 compatible\n\n// @param Center of the swirl\nuniform vec2 center; // = vec2(0.46, 0.52)\nuniform float direction; // = -1.0\nuniform float maxRotation; // = 1.95\nuniform float peakZoom; // = 2.22\nuniform float swirl; // = 2.85\nuniform float barrel; // = 0.38\nuniform float motionBlur; // = 1.0\nuniform float switchStart; // = 0.30\nuniform float switchEnd; // = 0.50\nuniform float shadow; // = 0.16\n\nfloat sat(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nfloat ease(float x) {\n x = sat(x);\n return x * x * (3.0 - 2.0 * x);\n}\n\nfloat revolveEnvelope(float t) {\n float rise = ease((t - 0.10) / 0.33);\n float fall = 1.0 - ease((t - 0.43) / 0.29);\n return rise * fall;\n}\n\nvec2 rotate2(vec2 p, float a) {\n float s = sin(a);\n float c = cos(a);\n return vec2(c * p.x - s * p.y, s * p.x + c * p.y);\n}\n\nvec2 warpUv(vec2 uv, float t) {\n float e = revolveEnvelope(t);\n\n vec2 p = uv - center;\n p.x *= ratio;\n\n float r = length(p);\n float edgeSpin = maxRotation * e;\n float coreSpin = swirl * e * pow(1.0 - sat(r / 0.96), 1.55);\n float visibleAngle = direction * (edgeSpin + coreSpin);\n\n p = rotate2(p, -visibleAngle);\n\n float sc = 1.0 + (peakZoom - 1.0) * pow(e, 0.85);\n p /= sc;\n\n float rr = length(p);\n p *= 1.0 + barrel * e * rr * rr * 2.8;\n\n p.x /= ratio;\n return clamp(p + center, vec2(0.001), vec2(0.999));\n}\n\nvec4 sampleRevolve(vec2 uv, float t) {\n vec2 p = warpUv(uv, t);\n float reveal = smoothstep(switchStart, switchEnd, t);\n return mix(getFromColor(p), getToColor(p), reveal);\n}\n\nvec4 transition(vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n\n float e = revolveEnvelope(progress);\n float span = 0.060 * motionBlur * e;\n\n vec4 color = vec4(0.0);\n float total = 0.0;\n\n for (int i = -8; i <= 8; i++) {\n float x = float(i) / 8.0;\n float w = 1.0 - abs(x);\n w = w * w + 0.01;\n\n float t = sat(progress + x * span);\n color += sampleRevolve(uv, t) * w;\n total += w;\n }\n\n color /= total;\n\n vec2 q = uv - vec2(0.5);\n q.x *= ratio;\n float vignette = 1.0 - shadow * e * smoothstep(0.35, 0.95, length(q));\n color.rgb *= vignette;\n\n return color;\n}\n","author":"bread","license":"MIT","description":"The outgoing image swirls and zooms with motion blur into the incoming one","tags":["swirl","zoom","rotate","blur"],"params":{"center":{"type":"vec2","default":[0.46,0.52],"description":"Center of the swirl"},"direction":{"type":"float","default":-1},"maxRotation":{"type":"float","default":1.95},"peakZoom":{"type":"float","default":2.22},"swirl":{"type":"float","default":2.85},"barrel":{"type":"float","default":0.38},"motionBlur":{"type":"float","default":1},"switchStart":{"type":"float","default":0.3},"switchEnd":{"type":"float","default":0.5},"shadow":{"type":"float","default":0.16}},"textures":[],"createdAt":"Wed, 10 Jun 2026 09:26:47 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Rolls","paramsTypes":{"type":"int","RotDown":"bool"},"defaultParams":{"type":0,"RotDown":false},"glsl":"// Author: Mark Craig\n// mrmcsoftware on github and youtube ( http://www.youtube.com/MrMcSoftware )\n// License: MIT\n// Description: The outgoing image rolls away around a corner, revealing the incoming one\n// Tags: rotate, roll\n\n// Rolls Transition by Mark Craig (Copyright © 2022)\n\n// @range(0, 3, 1) Corner to roll around\nuniform int type; // = 0\n// @param Roll the outgoing image down instead of up\nuniform bool RotDown; // = false\n// type (0-3): Rotate/Roll from which corner\n// RotDown: if true rotate old image down, otherwise rotate old image up\n\n#define M_PI 3.14159265358979323846\n\nvec4 transition(vec2 uv)\n{\nfloat theta, c1, s1;\nvec2 iResolution = vec2(ratio, 1.0);\nvec2 uvi;\n// I used if/else instead of switch in case it's an old GPU\nif (type == 0) { theta = (RotDown ? M_PI : -M_PI) / 2.0 * progress; uvi.x = 1.0 - uv.x; uvi.y = uv.y; }\nelse if (type == 1) { theta = (RotDown ? M_PI : -M_PI) / 2.0 * progress; uvi = uv; }\nelse if (type == 2) { theta = (RotDown ? -M_PI : M_PI) / 2.0 * progress; uvi.x = uv.x; uvi.y = 1.0 - uv.y; }\nelse if (type == 3) { theta = (RotDown ? -M_PI : M_PI) / 2.0 * progress; uvi = 1.0 - uv; }\nc1 = cos(theta); s1 = sin(theta);\nvec2 uv2;\nuv2.x = (uvi.x * iResolution.x * c1 - uvi.y * iResolution.y * s1);\nuv2.y = (uvi.x * iResolution.x * s1 + uvi.y * iResolution.y * c1);\nif ((uv2.x >= 0.0) && (uv2.x <= iResolution.x) && (uv2.y >= 0.0) && (uv2.y <= iResolution.y))\n\t{\n\tuv2 /= iResolution;\n\tif (type == 0) { uv2.x = 1.0 - uv2.x; }\n\telse if (type == 2) { uv2.y = 1.0 - uv2.y; }\n\telse if (type == 3) { uv2 = 1.0 - uv2; }\n\treturn(getFromColor(uv2));\n\t}\nreturn(getToColor(uv));\n}\n","author":"Mark Craig","license":"MIT","description":"The outgoing image rolls away around a corner, revealing the incoming one","tags":["rotate","roll"],"params":{"type":{"type":"int","default":0,"min":0,"max":3,"step":1,"description":"Corner to roll around"},"RotDown":{"type":"bool","default":false,"description":"Roll the outgoing image down instead of up"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 03:31:55 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"RotateScaleVanish","paramsTypes":{"FadeInSecond":"bool","ReverseEffect":"bool","ReverseRotation":"bool"},"defaultParams":{"FadeInSecond":true,"ReverseEffect":false,"ReverseRotation":false},"glsl":"// Author: Mark Craig\n// mrmcsoftware on github and youtube ( http://www.youtube.com/MrMcSoftware )\n// License: MIT\n// Description: The outgoing image spins and shrinks away over the incoming one\n// Tags: rotate, zoom, spin\n\n// RotateScaleVanish Transition by Mark Craig (Copyright © 2022)\n\n// @param Fade in the incoming image\nuniform bool FadeInSecond; // = true\n// @param Run the effect in reverse\nuniform bool ReverseEffect; // = false\n// @param Rotate the other way\nuniform bool ReverseRotation; // = false\n\n#define M_PI 3.14159265358979323846\n#define _TWOPI 6.283185307179586476925286766559\n\nvec4 transition(vec2 uv)\n{\nvec2 iResolution = vec2(ratio, 1.0);\nfloat t = ReverseEffect ? 1.0 - progress : progress;\nfloat theta = ReverseRotation ? _TWOPI * t : -_TWOPI * t;\nfloat c1 = cos(theta);\nfloat s1 = sin(theta);\nfloat rad = max(0.00001, 1.0 - t);\nfloat xc1 = (uv.x - 0.5) * iResolution.x;\nfloat yc1 = (uv.y - 0.5) * iResolution.y;\nfloat xc2 = (xc1 * c1 - yc1 * s1) / rad;\nfloat yc2 = (xc1 * s1 + yc1 * c1) / rad;\nvec2 uv2 = vec2(xc2 + iResolution.x / 2.0, yc2 + iResolution.y / 2.0);\nvec4 col3;\nvec4 ColorTo = ReverseEffect ? getFromColor(uv) : getToColor(uv);\nif ((uv2.x >= 0.0) && (uv2.x <= iResolution.x) && (uv2.y >= 0.0) && (uv2.y <= iResolution.y))\n\t{\n\tuv2 /= iResolution;\n\tcol3 = ReverseEffect ? getToColor(uv2) : getFromColor(uv2);\n\t}\nelse { col3 = FadeInSecond ? vec4(0.0, 0.0, 0.0, 1.0) : ColorTo; }\nreturn((1.0 - t) * col3 + t * ColorTo); // could have used mix\n}\n","author":"Mark Craig","license":"MIT","description":"The outgoing image spins and shrinks away over the incoming one","tags":["rotate","zoom","spin"],"params":{"FadeInSecond":{"type":"bool","default":true,"description":"Fade in the incoming image"},"ReverseEffect":{"type":"bool","default":false,"description":"Run the effect in reverse"},"ReverseRotation":{"type":"bool","default":false,"description":"Rotate the other way"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 03:31:48 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"SimpleFlip","paramsTypes":{},"defaultParams":{},"glsl":"// Author: nwoeanhinnogaehr\n// License: MIT\n// Description: The outgoing image flips around the vertical axis into the incoming one\n// Tags: flip, horizontal\n// Ported from https://gist.github.com/nwoeanhinnogaehr/408045772d255df97520\n\nvec4 transition(vec2 uv) {\n vec2 q = uv;\n uv.x = (uv.x - 0.5) / abs(progress - 0.5) * 0.5 + 0.5;\n vec4 a = getFromColor(uv);\n vec4 b = getToColor(uv);\n return vec4(mix(a, b, step(0.5, progress)).rgb * step(abs(q.x - 0.5), abs(progress - 0.5)), 1.0);\n}\n","author":"nwoeanhinnogaehr","license":"MIT","description":"The outgoing image flips around the vertical axis into the incoming one","tags":["flip","horizontal"],"params":{},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"SimpleZoom","paramsTypes":{"zoom_quickness":"float"},"defaultParams":{"zoom_quickness":0.8},"glsl":"// Author: 0gust1\n// License: MIT\n// Description: Zooms into the outgoing image, then fades to the incoming one\n// Tags: zoom, fade\n\n// @range(0.2, 1) Part of the transition spent zooming\nuniform float zoom_quickness; // = 0.8\nvec2 zoom(vec2 uv, float amount) {\n return 0.5 + ((uv - 0.5) * (1.0-amount));\t\n}\n\nvec4 transition (vec2 uv) {\n float nQuick = clamp(zoom_quickness,0.2,1.0);\n return mix(\n getFromColor(zoom(uv, smoothstep(0.0, nQuick, progress))),\n getToColor(uv),\n smoothstep(nQuick-0.2, 1.0, progress)\n );\n}","author":"0gust1","license":"MIT","description":"Zooms into the outgoing image, then fades to the incoming one","tags":["zoom","fade"],"params":{"zoom_quickness":{"type":"float","default":0.8,"min":0.2,"max":1,"description":"Part of the transition spent zooming"}},"textures":[],"createdAt":"Tue, 6 Mar 2018 00:43:47 +0100","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"SimpleZoomOut","paramsTypes":{"zoom_quickness":"float","fade":"bool"},"defaultParams":{"zoom_quickness":0.8,"fade":true},"glsl":"// Author: Tianshuo\n// License: MIT\n// Description: The incoming image zooms out into place while fading in\n// Tags: zoom, fade\n\n\n// @range(0.2, 1) Part of the transition spent zooming\nuniform float zoom_quickness; // = 0.8\n// @param Fade instead of cutting to the incoming image\nuniform bool fade; // = true\nvec2 zoom(vec2 uv, float amount) {\n return 0.5 + ((uv - 0.5) * (1.0-amount));\t\n}\n\nvec4 transition (vec2 uv) {\n float nQuick = clamp(zoom_quickness,0.2,1.0);\n return mix(\n getFromColor(uv),\n getToColor(zoom(uv,1.-smoothstep(1.-nQuick, 1., progress))),\n fade?smoothstep(1.0-nQuick, 1., progress):(progress<1.0-nQuick?0.0:1.0)\n );\n}\n","author":"Tianshuo","license":"MIT","description":"The incoming image zooms out into place while fading in","tags":["zoom","fade"],"params":{"zoom_quickness":{"type":"float","default":0.8,"min":0.2,"max":1,"description":"Part of the transition spent zooming"},"fade":{"type":"bool","default":true,"description":"Fade instead of cutting to the incoming image"}},"textures":[],"createdAt":"Sun, 29 Mar 2026 19:32:53 +0200","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"Slides","paramsTypes":{"type":"int","In":"bool"},"defaultParams":{"type":0,"In":false},"glsl":"// Author: Mark Craig\n// mrmcsoftware on github and youtube ( http://www.youtube.com/MrMcSoftware )\n// License: MIT\n// Description: The outgoing image slides out, or the incoming one slides in, toward an edge, a corner or the center\n// Tags: slide, directional\n\n// Slides Transition by Mark Craig (Copyright © 2022)\n\nuniform int type; // = 0\n// @param Slide the incoming image in instead of the outgoing one out\nuniform bool In; // = false\n// type: slide to/from which edge, which corner, or center\n// In: if true slide new image in, otherwise slide old image out\n\n#define rad2 rad / 2.0\n\nvec4 transition(vec2 uv)\n{\nvec2 uv0 = uv;\nfloat rad = In ? progress : 1.0 - progress;\nfloat xc1, yc1;\n// I used if/else instead of switch in case it's an old GPU\nif (type == 0) { xc1 = .5 - rad2; yc1 = 0.0; }\nelse if (type == 1) { xc1 = 1.0 - rad; yc1 = .5 - rad2; }\nelse if (type == 2) { xc1 = .5 - rad2; yc1 = 1.0 - rad; }\nelse if (type == 3) { xc1 = 0.0; yc1 = .5 - rad2; }\nelse if (type == 4) { xc1 = 1.0 - rad; yc1 = 0.0; }\nelse if (type == 5) { xc1 = 1.0 - rad; yc1 = 1.0 - rad; }\nelse if (type == 6) { xc1 = 0.0; yc1 = 1.0 - rad; }\nelse if (type == 7) { xc1 = 0.0; yc1 = 0.0; }\nelse if (type == 8) { xc1 = .5 - rad2; yc1 = .5 - rad2; }\nuv.y = 1.0 - uv.y;\nvec2 uv2;\nif ((uv.x >= xc1) && (uv.x <= xc1 + rad) && (uv.y >= yc1) && (uv.y <= yc1 + rad))\n\t{\n\tuv2 = vec2((uv.x - xc1) / rad, 1.0 - (uv.y - yc1) / rad);\n\treturn(In ? getToColor(uv2) : getFromColor(uv2));\n\t}\nreturn(In ? getFromColor(uv0) : getToColor(uv0));\n}\n","author":"Mark Craig","license":"MIT","description":"The outgoing image slides out, or the incoming one slides in, toward an edge, a corner or the center","tags":["slide","directional"],"params":{"type":{"type":"int","default":0},"In":{"type":"bool","default":false,"description":"Slide the incoming image in instead of the outgoing one out"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 03:32:13 -0400","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"StarWipe","paramsTypes":{"border_thickness":"float","star_rotation":"float","border_color":"vec4","star_center":"vec2"},"defaultParams":{"border_thickness":0.01,"star_rotation":0.75,"border_color":[1,1,1,1],"star_center":[0.5,0.5]},"glsl":"// Author: Ben Lucas\n// License: MIT\n// Description: A growing star reveals the incoming image\n// Tags: wipe, shape, star\n#define PI 3.141592653589793\n#define STAR_ANGLE 1.2566370614359172\n\n// @param Thickness of the star's border\nuniform float border_thickness;// = 0.01\nuniform float star_rotation;// = 0.75\n// @color Color of the star's border\nuniform vec4 border_color; // = vec4(1.0)\n// @param Center of the star\nuniform vec2 star_center;// = vec2(0.5)\n\nvec2 rotate(vec2 v, float theta) {\n float cosTheta = cos(theta);\n float sinTheta = sin(theta);\n\n return vec2(\n cosTheta * v.x - sinTheta * v.y,\n sinTheta * v.x + cosTheta * v.y\n );\n}\n\nbool inStar(vec2 uv, vec2 center, float radius){\n vec2 uv_centered = uv - center;\n uv_centered = rotate(uv_centered, star_rotation * STAR_ANGLE);\n float theta = atan(uv_centered.y, uv_centered.x) + PI;\n\n vec2 uv_rotated = rotate(uv_centered, -STAR_ANGLE * (floor(theta / STAR_ANGLE) + 0.5));\n\n float slope = 0.3;\n if(uv_rotated.y > 0.0){\n return (radius + uv_rotated.x * slope > uv_rotated.y);\n } else {\n return (-radius - uv_rotated.x * slope < uv_rotated.y);\n }\n}\n\nvec4 transition (vec2 uv) {\n float progressScaled = (2.0 * border_thickness + 1.0) * progress - border_thickness;\n if(inStar(uv, star_center, progressScaled)){\n return getToColor(uv);\n } else if(inStar(uv, star_center, progressScaled+border_thickness)){\n return border_color;\n } else {\n return getFromColor(uv);\n }\n}\n","author":"Ben Lucas","license":"MIT","description":"A growing star reveals the incoming image","tags":["wipe","shape","star"],"params":{"border_thickness":{"type":"float","default":0.01,"description":"Thickness of the star's border"},"star_rotation":{"type":"float","default":0.75},"border_color":{"type":"vec4","default":[1,1,1,1],"color":true,"description":"Color of the star's border"},"star_center":{"type":"vec2","default":[0.5,0.5],"description":"Center of the star"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 10:31:54 -0700","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"StaticFade","paramsTypes":{"n_noise_pixels":"float","static_luminosity":"float"},"defaultParams":{"n_noise_pixels":200,"static_luminosity":0.8},"glsl":"// Author: Ben Lucas\n// License: MIT\n// Description: Cuts to the incoming image halfway, hidden behind a burst of TV static\n// Tags: static, noise, retro\n\nuniform float n_noise_pixels ; // = 200.0\nuniform float static_luminosity ; // = 0.8\n\nfloat rnd (vec2 st) {\n return fract(sin(dot(st.xy,\n vec2(10.5302340293,70.23492931)))*\n 12345.5453123);\n}\n\nvec4 staticNoise (vec2 st, float offset, float luminosity) {\n float staticR = luminosity * rnd(st * vec2(offset * 2.0, offset * 3.0));\n float staticG = luminosity * rnd(st * vec2(offset * 3.0, offset * 5.0));\n float staticB = luminosity * rnd(st * vec2(offset * 5.0, offset * 7.0));\n return vec4(staticR, staticG, staticB, 1.0);\n}\n\nfloat staticIntensity(float t)\n{\n float transitionProgress = abs(2.0*(t-0.5));\n float transformedThreshold =1.2*(1.0 - transitionProgress)-0.1;\n return min(1.0, transformedThreshold);\n}\n \nvec4 transition (vec2 uv) {\n\n float baseMix = step(0.5, progress);\n vec4 transitionMix = mix(\n getFromColor(uv),\n getToColor(uv),\n baseMix\n );\n \n vec2 uvStatic = floor(uv * n_noise_pixels)/n_noise_pixels;\n \n vec4 staticColor = staticNoise(uvStatic, progress, static_luminosity);\n\n float staticThresh = staticIntensity(progress);\n float staticMix = step(rnd(uvStatic), staticThresh);\n\n return mix(transitionMix, staticColor, staticMix);\n}\n","author":"Ben Lucas","license":"MIT","description":"Cuts to the incoming image halfway, hidden behind a burst of TV static","tags":["static","noise","retro"],"params":{"n_noise_pixels":{"type":"float","default":200},"static_luminosity":{"type":"float","default":0.8}},"textures":[],"createdAt":"Fri, 2 Jun 2023 04:27:43 -0400","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"StereoViewer","paramsTypes":{"zoom":"float","corner_radius":"float"},"defaultParams":{"zoom":0.88,"corner_radius":0.22},"glsl":"// Tunable parameters\n// How much to zoom (out) for the effect ~ 0.5 - 1.0\n// @range(0.5, 1) How much the images zoom out\nuniform float zoom; // = 0.88\n// Corner radius as a fraction of the image height\nuniform float corner_radius; // = 0.22\n\n// Author: Ted Schundler\n// License: BSD 2 Clause\n// Description: Both images shrink into rounded cards that swap, like a stereo viewer toy\n// Tags: cards, zoom, retro\n// Free for use and modification by anyone with credit\n\n// Copyright (c) 2016, Theodore K Schundler\n// All rights reserved.\n\n// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\n// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n///////////////////////////////////////////////////////////////////////////////\n// Stereo Viewer Toy Transition //\n// //\n// Inspired by ViewMaster / Image3D image viewer devices. //\n// This effect is similar to what you see when you press the device's lever. //\n// There is a quick zoom in / out to make the transition 'valid' for GLSL.io //\n///////////////////////////////////////////////////////////////////////////////\n\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\nconst vec2 c00 = vec2(0.0, 0.0); // the four corner points\nconst vec2 c01 = vec2(0.0, 1.0);\nconst vec2 c11 = vec2(1.0, 1.0);\nconst vec2 c10 = vec2(1.0, 0.0);\n\n// Check if a point is within a given corner\nbool in_corner(vec2 p, vec2 corner, vec2 radius) {\n // determine the direction we want to be filled\n vec2 axis = (c11 - corner) - corner;\n\n // warp the point so we are always testing the bottom left point with the\n // circle centered on the origin\n p = p - (corner + axis * radius);\n p *= axis / radius;\n return (p.x > 0.0 && p.y > -1.0) || (p.y > 0.0 && p.x > -1.0) || dot(p, p) < 1.0;\n}\n\n// Check all four corners\n// return a float for v2 for anti-aliasing?\nbool test_rounded_mask(vec2 p, vec2 corner_size) {\n return\n in_corner(p, c00, corner_size) &&\n in_corner(p, c01, corner_size) &&\n in_corner(p, c10, corner_size) &&\n in_corner(p, c11, corner_size);\n}\n\n// Screen blend mode - https://en.wikipedia.org/wiki/Blend_modes\n// This more closely approximates what you see than linear blending\nvec4 screen(vec4 a, vec4 b) {\n return 1.0 - (1.0 - a) * (1.0 -b);\n}\n\n// Given RGBA, find a value that when screened with itself\n// will yield the original value.\nvec4 unscreen(vec4 c) {\n return 1.0 - sqrt(1.0 - c);\n}\n\n// Grab a pixel, only if it isn't masked out by the rounded corners\nvec4 sample_with_corners_from(vec2 p, vec2 corner_size) {\n p = (p - 0.5) / zoom + 0.5;\n if (!test_rounded_mask(p, corner_size)) {\n return black;\n }\n return unscreen(getFromColor(p));\n}\n\nvec4 sample_with_corners_to(vec2 p, vec2 corner_size) {\n p = (p - 0.5) / zoom + 0.5;\n if (!test_rounded_mask(p, corner_size)) {\n return black;\n }\n return unscreen(getToColor(p));\n}\n\n// special sampling used when zooming - extra zoom parameter and don't unscreen\nvec4 simple_sample_with_corners_from(vec2 p, vec2 corner_size, float zoom_amt) {\n p = (p - 0.5) / (1.0 - zoom_amt + zoom * zoom_amt) + 0.5;\n if (!test_rounded_mask(p, corner_size)) {\n return black;\n }\n return getFromColor(p);\n}\n\nvec4 simple_sample_with_corners_to(vec2 p, vec2 corner_size, float zoom_amt) {\n p = (p - 0.5) / (1.0 - zoom_amt + zoom * zoom_amt) + 0.5;\n if (!test_rounded_mask(p, corner_size)) {\n return black;\n }\n return getToColor(p);\n}\n\n// Basic 2D affine transform matrix helpers\n// These really shouldn't be used in a fragment shader - I should work out the\n// the math for a translate & rotate function as a pair of dot products instead\n\nmat3 rotate2d(float angle, float ratio) {\n float s = sin(angle);\n float c = cos(angle);\n return mat3(\n c, s ,0.0,\n -s, c, 0.0,\n 0.0, 0.0, 1.0);\n}\n\nmat3 translate2d(float x, float y) {\n return mat3(\n 1.0, 0.0, 0,\n 0.0, 1.0, 0,\n -x, -y, 1.0);\n}\n\nmat3 scale2d(float x, float y) {\n return mat3(\n x, 0.0, 0,\n 0.0, y, 0,\n 0, 0, 1.0);\n}\n\n// Split an image and rotate one up and one down along off screen pivot points\nvec4 get_cross_rotated(vec3 p3, float angle, vec2 corner_size, float ratio) {\n angle = angle * angle; // easing\n angle /= 2.4; // works out to be a good number of radians\n\n mat3 center_and_scale = translate2d(-0.5, -0.5) * scale2d(1.0, ratio);\n mat3 unscale_and_uncenter = scale2d(1.0, 1.0/ratio) * translate2d(0.5,0.5);\n mat3 slide_left = translate2d(-2.0,0.0);\n mat3 slide_right = translate2d(2.0,0.0);\n mat3 rotate = rotate2d(angle, ratio);\n\n mat3 op_a = center_and_scale * slide_right * rotate * slide_left * unscale_and_uncenter;\n mat3 op_b = center_and_scale * slide_left * rotate * slide_right * unscale_and_uncenter;\n\n vec4 a = sample_with_corners_from((op_a * p3).xy, corner_size);\n vec4 b = sample_with_corners_from((op_b * p3).xy, corner_size);\n\n return screen(a, b);\n}\n\n// Image stays put, but this time move two masks\nvec4 get_cross_masked(vec3 p3, float angle, vec2 corner_size, float ratio) {\n angle = 1.0 - angle;\n angle = angle * angle; // easing\n angle /= 2.4;\n\n vec4 img;\n\n mat3 center_and_scale = translate2d(-0.5, -0.5) * scale2d(1.0, ratio);\n mat3 unscale_and_uncenter = scale2d(1.0 / zoom, 1.0 / (zoom * ratio)) * translate2d(0.5,0.5);\n mat3 slide_left = translate2d(-2.0,0.0);\n mat3 slide_right = translate2d(2.0,0.0);\n mat3 rotate = rotate2d(angle, ratio);\n\n mat3 op_a = center_and_scale * slide_right * rotate * slide_left * unscale_and_uncenter;\n mat3 op_b = center_and_scale * slide_left * rotate * slide_right * unscale_and_uncenter;\n\n bool mask_a = test_rounded_mask((op_a * p3).xy, corner_size);\n bool mask_b = test_rounded_mask((op_b * p3).xy, corner_size);\n\n if (mask_a || mask_b) {\n img = sample_with_corners_to(p3.xy, corner_size);\n return screen(mask_a ? img : black, mask_b ? img : black);\n } else {\n return black;\n }\n}\n\nvec4 transition(vec2 uv) {\n float a;\n vec2 p=uv.xy/vec2(1.0).xy;\n vec3 p3 = vec3(p.xy, 1.0); // for 2D matrix transforms\n\n // corner is warped to represent to size after mapping to 1.0, 1.0\n vec2 corner_size = vec2(corner_radius / ratio, corner_radius);\n\n if (progress <= 0.0) {\n // 0.0: start with the base frame always\n return getFromColor(p);\n } else if (progress < 0.1) {\n // 0.0-0.1: zoom out and add rounded corners\n a = progress / 0.1;\n return simple_sample_with_corners_from(p, corner_size * a, a);\n } else if (progress < 0.48) {\n // 0.1-0.48: Split original image apart\n a = (progress - 0.1)/0.38;\n return get_cross_rotated(p3, a, corner_size, ratio);\n } else if (progress < 0.9) {\n // 0.48-0.52: black\n // 0.52 - 0.9: unmask new image\n return get_cross_masked(p3, (progress - 0.52)/0.38, corner_size, ratio);\n } else if (progress < 1.0) {\n // zoom out and add rounded corners\n a = (1.0 - progress) / 0.1;\n return simple_sample_with_corners_to(p, corner_size * a, a);\n } else {\n // 1.0 end with base frame\n return getToColor(p);\n }\n}\n","author":"Ted Schundler","license":"BSD 2 Clause","description":"Both images shrink into rounded cards that swap, like a stereo viewer toy","tags":["cards","zoom","retro"],"params":{"zoom":{"type":"float","default":0.88,"min":0.5,"max":1,"description":"How much the images zoom out"},"corner_radius":{"type":"float","default":0.22}},"textures":[],"createdAt":"Tue, 20 Feb 2018 23:20:29 +0100","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"StripDatamoshGlitch","paramsTypes":{"strength":"float","horizontalBars":"float","verticalSlits":"float","tear":"float","chroma":"float","residue":"float","noiseAmount":"float","scanAmount":"float","flashAmount":"float"},"defaultParams":{"strength":1,"horizontalBars":42,"verticalSlits":18,"tear":0.18,"chroma":0.032,"residue":0.62,"noiseAmount":0.16,"scanAmount":0.13,"flashAmount":0.2},"glsl":"// Author: bread\n// License: MIT\n// Description: A datamosh glitch: torn strips, chroma shifts and scan noise drag the outgoing image into the incoming one\n// Tags: glitch, datamosh, chromatic\n\nuniform float strength; // = 1.0\nuniform float horizontalBars; // = 42.0\nuniform float verticalSlits; // = 18.0\nuniform float tear; // = 0.18\nuniform float chroma; // = 0.032\nuniform float residue; // = 0.62\nuniform float noiseAmount; // = 0.16\nuniform float scanAmount; // = 0.13\nuniform float flashAmount; // = 0.20\n\nconst float PI = 3.141592653589793;\n\nfloat hash(float n) {\n return fract(sin(n) * 43758.5453123);\n}\n\nfloat hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);\n}\n\nfloat sat(float v) {\n return clamp(v, 0.0, 1.0);\n}\n\nfloat burst() {\n return pow(max(0.0, sin(progress * PI)), 0.42) * strength;\n}\n\nvec2 safeUv(vec2 uv) {\n return clamp(uv, vec2(0.0), vec2(1.0));\n}\n\nfloat stripeY(vec2 uv, float density, float seed, float minWidth, float maxWidth) {\n float y = uv.y * density + seed * 0.137;\n float id = floor(y);\n float f = fract(y);\n float c = hash(vec2(id, seed));\n float w = mix(minWidth, maxWidth, hash(vec2(id + 9.17, seed + 2.31)));\n return 1.0 - smoothstep(w, w + 0.018, abs(f - c));\n}\n\nfloat stripeX(vec2 uv, float density, float seed, float minWidth, float maxWidth) {\n float x = uv.x * density + seed * 0.091;\n float id = floor(x);\n float f = fract(x);\n float c = hash(vec2(id, seed + 41.0));\n float w = mix(minWidth, maxWidth, hash(vec2(id + 4.7, seed + 8.9)));\n return 1.0 - smoothstep(w, w + 0.012, abs(f - c));\n}\n\nfloat brokenGate(vec2 uv, float row, float rnd, float frame) {\n float segs = mix(1.0, 9.0, hash(vec2(row, frame + 44.0)));\n float seg = floor(uv.x * segs);\n return step(0.16, hash(vec2(seg, row + frame * 3.0 + rnd)));\n}\n\nfloat horizontalMask(vec2 uv, float frame) {\n float r1 = floor((uv.y + hash(frame) * 0.031) * horizontalBars * 0.38);\n float r2 = floor((uv.y + hash(frame + 2.0) * 0.013) * horizontalBars);\n float r3 = floor((uv.y + hash(frame + 7.0) * 0.006) * horizontalBars * 3.4);\n\n float thick = stripeY(uv, horizontalBars * 0.38, frame + 1.0, 0.035, 0.22);\n float mid = stripeY(uv, horizontalBars, frame + 4.0, 0.014, 0.11);\n float hair = stripeY(uv, horizontalBars * 3.4, frame + 9.0, 0.004, 0.035);\n\n thick *= step(0.42, hash(vec2(r1, frame + 10.0)));\n mid *= step(0.48, hash(vec2(r2, frame + 20.0)));\n hair *= step(0.62, hash(vec2(r3, frame + 30.0)));\n\n thick *= brokenGate(uv, r1, hash(vec2(r1, frame)), frame);\n mid *= brokenGate(uv, r2, hash(vec2(r2, frame)), frame + 3.0);\n\n return sat(max(thick, max(mid, hair)));\n}\n\nfloat verticalMask(vec2 uv, float frame) {\n float col = floor((uv.x + hash(frame + 12.0) * 0.017) * verticalSlits);\n float slit = stripeX(uv, verticalSlits, frame + 13.0, 0.01, 0.075);\n slit *= step(0.66, hash(vec2(col, frame + 19.0)));\n return sat(slit);\n}\n\nvec4 chromaFrom(vec2 uv, vec2 s) {\n uv = safeUv(uv);\n return vec4(\n getFromColor(safeUv(uv + s)).r,\n getFromColor(uv).g,\n getFromColor(safeUv(uv - s)).b,\n 1.0\n );\n}\n\nvec4 chromaTo(vec2 uv, vec2 s) {\n uv = safeUv(uv);\n return vec4(\n getToColor(safeUv(uv - s)).r,\n getToColor(uv).g,\n getToColor(safeUv(uv + s)).b,\n 1.0\n );\n}\n\nvec2 distortUv(vec2 uv, float dir, float b, float h, float v, float frame) {\n float row = floor(uv.y * horizontalBars);\n float col = floor(uv.x * verticalSlits);\n\n float rowRnd = hash(vec2(row, frame));\n float colRnd = hash(vec2(col, frame + 27.0));\n\n float xTear = (rowRnd - 0.5) * 2.0 * tear * b * h;\n xTear += sin(uv.y * 120.0 + progress * 95.0) * 0.006 * b;\n\n float yDrag = (colRnd - 0.5) * 0.13 * b * v;\n float micro = (hash(vec2(row, col + frame)) - 0.5) * 0.018 * b * max(h, v);\n\n return uv + vec2(xTear * dir + micro, yDrag);\n}\n\nvec4 transition(vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n\n float b = burst();\n float frame = floor(progress * 30.0);\n\n float h = horizontalMask(uv, frame);\n float v = verticalMask(uv, frame);\n float glitch = sat(max(h, v * 0.75));\n\n float row = floor(uv.y * horizontalBars);\n float rowRnd = hash(vec2(row, frame + 5.0));\n\n float bandDelay = (rowRnd - 0.5) * 0.30 * h;\n float reveal = smoothstep(0.18, 0.84, progress + bandDelay);\n\n vec2 split = vec2(chroma * b * (1.0 + 1.7 * glitch), chroma * 0.22 * b * v);\n\n vec2 fromUv = distortUv(uv, 1.0, b, h, v, frame);\n vec2 toUv = distortUv(uv, -1.0, b, h, v, frame);\n\n vec4 color = mix(\n chromaFrom(fromUv, split),\n chromaTo(toUv, split),\n reveal\n );\n\n // Horizontal time-slice residue: old/new frames dragged through uneven scan bands.\n vec2 smearUv = uv;\n smearUv.x += (rowRnd - 0.5) * 0.46 * b * h;\n smearUv.y += (hash(vec2(row, frame + 31.0)) - 0.5) * 0.045 * b * h;\n\n float sliceReveal = smoothstep(0.28, 0.78, progress + (rowRnd - 0.5) * 0.22);\n vec4 sliceColor = mix(\n chromaFrom(smearUv, split * 1.65),\n chromaTo(smearUv - vec2((rowRnd - 0.5) * 0.18 * b, 0.0), split * 1.65),\n sliceReveal\n );\n\n color = mix(color, sliceColor, h * b * residue);\n\n // Thin scan sparks and broken white lines, like the reference clip's bright horizontal noise.\n float hairLine = stripeY(uv, 190.0, frame + 55.0, 0.002, 0.012);\n hairLine *= step(0.70, hash(vec2(floor(uv.y * 190.0), frame + 56.0)));\n color.rgb += vec3(0.72, 0.90, 1.0) * hairLine * b * 0.28;\n\n float scan = 0.5 + 0.5 * sin(uv.y * 980.0 + progress * 130.0);\n color.rgb *= 1.0 - scanAmount * b * scan;\n\n vec2 nCell = floor(uv * vec2(360.0 * ratio, 210.0));\n float n = hash(nCell + vec2(frame * 7.0, frame * 13.0));\n color.rgb += (n - 0.5) * noiseAmount * b * (0.55 + glitch);\n\n // Slight desaturation during the damage peak makes it feel more like broadcast/video signal corruption.\n float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));\n color.rgb = mix(color.rgb, vec3(luma), 0.18 * b * glitch);\n\n float strobe = step(0.78, hash(vec2(frame, 3.14))) * pow(b, 1.65);\n color.rgb += vec3(strobe * flashAmount);\n\n return vec4(clamp(color.rgb, vec3(0.0), vec3(1.0)), 1.0);\n}\n","author":"bread","license":"MIT","description":"A datamosh glitch: torn strips, chroma shifts and scan noise drag the outgoing image into the incoming one","tags":["glitch","datamosh","chromatic"],"params":{"strength":{"type":"float","default":1},"horizontalBars":{"type":"float","default":42},"verticalSlits":{"type":"float","default":18},"tear":{"type":"float","default":0.18},"chroma":{"type":"float","default":0.032},"residue":{"type":"float","default":0.62},"noiseAmount":{"type":"float","default":0.16},"scanAmount":{"type":"float","default":0.13},"flashAmount":{"type":"float","default":0.2}},"textures":[],"createdAt":"Fri, 12 Jun 2026 15:15:42 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"Swirl","paramsTypes":{},"defaultParams":{},"glsl":"// License: MIT\n// Author: Sergey Kosarevsky\n// Description: Both images swirl around the center while crossfading\n// Tags: swirl, rotate, blend\n// ( http://www.linderdaum.com )\n// ported by gre from https://gist.github.com/corporateshark/cacfedb8cca0f5ce3f7c\n\nvec4 transition(vec2 UV)\n{\n\tfloat Radius = 1.0;\n\n\tfloat T = progress;\n\n\tUV -= vec2( 0.5, 0.5 );\n\n\tfloat Dist = length(UV);\n\n\tif ( Dist < Radius )\n\t{\n\t\tfloat Percent = (Radius - Dist) / Radius;\n\t\tfloat A = ( T <= 0.5 ) ? mix( 0.0, 1.0, T/0.5 ) : mix( 1.0, 0.0, (T-0.5)/0.5 );\n\t\tfloat Theta = Percent * Percent * A * 8.0 * 3.14159;\n\t\tfloat S = sin( Theta );\n\t\tfloat C = cos( Theta );\n\t\tUV = vec2( dot(UV, vec2(C, -S)), dot(UV, vec2(S, C)) );\n\t}\n\tUV += vec2( 0.5, 0.5 );\n\n\tvec4 C0 = getFromColor(UV);\n\tvec4 C1 = getToColor(UV);\n\n\treturn mix( C0, C1, T );\n}\n","author":"Sergey Kosarevsky","license":"MIT","description":"Both images swirl around the center while crossfading","tags":["swirl","rotate","blend"],"params":{},"textures":[],"createdAt":"Mon, 12 Jun 2017 12:38:27 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"TVStatic","paramsTypes":{"offset":"float"},"defaultParams":{"offset":0.05},"glsl":"// Author: Brandon Anzaldi\n// License: MIT\n// Description: Cuts to full-screen TV static, then to the incoming image\n// Tags: static, noise, retro\n// @param Part of the transition, at each end, that shows the images instead of static\nuniform float offset; // = 0.05\n\n// Pseudo-random noise function\n// http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/\nhighp float noise(vec2 co)\n{\n highp float a = 12.9898;\n highp float b = 78.233;\n highp float c = 43758.5453;\n highp float dt= dot(co.xy * progress, vec2(a, b));\n highp float sn= mod(dt,3.14);\n return fract(sin(sn) * c);\n}\n\nvec4 transition(vec2 p) {\n if (progress < offset) {\n return getFromColor(p);\n } else if (progress > (1.0 - offset)) {\n return getToColor(p);\n } else {\n return vec4(vec3(noise(p)), 1.0);\n }\n}\n","author":"Brandon Anzaldi","license":"MIT","description":"Cuts to full-screen TV static, then to the incoming image","tags":["static","noise","retro"],"params":{"offset":{"type":"float","default":0.05,"description":"Part of the transition, at each end, that shows the images instead of static"}},"textures":[],"createdAt":"Fri, 22 Mar 2019 11:53:09 -0700","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"TilesWave","paramsTypes":{"tileCount":"ivec2","flipX":"bool","flipY":"bool"},"defaultParams":{"tileCount":[8,8],"flipX":true,"flipY":false},"glsl":"// Author: numb3r23\n// License: MIT\n// Description: The incoming image is revealed tile by tile in a diagonal wave\n// Tags: tiles, wave, wipe\n// Ported from https://gist.github.com/numb3r23/169781bb76f310e2bfde\n\n// @param Number of tiles (columns, rows)\nuniform ivec2 tileCount; // = ivec2(8, 8)\nuniform bool flipX; // = true\nuniform bool flipY; // = false\n\nvec4 transition(vec2 uv) {\n vec2 tileSize = 1.0 / vec2(tileCount);\n vec2 posInTile = fract(uv * vec2(tileCount));\n vec2 tileNum = floor(uv * vec2(tileCount));\n float countTiles = float(tileCount.x * tileCount.y);\n\n // Diagonal wave from bottom-left to top-right\n float offset = (tileNum.y + tileNum.x * float(tileCount.y)) / countTiles;\n float timeOffset = clamp((progress - offset) * countTiles, 0.0, 0.5);\n float sinTime = 1.0 - abs(cos(fract(timeOffset) * 3.1415926));\n\n vec2 texC = posInTile;\n\n if (sinTime <= 0.5) {\n if (flipX) {\n if (texC.x < sinTime || texC.x > 1.0 - sinTime)\n return getFromColor(uv);\n texC.x = texC.x < 0.5\n ? (texC.x - sinTime) * 0.5 / (0.5 - sinTime)\n : (texC.x - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;\n }\n if (flipY) {\n if (texC.y < sinTime || texC.y > 1.0 - sinTime)\n return getFromColor(uv);\n texC.y = texC.y < 0.5\n ? (texC.y - sinTime) * 0.5 / (0.5 - sinTime)\n : (texC.y - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;\n }\n vec2 globalUV = tileNum * tileSize + texC * tileSize;\n return getFromColor(globalUV);\n } else {\n if (flipX) {\n if (texC.x > sinTime || texC.x < 1.0 - sinTime)\n return getToColor(uv);\n texC.x = texC.x < 0.5\n ? (texC.x - sinTime) * 0.5 / (0.5 - sinTime)\n : (texC.x - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;\n texC.x = 1.0 - texC.x;\n }\n if (flipY) {\n if (texC.y > sinTime || texC.y < 1.0 - sinTime)\n return getToColor(uv);\n texC.y = texC.y < 0.5\n ? (texC.y - sinTime) * 0.5 / (0.5 - sinTime)\n : (texC.y - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;\n texC.y = 1.0 - texC.y;\n }\n vec2 globalUV = tileNum * tileSize + texC * tileSize;\n return getToColor(globalUV);\n }\n}\n","author":"numb3r23","license":"MIT","description":"The incoming image is revealed tile by tile in a diagonal wave","tags":["tiles","wave","wipe"],"params":{"tileCount":{"type":"ivec2","default":[8,8],"description":"Number of tiles (columns, rows)"},"flipX":{"type":"bool","default":true},"flipY":{"type":"bool","default":false}},"textures":[],"createdAt":"Sun, 29 Mar 2026 20:32:54 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"TopBottom","paramsTypes":{},"defaultParams":{},"glsl":"// Author: zhmy\n// License: MIT\n// Description: The outgoing image shrinks away upward while the incoming one slides in from the bottom\n// Tags: slide, zoom, vertical\n\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n vec2 spfr,spto = vec2(-1.);\n float size = mix(1.0, 3.0, progress*0.2);\n spto = (uv + vec2(-0.5,-0.5))*vec2(size,size)+vec2(0.5,0.5);\n spfr = (uv + vec2(0.0, 1.0 - progress));\n if(inBounds(spfr)){\n return getToColor(spfr);\n } else if(inBounds(spto)){\n return getFromColor(spto) * (1.0 - progress);\n } else{\n return black;\n }\n}","author":"zhmy","license":"MIT","description":"The outgoing image shrinks away upward while the incoming one slides in from the bottom","tags":["slide","zoom","vertical"],"params":{},"textures":[],"createdAt":"Thu, 17 Dec 2020 11:50:34 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"VerticalClose","paramsTypes":{},"defaultParams":{},"glsl":"// Author: martiniti\n// License: MIT\n// Description: The incoming image closes in from the left and right edges toward the middle\n// Tags: wipe, split\n\nvec4 transition (vec2 uv) {\n\n float s = 2.0 - abs((uv.x - 0.5) / (progress - 1.0)) - 2.0 * progress;\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n smoothstep(0.5, 0.0, s)\n );\n}\n","author":"martiniti","license":"MIT","description":"The incoming image closes in from the left and right edges toward the middle","tags":["wipe","split"],"params":{},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:35:17 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"VerticalOpen","paramsTypes":{},"defaultParams":{},"glsl":"// Author: martiniti\n// License: MIT\n// Description: The incoming image opens from a line in the middle toward the left and right edges\n// Tags: wipe, split\n\nvec4 transition (vec2 uv) {\n\n float regress = 1.0 - progress;\n float s = 2.0 - abs((uv.x - 0.5) / (regress - 1.0)) - 2.0 * regress;\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n smoothstep(0.0, 0.5, s)\n );\n}\n","author":"martiniti","license":"MIT","description":"The incoming image opens from a line in the middle toward the left and right edges","tags":["wipe","split"],"params":{},"textures":[],"createdAt":"Tue, 4 Apr 2023 10:35:12 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"WaterDrop","paramsTypes":{"amplitude":"float","speed":"float"},"defaultParams":{"amplitude":30,"speed":30},"glsl":"// Author: Paweł Płóciennik\n// License: MIT\n// Description: Ripples spread from the center like a drop falling into water, crossfading to the incoming image\n// Tags: ripple, water, blend\n// @param Frequency of the ripples\nuniform float amplitude; // = 30\n// @param Speed of the ripples\nuniform float speed; // = 30\n\nvec4 transition(vec2 p) {\n vec2 dir = p - vec2(.5);\n float dist = length(dir);\n\n if (dist > progress) {\n return mix(getFromColor( p), getToColor( p), progress);\n } else {\n vec2 offset = dir * sin(dist * amplitude - progress * speed);\n return mix(getFromColor( p + offset), getToColor( p), progress);\n }\n}\n","author":"Paweł Płóciennik","license":"MIT","description":"Ripples spread from the center like a drop falling into water, crossfading to the incoming image","tags":["ripple","water","blend"],"params":{"amplitude":{"type":"float","default":30,"description":"Frequency of the ripples"},"speed":{"type":"float","default":30,"description":"Speed of the ripples"}},"textures":[],"createdAt":"Wed, 21 Feb 2018 19:37:15 +0100","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"ZoomInCircles","paramsTypes":{},"defaultParams":{},"glsl":"// License: MIT\n// Author: dycm8009\n// Description: Concentric rings of the outgoing image zoom at different speeds before revealing the incoming one\n// Tags: zoom, circle\n// ported by gre from https://gist.github.com/dycm8009/948e99b1800e81ad909a\n\nvec2 zoom(vec2 uv, float amount) {\n return 0.5 + ((uv - 0.5) * amount);\t\n}\n\nvec4 transition(vec2 uv) {\n vec2 ratio2 = vec2(1.0, 1.0 / ratio);\n // TODO: some timing are hardcoded but should be one or many parameters\n // TODO: should also be able to configure how much circles\n // TODO: if() branching should be avoided when possible, prefer use of step() & other functions\n vec2 r = 2.0 * ((vec2(uv.xy) - 0.5) * ratio2);\n float pro = progress / 0.8;\n float z = pro * 0.2;\n float t = 0.0;\n if (pro > 1.0) {\n z = 0.2 + (pro - 1.0) * 5.;\n t = clamp((progress - 0.8) / 0.07, 0.0, 1.0);\n }\n if (length(r) < 0.5+z) {\n // uv = zoom(uv, 0.9 - 0.1 * pro);\n }\n else if (length(r) < 0.8+z*1.5) {\n uv = zoom(uv, 1.0 - 0.15 * pro);\n t = t * 0.5;\n }\n else if (length(r) < 1.2+z*2.5) {\n uv = zoom(uv, 1.0 - 0.2 * pro);\n t = t * 0.2;\n }\n else {\n uv = zoom(uv, 1.0 - 0.25 * pro);\n }\n return mix(getFromColor(uv), getToColor(uv), t);\n}\n","author":"dycm8009","license":"MIT","description":"Concentric rings of the outgoing image zoom at different speeds before revealing the incoming one","tags":["zoom","circle"],"params":{},"textures":[],"createdAt":"Mon, 12 Jun 2017 11:24:34 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"ZoomLeftWipe","paramsTypes":{"zoom_quickness":"float"},"defaultParams":{"zoom_quickness":0.8},"glsl":"// Author: Handk\n// License: MIT\n// Description: Zooms into the outgoing image, then the incoming one wipes in from right to left\n// Tags: zoom, wipe, horizontal\n\n// @param Part of the first half spent zooming (capped at 0.5)\nuniform float zoom_quickness; // = 0.8\nvec2 zoom(vec2 uv, float amount) {\n if(amount<0.5)\n return 0.5 + ((uv - 0.5) * (1.0-amount));\n else\n return 0.5 + ((uv - 0.5) * (amount));\n \n}\n\nvec4 transition (vec2 uv) {\n float nQuick = clamp(zoom_quickness,0.0,0.5);\n if(progress<0.5){\n vec4 c= mix(\n getFromColor(zoom(uv, smoothstep(0.0, nQuick, progress))),\n getToColor(uv),\n step(0.5, progress)\n );\n \n return c;\n }\n else{\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 d=getFromColor(p);\n vec4 e=getToColor(p);\n vec4 f= mix(d, e, step(1.0-p.x,(progress-0.5)*2.0));\n \n return f;\n }\n}\n","author":"Handk","license":"MIT","description":"Zooms into the outgoing image, then the incoming one wipes in from right to left","tags":["zoom","wipe","horizontal"],"params":{"zoom_quickness":{"type":"float","default":0.8,"description":"Part of the first half spent zooming (capped at 0.5)"}},"textures":[],"createdAt":"Tue, 15 Mar 2022 21:20:28 +0900","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"ZoomRigthWipe","paramsTypes":{"zoom_quickness":"float"},"defaultParams":{"zoom_quickness":0.8},"glsl":"// Author: Handk\n// License: MIT\n// Description: Zooms into the outgoing image, then the incoming one wipes in from left to right\n// Tags: zoom, wipe, horizontal\n\n// @param Part of the first half spent zooming (capped at 0.5)\nuniform float zoom_quickness; // = 0.8\nvec2 zoom(vec2 uv, float amount) {\n if(amount<0.5)\n return 0.5 + ((uv - 0.5) * (1.0-amount));\n else\n return 0.5 + ((uv - 0.5) * (amount));\n \n}\n\nvec4 transition (vec2 uv) {\n float nQuick = clamp(zoom_quickness,0.0,0.5);\n if(progress<0.5){\n vec4 c= mix(\n getFromColor(zoom(uv, smoothstep(0.0, nQuick, progress))),\n getToColor(uv),\n step(0.5, progress)\n );\n \n return c;\n }\n else{\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 d=getFromColor(p);\n vec4 e=getToColor(p);\n vec4 f= mix(d, e, step(0.0+p.x,(progress-0.5)*2.0));\n \n return f;\n }\n}\n","author":"Handk","license":"MIT","description":"Zooms into the outgoing image, then the incoming one wipes in from left to right","tags":["zoom","wipe","horizontal"],"params":{"zoom_quickness":{"type":"float","default":0.8,"description":"Part of the first half spent zooming (capped at 0.5)"}},"textures":[],"createdAt":"Tue, 15 Mar 2022 21:20:28 +0900","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"angular","paramsTypes":{"startingAngle":"float"},"defaultParams":{"startingAngle":90},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: A wipe that sweeps around the center from a starting angle\n// Tags: wipe, radial, clock\n\n#define PI 3.141592653589\n\n// @range(0, 360) Angle where the wipe starts, in degrees\nuniform float startingAngle; // = 90\n\nvec4 transition (vec2 uv) {\n \n float offset = startingAngle * PI / 180.0;\n float angle = atan(uv.y - 0.5, uv.x - 0.5) + offset;\n float normalizedAngle = (angle + PI) / (2.0 * PI);\n \n normalizedAngle = normalizedAngle - floor(normalizedAngle);\n\n return mix(\n getFromColor(uv),\n getToColor(uv),\n step(normalizedAngle, progress)\n );\n}\n","author":"Fernando Kuteken","license":"MIT","description":"A wipe that sweeps around the center from a starting angle","tags":["wipe","radial","clock"],"params":{"startingAngle":{"type":"float","default":90,"min":0,"max":360,"description":"Angle where the wipe starts, in degrees"}},"textures":[],"createdAt":"Sun, 28 May 2017 18:30:24 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"burn","paramsTypes":{"color":"vec3"},"defaultParams":{"color":[0.9,0.4,0.2]},"glsl":"// Author: gre\n// License: MIT\n// Description: A crossfade that brightens toward a color in the middle\n// Tags: fade, color, flash\n// @color Color the images brighten toward\nuniform vec3 color /* = vec3(0.9, 0.4, 0.2) */;\nvec4 transition (vec2 uv) {\n return mix(\n getFromColor(uv) + vec4(progress*color, 1.0),\n getToColor(uv) + vec4((1.0-progress)*color, 1.0),\n progress\n );\n}\n","author":"gre","license":"MIT","description":"A crossfade that brightens toward a color in the middle","tags":["fade","color","flash"],"params":{"color":{"type":"vec3","default":[0.9,0.4,0.2],"color":true,"description":"Color the images brighten toward"}},"textures":[],"createdAt":"Sat, 20 May 2017 19:28:26 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"burn0","paramsTypes":{"burnColor":"vec3"},"defaultParams":{"burnColor":[1,0.5,0]},"glsl":"// Author: liubailin2020@gmail.com\n// License: MIT\n// Description: The outgoing image burns away in noisy, glowing patches\n// Tags: burn, fire, noise\n\n// @color Color of the burning edges\nuniform vec3 burnColor; // = vec3(1.0, 0.5, 0.0)\n\nfloat random (in vec2 st) {\n return fract(sin(dot(st.xy,\n vec2(12.9898,78.233)))*\n 43758.5453123);\n}\n\n// Based on Morgan McGuire @morgan3d\n// https://www.shadertoy.com/view/4dS3Wd\nfloat noise (in vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n\n float a = random(i);\n float b = random(i + vec2(1.0, 0.0));\n float c = random(i + vec2(0.0, 1.0));\n float d = random(i + vec2(1.0, 1.0));\n\n vec2 u = f * f * (3.0 - 2.0 * f);\n\n return mix(a, b, u.x) +\n (c - a)* u.y * (1.0 - u.x) +\n (d - b) * u.x * u.y;\n}\n\n#define OCTAVES 4\nfloat fbm (in vec2 st) {\n float value = 0.0;\n float amplitude = .5;\n for (int i = 0; i < OCTAVES; i++) {\n value += amplitude * noise(st);\n st *= 2.;\n amplitude *= .5;\n }\n return value;\n}\n\nvec4 transition (vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n vec4 from = getFromColor(uv);\n vec4 to = getToColor(uv);\n float n = fbm(uv * 4.);\n float l = smoothstep(progress, progress + 0.05, n);\n float edge = (1.0 - l) * l * 5.0;\n return mix(to, from, l) + vec4(burnColor, 0.0) * edge;\n}\n","author":"liubailin2020@gmail.com","license":"MIT","description":"The outgoing image burns away in noisy, glowing patches","tags":["burn","fire","noise"],"params":{"burnColor":{"type":"vec3","default":[1,0.5,0],"color":true,"description":"Color of the burning edges"}},"textures":[],"createdAt":"Thu, 4 Jul 2024 14:49:27 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"cannabisleaf","paramsTypes":{},"defaultParams":{},"glsl":"// Author: @Flexi23\n// License: MIT\n// Description: A cannabis-leaf shape grows from the center to reveal the incoming image\n// Tags: shape, wipe\n\n// inspired by http://www.wolframalpha.com/input/?i=cannabis+curve\n\nvec4 transition (vec2 uv) {\n if(progress == 0.0){\n return getFromColor(uv);\n }\n vec2 leaf_uv = (uv - vec2(0.5))/10./pow(progress,3.5);\n\tleaf_uv.y += 0.35;\n\tfloat r = 0.18;\n\tfloat o = atan(leaf_uv.y, leaf_uv.x);\n return mix(getFromColor(uv), getToColor(uv), 1.-step(1. - length(leaf_uv)+r*(1.+sin(o))*(1.+0.9 * cos(8.*o))*(1.+0.1*cos(24.*o))*(0.9+0.05*cos(200.*o)), 1.));\n}\n","author":"@Flexi23","license":"MIT","description":"A cannabis-leaf shape grows from the center to reveal the incoming image","tags":["shape","wipe"],"params":{},"textures":[],"createdAt":"Thu, 1 Jun 2017 15:58:58 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"chessboard","paramsTypes":{"grid_num":"float"},"defaultParams":{"grid_num":10},"glsl":"// Author: lql\n// License: MIT\n// Description: A chessboard pattern of squares reveals the incoming image\n// Tags: grid, squares, pattern\n\n// @param Number of squares per row\nuniform float grid_num; // = 10.0\n\nvec4 transition(vec2 uv) {\n vec2 st = uv * grid_num;\n vec2 idx = floor(st);\n vec2 grid = fract(st);\n\n vec4 a = getFromColor(uv);\n vec4 b = getToColor(uv);\n\n float checker = mod(idx.x + idx.y, 2.0);\n float mixFactor;\n\n if (progress <= 0.5) {\n mixFactor = (checker > 0.5) ? step(grid.x, progress * 2.0) : 0.0;\n } else {\n mixFactor = (checker < 0.5) ? step(grid.x, (progress - 0.5) * 2.0) : 1.0;\n }\n\n return mix(a, b, mixFactor);\n}\n","author":"lql","license":"MIT","description":"A chessboard pattern of squares reveals the incoming image","tags":["grid","squares","pattern"],"params":{"grid_num":{"type":"float","default":10,"description":"Number of squares per row"}},"textures":[],"createdAt":"Mon, 22 Jan 2024 22:35:57 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"circle","paramsTypes":{"center":"vec2","backColor":"vec3"},"defaultParams":{"center":[0.5,0.5],"backColor":[0.1,0.1,0.1]},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: The outgoing image closes into a circle over a background color, then the incoming one opens from it\n// Tags: circle, iris, shape\n\n// @param Center of the circle\nuniform vec2 center; // = vec2(0.5, 0.5)\n// @color Background color\nuniform vec3 backColor; // = vec3(0.1, 0.1, 0.1)\n\nvec4 transition (vec2 uv) {\n \n float distance = length(uv - center);\n float radius = sqrt(8.0) * abs(progress - 0.5);\n \n if (distance > radius) {\n return vec4(backColor, 1.0);\n }\n else {\n if (progress < 0.5) return getFromColor(uv);\n else return getToColor(uv);\n }\n}\n","author":"Fernando Kuteken","license":"MIT","description":"The outgoing image closes into a circle over a background color, then the incoming one opens from it","tags":["circle","iris","shape"],"params":{"center":{"type":"vec2","default":[0.5,0.5],"description":"Center of the circle"},"backColor":{"type":"vec3","default":[0.1,0.1,0.1],"color":true,"description":"Background color"}},"textures":[],"createdAt":"Sun, 28 May 2017 18:00:31 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"circleopen","paramsTypes":{"smoothness":"float","opening":"bool"},"defaultParams":{"smoothness":0.3,"opening":true},"glsl":"// Author: gre\n// License: MIT\n// Description: A soft-edged circle opens from the center to reveal the incoming image\n// Tags: circle, iris, wipe\n// @param Softness of the circle's edge\nuniform float smoothness; // = 0.3\n// @param Open the circle; false closes it instead\nuniform bool opening; // = true\n\nconst vec2 center = vec2(0.5, 0.5);\nconst float SQRT_2 = 1.414213562373;\n\nvec4 transition (vec2 uv) {\n float x = opening ? progress : 1.-progress;\n float m = smoothstep(-smoothness, 0.0, SQRT_2*distance(center, uv) - x*(1.+smoothness));\n return mix(getFromColor(uv), getToColor(uv), opening ? 1.-m : m);\n}\n","author":"gre","license":"MIT","description":"A soft-edged circle opens from the center to reveal the incoming image","tags":["circle","iris","wipe"],"params":{"smoothness":{"type":"float","default":0.3,"description":"Softness of the circle's edge"},"opening":{"type":"bool","default":true,"description":"Open the circle; false closes it instead"}},"textures":[],"createdAt":"Sat, 20 May 2017 19:28:26 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"colorphase","paramsTypes":{"fromStep":"vec4","toStep":"vec4"},"defaultParams":{"fromStep":[0,0.2,0.4,0],"toStep":[0.6,0.8,1,1]},"glsl":"// Author: gre\n// License: MIT\n// Description: A crossfade in which each color channel changes at a different time\n// Tags: fade, color\n\n// Usage: fromStep and toStep must be in [0.0, 1.0] range \n// and all(fromStep) must be < all(toStep)\n\n// @range(0, 1) When each channel (r, g, b, a) starts changing\nuniform vec4 fromStep; // = vec4(0.0, 0.2, 0.4, 0.0)\n// @range(0, 1) When each channel (r, g, b, a) finishes changing\nuniform vec4 toStep; // = vec4(0.6, 0.8, 1.0, 1.0)\n\nvec4 transition (vec2 uv) {\n vec4 a = getFromColor(uv);\n vec4 b = getToColor(uv);\n return mix(a, b, smoothstep(fromStep, toStep, vec4(progress)));\n}\n","author":"gre","license":"MIT","description":"A crossfade in which each color channel changes at a different time","tags":["fade","color"],"params":{"fromStep":{"type":"vec4","default":[0,0.2,0.4,0],"min":0,"max":1,"description":"When each channel (r, g, b, a) starts changing"},"toStep":{"type":"vec4","default":[0.6,0.8,1,1],"min":0,"max":1,"description":"When each channel (r, g, b, a) finishes changing"}},"textures":[],"createdAt":"Sat, 27 May 2017 14:09:58 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"coord-from-in","paramsTypes":{},"defaultParams":{},"glsl":"// Author: haiyoucuv\n// License: MIT\n// Description: A crossfade in which the colors of one image displace the other\n// Tags: displace, distort, blend\n\nvec4 transition (vec2 uv) {\n\n vec4 coordTo = getToColor(uv);\n vec4 coordFrom = getFromColor(uv);\n\n return mix(\n getFromColor(mix(uv, coordTo.rg, progress)),\n getToColor(mix(coordFrom.rg, uv, progress)),\n progress\n );\n\n}\n","author":"haiyoucuv","license":"MIT","description":"A crossfade in which the colors of one image displace the other","tags":["displace","distort","blend"],"params":{},"textures":[],"createdAt":"Tue, 15 Mar 2022 20:22:47 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"crosshatch","paramsTypes":{"center":"vec2","threshold":"float","fadeEdge":"float"},"defaultParams":{"center":[0.5,0.5],"threshold":3,"fadeEdge":0.1},"glsl":"// License: MIT\n// Author: pthrasher\n// Description: The incoming image appears through a crosshatch of lines spreading from the center\n// Tags: pattern, lines, noise\n// adapted by gre from https://gist.github.com/pthrasher/04fd9a7de4012cbb03f6\n\n// @param Point the lines spread from\nuniform vec2 center; // = vec2(0.5)\nuniform float threshold; // = 3.0\nuniform float fadeEdge; // = 0.1\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\nvec4 transition(vec2 p) {\n float dist = distance(center, p) / threshold;\n float r = progress - min(rand(vec2(p.y, 0.0)), rand(vec2(0.0, p.x)));\n return mix(getFromColor(p), getToColor(p), mix(0.0, mix(step(dist, r), 1.0, smoothstep(1.0-fadeEdge, 1.0, progress)), smoothstep(0.0, fadeEdge, progress))); \n}\n","author":"pthrasher","license":"MIT","description":"The incoming image appears through a crosshatch of lines spreading from the center","tags":["pattern","lines","noise"],"params":{"center":{"type":"vec2","default":[0.5,0.5],"description":"Point the lines spread from"},"threshold":{"type":"float","default":3},"fadeEdge":{"type":"float","default":0.1}},"textures":[],"createdAt":"Mon, 12 Jun 2017 10:02:12 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"crosswarp","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Eke Péter <peterekepeter@gmail.com>\n// License: MIT\n// Description: The outgoing image zooms in while the incoming one zooms out into place, sweeping from right to left\n// Tags: warp, zoom, horizontal\nvec4 transition(vec2 p) {\n float x = progress;\n x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));\n return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);\n}\n","author":"Eke Péter <peterekepeter@gmail.com>","license":"MIT","description":"The outgoing image zooms in while the incoming one zooms out into place, sweeping from right to left","tags":["warp","zoom","horizontal"],"params":{},"textures":[],"createdAt":"Sat, 27 May 2017 00:19:45 +0300","updatedAt":"Fri, 9 Oct 2026 22:46:55 +0200"},{"name":"cube","paramsTypes":{"persp":"float","unzoom":"float","reflection":"float","floating":"float"},"defaultParams":{"persp":0.7,"unzoom":0.3,"reflection":0.4,"floating":3},"glsl":"// Author: gre\n// License: MIT\n// Description: The two images are faces of a rotating 3D cube, with a floor reflection\n// Tags: 3d, cube, rotate, reflection\n// @range(0, 1) Amount of perspective\nuniform float persp; // = 0.7\nuniform float unzoom; // = 0.3\n// @range(0, 1) Strength of the reflection\nuniform float reflection; // = 0.4\nuniform float floating; // = 3.0\n\nvec2 project (vec2 p) {\n return p * vec2(1.0, -1.2) + vec2(0.0, -floating/100.);\n}\n\nbool inBounds (vec2 p) {\n return all(lessThan(vec2(0.0), p)) && all(lessThan(p, vec2(1.0)));\n}\n\nvec4 bgColor (vec2 p, vec2 pfr, vec2 pto) {\n vec4 c = vec4(0.0, 0.0, 0.0, 1.0);\n pfr = project(pfr);\n // FIXME avoid branching might help perf!\n if (inBounds(pfr)) {\n c += mix(vec4(0.0), getFromColor(pfr), reflection * mix(1.0, 0.0, pfr.y));\n }\n pto = project(pto);\n if (inBounds(pto)) {\n c += mix(vec4(0.0), getToColor(pto), reflection * mix(1.0, 0.0, pto.y));\n }\n return c;\n}\n\n// p : the position\n// persp : the perspective in [ 0, 1 ]\n// center : the xcenter in [0, 1] \\ 0.5 excluded\nvec2 xskew (vec2 p, float persp, float center) {\n float x = mix(p.x, 1.0-p.x, center);\n return (\n (\n vec2( x, (p.y - 0.5*(1.0-persp) * x) / (1.0+(persp-1.0)*x) )\n - vec2(0.5-distance(center, 0.5), 0.0)\n )\n * vec2(0.5 / distance(center, 0.5) * (center<0.5 ? 1.0 : -1.0), 1.0)\n + vec2(center<0.5 ? 0.0 : 1.0, 0.0)\n );\n}\n\nvec4 transition(vec2 op) {\n float uz = unzoom * 2.0*(0.5-distance(0.5, progress));\n vec2 p = -uz*0.5+(1.0+uz) * op;\n vec2 fromP = xskew(\n (p - vec2(progress, 0.0)) / vec2(1.0-progress, 1.0),\n 1.0-mix(progress, 0.0, persp),\n 0.0\n );\n vec2 toP = xskew(\n p / vec2(progress, 1.0),\n mix(pow(progress, 2.0), 1.0, persp),\n 1.0\n );\n // FIXME avoid branching might help perf!\n if (inBounds(fromP)) {\n return getFromColor(fromP);\n }\n else if (inBounds(toP)) {\n return getToColor(toP);\n }\n return bgColor(op, fromP, toP);\n}\n","author":"gre","license":"MIT","description":"The two images are faces of a rotating 3D cube, with a floor reflection","tags":["3d","cube","rotate","reflection"],"params":{"persp":{"type":"float","default":0.7,"min":0,"max":1,"description":"Amount of perspective"},"unzoom":{"type":"float","default":0.3},"reflection":{"type":"float","default":0.4,"min":0,"max":1,"description":"Strength of the reflection"},"floating":{"type":"float","default":3}},"textures":[],"createdAt":"Sat, 27 May 2017 11:39:22 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"directional-easing","paramsTypes":{"direction":"vec2"},"defaultParams":{"direction":[0,1]},"glsl":"// Author: Max Plotnikov\n// License: MIT\n// Description: Like Directional, with an eased movement\n// Tags: slide, push, directional\n\n// @param Direction of the movement\nuniform vec2 direction; // = vec2(0.0, 1.0)\n\nvec4 transition (vec2 uv) {\n float easing = sqrt((2.0 - progress) * progress);\n vec2 p = uv + easing * sign(direction);\n vec2 f = fract(p);\n return mix(\n getToColor(f),\n getFromColor(f),\n step(0.0, p.y) * step(p.y, 1.0) * step(0.0, p.x) * step(p.x, 1.0)\n );\n}\n","author":"Max Plotnikov","license":"MIT","description":"Like Directional, with an eased movement","tags":["slide","push","directional"],"params":{"direction":{"type":"vec2","default":[0,1],"description":"Direction of the movement"}},"textures":[],"createdAt":"Wed, 23 Sep 2020 22:54:49 +0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"directionalwarp","paramsTypes":{"smoothness":"float","direction":"vec2"},"defaultParams":{"smoothness":0.1,"direction":[-1,1]},"glsl":"// Author: pschroen\n// License: MIT\n// Description: A diagonal wipe with a warped, smeared edge\n// Tags: wipe, warp, directional\n\n// @param Softness of the edge\nuniform float smoothness; // = 0.1\n// @param Direction of the wipe\nuniform vec2 direction; // = vec2(-1.0, 1.0)\n\nconst vec2 center = vec2(0.5, 0.5);\n\nvec4 transition (vec2 uv) {\n vec2 v = normalize(direction);\n v /= abs(v.x) + abs(v.y);\n float d = v.x * center.x + v.y * center.y;\n float m = 1.0 - smoothstep(-smoothness, 0.0, v.x * uv.x + v.y * uv.y - (d - 0.5 + progress * (1.0 + smoothness)));\n return mix(getFromColor((uv - 0.5) * (1.0 - m) + 0.5), getToColor((uv - 0.5) * m + 0.5), m);\n}\n","author":"pschroen","license":"MIT","description":"A diagonal wipe with a warped, smeared edge","tags":["wipe","warp","directional"],"params":{"smoothness":{"type":"float","default":0.1,"description":"Softness of the edge"},"direction":{"type":"vec2","default":[-1,1],"description":"Direction of the wipe"}},"textures":[],"createdAt":"Wed, 13 Dec 2017 12:08:49 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"directionalwipe","paramsTypes":{"direction":"vec2","smoothness":"float"},"defaultParams":{"direction":[1,-1],"smoothness":0.5},"glsl":"// Author: gre\n// License: MIT\n// Description: A soft-edged diagonal wipe\n// Tags: wipe, directional\n\n// @param Direction of the wipe\nuniform vec2 direction; // = vec2(1.0, -1.0)\n// @param Softness of the edge\nuniform float smoothness; // = 0.5\n \nconst vec2 center = vec2(0.5, 0.5);\n \nvec4 transition (vec2 uv) {\n vec2 v = normalize(direction);\n v /= abs(v.x)+abs(v.y);\n float d = v.x * center.x + v.y * center.y;\n float m =\n (1.0-step(progress, 0.0)) * // there is something wrong with our formula that makes m not equals 0.0 with progress is 0.0\n (1.0 - smoothstep(-smoothness, 0.0, v.x * uv.x + v.y * uv.y - (d-0.5+progress*(1.+smoothness))));\n return mix(getFromColor(uv), getToColor(uv), m);\n}\n","author":"gre","license":"MIT","description":"A soft-edged diagonal wipe","tags":["wipe","directional"],"params":{"direction":{"type":"vec2","default":[1,-1],"description":"Direction of the wipe"},"smoothness":{"type":"float","default":0.5,"description":"Softness of the edge"}},"textures":[],"createdAt":"Fri, 26 May 2017 10:41:57 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"displacement","paramsTypes":{"strength":"float"},"defaultParams":{"strength":0.5},"glsl":"// Author: Travis Fischer\n// License: MIT\n// Description: A crossfade in which a displacement map (an extra grayscale texture) warps both images\n// Tags: displace, distort, blend\n//\n// Adapted from a Codrops article by Robin Delaporte\n// https://tympanus.net/Development/DistortionHoverEffect\n\nuniform sampler2D displacementMap;\n\n// @param Strength of the displacement\nuniform float strength; // = 0.5\n\nvec4 transition (vec2 uv) {\n float displacement = texture2D(displacementMap, uv).r * strength;\n\n vec2 uvFrom = vec2(uv.x + progress * displacement, uv.y);\n vec2 uvTo = vec2(uv.x - (1.0 - progress) * displacement, uv.y);\n\n return mix(\n getFromColor(uvFrom),\n getToColor(uvTo),\n progress\n );\n}\n","author":"Travis Fischer","license":"MIT","description":"A crossfade in which a displacement map (an extra grayscale texture) warps both images","tags":["displace","distort","blend"],"params":{"strength":{"type":"float","default":0.5,"description":"Strength of the displacement"}},"textures":["displacementMap"],"createdAt":"Tue, 10 Apr 2018 23:03:38 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"dissolve","paramsTypes":{"uLineWidth":"float","uSpreadClr":"vec3","uHotClr":"vec3","uPow":"float","uIntensity":"float"},"defaultParams":{"uLineWidth":0.1,"uSpreadClr":[1,0,0],"uHotClr":[0.9,0.9,0.2],"uPow":5,"uIntensity":1},"glsl":"// Author: hjm1fb\n// License: MIT\n// Description: The incoming image spreads over the outgoing one with a hot, glowing edge\n// Tags: dissolve, burn, glow\n\nuniform float uLineWidth; // = 0.1\n// @color Color of the spreading edge\nuniform vec3 uSpreadClr; // = vec3(1.0, 0.0, 0.0)\n// @color Color of the hottest part of the edge\nuniform vec3 uHotClr; // = vec3(0.9, 0.9, 0.2)\nuniform float uPow; // = 5.0\nuniform float uIntensity; // = 1.0\n\nvec2 hash(vec2 p) // replace this by something better\n{\n p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)));\n return -1.0 + 2.0 * fract(sin(p) * 43758.5453123);\n}\n\nfloat noise(in vec2 p) {\n const float K1 = 0.366025404; // (sqrt(3)-1)/2;\n const float K2 = 0.211324865; // (3-sqrt(3))/6;\n\n vec2 i = floor(p + (p.x + p.y) * K1);\n vec2 a = p - i + (i.x + i.y) * K2;\n float m = step(a.y, a.x);\n vec2 o = vec2(m, 1.0 - m);\n vec2 b = a - o + K2;\n vec2 c = a - 1.0 + 2.0 * K2;\n vec3 h = max(0.5 - vec3(dot(a, a), dot(b, b), dot(c, c)), 0.0);\n vec3 n = h * h * h * h * vec3(dot(a, hash(i + 0.0)), dot(b, hash(i + o)), dot(c, hash(i + 1.0)));\n return dot(n, vec3(70.0));\n}\n\nvec4 transition(vec2 uv) {\n vec4 from = getFromColor(uv);\n vec4 to = getToColor(uv);\n vec4 outColor;\n float burn;\n burn = 0.5 + 0.5 * (0.299 * from.r + 0.587 * from.g + 0.114 * from.b);\n\n float show = burn - progress;\n if (show < 0.001) {\n outColor = to;\n } else {\n float factor = 1.0 - smoothstep(0.0, uLineWidth, show);\n vec3 burnColor = mix(uSpreadClr, uHotClr, factor);\n burnColor = pow(burnColor, vec3(uPow)) * uIntensity;\n vec3 finalRGB = mix(from.rgb, burnColor, factor * step(0.0001, progress));\n outColor = vec4(finalRGB * from.a, from.a);\n }\n return outColor;\n}\n","author":"hjm1fb","license":"MIT","description":"The incoming image spreads over the outgoing one with a hot, glowing edge","tags":["dissolve","burn","glow"],"params":{"uLineWidth":{"type":"float","default":0.1},"uSpreadClr":{"type":"vec3","default":[1,0,0],"color":true,"description":"Color of the spreading edge"},"uHotClr":{"type":"vec3","default":[0.9,0.9,0.2],"color":true,"description":"Color of the hottest part of the edge"},"uPow":{"type":"float","default":5},"uIntensity":{"type":"float","default":1}},"textures":[],"createdAt":"Fri, 2 Jun 2023 16:25:50 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"doorway","paramsTypes":{"reflection":"float","perspective":"float","depth":"float"},"defaultParams":{"reflection":0.4,"perspective":0.4,"depth":3},"glsl":"// Author: gre\n// License: MIT\n// Description: The outgoing image opens like double doors as the incoming one comes forward, with a floor reflection\n// Tags: doors, 3d, reflection\n// @param Strength of the reflection\nuniform float reflection; // = 0.4\n// @param Amount of perspective\nuniform float perspective; // = 0.4\nuniform float depth; // = 3\n\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec2 project (vec2 p) {\n return p * vec2(1.0, -1.2) + vec2(0.0, -0.02);\n}\n\nvec4 bgColor (vec2 p, vec2 pto) {\n vec4 c = black;\n pto = project(pto);\n if (inBounds(pto)) {\n c += mix(black, getToColor(pto), reflection * mix(1.0, 0.0, pto.y));\n }\n return c;\n}\n\n\nvec4 transition (vec2 p) {\n vec2 pfr = vec2(-1.), pto = vec2(-1.);\n float middleSlit = 2.0 * abs(p.x-0.5) - progress;\n if (middleSlit > 0.0) {\n pfr = p + (p.x > 0.5 ? -1.0 : 1.0) * vec2(0.5*progress, 0.0);\n float d = 1.0/(1.0+perspective*progress*(1.0-middleSlit));\n pfr.y -= d/2.;\n pfr.y *= d;\n pfr.y += d/2.;\n }\n float size = mix(1.0, depth, 1.-progress);\n pto = (p + vec2(-0.5, -0.5)) * vec2(size, size) + vec2(0.5, 0.5);\n if (inBounds(pfr)) {\n return getFromColor(pfr);\n }\n else if (inBounds(pto)) {\n return getToColor(pto);\n }\n else {\n return bgColor(p, pto);\n }\n}\n","author":"gre","license":"MIT","description":"The outgoing image opens like double doors as the incoming one comes forward, with a floor reflection","tags":["doors","3d","reflection"],"params":{"reflection":{"type":"float","default":0.4,"description":"Strength of the reflection"},"perspective":{"type":"float","default":0.4,"description":"Amount of perspective"},"depth":{"type":"float","default":3}},"textures":[],"createdAt":"Sat, 20 May 2017 19:28:26 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"fade","paramsTypes":{},"defaultParams":{},"glsl":"// Author: gre\n// License: MIT\n// Description: A linear crossfade between the two images\n// Tags: fade, blend\n\nvec4 transition (vec2 uv) {\n return mix(\n getFromColor(uv),\n getToColor(uv),\n progress\n );\n}\n","author":"gre","license":"MIT","description":"A linear crossfade between the two images","tags":["fade","blend"],"params":{},"textures":[],"createdAt":"Sat, 20 May 2017 19:28:26 +0200","updatedAt":"Fri, 9 Oct 2026 22:46:55 +0200"},{"name":"fadecolor","paramsTypes":{"color":"vec3","colorPhase":"float"},"defaultParams":{"color":[0,0,0],"colorPhase":0.4},"glsl":"// Author: gre\n// License: MIT\n// Description: A fade through a solid color, black by default\n// Tags: fade, color\n// @color Color to fade through\nuniform vec3 color;// = vec3(0.0)\n// @range(0, 1) How long the color shows in the middle\nuniform float colorPhase; // = 0.4 ; // if 0.0, there is no black phase, if 0.9, the black phase is very important\nvec4 transition (vec2 uv) {\n return mix(\n mix(vec4(color, 1.0), getFromColor(uv), smoothstep(1.0-colorPhase, 0.0, progress)),\n mix(vec4(color, 1.0), getToColor(uv), smoothstep( colorPhase, 1.0, progress)),\n progress);\n}\n","author":"gre","license":"MIT","description":"A fade through a solid color, black by default","tags":["fade","color"],"params":{"color":{"type":"vec3","default":[0,0,0],"color":true,"description":"Color to fade through"},"colorPhase":{"type":"float","default":0.4,"min":0,"max":1,"description":"How long the color shows in the middle"}},"textures":[],"createdAt":"Sat, 20 May 2017 19:28:26 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"fadegrayscale","paramsTypes":{"intensity":"float"},"defaultParams":{"intensity":0.3},"glsl":"// Author: gre\n// License: MIT\n// Description: A crossfade through grayscale\n// Tags: fade, grayscale, color\n\n// @range(0, 1) How long the grayscale phase lasts\nuniform float intensity; // = 0.3; // if 0.0, the image directly turn grayscale, if 0.9, the grayscale transition phase is very important\n \nvec3 grayscale (vec3 color) {\n return vec3(0.2126*color.r + 0.7152*color.g + 0.0722*color.b);\n}\n \nvec4 transition (vec2 uv) {\n vec4 fc = getFromColor(uv);\n vec4 tc = getToColor(uv);\n return mix(\n mix(vec4(grayscale(fc.rgb), 1.0), fc, smoothstep(1.0-intensity, 0.0, progress)),\n mix(vec4(grayscale(tc.rgb), 1.0), tc, smoothstep( intensity, 1.0, progress)),\n progress);\n}\n","author":"gre","license":"MIT","description":"A crossfade through grayscale","tags":["fade","grayscale","color"],"params":{"intensity":{"type":"float","default":0.3,"min":0,"max":1,"description":"How long the grayscale phase lasts"}},"textures":[],"createdAt":"Fri, 26 May 2017 09:52:33 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"flyeye","paramsTypes":{"size":"float","zoom":"float","colorSeparation":"float"},"defaultParams":{"size":0.04,"zoom":50,"colorSeparation":0.3},"glsl":"// Author: gre\n// License: MIT\n// Description: The image breaks into a fly's-eye grid of lenses with color separation\n// Tags: lens, distort, chromatic\nuniform float size; // = 0.04\nuniform float zoom; // = 50.0\nuniform float colorSeparation; // = 0.3\n\nvec4 transition(vec2 p) {\n float inv = 1. - progress;\n vec2 disp = size*vec2(cos(zoom*p.x), sin(zoom*p.y));\n vec4 texTo = getToColor(p + inv*disp);\n vec4 texFrom = vec4(\n getFromColor(p + progress*disp*(1.0 - colorSeparation)).r,\n getFromColor(p + progress*disp).g,\n getFromColor(p + progress*disp*(1.0 + colorSeparation)).b,\n 1.0);\n return texTo*progress + texFrom*inv;\n}\n","author":"gre","license":"MIT","description":"The image breaks into a fly's-eye grid of lenses with color separation","tags":["lens","distort","chromatic"],"params":{"size":{"type":"float","default":0.04},"zoom":{"type":"float","default":50},"colorSeparation":{"type":"float","default":0.3}},"textures":[],"createdAt":"Sat, 27 May 2017 11:34:46 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"fragment","paramsTypes":{},"defaultParams":{},"glsl":"// Author: lbl\n// License: MIT\n// Description: The outgoing image shatters into fragments that fly away\n// Tags: shatter, fragments\n\n#define POINTS 10\n\nfloat random(vec2 par) {\n return fract(sin(dot(par.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvec2 random2(vec2 par) {\n float rand = random(par);\n return vec2(rand, random(par + rand));\n}\n\nvec4 transition (vec2 uv) {\n if (progress <= 0.0) return getFromColor(uv);\n if (progress >= 1.0) return getToColor(uv);\n\n const float duration = 8.0;\n float time = progress * duration;\n vec2 point[POINTS];\n for (int i = 0; i < POINTS; i++) {\n point[i] = random2(vec2(float(i)));\n }\n\n vec4 col = getToColor(uv);\n\n for (int i = 0; i < POINTS; i++) {\n vec2 dir = normalize(random2(vec2(float(i), float(i) + 11.)));\n float v = (1.0 + random(dir) * 0.5) * 0.2;\n vec2 ofst = dir * clamp(time - 0.5, 0.0, duration) * v;\n vec2 U = uv - ofst;\n\n if (U.x < 0.0 || U.x > 1.0 || U.y < 0.0 || U.y > 1.0) continue;\n\n float dist_i = distance(U, point[i]);\n bool closest = true;\n for (int j = 0; j < POINTS; j++) {\n if (distance(U, point[j]) < dist_i) {\n closest = false;\n break;\n }\n }\n\n if (closest) {\n col = getFromColor(U);\n break;\n }\n }\n return col;\n}\n","author":"lbl","license":"MIT","description":"The outgoing image shatters into fragments that fly away","tags":["shatter","fragments"],"params":{},"textures":[],"createdAt":"Thu, 4 Jul 2024 15:10:28 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"heart","paramsTypes":{},"defaultParams":{},"glsl":"// Author: gre\n// License: MIT\n// Description: A heart shape grows from the center to reveal the incoming image\n// Tags: shape, wipe, heart\n\nfloat inHeart (vec2 p, vec2 center, float size) {\n if (size==0.0) return 0.0;\n vec2 o = (p-center)/(1.6*size);\n float a = o.x*o.x+o.y*o.y-0.3;\n return step(a*a*a, o.x*o.x*o.y*o.y*o.y);\n}\nvec4 transition (vec2 uv) {\n return mix(\n getFromColor(uv),\n getToColor(uv),\n inHeart(uv, vec2(0.5, 0.4), progress)\n );\n}\n","author":"gre","license":"MIT","description":"A heart shape grows from the center to reveal the incoming image","tags":["shape","wipe","heart"],"params":{},"textures":[],"createdAt":"Fri, 26 May 2017 12:22:53 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"hexagonalize","paramsTypes":{"steps":"int","horizontalHexagons":"float"},"defaultParams":{"steps":50,"horizontalHexagons":20},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: Both images turn into hexagons, crossfade, then sharpen again\n// Tags: pixelate, hexagon, blend\n// Hexagonal math from: http://www.redblobgames.com/grids/hexagons/\n\nuniform int steps; // = 50\n// @param Number of hexagons across\nuniform float horizontalHexagons; // = 20\n\nstruct Hexagon {\n float q;\n float r;\n float s;\n};\n\nHexagon createHexagon(float q, float r){\n Hexagon hex;\n hex.q = q;\n hex.r = r;\n hex.s = -q - r;\n return hex;\n}\n\nHexagon roundHexagon(Hexagon hex){\n \n float q = floor(hex.q + 0.5);\n float r = floor(hex.r + 0.5);\n float s = floor(hex.s + 0.5);\n\n float deltaQ = abs(q - hex.q);\n float deltaR = abs(r - hex.r);\n float deltaS = abs(s - hex.s);\n\n if (deltaQ > deltaR && deltaQ > deltaS)\n q = -r - s;\n else if (deltaR > deltaS)\n r = -q - s;\n else\n s = -q - r;\n\n return createHexagon(q, r);\n}\n\nHexagon hexagonFromPoint(vec2 point, float size) {\n \n point.y /= ratio;\n point = (point - 0.5) / size;\n \n float q = (sqrt(3.0) / 3.0) * point.x + (-1.0 / 3.0) * point.y;\n float r = 0.0 * point.x + 2.0 / 3.0 * point.y;\n\n Hexagon hex = createHexagon(q, r);\n return roundHexagon(hex);\n \n}\n\nvec2 pointFromHexagon(Hexagon hex, float size) {\n \n float x = (sqrt(3.0) * hex.q + (sqrt(3.0) / 2.0) * hex.r) * size + 0.5;\n float y = (0.0 * hex.q + (3.0 / 2.0) * hex.r) * size + 0.5;\n \n return vec2(x, y * ratio);\n}\n\nvec4 transition (vec2 uv) {\n \n float dist = 2.0 * min(progress, 1.0 - progress);\n dist = steps > 0 ? ceil(dist * float(steps)) / float(steps) : dist;\n \n float size = (sqrt(3.0) / 3.0) * dist / horizontalHexagons;\n \n vec2 point = dist > 0.0 ? pointFromHexagon(hexagonFromPoint(uv, size), size) : uv;\n\n return mix(getFromColor(point), getToColor(point), progress);\n \n}\n","author":"Fernando Kuteken","license":"MIT","description":"Both images turn into hexagons, crossfade, then sharpen again","tags":["pixelate","hexagon","blend"],"params":{"steps":{"type":"int","default":50},"horizontalHexagons":{"type":"float","default":20,"description":"Number of hexagons across"}},"textures":[],"createdAt":"Tue, 30 May 2017 21:55:47 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"kaleidoscope","paramsTypes":{"speed":"float","angle":"float","power":"float"},"defaultParams":{"speed":1,"angle":1,"power":1.5},"glsl":"// Author: nwoeanhinnogaehr\n// License: MIT\n// Description: A crossfade through a spinning kaleidoscope\n// Tags: kaleidoscope, distort, blend\n\nuniform float speed; // = 1.0\nuniform float angle; // = 1.0\nuniform float power; // = 1.5\n\nvec4 transition(vec2 uv) {\n vec2 p = uv.xy / vec2(1.0).xy;\n vec2 q = p;\n float t = pow(progress, power)*speed;\n p = p -0.5;\n for (int i = 0; i < 7; i++) {\n p = vec2(sin(t)*p.x + cos(t)*p.y, sin(t)*p.y - cos(t)*p.x);\n t += angle;\n p = abs(mod(p, 2.0) - 1.0);\n }\n abs(mod(p, 1.0));\n return mix(\n mix(getFromColor(q), getToColor(q), progress),\n mix(getFromColor(p), getToColor(p), progress), 1.0 - 2.0*abs(progress - 0.5));\n}\n","author":"nwoeanhinnogaehr","license":"MIT","description":"A crossfade through a spinning kaleidoscope","tags":["kaleidoscope","distort","blend"],"params":{"speed":{"type":"float","default":1},"angle":{"type":"float","default":1},"power":{"type":"float","default":1.5}},"textures":[],"createdAt":"Wed, 31 May 2017 21:48:26 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"luma","paramsTypes":{},"defaultParams":{},"glsl":"// Author: gre\n// License: MIT\n// Description: A wipe that follows the brightness of a grayscale mask (the luma texture)\n// Tags: wipe, luma, mask\n\nuniform sampler2D luma;\n\nvec4 transition(vec2 uv) {\n return mix(\n getToColor(uv),\n getFromColor(uv),\n step(progress, texture2D(luma, uv).r)\n );\n}\n","author":"gre","license":"MIT","description":"A wipe that follows the brightness of a grayscale mask (the luma texture)","tags":["wipe","luma","mask"],"params":{},"textures":["luma"],"createdAt":"Fri, 26 May 2017 21:30:20 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"luminance_melt","paramsTypes":{"direction":"bool","l_threshold":"float","above":"bool"},"defaultParams":{"direction":true,"l_threshold":0.8,"above":false},"glsl":"// Author: 0gust1\n// License: MIT\n// Description: The outgoing image melts away in noisy vertical streaks, depending on its brightness\n// Tags: melt, noise, luma\n//My own first transition — based on crosshatch code (from pthrasher), using simplex noise formula (copied and pasted)\n//-> cooler with high contrasted images (isolated dark subject on light background f.e.)\n//TODO : try to rebase it on DoomTransition (from zeh)?\n//optimizations :\n//luminance (see http://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color#answer-596241)\n// Y = (R+R+B+G+G+G)/6\n//or Y = (R+R+R+B+G+G+G+G)>>3 \n\n\n//direction of movement : 0 : up, 1, down\n// @param Direction of the melt (false: up, true: down)\nuniform bool direction; // = true\n//luminance threshold\n// @range(0, 1) Luminance threshold\nuniform float l_threshold; // = 0.8 \n//does the movement takes effect above or below luminance threshold ?\n// @param Melt the parts above the threshold instead of below\nuniform bool above; // = false \n\n\n//Random function borrowed from everywhere\nfloat rand(vec2 co){\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\n\n// Simplex noise :\n// Description : Array and textureless GLSL 2D simplex noise function.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : ijm\n// Lastmod : 20110822 (ijm)\n// License : MIT \n// 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// \n\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec3 permute(vec3 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat snoise(vec2 v)\n {\n const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0\n 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)\n -0.577350269189626, // -1.0 + 2.0 * C.x\n 0.024390243902439); // 1.0 / 41.0\n// First corner\n vec2 i = floor(v + dot(v, C.yy) );\n vec2 x0 = v - i + dot(i, C.xx);\n\n// Other corners\n vec2 i1;\n //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0\n //i1.y = 1.0 - i1.x;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n // x0 = x0 - 0.0 + 0.0 * C.xx ;\n // x1 = x0 - i1 + 1.0 * C.xx ;\n // x2 = x0 - 1.0 + 2.0 * C.xx ;\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n\n// Permutations\n i = mod289(i); // Avoid truncation effects in permutation\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))\n\t\t+ i.x + vec3(0.0, i1.x, 1.0 ));\n\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n m = m*m ;\n m = m*m ;\n\n// Gradients: 41 points uniformly over a line, mapped onto a diamond.\n// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n\n// Normalise gradients implicitly by scaling m\n// Approximation of: m *= inversesqrt( a0*a0 + h*h );\n m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );\n\n// Compute final noise value at P\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\n// Simplex noise -- end\n\nfloat luminance(vec4 color){\n //(0.299*R + 0.587*G + 0.114*B)\n return color.r*0.299+color.g*0.587+color.b*0.114;\n}\n\nvec4 transition(vec2 uv) {\n vec2 center = vec2(1.0, direction);\n vec2 p = uv.xy / vec2(1.0).xy;\n if (progress == 0.0) {\n return getFromColor(p);\n } else if (progress == 1.0) {\n return getToColor(p);\n } else {\n float x = progress;\n float dist = distance(center, p)- progress*exp(snoise(vec2(p.x, 0.0)));\n float r = x - rand(vec2(p.x, 0.1));\n float m;\n if(above){\n m = dist <= r && luminance(getFromColor(p))>l_threshold ? 1.0 : (progress*progress*progress);\n }\n else{\n m = dist <= r && luminance(getFromColor(p))<l_threshold ? 1.0 : (progress*progress*progress); \n }\n return mix(getFromColor(p), getToColor(p), m); \n }\n}\n","author":"0gust1","license":"MIT","description":"The outgoing image melts away in noisy vertical streaks, depending on its brightness","tags":["melt","noise","luma"],"params":{"direction":{"type":"bool","default":true,"description":"Direction of the melt (false: up, true: down)"},"l_threshold":{"type":"float","default":0.8,"min":0,"max":1,"description":"Luminance threshold"},"above":{"type":"bool","default":false,"description":"Melt the parts above the threshold instead of below"}},"textures":[],"createdAt":"Wed, 24 Jan 2018 19:02:32 +0100","updatedAt":"Sat, 10 Oct 2026 11:13:38 +0200"},{"name":"morph","paramsTypes":{"strength":"float"},"defaultParams":{"strength":0.1},"glsl":"// Author: paniq\n// License: MIT\n// Description: A crossfade in which each image is displaced by the other's colors, like a morph\n// Tags: morph, distort, blend\n// @param Strength of the displacement\nuniform float strength; // = 0.1\n\nvec4 transition(vec2 p) {\n vec4 ca = getFromColor(p);\n vec4 cb = getToColor(p);\n \n vec2 oa = (((ca.rg+ca.b)*0.5)*2.0-1.0);\n vec2 ob = (((cb.rg+cb.b)*0.5)*2.0-1.0);\n vec2 oc = mix(oa,ob,0.5)*strength;\n \n float w0 = progress;\n float w1 = 1.0-w0;\n return mix(getFromColor(p+oc*w0), getToColor(p-oc*w1), progress);\n}\n","author":"paniq","license":"MIT","description":"A crossfade in which each image is displaced by the other's colors, like a morph","tags":["morph","distort","blend"],"params":{"strength":{"type":"float","default":0.1,"description":"Strength of the displacement"}},"textures":[],"createdAt":"Thu, 10 Aug 2017 00:27:36 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"mosaic_transition","paramsTypes":{"mosaicNum":"float"},"defaultParams":{"mosaicNum":10},"glsl":"// Author: YueDev\n// License: MIT\n// Description: Both images break into mosaic blocks that blend, then sharpen into the incoming image\n// Tags: mosaic, pixelate, blend\n\n// @param Number of mosaic blocks\nuniform float mosaicNum;// = 10.0\n\nvec2 getMosaicUV(vec2 uv) {\n float mosaicWidth = 2.0 / mosaicNum * min(progress, 1.0 - progress);\n float mX = floor(uv.x / mosaicWidth) + 0.5;\n float mY = floor(uv.y / mosaicWidth) + 0.5;\n return vec2(mX * mosaicWidth, mY * mosaicWidth);\n}\n\nvec4 transition (vec2 uv) {\n vec2 mosaicUV = min(progress, 1.0 - progress) == 0.0 ? uv : getMosaicUV(uv);\n return mix(getFromColor(mosaicUV), getToColor(mosaicUV), progress * progress);\n}\n","author":"YueDev","license":"MIT","description":"Both images break into mosaic blocks that blend, then sharpen into the incoming image","tags":["mosaic","pixelate","blend"],"params":{"mosaicNum":{"type":"float","default":10,"description":"Number of mosaic blocks"}},"textures":[],"createdAt":"Fri, 27 May 2022 19:14:24 +0800","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"multiply_blend","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: A crossfade through the multiplied blend of both images\n// Tags: blend, fade\n\nvec4 blend(vec4 a, vec4 b) {\n return a * b;\n}\n\nvec4 transition (vec2 uv) {\n \n vec4 blended = blend(getFromColor(uv), getToColor(uv));\n \n if (progress < 0.5)\n return mix(getFromColor(uv), blended, 2.0 * progress);\n else\n return mix(blended, getToColor(uv), 2.0 * progress - 1.0);\n}\n\n","author":"Fernando Kuteken","license":"MIT","description":"A crossfade through the multiplied blend of both images","tags":["blend","fade"],"params":{},"textures":[],"createdAt":"Mon, 29 May 2017 17:13:58 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"old_tv_lost_signal","paramsTypes":{},"defaultParams":{},"glsl":"// Author: mernking (gitlab.com/Godswork)\n// License: MIT\n// Description: A crossfade with drifting tracking lines and tearing, like a TV losing its signal\n// Tags: retro, glitch, scanlines\n\nfloat hash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n}\n\nvec4 transition(vec2 uv) {\n\n float p = progress;\n float strength = sin(p * 3.14159265);\n\n vec2 tv = uv;\n\n vec4 fromColor = getFromColor(tv);\n vec4 toColor = getToColor(tv);\n\n vec4 color = mix(fromColor, toColor, p);\n\n // horizontal tracking lines (key effect)\n float lineY = floor(tv.y * 120.0);\n\n float noise = hash(vec2(lineY, p * 20.0));\n\n float line = step(0.92, noise);\n\n // make lines drift during transition\n float drift =\n sin(tv.y * 30.0 + p * 10.0)\n * 0.02\n * strength;\n\n vec4 shiftedFrom = getFromColor(tv + vec2(drift, 0.0));\n vec4 shiftedTo = getToColor(tv + vec2(drift, 0.0));\n\n vec4 lineColor = mix(shiftedFrom, shiftedTo, p);\n\n // apply tearing only on selected scanlines\n color = mix(color, lineColor, line * strength);\n\n // mild scanline darkening (CRT feel)\n float scan =\n sin(tv.y * 900.0) * 0.03;\n\n color.rgb -= scan * strength;\n\n return color;\n}\n","author":"mernking (gitlab.com/Godswork)","license":"MIT","description":"A crossfade with drifting tracking lines and tearing, like a TV losing its signal","tags":["retro","glitch","scanlines"],"params":{},"textures":[],"createdAt":"Mon, 22 Jun 2026 00:33:17 +0100","updatedAt":"Sat, 10 Oct 2026 11:13:38 +0200"},{"name":"parametric_glitch","paramsTypes":{"ampx":"float","ampy":"float"},"defaultParams":{"ampx":1,"ampy":1},"glsl":"// Author: Yoni Maltsman @friendlyspinach\n// License: MIT\n// Description: A crossfade with glitchy horizontal bands and color shifts\n// Tags: glitch, blend\n\n\n\n// @param Horizontal amplitude of the glitch\nuniform float ampx; // =1.0\n// @param Vertical amplitude of the glitch\nuniform float ampy; //=1.0\n\nvec4 transition (vec2 uv) {\n vec4 from = getFromColor(uv);\n vec4 to = getToColor(uv);\n float r = from.r;\n float g = from.g;\n float b = from.b;\n float sphere = r*r + g*g + b*b - 1.0; //3 to 1\n float spiralX = cos(sphere - uv.x/(progress + .01));\n float spiralY = sin(sphere - uv.y/(progress+.01));\n vec2 st = uv;\n st.x = fract(ampx*st.x*spiralX); //1 to 2\n st.y = fract(ampy*st.y*spiralY);\n vec2 diff = uv - st;\n from = getFromColor(uv + progress*diff);\n return mix(from, to, progress);\n}\n","author":"Yoni Maltsman @friendlyspinach","license":"MIT","description":"A crossfade with glitchy horizontal bands and color shifts","tags":["glitch","blend"],"params":{"ampx":{"type":"float","default":1,"description":"Horizontal amplitude of the glitch"},"ampy":{"type":"float","default":1,"description":"Vertical amplitude of the glitch"}},"textures":[],"createdAt":"Sat, 22 Jun 2024 13:22:34 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"perlin","paramsTypes":{"scale":"float","smoothness":"float","seed":"float"},"defaultParams":{"scale":4,"smoothness":0.01,"seed":12.9898},"glsl":"// Author: Rich Harris\n// License: MIT\n// Description: The incoming image appears through blobs of Perlin noise\n// Tags: noise, dissolve\n\n// @param Scale of the noise; higher values make smaller blobs\nuniform float scale; // = 4.0\n// @param Softness of the blob edges\nuniform float smoothness; // = 0.01\n\n// @param Random seed\nuniform float seed; // = 12.9898\n\n// http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/\nfloat random(vec2 co)\n{\n float a = seed;\n float b = 78.233;\n float c = 43758.5453;\n float dt= dot(co.xy ,vec2(a,b));\n float sn= mod(dt,3.14);\n return fract(sin(sn) * c);\n}\n\n// 2D Noise based on Morgan McGuire @morgan3d\n// https://www.shadertoy.com/view/4dS3Wd\nfloat noise (in vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n\n // Four corners in 2D of a tile\n float a = random(i);\n float b = random(i + vec2(1.0, 0.0));\n float c = random(i + vec2(0.0, 1.0));\n float d = random(i + vec2(1.0, 1.0));\n\n // Smooth Interpolation\n\n // Cubic Hermine Curve. Same as SmoothStep()\n vec2 u = f*f*(3.0-2.0*f);\n // u = smoothstep(0.,1.,f);\n\n // Mix 4 coorners porcentages\n return mix(a, b, u.x) +\n (c - a)* u.y * (1.0 - u.x) +\n (d - b) * u.x * u.y;\n}\n\nvec4 transition (vec2 uv) {\n vec4 from = getFromColor(uv);\n vec4 to = getToColor(uv);\n float n = noise(uv * scale);\n\n float p = mix(-smoothness, 1.0 + smoothness, progress);\n float lower = p - smoothness;\n float higher = p + smoothness;\n\n float q = smoothstep(lower, higher, n);\n\n return mix(\n from,\n to,\n 1.0 - q\n );\n}\n","author":"Rich Harris","license":"MIT","description":"The incoming image appears through blobs of Perlin noise","tags":["noise","dissolve"],"params":{"scale":{"type":"float","default":4,"description":"Scale of the noise; higher values make smaller blobs"},"smoothness":{"type":"float","default":0.01,"description":"Softness of the blob edges"},"seed":{"type":"float","default":12.9898,"description":"Random seed"}},"textures":[],"createdAt":"Tue, 23 Jan 2018 21:35:10 -0500","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"pinwheel","paramsTypes":{"speed":"float"},"defaultParams":{"speed":2},"glsl":"// Author: Mr Speaker\n// License: MIT\n// Description: A spinning pinwheel reveals the incoming image\n// Tags: pinwheel, radial, rotate\n\n// @param Rotation speed\nuniform float speed; // = 2.0\n\nvec4 transition(vec2 uv) {\n \n vec2 p = uv.xy / vec2(1.0).xy;\n \n float circPos = atan(p.y - 0.5, p.x - 0.5) + progress * speed;\n float modPos = mod(circPos, 3.1415 / 4.);\n float signed = sign(progress - modPos);\n \n return mix(getToColor(p), getFromColor(p), step(signed, 0.5));\n \n}\n","author":"Mr Speaker","license":"MIT","description":"A spinning pinwheel reveals the incoming image","tags":["pinwheel","radial","rotate"],"params":{"speed":{"type":"float","default":2,"description":"Rotation speed"}},"textures":[],"createdAt":"Tue, 30 May 2017 09:04:31 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"pixelize","paramsTypes":{"squaresMin":"ivec2","steps":"int"},"defaultParams":{"squaresMin":[20,20],"steps":50},"glsl":"// Author: gre\n// License: MIT\n// Description: Both images pixelate, crossfade, then sharpen again\n// Tags: pixelate, blend\n// forked from https://gist.github.com/benraziel/c528607361d90a072e98\n\n// minimum number of squares (when the effect is at its higher level)\n// @param Number of squares at the strongest pixelation\nuniform ivec2 squaresMin; // = ivec2(20)\n// zero disable the stepping\n// @param Number of pixelation steps; 0 for a continuous effect\nuniform int steps; // = 50\n\nvec4 transition(vec2 uv) {\n float d = min(progress, 1.0 - progress);\n float dist = steps>0 ? ceil(d * float(steps)) / float(steps) : d;\n vec2 squareSize = 2.0 * dist / vec2(squaresMin);\n vec2 p = dist>0.0 ? (floor(uv / squareSize) + 0.5) * squareSize : uv;\n return mix(getFromColor(p), getToColor(p), progress);\n}\n","author":"gre","license":"MIT","description":"Both images pixelate, crossfade, then sharpen again","tags":["pixelate","blend"],"params":{"squaresMin":{"type":"ivec2","default":[20,20],"description":"Number of squares at the strongest pixelation"},"steps":{"type":"int","default":50,"description":"Number of pixelation steps; 0 for a continuous effect"}},"textures":[],"createdAt":"Mon, 29 May 2017 11:16:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"polar_function","paramsTypes":{"segments":"int"},"defaultParams":{"segments":5},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: A flower shape with several petals grows to reveal the incoming image\n// Tags: shape, wipe, polar\n\n#define PI 3.14159265359\n\n// @param Number of petals\nuniform int segments; // = 5\n\nvec4 transition (vec2 uv) {\n \n float angle = atan(uv.y - 0.5, uv.x - 0.5) - 0.5 * PI;\n float normalized = (angle + 1.5 * PI) * (2.0 * PI);\n \n float radius = (cos(float(segments) * angle) + 4.0) / 4.0;\n float difference = length(uv - vec2(0.5, 0.5));\n \n if (difference > radius * progress)\n return getFromColor(uv);\n else\n return getToColor(uv);\n}\n","author":"Fernando Kuteken","license":"MIT","description":"A flower shape with several petals grows to reveal the incoming image","tags":["shape","wipe","polar"],"params":{"segments":{"type":"int","default":5,"description":"Number of petals"}},"textures":[],"createdAt":"Sun, 28 May 2017 18:53:12 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"powerKaleido","paramsTypes":{"scale":"float","z":"float","speed":"float"},"defaultParams":{"scale":2,"z":1.5,"speed":5},"glsl":"// Name: Power Kaleido\n// Author: Boundless\n// License: MIT\n// Description: The image folds into an animated kaleidoscope before revealing the incoming one\n// Tags: kaleidoscope, distort\n#define PI 3.14159265358979\nconst float rad = 120.; // change this value to get different mirror effects\nconst float deg = rad / 180. * PI;\nuniform float scale; // = 2.0\nuniform float z; // = 1.5\nuniform float speed; // = 5.\nvec2 refl(vec2 p,vec2 o,vec2 n)\n{\n\treturn 2.0*o+2.0*n*dot(p-o,n)-p;\n}\n\nvec2 rot(vec2 p, vec2 o, float a)\n{\n float s = sin(a);\n float c = cos(a);\n\treturn o + mat2(c, -s, s, c) * (p - o);\n}\n\nvec4 mainImage(vec2 uv)\n{\n float dist = scale / 10.;\n vec2 uv0 = uv;\n\tuv -= 0.5;\n uv.x *= ratio;\n uv *= z;\n uv = rot(uv, vec2(0.0), progress*speed);\n // uv.x = fract(uv.x/l/3.0)*l*3.0;\n\tfloat theta = progress*6.+PI/.5;\n\tfor(int iter = 0; iter < 10; iter++) {\n for(float i = 0.; i < 2. * PI; i+=deg) {\n\t float ts = sign(asin(cos(i))) == 1.0 ? 1.0 : 0.0;\n if(((ts == 1.0) && (uv.y-dist*cos(i) > tan(i)*(uv.x+dist*+sin(i)))) || ((ts == 0.0) && (uv.y-dist*cos(i) < tan(i)*(uv.x+dist*+sin(i))))) {\n uv = refl(vec2(uv.x+sin(i)*dist*2.,uv.y-cos(i)*dist*2.), vec2(0.,0.), vec2(cos(i),sin(i)));\n }\n }\n }\n uv += 0.5;\n uv = rot(uv, vec2(0.5), progress*-speed);\n uv -= 0.5;\n uv.x /= ratio;\n uv += 0.5;\n uv = 2.*abs(uv/2.-floor(uv/2.+0.5));\n vec2 uvMix = mix(uv,uv0,cos(progress*PI*2.)/2.+0.5);\n vec4 color = mix(getFromColor(uvMix),getToColor(uvMix),cos((progress-1.)*PI)/2.+0.5);\n\treturn color;\n \n}\nvec4 transition (vec2 uv) {\n vec4 color = mainImage(uv);\n return color;\n}\n","author":"Boundless","license":"MIT","description":"The image folds into an animated kaleidoscope before revealing the incoming one","tags":["kaleidoscope","distort"],"params":{"scale":{"type":"float","default":2},"z":{"type":"float","default":1.5},"speed":{"type":"float","default":5}},"textures":[],"createdAt":"Tue, 15 Mar 2022 07:18:34 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"randomNoisex","paramsTypes":{},"defaultParams":{},"glsl":"// Author: towrabbit\n// License: MIT\n// Description: The incoming image appears pixel by pixel in random noise\n// Tags: dissolve, noise\n\nfloat random (vec2 st) {\n return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123);\n}\nvec4 transition (vec2 uv) {\n vec4 leftSide = getFromColor(uv);\n vec4 rightSide = getToColor(uv);\n float uvz = floor(random(uv)+progress);\n return mix(leftSide,rightSide,uvz);\n}\n","author":"towrabbit","license":"MIT","description":"The incoming image appears pixel by pixel in random noise","tags":["dissolve","noise"],"params":{},"textures":[],"createdAt":"Wed, 28 Oct 2020 15:02:19 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"randomsquares","paramsTypes":{"size":"ivec2","smoothness":"float"},"defaultParams":{"size":[10,10],"smoothness":0.5},"glsl":"// Author: gre\n// License: MIT\n// Description: The incoming image appears in random squares\n// Tags: squares, grid, dissolve\n\n// @param Number of squares (columns, rows)\nuniform ivec2 size; // = ivec2(10, 10)\n// @param Softness of each square's switch\nuniform float smoothness; // = 0.5\n \nfloat rand (vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nvec4 transition(vec2 p) {\n float r = rand(floor(vec2(size) * p));\n float m = smoothstep(0.0, -smoothness, r - (progress * (1.0 + smoothness)));\n return mix(getFromColor(p), getToColor(p), m);\n}\n","author":"gre","license":"MIT","description":"The incoming image appears in random squares","tags":["squares","grid","dissolve"],"params":{"size":{"type":"ivec2","default":[10,10],"description":"Number of squares (columns, rows)"},"smoothness":{"type":"float","default":0.5,"description":"Softness of each square's switch"}},"textures":[],"createdAt":"Sat, 27 May 2017 11:31:45 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"ripple","paramsTypes":{"amplitude":"float","speed":"float"},"defaultParams":{"amplitude":100,"speed":50},"glsl":"// Author: gre\n// License: MIT\n// Description: Ripples spread from the center while crossfading\n// Tags: ripple, wave, blend\n// @param Frequency of the ripples\nuniform float amplitude; // = 100.0\n// @param Speed of the ripples\nuniform float speed; // = 50.0\n\nvec4 transition (vec2 uv) {\n vec2 dir = uv - vec2(.5);\n float dist = length(dir);\n vec2 offset = dir * (sin(progress * dist * amplitude - progress * speed) + .5) / 30. * progress;\n return mix(\n getFromColor(uv + offset),\n getToColor(uv),\n smoothstep(0.2, 1.0, progress)\n );\n}\n","author":"gre","license":"MIT","description":"Ripples spread from the center while crossfading","tags":["ripple","wave","blend"],"params":{"amplitude":{"type":"float","default":100,"description":"Frequency of the ripples"},"speed":{"type":"float","default":50,"description":"Speed of the ripples"}},"textures":[],"createdAt":"Fri, 26 May 2017 12:25:18 +0200","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"rotateTransition","paramsTypes":{},"defaultParams":{},"glsl":"// Author: haiyoucuv\n// License: MIT\n// Description: The images spin around the center while crossfading\n// Tags: rotate, spin, blend\n\n#define PI 3.1415926\n\nvec2 rotate2D(in vec2 uv, in float angle){\n \n return uv * mat2(cos(angle), -sin(angle), sin(angle), cos(angle));\n}\nvec4 transition (vec2 uv) {\n \n vec2 p = fract(rotate2D(uv - 0.5, progress * PI * 2.0) + 0.5);\n\n return mix(\n getFromColor(p),\n getToColor(p),\n progress\n );\n}\n","author":"haiyoucuv","license":"MIT","description":"The images spin around the center while crossfading","tags":["rotate","spin","blend"],"params":{},"textures":[],"createdAt":"Thu, 25 Mar 2021 16:48:22 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"rotate_scale_fade","paramsTypes":{"center":"vec2","rotations":"float","scale":"float","backColor":"vec4"},"defaultParams":{"center":[0.5,0.5],"rotations":1,"scale":8,"backColor":[0.15,0.15,0.15,1]},"glsl":"// Author: Fernando Kuteken\n// License: MIT\n// Description: The outgoing image spins and zooms while fading to the incoming one, over a background color\n// Tags: rotate, zoom, fade\n\n#define PI 3.14159265359\n\n// @param Center of the rotation\nuniform vec2 center; // = vec2(0.5, 0.5)\n// @param Number of turns\nuniform float rotations; // = 1\n// @param Maximum zoom\nuniform float scale; // = 8\n// @color Background color\nuniform vec4 backColor; // = vec4(0.15, 0.15, 0.15, 1.0)\n\nvec4 transition (vec2 uv) {\n \n vec2 difference = uv - center;\n vec2 dir = normalize(difference);\n float dist = length(difference);\n \n float angle = 2.0 * PI * rotations * progress;\n \n float c = cos(angle);\n float s = sin(angle);\n \n float currentScale = mix(scale, 1.0, 2.0 * abs(progress - 0.5));\n \n vec2 rotatedDir = vec2(dir.x * c - dir.y * s, dir.x * s + dir.y * c);\n vec2 rotatedUv = center + rotatedDir * dist / currentScale;\n \n if (rotatedUv.x < 0.0 || rotatedUv.x > 1.0 ||\n rotatedUv.y < 0.0 || rotatedUv.y > 1.0)\n return backColor;\n \n return mix(getFromColor(rotatedUv), getToColor(rotatedUv), progress);\n}\n","author":"Fernando Kuteken","license":"MIT","description":"The outgoing image spins and zooms while fading to the incoming one, over a background color","tags":["rotate","zoom","fade"],"params":{"center":{"type":"vec2","default":[0.5,0.5],"description":"Center of the rotation"},"rotations":{"type":"float","default":1,"description":"Number of turns"},"scale":{"type":"float","default":8,"description":"Maximum zoom"},"backColor":{"type":"vec4","default":[0.15,0.15,0.15,1],"color":true,"description":"Background color"}},"textures":[],"createdAt":"Mon, 29 May 2017 18:25:00 -0300","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"scale-in","paramsTypes":{},"defaultParams":{},"glsl":"// Author: haiyoucuv\n// License: MIT\n// Description: The incoming image scales in from the center while fading in\n// Tags: zoom, fade\n\nvec4 scale(in vec2 uv){\n uv = 0.5 + (uv - 0.5) * progress;\n return getToColor(uv);\n}\n\nvec4 transition (vec2 uv) {\n return mix(\n getFromColor(uv),\n scale(uv),\n progress\n );\n}\n","author":"haiyoucuv","license":"MIT","description":"The incoming image scales in from the center while fading in","tags":["zoom","fade"],"params":{},"textures":[],"createdAt":"Tue, 15 Mar 2022 20:21:46 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideInHorizontal","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The incoming image slides in as two halves moving horizontally in opposite directions\n// Tags: slide, split, horizontal\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = reverse ? -1.0 : 1.0;\n vec2 toP = (uv.y > 0.5) ?\n vec2((uv.x - (progress * modifier)) + modifier, uv.y) :\n vec2((uv.x + (progress * modifier)) - modifier, uv.y);\n\n vec2 fromP = uv;\n\n return inBounds(toP) ? getToColor(toP) : getFromColor(fromP);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The incoming image slides in as two halves moving horizontally in opposite directions","tags":["slide","split","horizontal"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideInOutHorizontal","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The halves of both images slide horizontally in opposite directions, out and in at once\n// Tags: slide, split, horizontal\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = (uv.y > 0.5 ? 1.0 : -1.0) * (reverse ? -1.0 : 1.0) ;\n vec2 fromP = vec2(uv.x + (progress * modifier), uv.y);\n vec2 toP = vec2((uv.x + (progress * modifier)) - modifier, uv.y);\n\n return inBounds(fromP) ? getFromColor(fromP) : getToColor(toP);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The halves of both images slide horizontally in opposite directions, out and in at once","tags":["slide","split","horizontal"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideInOutVertical","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The halves of both images slide vertically in opposite directions, out and in at once\n// Tags: slide, split, vertical\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = (uv.x > 0.5 ? 1.0 : -1.0) * (reverse ? -1.0 : 1.0) ;\n vec2 fromP = vec2(uv.x, uv.y + (progress * modifier));\n vec2 toP = vec2(uv.x, (uv.y + (progress * modifier)) - modifier);\n\n return inBounds(fromP) ? getFromColor(fromP) : getToColor(toP);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The halves of both images slide vertically in opposite directions, out and in at once","tags":["slide","split","vertical"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideInVertical","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The incoming image slides in as two halves moving vertically in opposite directions\n// Tags: slide, split, vertical\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = reverse ? -1.0 : 1.0;\n vec2 p = (uv.x > 0.5) ?\n vec2(uv.x, (uv.y - (progress * modifier)) + modifier) :\n vec2(uv.x, (uv.y + (progress * modifier)) - modifier);\n\n return inBounds(p) ? getToColor(p) : getFromColor(uv);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The incoming image slides in as two halves moving vertically in opposite directions","tags":["slide","split","vertical"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideOutHorizontal","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The outgoing image slides out as two halves moving horizontally in opposite directions\n// Tags: slide, split, horizontal\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = (uv.y > 0.5 ? 1.0 : -1.0) * (reverse ? -1.0 : 1.0) ;\n vec2 p = vec2(uv.x + (progress * modifier), uv.y);\n\n return inBounds(p) ? getFromColor(p) : getToColor(uv);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The outgoing image slides out as two halves moving horizontally in opposite directions","tags":["slide","split","horizontal"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"splitSlideOutVertical","paramsTypes":{"reverse":"bool"},"defaultParams":{"reverse":false},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: The outgoing image slides out as two halves moving vertically in opposite directions\n// Tags: slide, split, vertical\n\n// @param Swap the directions of the halves\nuniform bool reverse; // = false\n\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n\nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n\nvec4 transition (vec2 uv) {\n float modifier = (uv.x > 0.5 ? 1.0 : -1.0) * (reverse ? -1.0 : 1.0) ;\n vec2 p = vec2(uv.x, uv.y + (progress * modifier));\n\n return inBounds(p) ? getFromColor(p) : getToColor(uv);\n}\n","author":"OllyOllyOlly","license":"MIT","description":"The outgoing image slides out as two halves moving vertically in opposite directions","tags":["slide","split","vertical"],"params":{"reverse":{"type":"bool","default":false,"description":"Swap the directions of the halves"}},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"squareswire","paramsTypes":{"squares":"ivec2","direction":"vec2","smoothness":"float"},"defaultParams":{"squares":[10,10],"direction":[1,-0.5],"smoothness":1.6},"glsl":"// Author: gre\n// License: MIT\n// Description: Squares grow along a diagonal sweep to reveal the incoming image\n// Tags: squares, grid, wipe, directional\n \n// @param Number of squares (columns, rows)\nuniform ivec2 squares;// = ivec2(10,10)\n// @param Direction of the sweep\nuniform vec2 direction;// = vec2(1.0, -0.5)\n// @param Softness of the sweep\nuniform float smoothness; // = 1.6\n\nconst vec2 center = vec2(0.5, 0.5);\nvec4 transition (vec2 p) {\n vec2 v = normalize(direction);\n v /= abs(v.x)+abs(v.y);\n float d = v.x * center.x + v.y * center.y;\n float offset = smoothness;\n float pr = smoothstep(-offset, 0.0, v.x * p.x + v.y * p.y - (d-0.5+progress*(1.+offset)));\n vec2 squarep = fract(p*vec2(squares));\n vec2 squaremin = vec2(pr/2.0);\n vec2 squaremax = vec2(1.0 - pr/2.0);\n float a = (1.0 - step(progress, 0.0)) * step(squaremin.x, squarep.x) * step(squaremin.y, squarep.y) * step(squarep.x, squaremax.x) * step(squarep.y, squaremax.y);\n return mix(getFromColor(p), getToColor(p), a);\n}\n","author":"gre","license":"MIT","description":"Squares grow along a diagonal sweep to reveal the incoming image","tags":["squares","grid","wipe","directional"],"params":{"squares":{"type":"ivec2","default":[10,10],"description":"Number of squares (columns, rows)"},"direction":{"type":"vec2","default":[1,-0.5],"description":"Direction of the sweep"},"smoothness":{"type":"float","default":1.6,"description":"Softness of the sweep"}},"textures":[],"createdAt":"Fri, 26 May 2017 12:48:21 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"squeeze","paramsTypes":{"colorSeparation":"float"},"defaultParams":{"colorSeparation":0.04},"glsl":"// Author: gre\n// License: MIT\n// Description: The outgoing image is squeezed into a line with color separation, revealing the incoming one\n// Tags: squeeze, chromatic, vertical\n \n// @param Amount of color separation\nuniform float colorSeparation; // = 0.04\n \nvec4 transition (vec2 uv) {\n float y = 0.5 + (uv.y-0.5) / (1.0-progress);\n if (y < 0.0 || y > 1.0) {\n return getToColor(uv);\n }\n else {\n vec2 fp = vec2(uv.x, y);\n vec2 off = progress * vec2(0.0, colorSeparation);\n vec4 c = getFromColor(fp);\n vec4 cn = getFromColor(fp - off);\n vec4 cp = getFromColor(fp + off);\n return vec4(cn.r, c.g, cp.b, c.a);\n }\n}\n","author":"gre","license":"MIT","description":"The outgoing image is squeezed into a line with color separation, revealing the incoming one","tags":["squeeze","chromatic","vertical"],"params":{"colorSeparation":{"type":"float","default":0.04,"description":"Amount of color separation"}},"textures":[],"createdAt":"Fri, 26 May 2017 12:34:44 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"static_wipe","paramsTypes":{"u_transitionUpToDown":"bool","u_max_static_span":"float"},"defaultParams":{"u_transitionUpToDown":true,"u_max_static_span":0.5},"glsl":"// Author: Ben Lucas\n// License: MIT\n// Description: A wipe from top to bottom with a band of TV static at its edge\n// Tags: wipe, static, noise, vertical\n\n#define PI 3.14159265359\n\nfloat rnd (vec2 st) {\n return fract(sin(dot(st.xy,\n vec2(10,70)))*\n 12345.5453123);\n}\n\n// @param Wipe from top to bottom; false wipes from bottom to top\nuniform bool u_transitionUpToDown; // = true\n// @param Maximum height of the static band\nuniform float u_max_static_span; // = 0.5\n\nvec4 transition (vec2 uv) {\n \n\n float span = u_max_static_span*pow(sin(PI*progress),0.5);\n \n float transitionEdge = u_transitionUpToDown ? 1.0-uv.y : uv.y;\n float mixRatio = 1.0 - step(progress, transitionEdge);\n\n vec4 transitionMix = mix(\n getFromColor(uv),\n getToColor(uv),\n mixRatio\n );\n \n float noiseEnvelope = smoothstep(progress-span, progress, transitionEdge) * (1.0 - smoothstep(progress, progress + span, transitionEdge));\n vec4 noise = vec4(vec3(rnd(uv*(1.0+progress))), 1.0);\n \n\n return mix(transitionMix, noise, noiseEnvelope);\n}\n","author":"Ben Lucas","license":"MIT","description":"A wipe from top to bottom with a band of TV static at its edge","tags":["wipe","static","noise","vertical"],"params":{"u_transitionUpToDown":{"type":"bool","default":true,"description":"Wipe from top to bottom; false wipes from bottom to top"},"u_max_static_span":{"type":"float","default":0.5,"description":"Maximum height of the static band"}},"textures":[],"createdAt":"Tue, 4 Apr 2023 03:29:01 -0400","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"swap","paramsTypes":{"reflection":"float","perspective":"float","depth":"float"},"defaultParams":{"reflection":0.4,"perspective":0.2,"depth":3},"glsl":"// Author: gre\n// License: MIT\n// Description: The two images swap places in 3D, with a floor reflection\n// Tags: 3d, swap, reflection\n// General parameters\n// @param Strength of the reflection\nuniform float reflection; // = 0.4\n// @param Amount of perspective\nuniform float perspective; // = 0.2\nuniform float depth; // = 3.0\n \nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\nconst vec2 boundMin = vec2(0.0, 0.0);\nconst vec2 boundMax = vec2(1.0, 1.0);\n \nbool inBounds (vec2 p) {\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\n}\n \nvec2 project (vec2 p) {\n return p * vec2(1.0, -1.2) + vec2(0.0, -0.02);\n}\n \nvec4 bgColor (vec2 p, vec2 pfr, vec2 pto) {\n vec4 c = black;\n pfr = project(pfr);\n if (inBounds(pfr)) {\n c += mix(black, getFromColor(pfr), reflection * mix(1.0, 0.0, pfr.y));\n }\n pto = project(pto);\n if (inBounds(pto)) {\n c += mix(black, getToColor(pto), reflection * mix(1.0, 0.0, pto.y));\n }\n return c;\n}\n \nvec4 transition(vec2 p) {\n vec2 pfr, pto = vec2(-1.);\n \n float size = mix(1.0, depth, progress);\n float persp = perspective * progress;\n pfr = (p + vec2(-0.0, -0.5)) * vec2(size/(1.0-perspective*progress), size/(1.0-size*persp*p.x)) + vec2(0.0, 0.5);\n \n size = mix(1.0, depth, 1.-progress);\n persp = perspective * (1.-progress);\n pto = (p + vec2(-1.0, -0.5)) * vec2(size/(1.0-perspective*(1.0-progress)), size/(1.0-size*persp*(0.5-p.x))) + vec2(1.0, 0.5);\n\n if (progress < 0.5) {\n if (inBounds(pfr)) {\n return getFromColor(pfr);\n }\n if (inBounds(pto)) {\n return getToColor(pto);\n } \n }\n if (inBounds(pto)) {\n return getToColor(pto);\n }\n if (inBounds(pfr)) {\n return getFromColor(pfr);\n }\n return bgColor(p, pfr, pto);\n}\n","author":"gre","license":"MIT","description":"The two images swap places in 3D, with a floor reflection","tags":["3d","swap","reflection"],"params":{"reflection":{"type":"float","default":0.4,"description":"Strength of the reflection"},"perspective":{"type":"float","default":0.2,"description":"Amount of perspective"},"depth":{"type":"float","default":3}},"textures":[],"createdAt":"Sat, 27 May 2017 11:36:00 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"tangentMotionBlur","paramsTypes":{},"defaultParams":{},"glsl":"\n// License: MIT\n// Author: chenkai\n// Description: The outgoing image is flung away along a curve with motion blur\n// Tags: motion-blur, rotate, slide\n// ported from https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/671116/\n\nfloat rand (vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n \n// motion blur for texture from\nvec4 motionBlurFrom(vec2 _st, vec2 speed) {\n vec2 texCoord = _st.xy / vec2(1.0).xy;\n vec3 color = vec3(0.0);\n float total = 0.0;\n float offset = rand(_st);\n for (float t = 0.0; t <= 20.0; t++) {\n float percent = (t + offset) / 20.0;\n float weight = 4.0 * (percent - percent * percent);\n vec2 newuv = texCoord + speed * percent;\n newuv = fract(newuv);\n color += getFromColor(newuv).rgb * weight;\n total += weight;\n }\n return vec4(color / total, 1.0);\n}\n\n// motion blur for texture to\nvec4 motionBlurTo(vec2 _st, vec2 speed) {\n vec2 texCoord = _st.xy / vec2(1.0).xy;\n vec3 color = vec3(0.0);\n float total = 0.0;\n float offset = rand(_st);\n for (float t = 0.0; t <= 20.0; t++) {\n float percent = (t + offset) / 20.0;\n float weight = 4.0 * (percent - percent * percent);\n vec2 newuv = texCoord + speed * percent;\n newuv = fract(newuv);\n color += getToColor(newuv).rgb * weight;\n total += weight;\n }\n return vec4(color / total, 1.0);\n}\n\n\n// bezier in gpu\nfloat A(float aA1, float aA2) {\n return 1.0 - 3.0 * aA2 + 3.0 * aA1;\n}\nfloat B(float aA1, float aA2) {\n return 3.0 * aA2 - 6.0 * aA1;\n}\nfloat C(float aA1) {\n return 3.0 * aA1;\n}\nfloat GetSlope(float aT, float aA1, float aA2) {\n return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1);\n}\nfloat CalcBezier(float aT, float aA1, float aA2) {\n return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT;\n}\nfloat GetTForX(float aX, float mX1, float mX2) {\n // iteration to solve\n float aGuessT = aX;\n for (int i = 0; i < 4; ++i) {\n float currentSlope = GetSlope(aGuessT, mX1, mX2);\n if (currentSlope == 0.0) return aGuessT;\n float currentX = CalcBezier(aGuessT, mX1, mX2) - aX;\n aGuessT -= currentX / currentSlope;\n }\n return aGuessT;\n}\nfloat KeySpline(float aX, float mX1, float mY1, float mX2, float mY2) {\n if (mX1 == mY1 && mX2 == mY2) return aX; // linear\n return CalcBezier(GetTForX(aX, mX1, mX2), mY1, mY2); // x to t, t to y\n}\n\n// norm distribution\nfloat normpdf(float x) {\n float d = x - .5;\n return exp(-20.*d*d);\n}\n\nvec2 rotateUv(vec2 uv, float angle, vec2 anchor, float zDirection) {\n uv = uv - anchor; // anchor to origin\n float s = sin(angle);\n\tfloat c = cos(angle);\n\tmat2 m = mat2(c, -s, s, c);\n uv = m * uv;\n uv += anchor; // anchor back\n return uv;\n}\n\n\n\nvec4 transition (vec2 uv) {\n \n vec2 myst = uv;\n float animationTime = progress; //getAnimationTime();\n float easingTime = KeySpline(animationTime, .68,.01,.17,.98);\n float blur = normpdf(easingTime);\n float r = 0.;\n float rotation = 180./180.*3.14159;\n if (easingTime <= .5) {\n r = rotation * easingTime;\n } else {\n r = -rotation + rotation * easingTime;\n }\n\n // rotation for current frame\n vec2 mystCurrent = myst;\n mystCurrent.y *= 1./ratio;\n mystCurrent = rotateUv(mystCurrent, r, vec2(1., 0.), -1.);\n mystCurrent.y *= ratio;\n \n // frame timeInterval by fps=30\n float timeInterval = 0.0167*2.0;\n if (easingTime <= .5) {\n r = rotation * (easingTime+timeInterval);\n } else {\n r = -rotation + rotation * (easingTime+timeInterval);\n }\n \n // rotation for next frame\n vec2 mystNext = myst;\n mystNext.y *= 1./ratio;\n mystNext = rotateUv(mystNext, r, vec2(1., 0.), -1.);\n mystNext.y *= ratio;\n \n // get speed at tagent direction\n vec2 speed = (mystNext - mystCurrent) / timeInterval * blur * 0.5;\n if (easingTime <= .5) {\n return motionBlurFrom(mystCurrent, speed);\n } else {\n return motionBlurTo(mystCurrent, speed);\n }\n}\n\n","author":"chenkai","license":"MIT","description":"The outgoing image is flung away along a curve with motion blur","tags":["motion-blur","rotate","slide"],"params":{},"textures":[],"createdAt":"Wed, 25 Mar 2020 10:46:29 +0800","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"undulatingBurnOut","paramsTypes":{"smoothness":"float","center":"vec2","color":"vec3"},"defaultParams":{"smoothness":0.03,"center":[0.5,0.5],"color":[0,0,0]},"glsl":"// License: MIT\n// Author: pthrasher\n// Description: A circle with a wavy edge burns out from the center to reveal the incoming image\n// Tags: circle, burn, wipe\n// adapted by gre from https://gist.github.com/pthrasher/8e6226b215548ba12734\n\n// @param Softness of the edge\nuniform float smoothness; // = 0.03\n// @param Center of the circle\nuniform vec2 center; // = vec2(0.5)\n// @color Color of the burning edge\nuniform vec3 color; // = vec3(0.0)\n\nconst float M_PI = 3.14159265358979323846;\n\nfloat quadraticInOut(float t) {\n float p = 2.0 * t * t;\n return t < 0.5 ? p : -p + (4.0 * t) - 1.0;\n}\n\nfloat getGradient(float r, float dist) {\n float d = r - dist;\n return mix(\n smoothstep(-smoothness, 0.0, r - dist * (1.0 + smoothness)),\n -1.0 - step(0.005, d),\n step(-0.005, d) * step(d, 0.01)\n );\n}\n\nfloat getWave(vec2 p){\n vec2 _p = p - center; // offset from center\n float rads = atan(_p.y, _p.x);\n float degs = degrees(rads) + 180.0;\n vec2 range = vec2(0.0, M_PI * 30.0);\n vec2 domain = vec2(0.0, 360.0);\n float ratio = (M_PI * 30.0) / 360.0;\n degs = degs * ratio;\n float x = progress;\n float magnitude = mix(0.02, 0.09, smoothstep(0.0, 1.0, x));\n float offset = mix(40.0, 30.0, smoothstep(0.0, 1.0, x));\n float ease_degs = quadraticInOut(sin(degs));\n float deg_wave_pos = (ease_degs * magnitude) * sin(x * offset);\n // The soft edge reaches `smoothness` beyond the radius and the burn band 0.005 inside it:\n // start the radius below both so nothing but the outgoing image shows at progress 0\n // (unchanged from progress 0.1 on).\n return x - max(smoothness, 0.01) * (1.0 - smoothstep(0.0, 0.1, x)) + deg_wave_pos;\n}\n\nvec4 transition(vec2 p) {\n float dist = distance(center, p);\n float m = getGradient(getWave(p), dist);\n vec4 cfrom = getFromColor(p);\n vec4 cto = getToColor(p);\n return mix(mix(cfrom, cto, m), mix(cfrom, vec4(color, 1.0), 0.75), step(m, -2.0));\n}\n","author":"pthrasher","license":"MIT","description":"A circle with a wavy edge burns out from the center to reveal the incoming image","tags":["circle","burn","wipe"],"params":{"smoothness":{"type":"float","default":0.03,"description":"Softness of the edge"},"center":{"type":"vec2","default":[0.5,0.5],"description":"Center of the circle"},"color":{"type":"vec3","default":[0,0,0],"color":true,"description":"Color of the burning edge"}},"textures":[],"createdAt":"Mon, 12 Jun 2017 10:23:37 +0800","updatedAt":"Sat, 10 Oct 2026 11:26:01 +0200"},{"name":"wind","paramsTypes":{"size":"float","reversed":"bool"},"defaultParams":{"size":0.2,"reversed":false},"glsl":"// Author: gre\n// License: MIT\n// Description: A ragged left-to-right wipe, as if the image was blown away by the wind\n// Tags: wipe, horizontal, noise\n\n// @range(0, 1) Width of the ragged edge\nuniform float size; // = 0.2\n// @param Wipe from right to left instead\nuniform bool reversed; // = false\n\nfloat rand (vec2 co) {\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nvec4 transition (vec2 uv) {\n float x = reversed ? 1. - uv.x : uv.x;\n float r = rand(vec2(0, uv.y));\n float m = smoothstep(0.0, -size, x*(1.0-size) + size*r - (progress * (1.0 + size)));\n return mix(\n getFromColor(uv),\n getToColor(uv),\n m\n );\n}\n","author":"gre","license":"MIT","description":"A ragged left-to-right wipe, as if the image was blown away by the wind","tags":["wipe","horizontal","noise"],"params":{"size":{"type":"float","default":0.2,"min":0,"max":1,"description":"Width of the ragged edge"},"reversed":{"type":"bool","default":false,"description":"Wipe from right to left instead"}},"textures":[],"createdAt":"Fri, 26 May 2017 09:55:44 +0200","updatedAt":"Fri, 9 Oct 2026 22:46:55 +0200"},{"name":"windowblinds","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Fabien Benetou\n// License: MIT\n// Description: A crossfade through horizontal window blinds\n// Tags: blinds, stripes, blend\n\nvec4 transition (vec2 uv) {\n float t = progress;\n \n if (mod(floor(uv.y*100.*progress),2.)==0.)\n t*=2.-.5;\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n mix(t, progress, smoothstep(0.8, 1.0, progress))\n );\n}\n","author":"Fabien Benetou","license":"MIT","description":"A crossfade through horizontal window blinds","tags":["blinds","stripes","blend"],"params":{},"textures":[],"createdAt":"Wed, 31 May 2017 14:11:48 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"windowslice","paramsTypes":{"count":"float","smoothness":"float"},"defaultParams":{"count":10,"smoothness":0.5},"glsl":"// Author: gre\n// License: MIT\n// Description: The incoming image appears through vertical slices that widen\n// Tags: slices, stripes, wipe\n\n// @param Number of slices\nuniform float count; // = 10.0\n// @param Softness of the slices' edges\nuniform float smoothness; // = 0.5\n\nvec4 transition (vec2 p) {\n float pr = smoothstep(-smoothness, 0.0, p.x - progress * (1.0 + smoothness));\n float s = step(pr, fract(count * p.x));\n return mix(getFromColor(p), getToColor(p), s);\n}\n","author":"gre","license":"MIT","description":"The incoming image appears through vertical slices that widen","tags":["slices","stripes","wipe"],"params":{"count":{"type":"float","default":10,"description":"Number of slices"},"smoothness":{"type":"float","default":0.5,"description":"Softness of the slices' edges"}},"textures":[],"createdAt":"Wed, 28 Mar 2018 17:23:26 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"wipeDown","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Jake Nelson\n// License: MIT\n// Description: A hard-edged wipe from top to bottom\n// Tags: wipe, vertical\n\nvec4 transition(vec2 uv) {\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 a=getFromColor(p);\n vec4 b=getToColor(p);\n return mix(a, b, step(1.0-p.y,progress));\n}\n","author":"Jake Nelson","license":"MIT","description":"A hard-edged wipe from top to bottom","tags":["wipe","vertical"],"params":{},"textures":[],"createdAt":"Wed, 1 Nov 2017 15:26:01 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"wipeLeft","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Jake Nelson\n// License: MIT\n// Description: A hard-edged wipe from right to left\n// Tags: wipe, horizontal\n\nvec4 transition(vec2 uv) {\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 a=getFromColor(p);\n vec4 b=getToColor(p);\n return mix(a, b, step(1.0-p.x,progress));\n}\n","author":"Jake Nelson","license":"MIT","description":"A hard-edged wipe from right to left","tags":["wipe","horizontal"],"params":{},"textures":[],"createdAt":"Wed, 1 Nov 2017 15:26:28 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"wipeRight","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Jake Nelson\n// License: MIT\n// Description: A hard-edged wipe from left to right\n// Tags: wipe, horizontal\n\nvec4 transition(vec2 uv) {\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 a=getFromColor(p);\n vec4 b=getToColor(p);\n return mix(a, b, step(0.0+p.x,progress));\n}\n","author":"Jake Nelson","license":"MIT","description":"A hard-edged wipe from left to right","tags":["wipe","horizontal"],"params":{},"textures":[],"createdAt":"Wed, 1 Nov 2017 15:27:02 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"wipeUp","paramsTypes":{},"defaultParams":{},"glsl":"// Author: Jake Nelson\n// License: MIT\n// Description: A hard-edged wipe from bottom to top\n// Tags: wipe, vertical\n\nvec4 transition(vec2 uv) {\n vec2 p=uv.xy/vec2(1.0).xy;\n vec4 a=getFromColor(p);\n vec4 b=getToColor(p);\n return mix(a, b, step(0.0+p.y,progress));\n}\n","author":"Jake Nelson","license":"MIT","description":"A hard-edged wipe from bottom to top","tags":["wipe","vertical"],"params":{},"textures":[],"createdAt":"Wed, 1 Nov 2017 15:24:36 -0500","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"},{"name":"x_axis_translation","paramsTypes":{},"defaultParams":{},"glsl":"// Author: lizhongjian\n// License: MIT\n// Description: The outgoing image slides to the right, uncovering a crossfade to the incoming one\n// Tags: slide, horizontal, blend\n\nvec4 transition (vec2 uv) {\n vec2 newUV = uv;\n newUV.x -= progress;\n if(uv.x >= progress)\n {\n return getFromColor(newUV);\n }\n\n \n return mix(\n getFromColor(uv),\n getToColor(uv),\n progress\n );\n}\n","author":"lizhongjian","license":"MIT","description":"The outgoing image slides to the right, uncovering a crossfade to the incoming one","tags":["slide","horizontal","blend"],"params":{},"textures":[],"createdAt":"Tue, 4 Apr 2023 15:34:35 +0800","updatedAt":"Sat, 10 Oct 2026 10:11:31 +0200"},{"name":"zoomInOut","paramsTypes":{},"defaultParams":{},"glsl":"// Author: OllyOllyOlly\n// License: MIT\n// Description: Zooms into the outgoing image until it blurs into a flat color, then out to the incoming one\n// Tags: zoom, blur\n\nvec2 zoom(vec2 uv, float amount) {\n return 0.5 + ((uv - 0.5) * (1.0 - amount));\n}\n\nvec4 transition (vec2 uv) {\n float zoomFrom = smoothstep(0.0, 1.0, progress * 2.0);\n float zoomTo = smoothstep(0.0, 1.0, (1.0 - progress) * 2.0);\n float crossfade = smoothstep(0.4, 0.6, progress);\n return mix(\n getFromColor(zoom(uv, zoomFrom)),\n getToColor(zoom(uv, zoomTo)),\n crossfade\n );\n}\n","author":"OllyOllyOlly","license":"MIT","description":"Zooms into the outgoing image until it blurs into a flat color, then out to the incoming one","tags":["zoom","blur"],"params":{},"textures":[],"createdAt":"Wed, 1 Apr 2026 19:33:08 +0200","updatedAt":"Fri, 9 Oct 2026 23:10:29 +0200"}]