// #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;
}