// #include "res://addons/rokojori_action_library/Runtime/Shading/Library/SDF.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Colors.gdshaderinc" void computeRectangleBounds( float in_offset, float in_radius, float in_maxRadius, vec2 size, out vec2 minP, out vec2 maxP, out float out_radius ) { out_radius = min( in_radius, in_maxRadius ); float borderSize = out_radius + in_offset; minP = vec2( borderSize, borderSize ); maxP = size - vec2( borderSize, borderSize ); } float roundedRectangleDistance( vec2 minP, vec2 maxP, vec2 pos) { vec2 leftTop = minP - pos; vec2 bottomRight = pos - maxP; vec2 maximum = max( leftTop, bottomRight ); maximum = max( maximum, vec2(0,0) ); return length( maximum ); } float roundedRectangle( vec2 minP, vec2 maxP, vec2 point, float borderSize, float sharp ) { float rectangleDistance = roundedRectangleDistance( minP, maxP, point ); rectangleDistance -= borderSize; rectangleDistance *= sharp; rectangleDistance = clamp( rectangleDistance, 0.0, 1.0 ); return 1.0 - rectangleDistance; } float sdf_fill( float sd ) { return 1.0 - clamp( sd, 0, 1 ); } float sdf_stroke( float sd, float strokeWidth ) { return sdf_fill( abs( sd ) - strokeWidth ); } vec2 sdf_shape( float sd, float strokeWidth ) { float fill = sdf_fill( sd + strokeWidth ); float stroke = sdf_stroke( sd, strokeWidth ); return vec2( fill, stroke ); } vec4 sdf_coloredShape( float _sd, float _strokeWidth, vec4 _fillColor, vec4 _strokeColor ) { vec2 _sdf_shape = sdf_shape( _sd, _strokeWidth ); vec4 _fill = fade( _fillColor, _sdf_shape.x ); vec4 _stroke = fade( _strokeColor, _sdf_shape.y ); return blendMode_alpha( _fill, _stroke ); } /* TAKEN FROM [ Inigo Quilez ] https://iquilezles.org/articles/distfunctions2d/ */ float dot2( in vec2 v ) { return dot(v,v); } float dot2( in vec3 v ) { return dot(v,v); } float ndot( in vec2 a, in vec2 b ) { return a.x * b.x - a.y * b.y; } float sdCircle( vec2 p, float r ) { return length(p) - r; } float sdRoundedBox( in vec2 p, in vec2 b, in vec4 r ) { r.xy = (p.x>0.0)?r.xy : r.zw; r.x = (p.y>0.0)?r.x : r.y; vec2 q = abs(p)-b+r.x; return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r.x; } float sdChamferBox( in vec2 p, in vec2 b, in float chamfer ) { p = abs(p)-b; p = (p.y>p.x) ? p.yx : p.xy; p.y += chamfer; const float k = 1.0-sqrt(2.0); if ( p.y<0.0 && p.y+p.x*k<0.0 ) { return p.x; } if( p.x p.y ) { p=p.yx;ab=ab.yx; } float l = ab.y*ab.y - ab.x*ab.x; float m = ab.x*p.x/l; float m2 = m*m; float n = ab.y*p.y/l; float n2 = n*n; float c = (m2+n2-1.0)/3.0; float c3 = c*c*c; float q = c3 + m2*n2*2.0; float d = c3 + m2*n2; float g = m + m*n2; float co; if( d < 0.0 ) { float h = acos(q/c3)/3.0; float s = cos(h); float t = sin(h)*sqrt(3.0); float rx = sqrt( -c*(s + t + 2.0) + m2 ); float ry = sqrt( -c*(s - t + 2.0) + m2 ); co = (ry+sign(l)*rx+abs(g)/(rx*ry)- m)/2.0; } else { float h = 2.0*m*n*sqrt( d ); float s = sign(q+h)*pow(abs(q+h), 1.0/3.0); float u = sign(q-h)*pow(abs(q-h), 1.0/3.0); float rx = -s - u - c*4.0 + 2.0*m2; float ry = (s - u)*sqrt(3.0); float rm = sqrt( rx*rx + ry*ry ); co = (ry/sqrt(rm-rx)+2.0*g/rm-m)/2.0; } vec2 r = ab * vec2(co, sqrt(1.0-co*co)); return length(r-p) * sign(p.y-r.y); } float sdEquilateralTriangle( in vec2 p, in float r ) { const float k = 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); } float sdPentagon( in vec2 p, in float r ) { const vec3 k = 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); return length(p)*sign(p.y); } float sdHexagon( in vec2 p, in float r ) { const vec3 k = 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); return length(p)*sign(p.y); } float sdOctogon( in vec2 p, in float r ) { const vec3 k = 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); return length(p)*sign(p.y); } float sdHexagram( in vec2 p, in float r ) { const vec4 k = 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); return length(p)*sign(p.y); } float sdPentagram(in vec2 p, in float r ) { const float k1x = 0.809016994; // cos(π/ 5) = ¼(√5+1) const float k2x = 0.309016994; // sin(π/10) = ¼(√5-1) const float k1y = 0.587785252; // sin(π/ 5) = ¼√(10-2√5) const float k2y = 0.951056516; // cos(π/10) = ¼√(10+2√5) const float k1z = 0.726542528; // tan(π/ 5) = √(5-2√5) const vec2 v1 = vec2( k1x,-k1y); const vec2 v2 = vec2(-k1x,-k1y); const vec2 v3 = 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); } float sdStar( in vec2 p, in float r, in int n, in float m) { // 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),abs(sin(bn))); p -= r*acs; p += ecs*clamp( -dot(p,ecs), 0.0, r*acs.y/ecs.y); return length(p)*sign(p.x); } float sdMoon(vec2 p, float d, float ra, float rb ) { p.y = abs(p.y); float a = (ra*ra - rb*rb + d*d)/(2.0*d); float b = sqrt(max(ra*ra-a*a,0.0)); if( d*(p.x*b-p.y*a) > d*d*max(b-p.y,0.0) ) return length(p-vec2(a,b)); return max( (length(p )-ra), -(length(p-vec2(d,0))-rb)); } float sdHeart( in vec2 p ) { p += vec2( 0, 0.6 ); p.x = abs(p.x); if( p.y+p.x>1.0 ) return sqrt(dot2(p-vec2(0.25,0.75))) - sqrt(2.0)/4.0; return sqrt(min(dot2(p-vec2(0.00,1.00)), dot2(p-0.5*max(p.x+p.y,0.0)))) * sign(p.x-p.y); } float sdRoundedX( in vec2 p, in float w, in float r ) { p = abs(p); return length(p-min(p.x+p.y,w)*0.5) - r; } // float sdPolygon( in vec2[N] v, in vec2 p ) // { // float d = dot(p-v[0],p-v[0]); // float s = 1.0; // for( int i=0, j=N-1; i=v[i].y,p.ye.y*w.x); // if( all(c) || all(not(c)) ) s*=-1.0; // } // return s*sqrt(d); // } /* TAKEN FROM [ Inigo Quilez ] https://iquilezles.org/articles/distfunctions/ and changed */ float sdPoint( vec3 position, vec3 point ) { return length( position - point ); } float sdSphere( vec3 position, vec3 sphereCenter, float shereRadius ) { return length( position - sphereCenter ) - shereRadius; } float sdBox( vec3 position, vec3 boxDimensions ) { vec3 p = position; vec3 b = boxDimensions; vec3 q = abs(p) - b; return length( max( q, 0.0 ) ) + min( max( q.x, max( q.y, q.z ) ), 0.0 ); } float sdRoundBox( vec3 position, vec3 boxDimensions, float boxRadius ) { vec3 p = position; vec3 b = boxDimensions; float r = boxRadius; vec3 q = abs( p ) - b + r; return length( max(q , 0.0 )) + min( max( q.x, max( q.y, q.z ) ), 0.0 ) - r; } float sdLine( vec3 position, vec3 lineStart, vec3 lineEnd ) { vec3 pa = position - lineStart; vec3 ba = lineEnd - lineStart; float h = clamp( dot( pa, ba )/ dot( ba, ba ), 0.0, 1.0 ); return length( pa - ba * h ); } float sdCapsule( vec3 position, vec3 capsuleStart, vec3 capsuleEnd, float capsuleRadius ) { vec3 pa = position - capsuleStart; vec3 ba = capsuleEnd - capsuleStart; float h = clamp( dot( pa, ba )/ dot( ba, ba ), 0.0, 1.0 ); return length( pa - ba * h ) - capsuleRadius; } float sdRoundCone( vec3 p, vec3 a, vec3 b, float r1, float r2 ) { vec3 ba = b - a; float l2 = dot( ba, ba ); float rr = r1 - r2; float a2 = l2 - rr * rr; float il2 = 1.0 / l2; vec3 pa = p - a; float y = dot( pa, ba ); float z = y - l2; float x2 = dot2( pa * l2 - ba * y ); float y2 = y * y * l2; float z2 = z * z * l2; float k = sign( rr ) * rr * rr * x2; if ( sign( z ) * a2 * z2 > k ) { return sqrt( x2 + z2 ) * il2 - r2; } if ( sign( y ) * a2 * y2 < k ) { return sqrt( x2 + y2 ) * il2 - r1; } return ( sqrt( x2 * a2 * il2 ) + y * rr ) * il2 - r1; }