175 lines
4.5 KiB
GLSL
175 lines
4.5 KiB
GLSL
// Originally from: https://www.shadertoy.com/view/ttBcRV
|
|
// License CC0: Flying through glowing stars
|
|
// The result of playing around trying to improve an old shader
|
|
|
|
#define PI 3.141592654
|
|
#define TAU (2.0*PI)
|
|
#define TIME iTime
|
|
#define RESOLUTION iResolution
|
|
|
|
#define LESS(a,b,c) mix(a,b,step(0.,c))
|
|
#define SABS(x,k) LESS((.5/(k))*(x)*(x)+(k)*.5,abs(x),abs(x)-(k))
|
|
|
|
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
|
|
|
|
vec3 hsv2rgb(vec3 c) {
|
|
const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
|
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
|
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
|
}
|
|
|
|
float hash(in vec3 co) {
|
|
return fract(sin(dot(co, vec3(12.9898,58.233, 12.9898+58.233))) * 13758.5453);
|
|
}
|
|
|
|
float starn(vec2 p, float r, int n, float m) {
|
|
// From IQ: https://www.shadertoy.com/view/3tSGDy
|
|
// https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
|
|
|
|
// Minor tweak to use SABS over abs to smooth inner corners
|
|
// SABS: https://www.shadertoy.com/view/Ws2SDK
|
|
|
|
// next 4 lines can be precomputed for a given shape
|
|
float an = 3.141593/float(n);
|
|
float en = 3.141593/m; // m is between 2 and n
|
|
vec2 acs = vec2(cos(an),sin(an));
|
|
vec2 ecs = vec2(cos(en),sin(en)); // ecs=vec2(0,1) for regular polygon,
|
|
|
|
float bn = mod(atan(p.x,p.y),2.0*an) - an;
|
|
p = length(p)*vec2(cos(bn),SABS(sin(bn), 0.15));
|
|
p -= r*acs;
|
|
p += ecs*clamp( -dot(p,ecs), 0.0, r*acs.y/ecs.y);
|
|
return length(p)*sign(p.x);
|
|
}
|
|
|
|
vec4 alphaBlend(vec4 back, vec4 front) {
|
|
vec3 xyz = mix(back.xyz*back.w, front.xyz, front.w);
|
|
float w = mix(back.w, 1.0, front.w);
|
|
return vec4(xyz, w);
|
|
}
|
|
|
|
void rot(inout vec2 p, float a) {
|
|
float c = cos(a);
|
|
float s = sin(a);
|
|
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
|
|
}
|
|
|
|
vec3 offset(float z) {
|
|
float a = z;
|
|
vec2 p = -0.075*(vec2(cos(a), sin(a*sqrt(2.0))) + vec2(cos(a*sqrt(0.75)), sin(a*sqrt(0.5))));
|
|
return vec3(p, z);
|
|
}
|
|
|
|
vec3 doffset(float z) {
|
|
float eps = 0.05;
|
|
return 0.5*(offset(z + eps) - offset(z - eps))/eps;
|
|
}
|
|
|
|
vec3 ddoffset(float z) {
|
|
float eps = 0.05;
|
|
return 0.5*(doffset(z + eps) - doffset(z - eps))/eps;
|
|
}
|
|
|
|
vec4 planeCol(vec3 ro, vec3 rd, float n, vec3 pp) {
|
|
const float s = 0.5;
|
|
|
|
vec2 p = pp.xy;
|
|
float z = pp.z;
|
|
vec2 dpy = dFdy(p);
|
|
float aa = length(dpy);
|
|
|
|
p -= (1.0+5.0*(pp.z - ro.z))*offset(z).xy;
|
|
|
|
p *= s;
|
|
float r = hash(vec3(floor(p+0.5), n));
|
|
p = fract(p+0.5)-0.5;
|
|
rot(p, ((TAU*r+n)*0.25));
|
|
float d = starn(p, 0.20, 3 + 2*int(3.0*r), 3.0);
|
|
d -= 0.06;
|
|
d/=s;
|
|
|
|
float ds = -d+0.03;
|
|
vec3 cols = hsv2rgb(vec3(337.0/360.0+0.1*sin(n*0.3), 0.8, 0.54+0.2*sin(n*0.3)));
|
|
float ts = 1.0 - smoothstep(-aa, 0.0, ds);
|
|
vec4 cs = vec4(cols, ts*0.93);
|
|
|
|
float db = abs(d) - (0.06);
|
|
db = abs(db) - 0.03;
|
|
db = abs(db) - 0.00;
|
|
db = max(db, -d+0.03);
|
|
vec3 colb = vec3(1.0, 0.7, 0.5);
|
|
float tb = exp(-(db)*30.0*(1.0 - 10.0*aa));
|
|
vec4 cb = vec4(1.5*colb, tb);
|
|
|
|
vec4 ct = alphaBlend(cs, cb);
|
|
|
|
return ct;
|
|
}
|
|
|
|
vec3 color(vec3 ww, vec3 uu, vec3 vv, vec3 ro, vec2 p) {
|
|
vec3 rd = normalize(p.x*uu + p.y*vv + (2.0-tanh(length(p)))*ww);
|
|
|
|
vec4 col = vec4(vec3(0.0), 1.0);
|
|
|
|
const float planeDist = 1.0;
|
|
const int furthest = 6;
|
|
const int fadeFrom = furthest-3;
|
|
|
|
float nz = floor(ro.z / planeDist);
|
|
|
|
for (int i = furthest; i >= 1; --i) {
|
|
float pz = planeDist*nz + planeDist*float(i);
|
|
|
|
float pd = (pz - ro.z)/rd.z;
|
|
|
|
if (pd > 0.0) {
|
|
vec3 pp = ro + rd*pd;
|
|
|
|
vec4 pcol = planeCol(ro, rd, nz+float(i), pp);
|
|
float fadeIn = 1.0-smoothstep(planeDist*float(fadeFrom), planeDist*float(furthest), pp.z-ro.z);
|
|
pcol.xyz *= sqrt(fadeIn);
|
|
|
|
col = alphaBlend(col, pcol);
|
|
}
|
|
}
|
|
|
|
return col.xyz*col.w;
|
|
}
|
|
|
|
vec3 postProcess(vec3 col, vec2 q) {
|
|
col=pow(clamp(col,0.0,1.0),vec3(0.75));
|
|
col=col*0.6+0.4*col*col*(3.0-2.0*col);
|
|
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4);
|
|
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7);
|
|
return col;
|
|
}
|
|
|
|
vec3 effect(vec2 p, vec2 q) {
|
|
float tm = TIME*0.65;
|
|
|
|
vec3 ro = offset(tm);
|
|
vec3 dro = doffset(tm);
|
|
vec3 ddro = ddoffset(tm);
|
|
|
|
vec3 ww = normalize(dro);
|
|
vec3 uu = normalize(cross(vec3(0.0,1.0,0.0)+1.5*ddro, ww));
|
|
vec3 vv = normalize(cross(ww, uu));
|
|
|
|
vec3 col = color(ww, uu, vv, ro, p);
|
|
col = postProcess(col, q);
|
|
|
|
const float fadeIn = 2.0;
|
|
|
|
return col*smoothstep(0.0, fadeIn, TIME);
|
|
}
|
|
|
|
void mainImage(out vec4 fragColor, vec2 fragCoord) {
|
|
vec2 q = fragCoord/RESOLUTION.xy;
|
|
vec2 p = -1. + 2. * q;
|
|
p.x *= RESOLUTION.x/RESOLUTION.y;
|
|
|
|
vec3 col = effect(p, q);
|
|
|
|
fragColor = vec4(col, 1.0);
|
|
}
|