/*{ "DESCRIPTION": "Glass Orrery: a translucent Crown Knot turns inside a sparse orbital glass instrument, with whole Life pixels shared across their combined depth contours.", "INPUTS": [ { "NAME": "speed", "TYPE": "float", "DEFAULT": 0.50, "MIN": 0.0, "MAX": 1.5 }, { "NAME": "braid", "TYPE": "float", "DEFAULT": 0.78, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "cellSize", "TYPE": "float", "DEFAULT": 6.0, "MIN": 2.0, "MAX": 12.0 }, { "NAME": "inlay", "TYPE": "float", "DEFAULT": 0.76, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "translucency", "TYPE": "float", "DEFAULT": 0.62, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "complexity", "TYPE": "float", "DEFAULT": 0.72, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "lifeRule", "TYPE": "long", "DEFAULT": 1, "MIN": 0, "MAX": 2, "VALUES": [0, 1, 2], "LABELS": ["Conway", "HighLife", "Seeds"] }, { "NAME": "decay", "TYPE": "float", "DEFAULT": 0.972, "MIN": 0.90, "MAX": 0.998 }, { "NAME": "seed", "TYPE": "float", "DEFAULT": 11.0, "MIN": 0.0, "MAX": 30.0 }, { "NAME": "gold", "TYPE": "color", "DEFAULT": [1.0, 0.58, 0.04, 1.0] }, { "NAME": "blue", "TYPE": "color", "DEFAULT": [0.04, 0.34, 1.0, 1.0] }, { "NAME": "pink", "TYPE": "color", "DEFAULT": [1.0, 0.05, 0.42, 1.0] } ], "PASSES": [ { "TARGET": "depthMap", "FLOAT": true }, { "TARGET": "glassLayer", "FLOAT": true }, { "TARGET": "life", "PERSISTENT": true, "FLOAT": true }, {} ] }*/ #define PI 3.14159265359 mat2 rot(float a){float c=cos(a),s=sin(a);return mat2(c,-s,s,c);} float hash21(vec2 p){ p=fract(p*vec2(419.2,371.9)); p+=dot(p,p.yx+31.7+seed); return fract(p.x*p.y); } float smin(float a,float b,float k){ float h=clamp(0.5+0.5*(b-a)/k,0.0,1.0); return mix(b,a,h)-k*h*(1.0-h); } float loopShape(vec3 p,float phase,float t){ float a=atan(p.z,p.x); float radial=length(p.xz); float lobes=3.0*a+phase+t*0.7; float ringRadius=0.72+cos(lobes)*0.16*braid; float ringY=sin(lobes)*0.28*braid; return length(vec2(radial-ringRadius,p.y-ringY))-0.145; } float knotMap(vec3 p,float t){ p.yz=rot(t*0.37)*p.yz; p.xz=rot(t*0.23)*p.xz; vec3 a=p-vec3(0.22,0.0,0.0); vec3 b=p+vec3(0.22,0.0,0.0); b.xy=rot(PI*0.5+sin(t*0.4)*0.18)*b.xy; float d=smin(loopShape(a,0.0,t),loopShape(b,PI,-t*0.83),0.10); float nucleus=length(p+vec3(0.0,sin(t)*0.08,0.0))-0.23; return smin(d,nucleus,0.11); } float torus(vec3 p,vec2 r){return length(vec2(length(p.xz)-r.x,p.y))-r.y;} float innerMap(vec3 p,float t){ p.yz=rot(t*0.37)*p.yz; p.xz=rot(t*0.23)*p.xz; vec3 q=p; q.xy=rot(0.82+sin(t*0.31)*0.18)*q.xy; float a=torus(q,vec2(0.43,0.036)); q=p; q.yz=rot(-0.92+cos(t*0.27)*0.16)*q.yz; float b=torus(q,vec2(0.34,0.030)); vec3 bead=vec3(cos(t*0.91)*0.29,sin(t*0.67)*0.16,sin(t*0.91)*0.29); float pearls=min(length(p-bead)-0.055,length(p+bead)-0.055); return min(min(a,b),pearls); } float orreryMap(vec3 p,float t){ vec3 q=p; q.xy=rot(0.62+t*0.12)*q.xy; q.yz=rot(0.48+sin(t*0.21)*0.12)*q.yz; float ringA=torus(q,vec2(1.00,0.026)); q=p; q.xz=rot(-0.72+t*0.09)*q.xz; q.xy=rot(-0.38)*q.xy; float ringB=torus(q,vec2(0.88,0.022)); float a=t*0.34; vec3 nodeA=vec3(cos(a)*0.79,sin(a*1.7)*0.20,sin(a)*0.79); vec3 nodeB=vec3(cos(a+PI)*0.93,sin(a*1.3+1.4)*0.16,sin(a+PI)*0.93); float nodes=min(length(p-nodeA)-0.052,length(p-nodeB)-0.044); return min(min(ringA,ringB),nodes)+mix(0.075,0.0,complexity); } float sceneMap(vec3 p,float t){return min(knotMap(p,t),orreryMap(p,t));} vec3 knotNormal(vec3 p,float t){ vec2 e=vec2(0.0025,0.0); return normalize(vec3( knotMap(p+e.xyy,t)-knotMap(p-e.xyy,t), knotMap(p+e.yxy,t)-knotMap(p-e.yxy,t), knotMap(p+e.yyx,t)-knotMap(p-e.yyx,t) )); } vec4 renderKnot(vec2 uv,float t){ vec2 p=uv*2.0-1.0; p.x*=RENDERSIZE.x/RENDERSIZE.y; p=rot(sin(t*0.41)*0.13)*p; vec3 ro=vec3(0.0,0.0,3.05); vec3 rd=normalize(vec3(p,-2.05)); float travel=0.0,hit=0.0; for(int i=0;i<36;i++){ float d=sceneMap(ro+rd*travel,t); if(d<0.0025){hit=1.0;break;} travel+=max(d*0.72,0.011); if(travel>6.0)break; } vec3 bg=vec3(0.006,0.004,0.018)+blue.rgb*pow(max(0.0,1.0-length(p)*0.58),5.0)*0.03; if(hit<0.5)return vec4(bg,0.0); vec3 pos=ro+rd*travel; vec3 n=knotNormal(pos,t); vec3 l=normalize(vec3(-0.45,0.85,0.65)); float diff=max(dot(n,l),0.0); float rim=pow(1.0-max(dot(n,-rd),0.0),2.4); float spec=pow(max(dot(reflect(-l,n),-rd),0.0),52.0); float phase=0.5+0.5*sin(atan(pos.z,pos.x)*5.0+pos.y*6.0-t*1.7); vec3 skin=mix(blue.rgb*0.34,gold.rgb*0.38,phase); vec3 color=skin*(0.18+diff*0.88)+mix(pink.rgb,blue.rgb,phase)*rim*0.72+spec; float sceneDepth=clamp((travel-1.65)/2.15,0.0,1.0); return vec4(color,0.08+sceneDepth*0.90); } vec4 renderDepth(vec2 uv,float t){ vec2 p=uv*2.0-1.0; p.x*=RENDERSIZE.x/RENDERSIZE.y; p=rot(sin(t*0.41)*0.13)*p; vec3 ro=vec3(0.0,0.0,3.05); vec3 rd=normalize(vec3(p,-2.05)); float travel=0.0,hit=0.0; for(int i=0;i<44;i++){ float d=sceneMap(ro+rd*travel,t); if(d<0.0025){hit=1.0;break;} travel+=max(d*0.72,0.009); if(travel>6.0)break; } if(hit<0.5)return vec4(0.0); float exitT=travel+0.012; for(int i=0;i<30;i++){ float d=sceneMap(ro+rd*exitT,t); exitT+=max(abs(d)*0.56,0.008); if(d>0.004&&exitT>travel+0.045)break; } float thickness=clamp((exitT-travel)*2.15,0.0,1.0); vec3 hitPos=ro+rd*travel; float structure=step(orreryMap(hitPos,t),knotMap(hitPos,t)); float depth=clamp((travel-1.65)/2.15,0.0,1.0); return vec4(depth,thickness,structure,1.0); } vec4 renderGlass(vec2 uv,float t){ vec2 p=uv*2.0-1.0; p.x*=RENDERSIZE.x/RENDERSIZE.y; vec3 bg=vec3(0.004,0.003,0.014)+blue.rgb*pow(max(0.0,1.0-length(p)*0.46),5.0)*0.035; bg+=mix(blue.rgb,pink.rgb,uv.y)*0.012*(0.5+0.5*sin(p.x*5.0-p.y*3.0+t*0.18)); vec4 g=IMG_NORM_PIXEL(depthMap,uv); if(g.a<0.5)return vec4(bg,1.0); vec2 px=1.5/RENDERSIZE; vec4 l=IMG_NORM_PIXEL(depthMap,uv-vec2(px.x,0.0)); vec4 r=IMG_NORM_PIXEL(depthMap,uv+vec2(px.x,0.0)); vec4 d=IMG_NORM_PIXEL(depthMap,uv-vec2(0.0,px.y)); vec4 u=IMG_NORM_PIXEL(depthMap,uv+vec2(0.0,px.y)); float zL=mix(g.r,l.r,l.a),zR=mix(g.r,r.r,r.a); float zD=mix(g.r,d.r,d.a),zU=mix(g.r,u.r,u.a); vec3 n=normalize(vec3((zL-zR)*8.0,(zD-zU)*8.0,0.30)); float rim=pow(1.0-clamp(n.z,0.0,1.0),2.1); float diff=0.5+0.5*dot(n,normalize(vec3(-0.45,0.72,0.55))); float phase=0.5+0.5*sin(g.r*21.0+uv.x*7.0-uv.y*5.0-t*0.62); vec3 tint=mix(blue.rgb,gold.rgb,phase); float opacity=mix(0.58,0.18,translucency)+g.g*0.15; vec3 transmission=bg*exp(-tint*(0.65+g.g*1.65)); vec3 color=mix(transmission,tint*(0.12+diff*0.48),opacity); color+=mix(pink.rgb,blue.rgb,phase)*rim*(0.28+0.54*translucency); color+=mix(gold.rgb,pink.rgb,0.25+0.25*sin(t+g.r*14.0))*g.b*(0.22+0.52*complexity); color+=vec3(1.0)*pow(max(diff,0.0),18.0)*0.22; return vec4(color,1.0); } void main(){ vec2 uv=isf_FragNormCoord; float t=TIME*speed; if(PASSINDEX==0){gl_FragColor=renderDepth(uv,t);return;} if(PASSINDEX==1){gl_FragColor=renderGlass(uv,t);return;} if(PASSINDEX==2){ float grid=max(cellSize,2.0); vec2 id=floor(uv*RENDERSIZE/grid); vec2 center=(id+0.5)*grid/RENDERSIZE; vec2 d=grid/RENDERSIZE; vec4 old=IMG_NORM_PIXEL(life,center); float count=0.0; count+=step(0.48,IMG_NORM_PIXEL(life,center+d*vec2(-1.0,-1.0)).r); count+=step(0.48,IMG_NORM_PIXEL(life,center+d*vec2( 0.0,-1.0)).r); count+=step(0.48,IMG_NORM_PIXEL(life,center+d*vec2( 1.0,-1.0)).r); count+=step(0.48,IMG_NORM_PIXEL(life,center+d*vec2(-1.0, 0.0)).r); count+=step(0.48,IMG_NORM_PIXEL(life,center+d*vec2( 1.0, 0.0)).r); count+=step(0.48,IMG_NORM_PIXEL(life,center+d*vec2(-1.0, 1.0)).r); count+=step(0.48,IMG_NORM_PIXEL(life,center+d*vec2( 0.0, 1.0)).r); count+=step(0.48,IMG_NORM_PIXEL(life,center+d*vec2( 1.0, 1.0)).r); float birth=smoothstep(2.55,2.92,count)*(1.0-smoothstep(3.08,3.45,count)); float six=smoothstep(5.55,5.92,count)*(1.0-smoothstep(6.08,6.45,count)); float two=smoothstep(1.55,1.92,count)*(1.0-smoothstep(2.08,2.45,count)); float survive=max(two,birth); if(lifeRule==1)birth=max(birth,six); if(lifeRule==2){birth=two;survive=0.0;} float rule=mix(birth,survive,step(0.5,old.r)); vec4 depthCell=IMG_NORM_PIXEL(depthMap,center); vec4 depthL=IMG_NORM_PIXEL(depthMap,center-d*vec2(1.0,0.0)); vec4 depthR=IMG_NORM_PIXEL(depthMap,center+d*vec2(1.0,0.0)); vec4 depthD=IMG_NORM_PIXEL(depthMap,center-d*vec2(0.0,1.0)); vec4 depthU=IMG_NORM_PIXEL(depthMap,center+d*vec2(0.0,1.0)); float surface=step(0.5,depthCell.a); float depthEdge=max(max(abs(depthCell.r-depthL.r),abs(depthCell.r-depthR.r)),max(abs(depthCell.r-depthD.r),abs(depthCell.r-depthU.r))); depthEdge=max(depthEdge,max(max(abs(depthCell.a-depthL.a),abs(depthCell.a-depthR.a)),max(abs(depthCell.a-depthD.a),abs(depthCell.a-depthU.a)))*0.32); depthEdge=smoothstep(0.028,0.14,depthEdge); float contour=1.0-smoothstep(0.055,0.18,abs(fract(depthCell.r*7.5-t*0.035)-0.5)); float source=surface*max(depthEdge,contour*0.55); float pulse=step(0.67,hash21(id+floor(float(FRAMEINDEX)/7.0))); float dt=min(TIMEDELTA,1.0/20.0); float response=1.0-exp(-dt*36.0); float next=mix(old.r*decay,rule,response*0.80); next=max(next,source*pulse*mix(0.64,1.0,inlay)); float age=clamp(old.g*decay+next*response*0.12,0.0,1.0); gl_FragColor=vec4(clamp(next,0.0,1.0),age,source,1.0); return; } float grid=max(cellSize,2.0); vec2 id=floor(uv*RENDERSIZE/grid); vec2 center=(id+0.5)*grid/RENDERSIZE; vec2 d=grid/RENDERSIZE; vec4 cell=IMG_NORM_PIXEL(life,center); vec4 depthCell=IMG_NORM_PIXEL(depthMap,center); vec4 depthL=IMG_NORM_PIXEL(depthMap,center-d*vec2(1.0,0.0)); vec4 depthR=IMG_NORM_PIXEL(depthMap,center+d*vec2(1.0,0.0)); vec4 depthD=IMG_NORM_PIXEL(depthMap,center-d*vec2(0.0,1.0)); vec4 depthU=IMG_NORM_PIXEL(depthMap,center+d*vec2(0.0,1.0)); float surface=step(0.5,depthCell.a); float depthEdge=max(max(abs(depthCell.r-depthL.r),abs(depthCell.r-depthR.r)),max(abs(depthCell.r-depthD.r),abs(depthCell.r-depthU.r))); depthEdge=max(depthEdge,max(max(abs(depthCell.a-depthL.a),abs(depthCell.a-depthR.a)),max(abs(depthCell.a-depthD.a),abs(depthCell.a-depthU.a)))*0.32); depthEdge=smoothstep(0.028,0.14,depthEdge); float contour=1.0-smoothstep(0.05,0.18,abs(fract(depthCell.r*7.5-t*0.035)-0.5)); float groove=surface*max(depthEdge,contour*0.70); vec3 subject=IMG_NORM_PIXEL(glassLayer,uv).rgb; vec2 q=fract(uv*RENDERSIZE/grid); float tile=smoothstep(0.02,0.15,min(min(q.x,1.0-q.x),min(q.y,1.0-q.y))); float alive=smoothstep(0.40,0.76,cell.r)*tile*groove; vec3 lifeColor=mix(gold.rgb,pink.rgb,fract(cell.g+id.x*0.07+id.y*0.11)); float nearLight=mix(0.68,1.18,1.0-depthCell.r); vec3 color=mix(subject,subject*0.52,groove*inlay*0.42); color+=lifeColor*alive*(0.48+inlay*0.76)*nearLight; color+=mix(blue.rgb,pink.rgb,depthCell.r)*depthEdge*surface*(0.08+0.25*inlay); vec2 px=1.25/RENDERSIZE; vec4 raw=IMG_NORM_PIXEL(depthMap,uv); float silhouette=max(max(abs(raw.a-IMG_NORM_PIXEL(depthMap,uv-vec2(px.x,0.0)).a),abs(raw.a-IMG_NORM_PIXEL(depthMap,uv+vec2(px.x,0.0)).a)),max(abs(raw.a-IMG_NORM_PIXEL(depthMap,uv-vec2(0.0,px.y)).a),abs(raw.a-IMG_NORM_PIXEL(depthMap,uv+vec2(0.0,px.y)).a))); color+=pink.rgb*silhouette*0.34; color=1.0-exp(-max(color,0.0)*1.34); gl_FragColor=vec4(color,1.0); }
Glass Orrery: a translucent Crown Knot turns inside a sparse orbital glass instrument, with whole Life pixels shared across their combined depth contours.
generation prompt
Human-directed Goop Life Lab: translucent Crown Knot with cell-centered depth-aware Life and orbital glass forms.
export clip · render a video in your browser
Renders to video in your browser (no upload), stepping the real renderer frame by frame so multipass + feedback come out right. motion auto-animates the shader's own knobs — each export rolls a fresh take (🎲 re-roll, 🔒 to pin one you like). GIF is slower with a tighter length cap; MP4/WebM are faster. Some devices record in real time (noted below if so) — keep the tab visible.
embed · drop this shader into any page
Renders client-side in the reader's browser (CC0 — no attribution required, but the backlink is appreciated).