open .fs { "DESCRIPTION" : "generated" , "CATEGORIES" : [ "generative" ] , "INPUTS" : [
{ "NAME" : "speed" , "TYPE" : "float" , "MIN" : 0.0 , "MAX" : 4.0 , "DEFAULT" : 1.0 } ,
{ "NAME" : "spin" , "TYPE" : "float" , "MIN" : 0.0 , "MAX" : 2.0 , "DEFAULT" : 1.0 } ,
{ "NAME" : "zoom" , "TYPE" : "float" , "MIN" : 0.1 , "MAX" : 3.0 , "DEFAULT" : 1.0 } ,
{ "NAME" : "lens" , "TYPE" : "float" , "MIN" : 0.1 , "MAX" : 1.5 , "DEFAULT" : 0.9 } ,
{ "NAME" : "tube" , "TYPE" : "float" , "MIN" : 0.01 , "MAX" : 0.3 , "DEFAULT" : 0.08 } ,
{ "NAME" : "hue" , "TYPE" : "float" , "MIN" : 0.0 , "MAX" : 1.0 , "DEFAULT" : 0.0 } ,
{ "NAME" : "glow" , "TYPE" : "float" , "MIN" : 0.0 , "MAX" : 3.0 , "DEFAULT" : 1.0 }
] }
#define PI 3.14159265359
#define TAU 6.28318530718
#define NV 24
const float PERIOD = 16.0 ;
mat2 rot (float a){ float c = cos (a), s = sin (a); return mat2 (c, -s, s, c); }
vec3 pal (float t){
vec3 p1 = 0.5 + 0.5 * cos (TAU * (t + vec3 (0.0 , 0.33 , 0.66 )));
vec3 p2 = 0.5 + 0.5 * cos (TAU * (t + vec3 (0.55 , 0.40 , 0.18 )));
return mix (p1, p2, 0.5 );
}
vec4 vert24 (int k){
int pp = k / 4 ;
int ss = k - pp * 4 ;
float s0 = mod (float (ss), 2.0 ) * 2.0 - 1.0 ;
float s1 = floor (float (ss) / 2.0 ) * 2.0 - 1.0 ;
if (pp == 0 ) return vec4 (s0, s1, 0.0 , 0.0 );
if (pp == 1 ) return vec4 (s0, 0.0 , s1, 0.0 );
if (pp == 2 ) return vec4 (s0, 0.0 , 0.0 , s1);
if (pp == 3 ) return vec4 (0.0 , s0, s1, 0.0 );
if (pp == 4 ) return vec4 (0.0 , s0, 0.0 , s1);
return vec4 (0.0 , 0.0 , s0, s1);
}
float segDist (vec3 ro, vec3 rd, vec3 A, vec3 B, out float tray, out float edgeParam){
vec3 d2 = B - A;
vec3 r = ro - A;
float e = dot (d2, d2);
float f = dot (d2, r);
float b = dot (rd, d2);
float c = dot (rd, r);
float den = e - b * b;
float s = (den > 1e-5 ) ? (b * f - c * e) / den : 0.0 ;
s = max (s, 0.0 );
float u = clamp ((b * s + f) / e, 0.0 , 1.0 );
s = max (dot (A + d2 * u - ro, rd), 0.0 );
tray = s;
edgeParam = u;
vec3 pr = ro + rd * s;
vec3 ps = A + d2 * u;
return length (pr - ps);
}
void main (){
vec2 uv = (gl_FragCoord .xy - 0.5 * RENDERSIZE .xy) / RENDERSIZE .y;
float ph = fract (TIME * speed / PERIOD);
float th = TAU * ph;
mat2 Rroll = rot (0.4 * spin * sin (th));
vec4 base[NV];
vec3 proj[NV];
float rotw[NV];
for (int k = 0 ; k < NV; k++){
vec4 v = vert24 (k);
base[k] = v;
v.xz = rot (0.62 ) * v.xz;
v.yw = rot (1.13 ) * v.yw;
v.xy = rot (th) * v.xy;
v.zw = rot (th) * v.zw;
v.xy = Rroll * v.xy;
rotw[k] = v.w;
proj[k] = v.xyz / (2.6 - v.w);
}
float R = 1.4 * zoom;
float a = th;
float a2 = th + 0.32 ;
vec3 ro = vec3 (R * (sin (a) + 0.35 * sin (3.0 * a)), 0.65 * sin (2.0 * a),
R * (cos (a) + 0.35 * cos (2.0 * a)));
vec3 look = vec3 (R * (sin (a2) + 0.35 * sin (3.0 * a2)), 0.65 * sin (2.0 * a2),
R * (cos (a2) + 0.35 * cos (2.0 * a2)));
vec3 fwd = normalize (mix (normalize (look - ro), normalize (-ro), 0.45 ));
vec3 rgt = normalize (cross (vec3 (0.0 , 1.0 , 0.0 ), fwd));
vec3 upv = cross (fwd, rgt);
float rr = length (uv);
float theta = rr * lens * PI ;
vec2 dir2 = rr > 1.0e-5 ? uv / rr : vec2 (0.0 , 1.0 );
vec3 rd = normalize (cos (theta) * fwd + sin (theta) * (dir2.x * rgt + dir2.y * upv));
float w0 = tube * tube;
vec3 col = vec3 (0.0 );
for (int i = 0 ; i < NV; i++){
for (int j = 0 ; j < NV; j++){
if (j <= i) continue ;
vec4 dv = base[i] - base[j];
if (abs (dot (dv, dv) - 2.0 ) > 0.05 ) continue ;
float tray, edgeParam;
float d = segDist (ro, rd, proj[i], proj[j], tray, edgeParam);
float g = w0 / (d * d + w0);
g = g * g;
float dots = 0.5 + 0.5 * cos (TAU * edgeParam * 6.0 );
g *= 0.4 + 0.6 * dots;
float fog = exp (-0.22 * max (tray - 2.0 , 0.0 ));
float wMid = 0.5 * (rotw[i] + rotw[j]);
col += pal (hue + wMid * 0.15 + th * 0.02 ) * g * fog * glow;
}
}
col += vec3 (0.02 , 0.01 , 0.03 ) * (1.0 - rr * 0.3 );
col = pow (col, vec3 (0.7 ));
gl_FragColor = vec4 (col, 1.0 );
}