2024-01-07 12:18:20 +01:00
|
|
|
// 2D Signed Distance equations by InigoQuilez
|
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
varying vec2 v_vTexcoord;
|
|
|
|
varying vec4 v_vColour;
|
|
|
|
|
2024-01-07 12:18:20 +01:00
|
|
|
uniform int shape;
|
|
|
|
uniform int bg;
|
|
|
|
uniform int aa;
|
|
|
|
uniform int sides;
|
|
|
|
uniform int drawDF;
|
|
|
|
uniform int tile;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2024-01-07 12:18:20 +01:00
|
|
|
uniform float angle;
|
|
|
|
uniform float inner;
|
|
|
|
uniform float outer;
|
|
|
|
uniform float corner;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2024-01-07 12:18:20 +01:00
|
|
|
uniform float stRad;
|
|
|
|
uniform float edRad;
|
2023-01-17 08:11:55 +01:00
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
uniform vec2 angle_range;
|
|
|
|
|
|
|
|
uniform vec2 dimension;
|
|
|
|
uniform vec2 center;
|
|
|
|
uniform vec2 scale;
|
|
|
|
|
2022-08-30 07:36:37 +02:00
|
|
|
uniform vec4 bgColor;
|
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
#define PI 3.14159265359
|
2023-02-23 07:02:19 +01:00
|
|
|
#define TAU 6.283185307179586
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2024-01-07 12:18:20 +01:00
|
|
|
float sdRegularPolygon(in vec2 p, in float r, in int n, in float ang ) { #region
|
2022-01-13 05:24:03 +01:00
|
|
|
// these 4 lines can be precomputed for a given shape
|
|
|
|
float an = PI / float(n);
|
|
|
|
vec2 acs = vec2(cos(an), sin(an));
|
|
|
|
|
|
|
|
// reduce to first sector
|
|
|
|
float bn = mod(atan(p.x, p.y) + PI - ang, 2.0 * an) - an;
|
|
|
|
p = length(p) * vec2(cos(bn), abs(sin(bn)));
|
|
|
|
|
|
|
|
// line sdf
|
|
|
|
p -= r * acs;
|
|
|
|
p.y += clamp( -p.y, 0.0, r * acs.y);
|
|
|
|
return length(p) * sign(p.x);
|
2024-01-07 12:18:20 +01:00
|
|
|
} #endregion
|
2022-01-13 05:24:03 +01:00
|
|
|
|
|
|
|
// signed distance to a n-star polygon with external angle en
|
2024-01-07 12:18:20 +01:00
|
|
|
float sdStar(in vec2 p, in float r, in int n, in float m, in float ang) { #region m=[2,n]
|
2022-01-13 05:24:03 +01:00
|
|
|
// these 4 lines can be precomputed for a given shape
|
|
|
|
float an = PI / float(n);
|
|
|
|
float en = PI / m;
|
|
|
|
vec2 acs = vec2(cos(an), sin(an));
|
|
|
|
vec2 ecs = vec2(cos(en), sin(en)); // ecs=vec2(0,1) and simplify, for regular polygon,
|
|
|
|
|
|
|
|
// reduce to first sector
|
|
|
|
float bn = mod( atan(p.x, p.y) + PI - ang, 2.0 * an) - an;
|
|
|
|
p = length(p) * vec2(cos(bn), abs(sin(bn)));
|
|
|
|
|
|
|
|
// line sdf
|
|
|
|
p -= r * acs;
|
|
|
|
p += ecs * clamp( -dot(p, ecs), 0.0, r * acs.y / ecs.y);
|
|
|
|
return length(p)*sign(p.x);
|
2024-01-07 12:18:20 +01:00
|
|
|
} #endregion
|
2022-01-13 05:24:03 +01:00
|
|
|
|
|
|
|
// sca is the sin/cos of the orientation
|
|
|
|
// scb is the sin/cos of the aperture
|
2024-01-07 12:18:20 +01:00
|
|
|
float sdArc( in vec2 p, in vec2 sca, in vec2 scb, in float ra, in float rb ) { #region
|
2022-01-13 05:24:03 +01:00
|
|
|
p *= mat2(sca.x, sca.y, -sca.y, sca.x);
|
|
|
|
p.x = abs(p.x);
|
|
|
|
float k = (scb.y * p.x > scb.x * p.y) ? dot(p.xy,scb) : length(p);
|
|
|
|
return sqrt( dot(p, p) + ra * ra - 2.0 * ra * k ) - rb;
|
2024-01-07 12:18:20 +01:00
|
|
|
} #endregion
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2024-01-07 12:18:20 +01:00
|
|
|
float sdRoundBox( in vec2 p, in vec2 b, in vec4 r ) { #region
|
2022-01-13 05:24:03 +01:00
|
|
|
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;
|
2024-01-07 12:18:20 +01:00
|
|
|
} #endregion
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2024-01-07 12:18:20 +01:00
|
|
|
float sdBox( in vec2 p, in vec2 b ) { #region
|
2022-01-13 05:24:03 +01:00
|
|
|
vec2 d = abs(p) - b;
|
|
|
|
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
|
2024-01-07 12:18:20 +01:00
|
|
|
} #endregion
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2024-01-07 12:18:20 +01:00
|
|
|
float sdTearDrop( vec2 p, float r1, float r2, float h ) { #region
|
2023-01-17 08:11:55 +01:00
|
|
|
p.x = abs(p.x);
|
|
|
|
float b = (r1-r2)/h;
|
|
|
|
float a = sqrt(1.0-b*b);
|
|
|
|
float k = dot(p,vec2(-b,a));
|
|
|
|
if( k < 0.0 ) return length(p) - r1;
|
|
|
|
if( k > a*h ) return length(p-vec2(0.0,h)) - r2;
|
|
|
|
return dot(p, vec2(a,b) ) - r1;
|
2024-01-07 12:18:20 +01:00
|
|
|
} #endregion
|
2023-01-17 08:11:55 +01:00
|
|
|
|
2024-01-07 12:18:20 +01:00
|
|
|
float sdCross( in vec2 p, in vec2 b, float r ) { #region
|
2023-01-17 08:11:55 +01:00
|
|
|
p = abs(p); p = (p.y>p.x) ? p.yx : p.xy;
|
|
|
|
vec2 q = p - b;
|
|
|
|
float k = max(q.y,q.x);
|
|
|
|
vec2 w = (k>0.0) ? q : vec2(b.y-p.x,-k);
|
|
|
|
return sign(k)*length(max(w,0.0)) + r;
|
2024-01-07 12:18:20 +01:00
|
|
|
} #endregion
|
2023-01-17 08:11:55 +01:00
|
|
|
|
2024-01-07 12:18:20 +01:00
|
|
|
float sdVesica(vec2 p, float r, float d) { #region
|
2023-01-17 08:11:55 +01:00
|
|
|
p = abs(p);
|
|
|
|
|
|
|
|
float b = sqrt(r*r-d*d); // can delay this sqrt by rewriting the comparison
|
|
|
|
return ((p.y-b)*d > p.x*b) ? length(p-vec2(0.0,b))*sign(d)
|
|
|
|
: length(p-vec2(-d,0.0))-r;
|
2024-01-07 12:18:20 +01:00
|
|
|
} #endregion
|
|
|
|
|
2024-01-19 14:39:26 +01:00
|
|
|
float sdCrescent(vec2 p, float s, float c, float a) { #region
|
2024-01-07 12:18:20 +01:00
|
|
|
float o = length(p) - 1.;
|
2024-01-19 14:39:26 +01:00
|
|
|
float i = length(p - vec2(cos(a) * (1. - s * c), sin(a) * (1. - s * c))) / s - 1.;
|
|
|
|
|
|
|
|
return max(o, -i);
|
|
|
|
} #endregion
|
|
|
|
|
|
|
|
float sdDonut(vec2 p, float s) { #region
|
|
|
|
float o = length(p) - 1.;
|
|
|
|
float i = length(p) / s - 1.;
|
2024-01-07 12:18:20 +01:00
|
|
|
|
|
|
|
return max(o, -i);
|
|
|
|
} #endregion
|
2023-01-17 08:11:55 +01:00
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
void main() {
|
|
|
|
float color = 0.;
|
2024-01-07 12:18:20 +01:00
|
|
|
vec2 coord = (v_vTexcoord - center) / scale;
|
|
|
|
vec2 ratio = dimension / dimension.y;
|
2022-12-12 09:08:03 +01:00
|
|
|
float d;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2024-01-07 12:18:20 +01:00
|
|
|
if(tile == 1) coord = mod(coord + 1., 2.) - 1.;
|
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
if(shape == 0) {
|
2023-01-17 08:11:55 +01:00
|
|
|
d = sdBox( (v_vTexcoord - center) * ratio, (scale * ratio - corner));
|
|
|
|
d -= corner;
|
2022-01-13 05:24:03 +01:00
|
|
|
} else if(shape == 1) {
|
2024-01-07 12:18:20 +01:00
|
|
|
d = length(coord) - 1.;
|
2022-01-13 05:24:03 +01:00
|
|
|
} else if(shape == 2) {
|
2024-01-07 12:18:20 +01:00
|
|
|
d = sdRegularPolygon( coord, 0.9 - corner, sides, angle );
|
2022-01-13 05:24:03 +01:00
|
|
|
d -= corner;
|
|
|
|
} else if(shape == 3) {
|
2024-01-07 12:18:20 +01:00
|
|
|
d = sdStar( coord, 0.9 - corner, sides, 2. + inner * (float(sides) - 2.), angle );
|
2022-01-13 05:24:03 +01:00
|
|
|
d -= corner;
|
2024-01-19 14:39:26 +01:00
|
|
|
} else if(shape == 4) d = sdArc( coord, vec2(sin(angle), cos(angle)), angle_range, 0.9 - inner, inner );
|
|
|
|
else if(shape == 5) d = sdTearDrop( coord + vec2(0., 0.5), stRad, edRad, 1. );
|
|
|
|
else if(shape == 6) d = sdCross( coord, vec2(1. + corner, outer), corner );
|
|
|
|
else if(shape == 7) d = sdVesica( coord, inner, outer );
|
|
|
|
else if(shape == 8) d = sdCrescent( coord, inner, outer, angle );
|
|
|
|
else if(shape == 9) d = sdDonut( coord, inner );
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2022-12-12 09:08:03 +01:00
|
|
|
if(drawDF == 1)
|
2022-12-13 09:20:36 +01:00
|
|
|
color = -d;
|
2022-12-12 09:08:03 +01:00
|
|
|
else if(aa == 0)
|
|
|
|
color = step(d, 0.0);
|
|
|
|
else
|
2023-03-13 10:45:56 +01:00
|
|
|
color = smoothstep(0.02, -0.02, d);
|
2022-12-12 09:08:03 +01:00
|
|
|
|
2022-08-30 07:36:37 +02:00
|
|
|
gl_FragColor = mix(bgColor, v_vColour, color);
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|