Intro


The3D SDF functions articleis pretty popular, so I decided to write a similar one for 2D primitives, since most of the 3D primitives are grown as extrusions or revolutions of these 2D shapes. So getting these right is important. In particular, the functions bellow use the minimum number of square roots and divisions possible, and also produce better/faster results than constructing them from other primitives (when possible).

Note that all the primitives listed here come with a link to a realtime online demo in Shadertoy. In fact, this public playlist contains all the Shadertoy examples:https://www.shadertoy.com/playlist/MXdSRf, so don't miss that out.

Lastly, as with all in this website, all formulas and code are derived by myself (unless otherwise stated), so there might be errors or better ways to do things. Let me know if you think that's the case.

Primitives


All primitives are centered at the origin; you will have to transform the point to get arbitrarily rotated, translated and scaled objects (see below). Thedot2(v) function returns the dot product of a vector with itself (or the square of its length).


Circle - exact
https://www.shadertoy.com/view/3ltSW2

floatsdCircle(vec2p,floatr ) {returnlength(p) - r; }
Rounded Box - exact
https://www.shadertoy.com/view/4llXD7
https://www.youtube.com/watch?v=s5NGeUV2EyU

floatsdRoundedBox(in vec2p,in vec2b,in vec4r ) { r.xy = (p.x>0.0)?r.xy : r.zw; r.x = (p.y>0.0)?r.x : r.y;vec2q =abs(p)-b+r.x;returnmin(max(q.x,q.y),0.0) +length(max(q,0.0)) - r.x; }
Chamfer Box - exact
https://www.shadertoy.com/view/3fc3zs

floatsdChamferBox(in vec2p,in vec2b,in floatchamfer ) { p =abs(p)-b; p = (p.y>p.x) ? p.yx : p.xy; p.y += chamfer;const floatk =1.0-sqrt(2.0);if( p.y<0.0&& p.y+p.x*k<0.0)returnp.x;if( p.x<p.y )return(p.x+p.y)*sqrt(0.5);return length(p); }
Box - exact
https://www.youtube.com/watch?v=62-pRVZuS5c

floatsdBox(in vec2p,in vec2b ) {vec2d =abs(p)-b;returnlength(max(d,0.0)) +min(max(d.x,d.y),0.0); }
Oriented Box - exact
https://www.shadertoy.com/view/stcfzn

floatsdOrientedBox(in vec2p,in vec2a,in vec2b,floatth ) {floatl =length(b-a);vec2d = (b-a)/l;vec2q = (p-(a+b)*0.5); q =mat2(d.x,-d.y,d.y,d.x)*q; q =abs(q)-vec2(l,th)*0.5;returnlength(max(q,0.0)) +min(max(q.x,q.y),0.0); }
Segment - exact
https://www.shadertoy.com/view/3tdSDj
https://www.youtube.com/watch?v=PMltMdi1Wzg

floatsdSegment(in vec2p,in vec2a,in vec2b ) {vec2pa = p-a, ba = b-a;floath =clamp(dot(pa,ba)/dot(ba,ba),0.0,1.0);returnlength( pa - ba*h ); }
Rhombus - exact
https://www.shadertoy.com/view/XdXcRB

floatsdRhombus(in vec2p,in vec2b ) { b.y = -b.y; p =abs(p);floath =clamp( (dot(b,p)+b.y*b.y)/dot(b,b),0.0,1.0); p -= b*vec2(h,h-1.0);return length(p)*sign(p.x); }
Isosceles Trapezoid - exact
https://www.shadertoy.com/view/MlycD3

floatsdTrapezoid(in vec2p,in floatr1,floatr2,floathe ) {vec2k1 =vec2(r2,he);vec2k2 =vec2(r2-r1,2.0*he); p.x =abs(p.x);vec2ca =vec2(p.x-min(p.x,(p.y<0.0)?r1:r2),abs(p.y)-he);vec2cb = p - k1 + k2*clamp(dot(k1-p,k2)/dot2(k2),0.0,1.0);floats = (cb.x<0.0&& ca.y<0.0) ? -1.0:1.0;returns*sqrt(min(dot2(ca),dot2(cb)) ); }
Parallelogram - exact
https://www.shadertoy.com/view/7dlGRf

floatsdParallelogram(in vec2p,floatwi,floathe,floatsk ) {vec2e =vec2(sk,he); p = (p.y<0.0)?-p:p;vec2w = p - e; w.x -=clamp(w.x,-wi,wi);vec2d =vec2(dot(w,w), -w.y);floats = p.x*e.y - p.y*e.x; p = (s<0.0)?-p:p;vec2v = p -vec2(wi,0); v -= e*clamp(dot(v,e)/dot(e,e),-1.0,1.0); d =min( d,vec2(dot(v,v), wi*he-abs(s)));returnsqrt(d.x)*sign(-d.y); }
Equilateral Triangle - exact
https://www.shadertoy.com/view/Xl2yDW

floatsdEquilateralTriangle(in vec2p,in floatr ) {constfloatk =sqrt(3.0); p.x =abs(p.x) - r; p.y = p.y + r/k;if( p.x+k*p.y>0.0) p =vec2(p.x-k*p.y,-k*p.x-p.y)/2.0; p.x -=clamp( p.x, -2.0*r,0.0);return-length(p)*sign(p.y); }
Isosceles Triangle - exact
https://www.shadertoy.com/view/MldcD7

floatsdTriangleIsosceles(in vec2p,in vec2q ) { p.x =abs(p.x);vec2a = p - q*clamp(dot(p,q)/dot(q,q),0.0,1.0);vec2b = p - q*vec2(clamp( p.x/q.x,0.0,1.0),1.0);floats = -sign( q.y );vec2d =min(vec2(dot(a,a), s*(p.x*q.y-p.y*q.x) ),vec2(dot(b,b), s*(p.y-q.y) ));return-sqrt(d.x)*sign(d.y); }
Triangle - exact
https://www.shadertoy.com/view/XsXSz4

floatsdTriangle(in vec2p,in vec2p0,in vec2p1,in vec2p2 ) {vec2e0 = p1-p0, e1 = p2-p1, e2 = p0-p2;vec2v0 = p -p0, v1 = p -p1, v2 = p -p2;vec2pq0 = v0 - e0*clamp(dot(v0,e0)/dot(e0,e0),0.0,1.0);vec2pq1 = v1 - e1*clamp(dot(v1,e1)/dot(e1,e1),0.0,1.0);vec2pq2 = v2 - e2*clamp(dot(v2,e2)/dot(e2,e2),0.0,1.0);floats =sign( e0.x*e2.y - e0.y*e2.x );vec2d =min(min(vec2(dot(pq0,pq0), s*(v0.x*e0.y-v0.y*e0.x)),vec2(dot(pq1,pq1), s*(v1.x*e1.y-v1.y*e1.x))),vec2(dot(pq2,pq2), s*(v2.x*e2.y-v2.y*e2.x)));return-sqrt(d.x)*sign(d.y); }
Uneven Capsule - exact
https://www.shadertoy.com/view/4lcBWn

floatsdUnevenCapsule(vec2p,floatr1,floatr2,floath ) { p.x =abs(p.x);floatb = (r1-r2)/h;floata =sqrt(1.0-b*b);floatk =dot(p,vec2(-b,a)); if( k <0.0)returnlength(p) - r1; if( k > a*h )returnlength(p-vec2(0.0,h)) - r2;returndot(p,vec2(a,b) ) - r1; }
Regular Pentagon - exact
https://www.shadertoy.com/view/llVyWW

floatsdPentagon(in vec2p,in floatr ) {constvec3k =vec3(0.809016994,0.587785252,0.726542528); p.x =abs(p.x); p -=2.0*min(dot(vec2(-k.x,k.y),p),0.0)*vec2(-k.x,k.y); p -=2.0*min(dot(vec2( k.x,k.y),p),0.0)*vec2( k.x,k.y); p -=vec2(clamp(p.x,-r*k.z,r*k.z),r);returnlength(p)*sign(p.y); }
Regular Hexagon - exact

floatsdHexagon(in vec2p,in floatr ) {constvec3k =vec3(-0.866025404,0.5,0.577350269); p =abs(p); p -=2.0*min(dot(k.xy,p),0.0)*k.xy; p -=vec2(clamp(p.x, -k.z*r, k.z*r), r);returnlength(p)*sign(p.y); }
Regular Octogon - exact
https://www.shadertoy.com/view/llGfDG

floatsdOctogon(in vec2p,in floatr ) {constvec3k =vec3(-0.9238795325,0.3826834323,0.4142135623); p =abs(p); p -=2.0*min(dot(vec2( k.x,k.y),p),0.0)*vec2( k.x,k.y); p -=2.0*min(dot(vec2(-k.x,k.y),p),0.0)*vec2(-k.x,k.y); p -=vec2(clamp(p.x, -k.z*r, k.z*r), r);returnlength(p)*sign(p.y); }
Hexagram - exact
https://www.shadertoy.com/view/tt23RR

floatsdHexagram(in vec2p,in floatr ) {const vec4k =vec4(-0.5,0.8660254038,0.5773502692,1.7320508076); p =abs(p); p -=2.0*min(dot(k.xy,p),0.0)*k.xy; p -=2.0*min(dot(k.yx,p),0.0)*k.yx; p -=vec2(clamp(p.x,r*k.z,r*k.w),r);returnlength(p)*sign(p.y); }
Pentagram - exact
https://www.shadertoy.com/view/t3X3z4

floatsdPentagram(in vec2p,in floatr ) {const floatk1x =0.809016994;// cos(π/ 5) = ¼(√5+1)const floatk2x =0.309016994;// sin(π/10) = ¼(√5-1)const floatk1y =0.587785252;// sin(π/ 5) = ¼√(10-2√5)const floatk2y =0.951056516;// cos(π/10) = ¼√(10+2√5)const floatk1z =0.726542528;// tan(π/ 5) = √(5-2√5)const vec2v1 =vec2( k1x,-k1y);const vec2v2 =vec2(-k1x,-k1y);const vec2v3 =vec2( k2x,-k2y); p.x =abs(p.x); p -=2.0*max(dot(v1,p),0.0)*v1; p -=2.0*max(dot(v2,p),0.0)*v2; p.x =abs(p.x); p.y -= r;return length(p-v3*clamp(dot(p,v3),0.0,k1z*r)) *sign(p.y*v3.x-p.x*v3.y); }
Regular Star - exact
https://www.shadertoy.com/view/3tSGDy

floatsdStar(in vec2p,in floatr,in intn,in floatm) {// next 4 lines can be precomputed for a given shapefloatan =3.141593/float(n);floaten =3.141593/m;// m is between 2 and nvec2acs =vec2(cos(an),sin(an));vec2ecs =vec2(cos(en),sin(en));// ecs=vec2(0,1) for regular polygonfloatbn =mod(atan(p.x,p.y),2.0*an) - an; p =length(p)*vec2(cos(bn),abs(sin(bn))); p -= r*acs; p += ecs*clamp( -dot(p,ecs),0.0, r*acs.y/ecs.y);returnlength(p)*sign(p.x); }
Pie - exact
https://www.shadertoy.com/view/3l23RK

floatsdPie(in vec2p,in vec2c,in floatr ) { p.x =abs(p.x);floatl =length(p) - r;floatm =length(p-c*clamp(dot(p,c),0.0,r));// c=sin/cos of aperturereturnmax(l,m*sign(c.y*p.x-c.x*p.y)); }
Cut Disk - exact
https://www.shadertoy.com/view/ftVXRc

floatsdCutDisk(in vec2p,in floatr,in floath ) {floatw =sqrt(r*r-h*h);// constant for any given shapep.x =abs(p.x);floats =max( (h-r)*p.x*p.x+w*w*(h+r-2.0*p.y), h*p.x-w*p.y );return(s<0.0) ?length(p)-r : (p.x<w) ? h - p.y :length(p-vec2(w,h)); }
Arc - exact
https://www.shadertoy.com/view/wl23RK

floatsdArc(in vec2p,in vec2sc,in floatra,floatrb ) { // sc is thesin/cosof the arc's aperture p.x =abs(p.x);return((sc.y*p.x>sc.x*p.y) ?length(p-sc*ra) :abs(length(p)-ra)) - rb; }
Ring - exact
https://www.shadertoy.com/view/DsccDH

floatsdRing(in vec2p,in vec2n,in floatr,floatth ) { p.x =abs(p.x); p =mat2x2(n.x,n.y,-n.y,n.x)*p;return max(abs(length(p)-r)-th*0.5,length(vec2(p.x,max(0.0,abs(r-p.y)-th*0.5)))*sign(p.x) ); }
Horseshoe - exact
https://www.shadertoy.com/view/WlSGW1

floatsdHorseshoe(in vec2p,in vec2c,in floatr,in vec2w ) { p.x =abs(p.x);floatl =length(p); p =mat2(-c.x, c.y, c.y, c.x)*p; p =vec2((p.y>0.0|| p.x>0.0)?p.x:l*sign(-c.x), (p.x>0.0)?p.y:l ); p =vec2(p.x,abs(p.y-r))-w;returnlength(max(p,0.0)) +min(0.0,max(p.x,p.y)); }
Vesica - exact
https://www.shadertoy.com/view/XtVfRW

floatsdVesica(vec2p,floatw,floath) {vec3d =0.5*(w*w-h*h)/h; p =abs(p);vec3c = (w*p.y<d*(p.x-w)) ?vec3(0.0,w,0.0) :vec3(-d,0.0,d+h);return length(p-c.yx) - c.z; }
Oriented Vesica - exact
https://www.shadertoy.com/view/cs2yzG

floatsdOrientedVesica(vec2p,vec2a,vec2b,floatw ) {floatr =0.5*length(b-a);floatd =0.5*(r*r-w*w)/w;vec2v = (b-a)/r;vec2c = (b+a)*0.5;vec2q =0.5*abs(mat2(v.y,v.x,-v.x,v.y)*(p-c));vec3h = (r*q.x<d*(q.y-r)) ?vec3(0.0,r,0.0) :vec3(-d,0.0,d+w);return length( q-h.xy) - h.z; }
Moon - exact
https://www.shadertoy.com/view/WtdBRS

floatsdMoon(vec2p,floatd,floatra,floatrb ) { p.y =abs(p.y);floata = (ra*ra - rb*rb + d*d)/(2.0*d);floatb =sqrt(max(ra*ra-a*a,0.0));if( d*(p.x*b-p.y*a) > d*d*max(b-p.y,0.0) )returnlength(p-vec2(a,b));returnmax( (length(p )-ra), -(length(p-vec2(d,0))-rb)); }
Circle Cross - exact
https://www.shadertoy.com/view/NslXDM

floatsdRoundedCross(in vec2p,in floath ) {floatk =0.5*(h+1.0/h); p =abs(p);return( p.x<1.0&& p.y<p.x*(k-h)+h ) ? k-sqrt(dot2(p-vec2(1,k))) :sqrt(min(dot2(p-vec2(0,h)),dot2(p-vec2(1,0)))); }
Simple Egg - exact
https://www.shadertoy.com/view/XtVfRW

floatsdEgg(in vec2p,in floathe,in floatra,in floatrb,in floatbu ) {// all this can be precomputed for any given shapefloatr =0.5*(he + ra+rb)/bu;floatda = r - ra;floatdb = r - rb;floaty = (db*db - da*da - he*he)/(2.0*he);floatx =sqrt(da*da - y*y);// only this needs to be run per pixelp.x =abs(p.x);floatk = p.y*x - p.x*y;if( k>0.0&& k<he*(p.x+x) )return length(p+vec2(x,y))-r;return min(length(p)-ra,length(vec2(p.x,p.y-he))-rb ); }
Heart - exact
https://www.shadertoy.com/view/3tyBzV

floatsdHeart(in vec2p ) { p.x =abs(p.x);if( p.y+p.x>1.0)returnsqrt(dot2(p-vec2(0.25,0.75))) -sqrt(2.0)/4.0;returnsqrt(min(dot2(p-vec2(0.00,1.00)),dot2(p-0.5*max(p.x+p.y,0.0)))) *sign(p.x-p.y); }
Cross - exact exterior, bound interior
https://www.shadertoy.com/view/XtGfzw

floatsdCross(in vec2p,in vec2b,floatr ) { p =abs(p); p = (p.y>p.x) ? p.yx : p.xy;vec2q = p - b;floatk =max(q.y,q.x);vec2w = (k>0.0) ? q :vec2(b.y-p.x,-k);returnsign(k)*length(max(w,0.0)) + r; }
Rounded X - exact
https://www.shadertoy.com/view/3dKSDc

floatsdRoundedX(in vec2p,in floatw,in floatr ) { p =abs(p);returnlength(p-min(p.x+p.y,w)*0.5) - r; }
Polygon - exact
https://www.shadertoy.com/view/wdBXRW

floatsdPolygon(in vec2[N] v,in vec2p ) {floatd =dot(p-v[0],p-v[0]);floats =1.0;for(inti=0, j=N-1; i<N; j=i, i++ ) {vec2e = v[j] - v[i];vec2w = p - v[i];vec2b = w - e*clamp(dot(w,e)/dot(e,e),0.0,1.0); d =min( d,dot(b,b) ); bvec3c = bvec3(p.y>=v[i].y,p.y<v[j].y,e.x*w.y>e.y*w.x);if(all(c) ||all(not(c)) ) s*=-1.0; }returns*sqrt(d); }
Ellipse - exact
https://www.shadertoy.com/view/4sS3zz

floatsdEllipse(in vec2p,in vec2ab ) { p =abs(p);if( p.x > p.y ) {p=p.yx;ab=ab.yx;}floatl = ab.y*ab.y - ab.x*ab.x;floatm = ab.x*p.x/l;floatm2 = m*m;floatn = ab.y*p.y/l;floatn2 = n*n;floatc = (m2+n2-1.0)/3.0;floatc3 = c*c*c;floatq = c3 + m2*n2*2.0;floatd = c3 + m2*n2;floatg = m + m*n2;floatco;if( d<0.0) {floath =acos(q/c3)/3.0;floats =cos(h);floatt =sin(h)*sqrt(3.0);floatrx =sqrt( -c*(s + t +2.0) + m2 );floatry =sqrt( -c*(s - t +2.0) + m2 ); co = (ry+sign(l)*rx+abs(g)/(rx*ry)- m)/2.0; }else{floath =2.0*m*n*sqrt( d );floats =sign(q+h)*pow(abs(q+h),1.0/3.0);floatu =sign(q-h)*pow(abs(q-h),1.0/3.0);floatrx = -s - u - c*4.0+2.0*m2;floatry = (s - u)*sqrt(3.0);floatrm =sqrt( rx*rx + ry*ry ); co = (ry/sqrt(rm-rx)+2.0*g/rm-m)/2.0; }vec2r = ab *vec2(co,sqrt(1.0-co*co));returnlength(r-p) *sign(p.y-r.y); }
Parabola - exact
https://www.shadertoy.com/view/ws3GD7

floatsdParabola(in vec2pos,in floatk ) { pos.x =abs(pos.x);floatik =1.0/k;floatp = ik*(pos.y -0.5*ik)/3.0;floatq =0.25*ik*ik*pos.x;floath = q*q - p*p*p;floatx;if( h>0.0) {floatr =pow(q+sqrt(h),1.0/3.0); x = r + p/r; }else{floatr =sqrt(p); x =2.0*r*cos(acos(q/(p*r))/3.0); }returnlength(pos-vec2(x,k*x*x)) *sign(pos.x-x); }
Parabola Segment - exact
https://www.shadertoy.com/view/3lSczz

floatsdParabola(in vec2pos,in floatwi,in floathe ) { pos.x =abs(pos.x);floatik = wi*wi/he;floatp = ik*(he-pos.y-0.5*ik)/3.0;floatq = pos.x*ik*ik/4.0;floath = q*q - p*p*p;floatx;if( h>0.0) {floatr =pow(q+sqrt(h),1.0/3.0); x = r + p/r; }else{floatr =sqrt(p); x =2.0*r*cos(acos(q/(p*r))/3.0); } x =min(x,wi);returnlength(pos-vec2(x,he-x*x/ik)) *sign(ik*(pos.y-he)+pos.x*pos.x); }
Quadratic Bezier - exact
https://www.shadertoy.com/view/MlKcDD

floatsdBezier(in vec2pos,in vec2A,in vec2B,in vec2C ) {vec2a = B - A;vec2b = A -2.0*B + C;vec2c = a *2.0;vec2d = A - pos;floatkk =1.0/dot(b,b);floatkx = kk *dot(a,b);floatky = kk * (2.0*dot(a,a)+dot(d,b)) /3.0;floatkz = kk *dot(d,a);floatres =0.0;floatp = ky - kx*kx;floatp3 = p*p*p;floatq = kx*(2.0*kx*kx-3.0*ky) + kz;floath = q*q +4.0*p3;if( h >=0.0) { h =sqrt(h);vec2x = (vec2(h,-h)-q)/2.0;vec2uv =sign(x)*pow(abs(x),vec2(1.0/3.0));floatt =clamp( uv.x+uv.y-kx,0.0,1.0); res =dot2(d + (c + b*t)*t); }else{floatz =sqrt(-p);floatv =acos( q/(p*z*2.0) ) /3.0;floatm =cos(v);floatn =sin(v)*1.732050808;vec3t =clamp(vec3(m+m,-n-m,n-m)*z-kx,0.0,1.0); res =min(dot2(d+(c+b*t.x)*t.x),dot2(d+(c+b*t.y)*t.y) );// the third root cannot be the closest// res = min(res,dot2(d+(c+b*t.z)*t.z));}returnsqrt( res ); }
Bobbly Cross - exact
https://www.shadertoy.com/view/NssXWM

floatsdBlobbyCross(in vec2pos,floathe ) { pos =abs(pos); pos =vec2(abs(pos.x-pos.y),1.0-pos.x-pos.y)/sqrt(2.0);floatp = (he-pos.y-0.25/he)/(6.0*he);floatq = pos.x/(he*he*16.0);floath = q*q - p*p*p;floatx;if( h>0.0) {floatr =sqrt(h); x =pow(q+r,1.0/3.0)-pow(abs(q-r),1.0/3.0)*sign(r-q); }else{floatr =sqrt(p); x =2.0*r*cos(acos(q/(p*r))/3.0); } x =min(x,sqrt(2.0)/2.0);vec2z =vec2(x,he*(1.0-2.0*x*x)) - pos;returnlength(z) *sign(z.y); }
Tunnel - exact
https://www.shadertoy.com/view/flSSDy

floatsdTunnel(in vec2p,in vec2wh ) { p.x =abs(p.x); p.y = -p.y;vec2q = p - wh;floatd1 =dot2(vec2(max(q.x,0.0),q.y)); q.x = (p.y>0.0) ? q.x :length(p)-wh.x;floatd2 =dot2(vec2(q.x,max(q.y,0.0)));floatd =sqrt(min(d1,d2) );return(max(q.x,q.y)<0.0) ? -d : d; }
Stairs - exact
https://www.shadertoy.com/view/7tKSWt

floatsdStairs(in vec2p,in vec2wh,in floatn ) {vec2ba = wh*n;floatd =min(dot2(p-vec2(clamp(p.x,0.0,ba.x),0.0)),dot2(p-vec2(ba.x,clamp(p.y,0.0,ba.y))) );floats =sign(max(-p.y,p.x-ba.x) );floatdia =length(wh); p =mat2(wh.x,-wh.y, wh.y,wh.x)*p/dia;floatid =clamp(round(p.x/dia),0.0,n-1.0); p.x = p.x - id*dia; p =mat2(wh.x, wh.y,-wh.y,wh.x)*p/dia;floathh = wh.y/2.0; p.y -= hh;if( p.y>hh*sign(p.x) ) s=1.0; p = (id<0.5|| p.x>0.0) ? p : -p; d =min( d,dot2(p-vec2(0.0,clamp(p.y,-hh,hh))) ); d =min( d,dot2(p-vec2(clamp(p.x,0.0,wh.x),hh)) );returnsqrt(d)*s; }
Quadratic Circle - exact
https://www.shadertoy.com/view/Nd3cW8

floatsdQuadraticCircle(in vec2p ) { p =abs(p);if( p.y>p.x ) p=p.yx;floata = p.x-p.y;floatb = p.x+p.y;floatc = (2.0*b-1.0)/3.0;floath = a*a + c*c*c;floatt;if( h>=0.0) { h =sqrt(h); t =sign(h-a)*pow(abs(h-a),1.0/3.0) -pow(h+a,1.0/3.0); }else{floatz =sqrt(-c);floatv =acos(a/(c*z))/3.0; t = -z*(cos(v)+sin(v)*1.732050808); } t *=0.5;vec2w =vec2(-t,t) +0.75- t*t - p;returnlength(w) *sign( a*a*0.5+b-1.5 ); }
Hyperbola - exact
https://www.shadertoy.com/view/DtjXDG

floatsdHyberbola(in vec2p,in floatk,in floathe )// k in (0,inf){ p =abs(p); p =vec2(p.x-p.y,p.x+p.y)/sqrt(2.0);floatx2 = p.x*p.x/16.0;floaty2 = p.y*p.y/16.0;floatr = k*(4.0*k - p.x*p.y)/12.0;floatq = (x2 - y2)*k*k;floath = q*q + r*r*r;floatu;if( h<0.0) {floatm =sqrt(-r); u = m*cos(acos(q/(r*m))/3.0); }else{floatm =pow(sqrt(h)-q,1.0/3.0); u = (m - r/m)/2.0; }floatw =sqrt( u + x2 );floatb = k*p.y - x2*p.x*2.0;floatt = p.x/4.0- w +sqrt(2.0*x2 - u + b/w/4.0); t =max(t,sqrt(he*he*0.5+k)-he/sqrt(2.0));floatd =length( p-vec2(t,k/t) );returnp.x*p.y < k ? d : -d; }
Cool S - exact
https://www.shadertoy.com/view/clVXWc

floatsdfCoolS(in vec2p ) {floatsix = (p.y<0.0) ? -p.x : p.x; p.x =abs(p.x); p.y =abs(p.y) -0.2;floatrex = p.x -min(round(p.x/0.4),0.4);floataby =abs(p.y-0.2)-0.6;floatd =dot2(vec2(six,-p.y)-clamp(0.5*(six-p.y),0.0,0.2)); d =min(d,dot2(vec2(p.x,-aby)-clamp(0.5*(p.x-aby),0.0,0.4))); d =min(d,dot2(vec2(rex,p.y -clamp(p.y ,0.0,0.4))));floats =2.0*p.x + aby +abs(aby+0.4) -0.4;return sqrt(d) *sign(s); }
Circle Wave - exact
https://www.shadertoy.com/view/stGyzt

floatsdCircleWave(in vec2p,in floattb,in floatra ) { tb =3.1415927*5.0/6.0*max(tb,0.0001);vec2co = ra*vec2(sin(tb),cos(tb)); p.x =abs(mod(p.x,co.x*4.0)-co.x*2.0);vec2p1 = p;vec2p2 =vec2(abs(p.x-2.0*co.x),-p.y+2.0*co.y);floatd1 = ((co.y*p1.x>co.x*p1.y) ?length(p1-co) :abs(length(p1)-ra));floatd2 = ((co.y*p2.x>co.x*p2.y) ?length(p2-co) :abs(length(p2)-ra));return min(d1, d2); }



Making shapes rounded



All the shapes above can be converted into rounded shapes by subtracting a constant from their distance function. That, effectively moves the isosurface (isoperimeter I guess) from the level zero to one of the outer rings, which naturally are rounded, as it can be seen in the yellow areas in all the images above. So, basically, for any shape defined byd(x,y) = sdf(x,y), one can make it sounded by computingd(x,y) = sdf(x,y) - r. You can learn more about this inthis Youtube video.

floatopRound(in vec2p,in floatr ) {returnsdShape(p) - r; }

These are a few examples: rounded line, rounded triangle, rounded box and a rounded pentagon:




Making shapes annular



Similarly, shapes can be made annular (like a ring or the layers of an onion), but taking theirabsolute value and then subtracting aconstant from their field. So, for any shape defined byd(x,y) = sdf(x,y)computed(x,y) = |sdf(x,y)| - r:

floatopOnion(in vec2p,in floatr ) {returnabs(sdShape(p)) - r; }

These are a few examples: annular rounded line, an annular triangle, an annular box and a annular pentagon:




Rigid deformations, domain repetition, range distortion, boolean operations, smooth connections, etc



All of these work just as well as in 3D case, so I won't repeat the examples already exist inthis article.