// classic(300es)
precision highp float;
precision highp int;
uniform vec2 resolution;
uniform float time;
uniform sampler2D backbuffer;
out vec4 outColor;
// const
const float PI = 3.141592653589793;
// utilities
float atan2(float y, float x){
return x == 0.0 ? 0.5*PI*sign(y) : atan(y, x);
}
vec3 hsv2rgb(float h, float s, float v){
return ((clamp(abs(fract(h+vec3(0.0, 2.0, 1.0) / 3.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0) - 1.0) * s + 1.0) * v;
}
mat2 rotate2D(float th){
float c = cos(th);
float s = sin(th);
return mat2(c, -s, s, c);
}
float smootherstep(float e0, float e1, float x){
x = clamp((x - e0) / (e1 - e0), 0.0, 1.0);
return x*x*x*(x*(x*6.0-15.0)+10.0);
}
// hash
const uint UINT_MAX = 0xffffffffu;
uvec3 k = uvec3(0x456789abu, 0x6789ab45u, 0x89ab4567u);
uvec3 u = uvec3(1u, 2u, 3u);
uint uhash11(uint n){
n ^= n << u.x;
n ^= n >> u.x;
n *= k.x;
n ^= n << u.x;
return n * k.x;
}
uvec2 uhash22(uvec2 n){
n ^= n.yx << u.xy;
n ^= n.yx >> u.xy;
n *= k.xy;
n ^= n.yx << u.xy;
return n * k.xy;
}
uvec3 uhash33(uvec3 n){
n ^= n.yzx << u;
n ^= n.yzx >> u;
n *= k;
n ^= n.yzx << u;
return n * k;
}
float hash11(float p){
uint n = floatBitsToUint(p);
return float(uhash11(n)) / float(UINT_MAX);
}
vec2 hash22(vec2 p){
uvec2 n = floatBitsToUint(p);
return vec2(uhash22(n)) / vec2(UINT_MAX);
}
vec3 hash33(vec3 p){
uvec3 n = floatBitsToUint(p);
return vec3(uhash33(n)) / vec3(UINT_MAX);
}
float hash21(vec2 p){
uvec2 n = floatBitsToUint(p);
return float(uhash22(n).x) / float(UINT_MAX);
}
float hash31(vec3 p){
uvec3 n = floatBitsToUint(p);
return float(uhash33(n).x) / float(UINT_MAX);
}
// perlin noise
float gtable2(vec2 lattice, vec2 p){
uvec2 n = floatBitsToUint(lattice);
uint ind = uhash22(n).x >> 29;
float u = 0.9238795325112867 * (ind < 4u ? p.x : p.y); // cos(PI*0.125)
float v = 0.3826834323650898 * (ind < 4u ? p.y : p.x); // sin(PI*0.125)
return ((ind & 1u) == 0u ? u : -u) + ((ind & 2u) == 0u? v : -v);
}
float pnoise21(vec2 p){
vec2 n = floor(p);
vec2 f = fract(p);
float v00 = gtable2(n + vec2(0.0, 0.0), f - vec2(0.0, 0.0));
float v10 = gtable2(n + vec2(1.0, 0.0), f - vec2(1.0, 0.0));
float v01 = gtable2(n + vec2(0.0, 1.0), f - vec2(0.0, 1.0));
float v11 = gtable2(n + vec2(1.0, 1.0), f - vec2(1.0, 1.0));
f = f * f * f * (10.0 - 15.0 * f + 6.0 * f * f);
return 0.5 + 0.5 * mix(mix(v00, v10, f.x), mix(v01, v11, f.x), f.y);
}
float gtable3(vec3 lattice, vec3 p){
uvec3 n = floatBitsToUint(lattice);
uint ind = uhash33(n).x >> 28;
float u = ind < 8u ? p.x : p.y;
float v = ind < 4u ? p.y : ind == 12u || ind == 14u ? p.x : p.z;
return ((ind & 1u) == 0u? u: -u) + ((ind & 2u) == 0u? v : -v);
}
float pnoise31(vec3 p){
vec3 n = floor(p);
vec3 f = fract(p);
float v000 = gtable3(n + vec3(0.0, 0.0, 0.0), f - vec3(0.0, 0.0, 0.0)) * 0.7071067811865475; // 1.0 / sqrt(2.0)
float v100 = gtable3(n + vec3(1.0, 0.0, 0.0), f - vec3(1.0, 0.0, 0.0)) * 0.7071067811865475; // 1.0 / sqrt(2.0)
float v010 = gtable3(n + vec3(0.0, 1.0, 0.0), f - vec3(0.0, 1.0, 0.0)) * 0.7071067811865475; // 1.0 / sqrt(2.0)
float v001 = gtable3(n + vec3(0.0, 0.0, 1.0), f - vec3(0.0, 0.0, 1.0)) * 0.7071067811865475; // 1.0 / sqrt(2.0)
float v011 = gtable3(n + vec3(0.0, 1.0, 1.0), f - vec3(0.0, 1.0, 1.0)) * 0.7071067811865475; // 1.0 / sqrt(2.0)
float v101 = gtable3(n + vec3(1.0, 0.0, 1.0), f - vec3(1.0, 0.0, 1.0)) * 0.7071067811865475; // 1.0 / sqrt(2.0)
float v110 = gtable3(n + vec3(1.0, 1.0, 0.0), f - vec3(1.0, 1.0, 0.0)) * 0.7071067811865475; // 1.0 / sqrt(2.0)
float v111 = gtable3(n + vec3(1.0, 1.0, 1.0), f - vec3(1.0, 1.0, 1.0)) * 0.7071067811865475; // 1.0 / sqrt(2.0)
f = f * f * f * (10.0 - 15.0 * f + 6.0 * f * f);
float v00 = mix(v000, v100, f.x);
float v10 = mix(v010, v110, f.x);
float v01 = mix(v001, v101, f.x);
float v11 = mix(v011, v111, f.x);
float v0 = mix(v00, v10, f.y);
float v1 = mix(v01, v11, f.y);
return 0.5 + 0.5 * mix(v0, v1, f.z);
}
// domain warping
float warp21(vec2 p, float g){
float val = 0.0;
float th;
for (int i=0; i<4; i++){
th = 2.0 * PI * val;
//val = fbm21(p + g * vec2(cos(th) ,sin(th)), 0.5);
//val = fbm21(p + g * val, 0.5);
//val = pnoise21(p + g * val);
val = pnoise21(p + g * vec2(cos(th) ,sin(th)));
}
return val;
}
void main(){
float t = time;
vec2 r = resolution;
vec4 FC = gl_FragCoord;
vec4 o;
vec2 p = (2.0*FC.xy - r) / min(r.x, r.y);
p *= 4.0;
// skybox
vec2 pt = p;
pt *= 2.0;
pt = 2.0*fract(pt)-1.0;
pt = abs(pt);
vec3 color = pt.x + pt.y < 1.0 ? vec3(0.4) : vec3(0.8);
// truchet
float k = 8.0;
//p *= rotate2D(2.0*PI*cos(0.055*PI*t));
for (float i = 0.0; i < k; i++){
pt = p;
pt *= rotate2D(2.0*PI*cos(0.055*PI*(t+0.25*i)));
pt.y += 8.0*sin(0.17*PI*t);
pt.x += 8.0*cos(0.19*PI*t);
float h = 5.0 * hash21(floor(pt));
vec2 pf = 2.0*fract(pt) - 1.0;
float d;
float rs = 0.2;
float rl = 0.5;
if (h < 1.0){
d = min(
abs(length(pf-vec2(1.0, -1.0))-1.0)-rs,
abs(length(pf-vec2(-1.0, 1.0))-1.0)-rs
);
}
else if (h < 2.0){
d = min(
abs(length(pf-vec2(1.0, 1.0))-1.0)-rs,
abs(length(pf-vec2(-1.0, -1.0))-1.0)-rs
);
}
else if (h < 3.0){
d = min(
abs(pf.x)-rs,
abs(pf.y)-rs
);
}
else if (h < 4.0){
pf = abs(pf);
d = min(
abs(pf.x)-rs,
length(pf-vec2(1.0, 0.0))-rl
);
}
else{
pf = abs(pf);
d = min(
abs(pf.y)-rs,
length(pf-vec2(0.0, 1.0))-rl
);
}
if (d < 0.0){
color = hsv2rgb(
0.125*t - 0.125*i/k - 0.0625*length(vec2(2.0*pt.x, pt.y)),
1.0 - i/k,
1.0
) * warp21(vec2(pt.x, pt.y+4.0*t), 1.5+1.0*cos(1.0*(floor(t)+smootherstep(0.0, 1.0, fract(t)))*PI));
break;
}
else{
p *= 1.2;
}
}
o.xyz = color;
o.w = 1.0;
outColor = o;
}