// CC0: Let's self reflect// Always enjoyed the videos of Platonic solids with inner mirrors// I made some previous attempts but thought I make another attempt it// Reducing the alias effects on the inner reflections turned out to be a bit tricky. // Simplest solution is just to run run fullscreen on a 4K screen ;)// Function to generate the solid found here: https://www.shadertoy.com/view/MsKGzw// Tinker with these parameters to create different solids// -------------------------------------------------------constfloatrotation_speed=0.25;constfloatpoly_U=1.;// [0, inf]constfloatpoly_V=0.5;// [0, inf]constfloatpoly_W=1.0;// [0, inf]constintpoly_type=3;// [2, 5]constfloatpoly_zoom=2.0;constfloatinner_sphere=1.;constfloatrefr_index=0.9;#define MAX_BOUNCES2 6
// -------------------------------------------------------#define TIME iTime
#define RESOLUTION iResolution
#define PI 3.141592654
#define TAU (2.0*PI)
// License: WTFPL, author: sam hocevar, found: https://stackoverflow.com/a/17897228/418488constvec4hsv2rgb_K=vec4(1.0,2.0/3.0,1.0/3.0,3.0);vec3hsv2rgb(vec3c){vec3p=abs(fract(c.xxx+hsv2rgb_K.xyz)*6.0-hsv2rgb_K.www);returnc.z*mix(hsv2rgb_K.xxx,clamp(p-hsv2rgb_K.xxx,0.0,1.0),c.y);}// License: WTFPL, author: sam hocevar, found: https://stackoverflow.com/a/17897228/418488// Macro version of above to enable compile-time constants#define HSV2RGB(c) (c.z * mix(hsv2rgb_K.xxx, clamp(abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www) - hsv2rgb_K.xxx, 0.0, 1.0), c.y))
#define TOLERANCE2 0.0005
//#define MAX_RAY_LENGTH2 10.0#define MAX_RAY_MARCHES2 50
#define NORM_OFF2 0.005
#define BACKSTEP2
#define TOLERANCE3 0.0005
#define MAX_RAY_LENGTH3 10.0
#define MAX_RAY_MARCHES3 90
#define NORM_OFF3 0.005
constvec3rayOrigin=vec3(0.0,1.,-5.);constvec3sunDir=normalize(-rayOrigin);constvec3sunCol=HSV2RGB(vec3(0.06,0.90,1E-2))*1.;constvec3bottomBoxCol=HSV2RGB(vec3(0.66,0.80,0.5))*1.;constvec3topBoxCol=HSV2RGB(vec3(0.60,0.90,1.))*1.;constvec3glowCol0=HSV2RGB(vec3(0.05,0.7,1E-3))*1.;constvec3glowCol1=HSV2RGB(vec3(0.95,0.7,1E-3))*1.;constvec3beerCol=-HSV2RGB(vec3(0.15+0.5,0.7,2.));constfloatrrefr_index=1./refr_index;// License: Unknown, author: knighty, found: https://www.shadertoy.com/view/MsKGzwconstfloatpoly_cospin=cos(PI/float(poly_type));constfloatpoly_scospin=sqrt(0.75-poly_cospin*poly_cospin);constvec3poly_nc=vec3(-0.5,-poly_cospin,poly_scospin);constvec3poly_pab=vec3(0.,0.,1.);constvec3poly_pbc_=vec3(poly_scospin,0.,0.5);constvec3poly_pca_=vec3(0.,poly_scospin,poly_cospin);constvec3poly_p=normalize((poly_U*poly_pab+poly_V*poly_pbc_+poly_W*poly_pca_));constvec3poly_pbc=normalize(poly_pbc_);constvec3poly_pca=normalize(poly_pca_);mat3g_rot;vec2g_gd;// License: MIT, author: Inigo Quilez, found: https://iquilezles.org/articles/noacos/mat3rot(vec3d,vec3z){vec3v=cross(z,d);floatc=dot(z,d);floatk=1.0/(1.0+c);returnmat3(v.x*v.x*k+c,v.y*v.x*k-v.z,v.z*v.x*k+v.y,v.x*v.y*k+v.z,v.y*v.y*k+c,v.z*v.y*k-v.x,v.x*v.z*k-v.y,v.y*v.z*k+v.x,v.z*v.z*k+c);}// License: Unknown, author: Matt Taylor (https://github.com/64), found: https://64.github.io/tonemapping/vec3aces_approx(vec3v){v=max(v,0.0);v*=0.6;floata=2.51;floatb=0.03;floatc=2.43;floatd=0.59;floate=0.14;returnclamp((v*(a*v+b))/(v*(c*v+d)+e),0.0,1.0);}floatsphere(vec3p,floatr){returnlength(p)-r;}// License: MIT, author: Inigo Quilez, found: https://iquilezles.org/articles/distfunctions/floatbox(vec2p,vec2b){vec2d=abs(p)-b;returnlength(max(d,0.0))+min(max(d.x,d.y),0.0);}// License: Unknown, author: knighty, found: https://www.shadertoy.com/view/MsKGzwvoidpoly_fold(inoutvec3pos){vec3p=pos;for(inti=0;i<poly_type;++i){p.xy=abs(p.xy);p-=2.*min(0.,dot(p,poly_nc))*poly_nc;}pos=p;}floatpoly_plane(vec3pos){floatd0=dot(pos,poly_pab);floatd1=dot(pos,poly_pbc);floatd2=dot(pos,poly_pca);floatd=d0;d=max(d,d1);d=max(d,d2);returnd;}floatpoly_corner(vec3pos){floatd=length(pos)-.0125;returnd;}floatdot2(vec3p){returndot(p,p);}floatpoly_edge(vec3pos){floatdla=dot2(pos-min(0.,pos.x)*vec3(1.,0.,0.));floatdlb=dot2(pos-min(0.,pos.y)*vec3(0.,1.,0.));floatdlc=dot2(pos-min(0.,dot(pos,poly_nc))*poly_nc);returnsqrt(min(min(dla,dlb),dlc))-2E-3;}vec3shape(vec3pos){pos*=g_rot;pos/=poly_zoom;poly_fold(pos);pos-=poly_p;returnvec3(poly_plane(pos),poly_edge(pos),poly_corner(pos))*poly_zoom;}vec3render0(vec3ro,vec3rd){vec3col=vec3(0.0);floatsrd=sign(rd.y);floattp=-(ro.y-6.)/abs(rd.y);if(srd<0.){col+=bottomBoxCol*exp(-0.5*(length((ro+tp*rd).xz)));}if(srd>0.0){vec3pos=ro+tp*rd;vec2pp=pos.xz;floatdb=box(pp,vec2(5.0,9.0))-3.0;col+=topBoxCol*rd.y*rd.y*smoothstep(0.25,0.0,db);col+=0.2*topBoxCol*exp(-0.5*max(db,0.0));col+=0.05*sqrt(topBoxCol)*max(-db,0.0);}col+=sunCol/(1.001-dot(sunDir,rd));returncol;}floatdf2(vec3p){vec3ds=shape(p);floatd2=ds.y-5E-3;floatd0=min(-ds.x,d2);floatd1=sphere(p,inner_sphere);g_gd=min(g_gd,vec2(d2,d1));floatd=(min(d0,d1));returnd;}floatrayMarch2(vec3ro,vec3rd,floattinit){floatt=tinit;#if defined(BACKSTEP2)
vec2dti=vec2(1e10,0.0);#endif
inti;for(i=0;i<MAX_RAY_MARCHES2;++i){floatd=df2(ro+rd*t);#if defined(BACKSTEP2)
if(d<dti.x){dti=vec2(d,t);}#endif
// Bouncing in a closed shell, will never missif(d<TOLERANCE2/* || t > MAX_RAY_LENGTH3 */){break;}t+=d;}#if defined(BACKSTEP2)
if(i==MAX_RAY_MARCHES2){t=dti.y;};#endif
returnt;}vec3normal2(vec3pos){vec2eps=vec2(NORM_OFF2,0.0);vec3nor;nor.x=df2(pos+eps.xyy)-df2(pos-eps.xyy);nor.y=df2(pos+eps.yxy)-df2(pos-eps.yxy);nor.z=df2(pos+eps.yyx)-df2(pos-eps.yyx);returnnormalize(nor);}vec3render2(vec3ro,vec3rd,floatdb){vec3agg=vec3(0.0);floatragg=1.;floattagg=0.;for(intbounce=0;bounce<MAX_BOUNCES2;++bounce){if(ragg<0.1)break;g_gd=vec2(1E3);floatt2=rayMarch2(ro,rd,min(db+0.05,0.3));vec2gd2=g_gd;tagg+=t2;vec3p2=ro+rd*t2;vec3n2=normal2(p2);vec3r2=reflect(rd,n2);vec3rr2=refract(rd,n2,rrefr_index);floatfre2=1.+dot(n2,rd);vec3beer=ragg*exp(0.2*beerCol*tagg);agg+=glowCol1*beer*((1.+tagg*tagg*4E-2)*6./max(gd2.x,5E-4+tagg*tagg*2E-4/ragg));vec3ocol=0.2*beer*render0(p2,rr2);if(gd2.y<=TOLERANCE2){ragg*=1.-0.9*fre2;}else{agg+=ocol;ragg*=0.8;}ro=p2;rd=r2;db=gd2.x;}returnagg;}floatdf3(vec3p){vec3ds=shape(p);g_gd=min(g_gd,ds.yz);constfloatsw=0.02;floatd1=min(ds.y,ds.z)-sw;floatd0=ds.x;d0=min(d0,ds.y);d0=min(d0,ds.z);returnd0;}floatrayMarch3(vec3ro,vec3rd,floattinit,outintiter){floatt=tinit;inti;for(i=0;i<MAX_RAY_MARCHES3;++i){floatd=df3(ro+rd*t);if(d<TOLERANCE3||t>MAX_RAY_LENGTH3){break;}t+=d;}iter=i;returnt;}vec3normal3(vec3pos){vec2eps=vec2(NORM_OFF3,0.0);vec3nor;nor.x=df3(pos+eps.xyy)-df3(pos-eps.xyy);nor.y=df3(pos+eps.yxy)-df3(pos-eps.yxy);nor.z=df3(pos+eps.yyx)-df3(pos-eps.yyx);returnnormalize(nor);}vec3render3(vec3ro,vec3rd){intiter;vec3skyCol=render0(ro,rd);vec3col=skyCol;g_gd=vec2(1E3);floatt1=rayMarch3(ro,rd,0.1,iter);vec2gd1=g_gd;vec3p1=ro+t1*rd;vec3n1=normal3(p1);vec3r1=reflect(rd,n1);vec3rr1=refract(rd,n1,refr_index);floatfre1=1.+dot(rd,n1);fre1*=fre1;floatifo=mix(0.5,1.,smoothstep(1.0,0.9,float(iter)/float(MAX_RAY_MARCHES3)));if(t1<MAX_RAY_LENGTH3){col=render0(p1,r1)*(0.5+0.5*fre1)*ifo;vec3icol=render2(p1,rr1,gd1.x);if(gd1.x>TOLERANCE3&&gd1.y>TOLERANCE3&&rr1!=vec3(0.)){col+=icol*(1.-0.75*fre1)*ifo;}}col+=(glowCol0+1.*fre1*(glowCol0))/max(gd1.x,3E-4);returncol;}vec3effect(vec2p,vec2pp){constfloatfov=2.0;constvec3up=vec3(0.,1.,0.);constvec3la=vec3(0.0);constvec3ww=normalize(normalize(la-rayOrigin));constvec3uu=normalize(cross(up,ww));constvec3vv=cross(ww,uu);vec3rd=normalize(-p.x*uu+p.y*vv+fov*ww);vec3col=vec3(0.0);col=render3(rayOrigin,rd);col-=2E-2*vec3(2.,3.,1.)*(length(p)+0.25);col=aces_approx(col);col=sqrt(col);returncol;}voidmainImage(outvec4fragColor,invec2fragCoord){vec2q=fragCoord/RESOLUTION.xy;vec2p=-1.+2.*q;vec2pp=p;p.x*=RESOLUTION.x/RESOLUTION.y;floata=TIME*rotation_speed;vec3r0=vec3(1.0,sin(vec2(sqrt(0.5),1.0)*a));vec3r1=vec3(cos(vec2(sqrt(0.5),1.0)*0.913*a),1.0);mat3rot=rot(normalize(r0),normalize(r1));g_rot=rot;vec3col=effect(p,pp);fragColor=vec4(col,1.0);}
Our centralized storage agent works on-device, unifying various developer tools to proactively capture and enrich useful materials, streamline collaboration, and solve complex problems through a contextual understanding of your unique workflow.
👥 Ideal for solo developers, teams, and cross-company projects
Top comments (0)