#define rainbowSeizure
//rainbowSeizure shows underlining geometry.

//in conclusion: trigonometry functions like sin()
//quickly accumulate larger rounding errors than
//the precision that you could get from
//using them to calculate more precise constants for skewed gradients.
//and this only gets worse for mobile hardware that rounds sin() even more.

//skewing (rotated) gradients for distance functions
//easily is more precise than inverse square roots or asin()

//this is all about the constants of this hex function.
const float tau=asin(1.)*4.,
    c1=0.57735,//0.57735
    c2=1.1547;//1.1547
//return distance of p to border of hexagon with inner radius r.
float hexBase(const in vec2 p,const in float r){vec2 q=abs(p);
 return max(q.x,max(q.x+q.y*c1,q.y*c2))-r;}
//i was curious if i could 
//trigonometrically calculate them to higher precision.
//but i gave up, realizing tha they already are VERY precise
//for pretty much all purposes of signed distance functions.
//they are more precise than the accumulative
//precision loss of a few sin() mod() (1/x*x) (1+1/x) functions.
//showing that hexBase() is not only tiny 
//but also bestPerformance and PreciseEnough
//unless you want some subpixel precision for antialiasing
//which i do not care for.

//hex()==hexBase() but with 2 more components
vec3 hex(const in vec2 p,const in float r){vec2 q=abs(p);
 vec3 s=vec3(0.);//return value.                    
 s.x=q.x+q.y*c1;
 s.y=    q.y*c2;   
 s.z=max(q.x,max(q.x+q.y*c1,q.y*c2))-r;
 return s;}
//for optional visualization of what shapes are defined by the constants.
//via "#rainbowSeizure"

//return 2d rotation matrix r=2.*pi->full rotation;
mat2 r2(float r){float s=sin(r),c=cos(r);return mat2(c,s,-s,c);}
#define oz vec3(1,0,-1)
//shorter faster (less precise) variant of r2();
#define r2s(r) mat2(sin(r+oz.xyyz*asin(1.)))
//for single rotations only !!!
//as it rotates by mirroring along half-rotation.
//and that mirror symmetry cancels out all accumulativeEven rotations 
//(similar to how 2 quaternion rotations of an inaginary vector cancel out the real part)

#define ssb(a,b,c) smoothstep(a-b,a+b,c)

void mainImage(out vec4 r,in vec2 f){
 vec2 p=f.xy/iResolution.xy;//scale frame to screen resolution.
 p-=vec2(.5);//move frame so that p=vec2(0,0)=frame.center
 p.x/=iResolution.y/iResolution.x;//scale frame.x to aspect ratio
 p*=2.;//scale frame
 p*=r2s(tau/6.);//rotate frame by fullRotation/6;
 float blur=sin(iTime)*.5+.52;//vary blur ovrer time
 vec3 h=hex(p,1.);
 h=mod(h*2./blur,2.);//blur also sets some scaling.
    //mod(x.2.)makes the image brighter, i want to see the circles
 //r.rgb=ssb(.5,blur,h);
 r.rgb=vec3(ssb(.5,blur,h.z))*.8+.2;
#ifdef rainbowSeizure
 r.rg*=h.rg;//optional
#endif
 //
 //draw 6 circles to measure the corners of the hexagon.
 vec2 d=vec2(1.,.0);//circle.center , gets rotated.
 #define tru g=length(p-d);if(mod(g,1.)<.005 
 float tru)r.r-=.5+.2;//1 blue circle
 for(int i=0;i<6;i++){
  d*=r2(tau/6.);tru)r.g-=.5+.2;//rotate redraw.
}}
