Back to shaders
Shader test bench
Zoom In Circles.fs
runnable fragment
Complete GLSL fragment shader. Stronghold runs it directly when the browser can compile it.
Code
uniform sampler2D startImage;
uniform sampler2D endImage;
uniform float progress;
precision mediump float;
/*
{
"CATEGORIES" : [
"Wipe"
],
"CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/ZoomInCircles.glsl",
"DESCRIPTION": "",
"INPUTS" : [
{
"TYPE" : "image",
"NAME" : "startImage"
},
{
"TYPE" : "image",
"NAME" : "endImage"
},
{
"DEFAULT" : 0,
"TYPE" : "float",
"NAME" : "progress",
"MIN" : 0,
"MAX" : 1
}
],
"ISFVSN" : "2"
}
*/
vec4 getFromColor(vec2 inUV) {
return texture2D(startImage, inUV);
}
vec4 getToColor(vec2 inUV) {
return texture2D(endImage, inUV);
}
float ratio = u_resolution.x/u_resolution.y;
// License: MIT
// Author: dycm8009
// ported by gre from https://gist.github.com/dycm8009/948e99b1800e81ad909a
vec2 zoom(vec2 uv, float amount) {
return 0.5 + ((uv - 0.5) * amount);
}
vec2 ratio2 = vec2(1.0, 1.0 / ratio);
vec4 transition(vec2 uv) {
// TODO: some timing are hardcoded but should be one or many parameters
// TODO: should also be able to configure how much circles
// TODO: if() branching should be avoided when possible, prefer use of step() & other functions
vec2 r = 2.0 * ((vec2(uv.xy) - 0.5) * ratio2);
float pro = progress / 0.8;
float z = pro * 0.2;
float t = 0.0;
if (pro > 1.0) {
z = 0.2 + (pro - 1.0) * 5.;
t = clamp((progress - 0.8) / 0.07, 0.0, 1.0);
}
if (length(r) < 0.5+z) {
// uv = zoom(uv, 0.9 - 0.1 * pro);
}
else if (length(r) < 0.8+z*1.5) {
uv = zoom(uv, 1.0 - 0.15 * pro);
t = t * 0.5;
}
else if (length(r) < 1.2+z*2.5) {
uv = zoom(uv, 1.0 - 0.2 * pro);
t = t * 0.2;
}
else {
uv = zoom(uv, 1.0 - 0.25 * pro);
}
return mix(getFromColor(uv), getToColor(uv), t);
}
void main() {
gl_FragColor = transition((gl_FragCoord.xy / u_resolution.xy).xy);
}