webgl2-sdf 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,3 @@
1
- WORK IN PROGRESS!!
2
1
  Bug reports, pull requests and ⭐⭐⭐⭐⭐s are welcome and appreciated!
3
2
 
4
3
  ## Overview
@@ -12,7 +11,7 @@ applications even on slow on-board GPUs
12
11
  The bezier curves can be given in raw form or as an SVG path string (except, arcs are
13
12
  not supported yet).
14
13
 
15
- Supported path commands: `L, Q, C, H, V, S, T, Z l, q, c, h, v, s, t, z`
14
+ Supported path commands: `L, Q, C, H, V, S, T, Z l, q, c, h, v, s, t, z`
16
15
 
17
16
  ## Installation
18
17
 
@@ -31,7 +30,7 @@ calculation
31
30
 
32
31
  ## Usage
33
32
  ```typescript
34
- import { getWebGlContext, generateSdf } from "webgl2-sdf";
33
+ import { getWebGlContext, generateSdf, GLSL_PATTERN1 } from "webgl2-sdf";
35
34
 
36
35
 
37
36
  function drawSdf() {
@@ -39,7 +38,7 @@ function drawSdf() {
39
38
  'webgl2',
40
39
  {
41
40
  depth: false, stencil: false, antialias: false,
42
- premultipliedAlpha: false
41
+ premultipliedAlpha: false, preserveDrawingBuffer: true
43
42
  }
44
43
  );
45
44
 
@@ -65,16 +64,24 @@ function drawSdf() {
65
64
  generateSdf(
66
65
  glContext!,
67
66
  someShape,
67
+ [-50, -50, 150, 150], // viewBox
68
68
  canvasWidth, // width (of drawing area)
69
69
  canvasHeight, // height (of drawing area)
70
- [-50, -50, 150, 150], // viewBox
71
- 100, // max sdf distance
72
- 1, // TODO
73
- true, // include inside
74
- true, // include outside
75
- 0, // canvas x coordinate
76
- 0, // canvas y coordinate
77
- 0, // channel // TODO
70
+ 50, // max sdf distance
71
+
72
+ // The below options are optional (see function signature for details)
73
+ {
74
+ x: 0, y: 0, // canvas x, y coordinates; [0,0] is bottom left!
75
+ testInteriorExterior: true,
76
+ calcSdfForInside: true,
77
+ calcSdfForOutside: true,
78
+ customData: [
79
+ 2.0, // exponent when using default `glslRgbaCalcStr`
80
+ 0, 0, 0
81
+ ],
82
+ colorMask: [true, true, true, true],
83
+ // glslRgbaCalcStr: GLSL_PATTERN1
84
+ }
78
85
  );
79
86
  } catch (e) {
80
87
  console.log(e);
@@ -1 +1 @@
1
- const n=32,e={};function t(n,e,t){const r=n.createShader(t);return n.shaderSource(r,e),n.compileShader(r),r}function r(n,e,t){const{gl:r,textures:o}=n;r.activeTexture(r.TEXTURE0+e);let s=o[t];return s?r.bindTexture(r.TEXTURE_2D,s.tex):(s=o[t]={tex:r.createTexture()},r.bindTexture(r.TEXTURE_2D,s.tex),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MIN_FILTER,r.NEAREST),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MAG_FILTER,r.NEAREST),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,r.CLAMP_TO_EDGE),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,r.CLAMP_TO_EDGE)),s}const{BYTE:o,UNSIGNED_BYTE:s,SHORT:i,UNSIGNED_SHORT:l,INT:c,UNSIGNED_INT:u,FLOAT:a,HALF_FLOAT:d,INT_2_10_10_10_REV:f,UNSIGNED_INT_2_10_10_10_REV:g}=WebGL2RenderingContext;function h(n){return(e,t,r)=>{const{gl:o,uniformBlocks:s,program:i}=n;let l=s[e];if(void 0===s[e]){const n=o.getUniformBlockIndex(i,e);o.uniformBlockBinding(i,n,t);const r=o.createBuffer();o.bindBuffer(o.UNIFORM_BUFFER,r),l={blockName:e,blockIndex:n,buf:r},s[e]=l}else o.bindBuffer(o.UNIFORM_BUFFER,l.buf);const{buf:c}=l;o.bufferData(o.UNIFORM_BUFFER,r,o.STATIC_DRAW),o.bindBufferBase(o.UNIFORM_BUFFER,t,c)}}function x(n){const e=n[0][0],t=n[0][1];for(let r=1;r<n.length;r++)if(e!==n[r][0]||t!==n[r][1])return!1;return!0}function I(n,e){if(0===e)return n[0];if(1===e)return n[n.length-1];if(4===n.length){const[[t,r],[o,s],[i,l],[c,u]]=n,a=t+(o-t)*e,d=o+(i-o)*e,f=a+(d-a)*e,g=r+(s-r)*e,h=s+(l-s)*e,x=g+(h-g)*e;return[f+(d+(i+(c-i)*e-d)*e-f)*e,x+(h+(l+(u-l)*e-h)*e-x)*e]}if(3===n.length){const[[t,r],[o,s],[i,l]]=n,c=t+(o-t)*e,u=r+(s-r)*e;return[c+(o+(i-o)*e-c)*e,u+(s+(l-s)*e-u)*e]}if(2===n.length){const[[t,r],[o,s]]=n;return[t+(o-t)*e,r+(s-r)*e]}if(1===n.length)return n[0];throw new Error("The given bezier curve must be of order <= 3.")}const{sqrt:_}=Math;function p(n,e){const t=n[0],r=n[1],o=e[0],s=e[1],i=r-s,l=o-t,c=t*s-o*r,u=_(i*i+l*l);return function(n){const e=n[0],o=n[1];return 0!==u?(i*e+l*o+c)/u:_((e-t)**2+(o-r)**2)}}{const n=[10,1];p([6,2],[6,2])(n)}function v(n,e,t){if(4===n.length)return function(n,e,t){return 0===e?1===t?n:function(n,e){const t=n[0],r=n[1],o=n[2],s=n[3],i=t[0],l=t[1],c=r[0],u=r[1],a=o[0],d=o[1],f=i-e*(i-c),g=c-e*(c-a),h=f-e*(f-g),x=l-e*(l-u),I=u-e*(u-d),_=x-e*(x-I);return[t,[f,x],[h,_],[h-e*(h-(g-e*(g-(a-e*(a-s[0]))))),_-e*(_-(I-e*(I-(d-e*(d-s[1])))))]]}(n,t):1===t?function(n,e){const t=n[0],r=n[1],o=n[2],s=n[3],i=t[0],l=t[1],c=r[0],u=r[1],a=o[0],d=o[1],f=i-e*(i-c),g=c-e*(c-a),h=a-e*(a-s[0]),x=f-e*(f-g),I=g-e*(g-h),_=l-e*(l-u),p=u-e*(u-d),v=d-e*(d-s[1]),m=_-e*(_-p),C=p-e*(p-v);return[[x-e*(x-I),m-e*(m-C)],[I,C],[h,v],s]}(n,e):function(n,e,t){const r=n[0],o=n[1],s=n[2],i=n[3],l=r[0],c=r[1],u=o[0],a=o[1],d=s[0],f=s[1],g=e*e,h=e*g,x=t*t,I=t*x,_=e*t,p=l-u,v=d-u,m=p+v,C=e*p,S=t*p,R=i[0]-l-3*v,E=c-a,T=f-a,b=E+T,P=e*E,w=t*E,A=i[1]-c-3*T;return[[h*R+(3*e*(e*m-p)+l),h*A+(3*e*(e*b-E)+c)],[_*(e*R+2*m)+(g*m+l-(S+2*C)),_*(e*A+2*b)+(g*b+c-(w+2*P))],[_*(t*R+2*m)+(x*m+l-(2*S+C)),_*(t*A+2*b)+(x*b+c-(2*w+P))],[I*R+(3*t*(t*m-p)+l),I*A+(3*t*(t*b-E)+c)]]}(n,e,t)}(n,e,t);if(3===n.length)return function(n,e,t){return 0===e?1===t?n:function(n,e){const t=n[0],r=n[1],o=n[2],s=t[0],i=t[1],l=r[0],c=r[1],u=e*e,a=s-l,d=i-c;return[t,[-e*a+s,-e*d+i],[u*(a+(o[0]-l))-(2*e*a-s),u*(d+(o[1]-c))-(2*e*d-i)]]}(n,t):1===t?function(n,e){const t=n[0],r=n[1],o=n[2],s=t[0],i=t[1],l=r[0],c=r[1],u=e*e,a=s-l,d=o[0]-l,f=i-c,g=o[1]-c;return[[u*(a+d)-(2*e*a-s),u*(f+g)-(2*e*f-i)],[e*d+l,e*g+c],o]}(n,e):function(n,e,t){const r=n[0],o=n[1],s=n[2],i=r[0],l=r[1],c=o[0],u=o[1],a=e*e,d=t*t,f=e*t,g=i-c,h=g+(s[0]-c),x=l-u,I=x+(s[1]-u);return[[a*h-(2*e*g-i),a*I-(2*e*x-l)],[f*h-(g*(t+e)-i),f*I-(x*(t+e)-l)],[d*h-(2*t*g-i),d*I-(2*t*x-l)]]}(n,e,t)}(n,e,t);throw new Error("The given bezier curve must be of order 2 or 3.")}function m(n,e){return[e[0]-n[0],e[1]-n[1]]}function C(n,e){return n[0]*e[0]+n[1]*e[1]}function S(n){const e=m(n[0],n[1]),t=m(n[1],n[3]),r=m(n[3],n[0]),o=m(n[0],n[2]),s=m(n[2],n[3]);return C(r,e)>0||C(t,r)>0||C(r,o)>0||C(s,r)>0}const{abs:R,max:E}=Math;function T(n){const e=p(n[0],n[3]),t=e(n[1]),r=e(n[2]);return(t*r<=0?4/9:3/4)*E(R(t),R(r))}function b(n){const e=m(n[0],n[1]),t=m(n[1],n[2]),r=m(n[2],n[0]);return C(r,e)>0||C(t,r)>0}const{abs:P}=Math;function w(n){if(n[0][0]===n[1][0]&&n[0][1]===n[1][1])return 0;const e=I(n,.5),t=p(n[0],n[2]);return P(t(e))}function A(n){const e=3===n.length?function(n){const e=[0],t=[1];for(;;){const r=e[e.length-1],o=t[t.length-1],s=v(n,r,o);if(!b(s)&&w(s)<=.5){if(e.push(t.pop()),1===o)return e;continue}const i=(r+o)/2;t.push(i)}}(n):function(n){const e=[0],t=[1];for(;;){const r=e[e.length-1],o=t[t.length-1],s=v(n,r,o);if(!S(s)&&T(s)<=.5){if(e.push(t.pop()),1===o)return e;continue}const i=(r+o)/2;t.push(i)}}(n),t=[];for(let r=0;r<e.length-1;r++){const o=I(n,e[r]),s=I(n,e[r+1]);t.push([o,s])}return t}function D(n){return Math.sqrt(n[0]*n[0]+n[1]*n[1])}const y=function(){const e=[{from:0,u:0,v:0}];for(let t=0;t<128;t++){e.push({from:t+.5,u:t+1,v:0}),e.push({from:t+.5,u:-t-1,v:0}),e.push({from:t+.5,u:0,v:t+1}),e.push({from:t+.5,u:0,v:-t-1});for(let r=0;r<n;r++){const n=D([.5+t,.5+r]),o=t+1,s=r+1;e.push({from:n,u:o,v:s}),0!==o&&e.push({from:n,u:-o,v:s}),0!==s&&e.push({from:n,u:o,v:-s}),0!==o&&0!==s&&e.push({from:n,u:-o,v:-s})}e.sort((n,e)=>n.from-e.from)}return e}(),{max:U,E:F}=Math;const{min:N,max:M,SQRT2:k}=Math;function L(e,t,r,o,s){const i=function(e,t,r,o,s){return function(i,l,c){let u=function(n){let e=function(n){let e=0,t=y.length-1,r=0;for(;e<=t;){r=e+t>>>1;const o=y[r].from;if(o===n)return r;n>o?e=r+1:t=r-1}return r}(n);if(n=U(0,n),0===e)return 0;for(;y[e].from===y[e-1].from;)e--;return e}((c-k*r)/r),a=Number.POSITIVE_INFINITY;for(;;){if(u>=y.length){a=r*(y[y.length-1].from-k);break}const{u:c,v:d,from:f}=y[u];if(r*f>o+k*r){a=r*(f-2*k);break}const g=c+i,h=d+l;if(g<0||g>=t+2*s||h<0||h>=n+2*s){u++;continue}const{lineSegs:x}=e[g][h];if(x.length>0){a=r*(f-k);break}u++}const{closeCells:d}=e[i][l];let f=M(0,u-1);for(;f<y.length;){const{from:c,u,v:g}=y[f];if(r*c>N(a,o)+2*k*r)break;const h=u+i,x=g+l;if(h<0||h>=t+2*s||x<0||x>=n+2*s){f++;continue}const{lineSegs:I}=e[h][x];I.length>0&&d.push((2*s+n)*h+x),f++}return a}}(e,t,r,o,s);let l=0,c=0;for(let e=s;e<t+s;e++){c=l;for(let t=s;t<n+s;t++)c=i(e,t,c),t===s&&(l=c)}}const{floor:B,ceil:O}=Math;function X(n,e,t,r,o,s){const i=r*s,[[l,c],[u,a]]=o,d=e+i,f=t+i,g=function(n,e){const[t,r]=n,[o,s]=t,[i,l]=r,[[c,u],[a,d]]=e,f=i-o,g=l-s,h=[];if(0!==f){const n=(c-o)/f;if(n>=0&&n<=1){const e=s+n*g;e>=u&&e<=d&&h.push({t:n,p:[c,e]})}const e=(a-o)/f;if(e>=0&&e<=1){const n=s+e*g;n>=u&&n<=d&&h.push({t:e,p:[a,n]})}}if(0!==g){const n=(u-s)/g;if(n>=0&&n<=1){const e=o+n*f;e>=c&&e<=a&&h.push({t:n,p:[e,u]})}const e=(d-s)/g;if(e>=0&&e<=1){const n=o+e*f;n>=c&&n<=a&&h.push({t:e,p:[n,d]})}}const x=new Set,I=h.filter(n=>{const{t:e}=n;return!x.has(e)&&(x.add(e),!0)});return I.sort((n,e)=>n.t-e.t).map(n=>n.p)}(o,[[-i,-i],[d,f]]),h=l>-i&&l<d&&c>-i&&c<f,x=u>-i&&u<d&&a>-i&&a<f;if(g.length<2&&!h&&!x)return;const I=u-l,_=a-c,p=u>l?r:-r,v=a>c?r:-r;let m=l,C=c,S=0;const R=p>0,E=v>0,T=R?B:O,b=E?B:O;for(;;){let e=r*T((m+p)/r),t=r*b((C+v)/r);const o=(e-l)/I,x=(t-c)/_,P=o<x&&0!==I||0===_,w=P?e:l+x*I,A=P?c+o*_:t;if((o>1||0===I)&&(x>1||0===_)){const e=B(u/r)+s,t=B(a/r)+s;n[e]?.[t]?.lineSegs.push([[m,C],[u,a]]);break}if(w<=-i||A<=-i||w>=d||A>=f){if(!h&&0===S){[m,C]=g[0],S++;continue}{const e=T(m/r)-(R?0:1)+s,t=b(C/r)-(E?0:1)+s,o=[[m,C],g[S]];n[e]?.[t]?.lineSegs.push(o);break}}const D=T(m/r)-(R?0:1)+s,y=b(C/r)-(E?0:1)+s;n[D]?.[y]?.lineSegs.push([[m,C],[w,A]]),m=w,C=A}}const j=256,{floor:G,ceil:Y}=Math;function Q(n,e,t){const r=e/n.length,[o,s]=t,i=function(n,e){const[t,r]=n,[o,s]=t,[i,l]=r,[c,u,a]=e,d=i-o,f=l-s,g=[],h=[];if(0!==d){const n=(c-o)/d;if(n>=0&&n<=1){const e=s+n*f;e>=u&&e<=a&&(g.push(n),h.push([c,e]))}}if(0!==f){const n=(u-s)/f;if(n>=0&&n<=1){const e=o+n*d;e<=c&&(g.push(n),h.push([e,u]))}const e=(a-s)/f;if(e>=0&&e<=1){const n=o+e*d;n<=c&&(g.push(e),h.push([n,a]))}}return 2===g.length?g[0]<g[1]?h:[h[1],h[0]]:h}(t,[0,0,e]),[l,c]=o,[u,a]=s,d=u-l,f=a-c,g=l<0&&c>0&&c<e,h=u<0&&a>0&&a<e;if(i.length<2&&!g&&!h&&(0!==l||0!==d||c<=0&&a<=0||c>=e&&a>=e))return;if(0===f)return;const x=a>c?r:-r;let I=l,_=c,p=0;const v=u>l,m=a>c,C=m?G:Y;for(;;){let t=v&&I<0||!v&&I>0?0:Number.NEGATIVE_INFINITY,o=r*C((_+x)/r);const u=(t-l)/d,a=(o-c)/f,h=u<a&&0!==d,S=h?0:l+a*d,R=h?c+u*f:o;if((u>1||0===d)&&a>1){const e=G(s[1]/r);n[e]?.push([[I,_],s]);break}if(S>=0&&(0!==l||0!==d)||R<=0||R>=e){if(!g&&0===p){[I,_]=i[0],p++;continue}{const e=C(_/r)-(m?0:1),t=[[I,_],i[p]];n[e]?.push(t);break}}const E=C(_/r)-(m?0:1);n[E]?.push([[I,_],[S,R]]),I=S,_=R}}function V(e,t,o,s,i,l,c,u,f,g,I,_,p,v,m,C){const{gl:S}=e,R=[],E=.03125,T=.03125;R.push(0,0,E,0,0,T),R.push(E,0,E,T,0,T);const b=new Float32Array(R),P=(w=t,(n,e,...t)=>{const{gl:r,uniforms:o}=w,s=o[e]||(o[e]=r.getUniformLocation(w.program,e));r[`uniform${n}`](s,...t)});var w;const D=function(n){return(e,t,r,o,s,i=0,l=0,c=0)=>{const{gl:u,attributes:f}=n,g=f[e]=f[e]??{buf:u.createBuffer(),loc:u.getAttribLocation(n.program,e),data:null},{loc:h,buf:x}=g;u.bindBuffer(u.ARRAY_BUFFER,x),r===a||r===d?u.vertexAttribPointer(h,t,r,!1,l,c):u.vertexAttribIPointer(h,t,r,l,c),u.enableVertexAttribArray(h),0!==i&&u.vertexAttribDivisor(h,i),s!==g.data&&(u.bufferData(u.ARRAY_BUFFER,s,o),g.data=s)}}(t),{lineSegPtCoords_Arr:y,segIdxs_PerCell_Range_Arr:U,closeCellIdxs_PerCell_Arr:F,closeCellIdxs_PerCell_Range_Arr:N,crossCellIdxs_PerCell_Arr:M,crossCellIdxs_perCell_Range_Arr:k,segIdxs_PerStrip_Range_Arr:B}=function(e,t,r,o,s,i,l,c=[0,0,t,r],u=1){const a=function(n,e,t,r){if(0===n[0]&&0===n[1]&&n[2]===e&&n[3]===t)return r;const[o,s,i,l]=n,c=e/i,u=t/l,a=[];for(let n=0;n<r.length;n++){const e=r[n],t=[];for(let n=0;n<e.length;n++){const r=e[n],i=[];for(let n=0;n<r.length;n++){const[e,t]=r[n],l=c*e-o,a=u*t-s;i.push([l,a])}t.push(i)}a.push(t)}return a}(c,t,r/u,e),d=function(n){let e=[];for(let t=0;t<n.length;t++){const r=n[t];for(let n=0;n<r.length;n++){const t=r[n];if(x(t))continue;if(2===t.length){e.push(t);continue}const o=A(t);e.push(...o.filter(n=>!x(n)))}}return e}(a),f=function(e,t){const r=[];for(let o=0;o<e+2*t;o++){const e=[];for(let r=0;r<n+2*t;r++)e.push({lineSegs:[],closeCells:[],crossingCells:[]});r.push(e)}return r}(o,l),g=new Array(n).fill(void 0).map(n=>[]);for(let n=0;n<d.length;n++){const e=d[n];X(f,t,r,s,e,l),Q(g,r,e)}L(f,o,s,i,l),function(e,t,r){for(let o=r;o<t+r;o++)for(let t=r;t<n+r;t++){const s=e[o][t].crossingCells;for(let i=r;i<=o;i++)0!==e[i][t].lineSegs.length&&s.push((n+2*r)*i+t)}}(f,o,l);const h=[],I=[],_=[],p=[],v=[],m=[];let C=0,S=0,R=0;for(let e=0;e<o+2*l;e++)for(let t=0;t<n+2*l;t++){const r=f[e][t];if(e>=l&&e<o+l&&t>=l&&t<n+l){const{closeCells:n,crossingCells:e}=r,t=e.length,o=n.length;v.push(...e),_.push(...n),m.push(C,t),p.push(S,o),C+=t,S+=o}const{lineSegs:s}=r,i=s.length;I.push(R,i),R+=i,h.push(...s.flat(2))}const E=[];for(let e=0;e<n;e++){const n=g[e],t=n.length;E.push([R,t]),R+=t,h.push(...n.flat(2))}for(;_.length%j!==0;)_.push(0);for(;v.length%j!==0;)v.push(0);for(;h.length%1024!=0;)h.push(0);const T=new Float32Array(h),b=new Int32Array(I),P=new Int32Array(p);return{lineSegPtCoords_Arr:T,segIdxs_PerCell_Range_Arr:b,closeCellIdxs_PerCell_Arr:new Int32Array(_),closeCellIdxs_PerCell_Range_Arr:P,crossCellIdxs_PerCell_Arr:new Int32Array(v),crossCellIdxs_perCell_Range_Arr:new Int32Array(m),segIdxs_PerStrip_Range_Arr:new Int32Array(E.flat())}}(o,I,_,p,v,i,m,s,C);D("aUV",2,S.FLOAT,S.STATIC_DRAW,b),D("aCrossIdxRangePerCell",2,S.INT,S.STATIC_DRAW,k,1),D("aCloseCellIdxRangePerCell",2,S.INT,S.STATIC_DRAW,N,1),P("2f","uWidthHeight",I,_),P("1f","uMaxDistance",i),P("1i","uIncl",(l?1:0)+(c?2:0)),P("4f","uCustom",...u),h(t)("SegIdxRangePerCellBlock",0,U),h(t)("SegIdxRangePerStripBlock",1,B),r(e,0,"segs"),S.texImage2D(S.TEXTURE_2D,0,S.RGBA32F,j,y.length/4/j,0,S.RGBA,S.FLOAT,y);const O=S.getUniformLocation(t.program,"uSegs");S.uniform1i(O,0),r(e,1,"closeCellIdxsPerCell"),S.texImage2D(S.TEXTURE_2D,0,S.R32I,j,F.length/j,0,S.RED_INTEGER,S.INT,F);const G=S.getUniformLocation(t.program,"uCloseCellIdxs");S.uniform1i(G,1),r(e,2,"crossCellIdxsPerCell"),S.texImage2D(S.TEXTURE_2D,0,S.R32I,j,M.length/j,0,S.RED_INTEGER,S.INT,M);const Y=S.getUniformLocation(t.program,"uCrossCellIdxs");S.uniform1i(Y,2),C>1&&(S.enable(S.SCISSOR_TEST),S.scissor(f,g,I,_/C)),S.viewport(f,g,I,_),S.drawArraysInstanced(S.TRIANGLES,0,6,p*n),C>1&&S.disable(S.SCISSOR_TEST)}function z(n){const e=[n.p,n.initialPoint];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=void 0,e}const H={c:function(n){const e=[n.p,[n.vals[0],n.vals[1]],[n.vals[2],n.vals[3]],[n.vals[4],n.vals[5]]];return n.prev2ndCubicControlPoint=e[2],n.prev2ndQuadraticControlPoint=void 0,e},h:function(n){const e=[n.p,[n.vals[0],n.p[1]]];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=void 0,e},l:function(n){const e=[n.p,n.vals];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=void 0,e},q:function(n){const e=[n.vals[0],n.vals[1]],t=[n.vals[2],n.vals[3]];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=e,[n.p,e,t]},s:function(n){const e=n.prev2ndCubicControlPoint?[n.p[0]-n.prev2ndCubicControlPoint[0]+n.p[0],n.p[1]-n.prev2ndCubicControlPoint[1]+n.p[1]]:n.p,t=[n.p,e,[n.vals[0],n.vals[1]],[n.vals[2],n.vals[3]]];return n.prev2ndCubicControlPoint=t[2],n.prev2ndQuadraticControlPoint=void 0,t},t:function(n){const e=n.prev2ndQuadraticControlPoint?[n.p[0]-n.prev2ndQuadraticControlPoint[0]+n.p[0],n.p[1]-n.prev2ndQuadraticControlPoint[1]+n.p[1]]:n.p,t=[n.vals[0],n.vals[1]];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=e,[n.p,e,t]},v:function(n){const e=[n.p,[n.p[0],n.vals[0]]];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=void 0,e},z};function W(n){let e=0,t=0,r=1,o=0,s=1,i=1;const l=n._currentIndex;if(n._skipOptionalSpaces(),n._currentIndex<n._endIndex&&"+"===n._string[n._currentIndex]?n._currentIndex+=1:n._currentIndex<n._endIndex&&"-"===n._string[n._currentIndex]&&(n._currentIndex+=1,s=-1),n._currentIndex===n._endIndex||(n._string[n._currentIndex]<"0"||n._string[n._currentIndex]>"9")&&"."!==n._string[n._currentIndex])throw new Error("The first character of a number must be one of [0-9+-.].");const c=n._currentIndex;for(;n._currentIndex<n._endIndex&&n._string[n._currentIndex]>="0"&&n._string[n._currentIndex]<="9";)n._currentIndex+=1;if(n._currentIndex!==c){let e=n._currentIndex-1,r=1;for(;e>=c;)t+=r*(Number(n._string[e])-0),e-=1,r*=10}if(n._currentIndex<n._endIndex&&"."===n._string[n._currentIndex]){if(n._currentIndex+=1,n._currentIndex>=n._endIndex||n._string[n._currentIndex]<"0"||n._string[n._currentIndex]>"9")throw new Error("There must be a least one digit following the .");for(;n._currentIndex<n._endIndex&&n._string[n._currentIndex]>="0"&&n._string[n._currentIndex]<="9";)r*=10,o+=Number(n._string.charAt(n._currentIndex))/r,n._currentIndex+=1}if(n._currentIndex!==l&&n._currentIndex+1<n._endIndex&&("e"===n._string[n._currentIndex]||"E"===n._string[n._currentIndex])&&"x"!==n._string[n._currentIndex+1]&&"m"!==n._string[n._currentIndex+1]){if(n._currentIndex+=1,"+"===n._string[n._currentIndex]?n._currentIndex+=1:"-"===n._string[n._currentIndex]&&(n._currentIndex+=1,i=-1),n._currentIndex>=n._endIndex||n._string[n._currentIndex]<"0"||n._string[n._currentIndex]>"9")throw new Error("There must be an exponent.");for(;n._currentIndex<n._endIndex&&n._string[n._currentIndex]>="0"&&n._string[n._currentIndex]<="9";)e*=10,e+=Number(n._string[n._currentIndex]),n._currentIndex+=1}let u=t+o;if(u*=s,e&&(u*=Math.pow(10,i*e)),l===n._currentIndex)throw new Error("Internal error: startIndex === source._currentIndex");return n._skipOptionalSpacesOrDelimiter(),u}const q={Z:"Z",M:"M",L:"L",C:"C",Q:"Q",A:"A",H:"H",V:"V",S:"S",T:"T",z:"Z",m:"m",l:"l",c:"c",q:"q",a:"a",h:"h",v:"v",s:"s",t:"t"};class Z{_string;_currentIndex;_endIndex;_prevCommand;constructor(n){this._string=n,this._currentIndex=0,this._endIndex=this._string.length,this._prevCommand=void 0,this._skipOptionalSpaces()}parseSegment(){const n=this._string[this._currentIndex];let e,t=q[n];if(void 0===t){if(void 0===this._prevCommand)throw new Error("Implicit command not allowed for first commands.");if(!("+"===n||"-"===n||"."===n||n>="0"&&n<="9")||"Z"===this._prevCommand)throw new Error("Remaining coordinates not found for implicit command");t="M"===this._prevCommand?"L":"m"===this._prevCommand?"l":this._prevCommand}else this._currentIndex+=1;this._prevCommand=t;const r=t.toUpperCase();if("H"===r||"V"===r?e=[W(this)]:"M"===r||"L"===r||"T"===r?e=[W(this),W(this)]:"S"===r||"Q"===r?e=[W(this),W(this),W(this),W(this)]:"C"===r?e=[W(this),W(this),W(this),W(this),W(this),W(this)]:"A"===r?e=[W(this),W(this),W(this),this._parseArcFlag(),this._parseArcFlag(),W(this),W(this)]:"Z"===r&&(this._skipOptionalSpaces(),e=[]),void 0===e)throw new Error("Unknown command");return{type:t,values:e}}hasMoreData(){return this._currentIndex<this._endIndex}initialCommandIsMoveTo(){if(!this.hasMoreData())return!0;const n=q[this._string[this._currentIndex]];return"M"===n||"m"===n}_isCurrentSpace(){const n=this._string[this._currentIndex];return n<=" "&&(" "===n||"\n"===n||"\t"===n||"\r"===n||"\f"===n)}_skipOptionalSpaces(){for(;this._currentIndex<this._endIndex&&this._isCurrentSpace();)this._currentIndex+=1;return this._currentIndex<this._endIndex}_skipOptionalSpacesOrDelimiter(){return!(this._currentIndex<this._endIndex&&!this._isCurrentSpace()&&","!==this._string[this._currentIndex])&&(this._skipOptionalSpaces()&&this._currentIndex<this._endIndex&&","===this._string[this._currentIndex]&&(this._currentIndex+=1,this._skipOptionalSpaces()),this._currentIndex<this._endIndex)}_parseArcFlag(){if(this._currentIndex>=this._endIndex)throw new Error("Unable to parse arc flag");let n;const e=this._string[this._currentIndex];if(this._currentIndex+=1,"0"===e)n=0;else{if("1"!==e)throw new Error("Unable to parse arc flag - arc flag must be 0 or 1");n=1}return this._skipOptionalSpacesOrDelimiter(),n}}const{ceil:$,min:J,max:K}=Math;function nn(r,o,s,i,l,c=0,u=0,a,d=!0,f=!0,g,h=0){const x="string"==typeof o?function(n){if(0===n.length)return[];if("m"!==n[0].type.toLowerCase())throw new Error("Invalid SVG - every new path must start with an M or m.");const e={p:[0,0]},t=[];let r,o=[];for(let s=0;s<n.length;s++){const i=n[s],l=i.type.toLowerCase();if(e.vals=i.values,i.type===l)if("v"===l)e.vals[0]+=e.p[1];else if("a"===l)e.vals[5]+=e.p[0],e.vals[6]+=e.p[1];else for(let n=0;n<e.vals.length;n++)e.vals[n]+=e.p[n%2];if("m"===l){o.length&&("z"!==r&&o.push(z(e)),t.push(o),o=[]),e.initialPoint=e.p=e.vals,r=l;continue}const c=H[l];if(!c)throw new Error("Invalid SVG - command not recognized.");const u=c(e);e.p=u[u.length-1],o.push(u),r=l}return o.length>0&&("z"!==r&&o.push(z(e)),t.push(o)),t}(function(n){if(!n.length)return[];const e=new Z(n),t=[];if(!e.initialCommandIsMoveTo())throw new Error("Path must start with m or M");for(;e.hasMoreData();)t.push(e.parseSegment());return t}(o)):o;let I=1;if(i/l>4){const n=i/4;I=n/l,l=n}const _=l/n,p=K(i,l),v=$(i/_),m=2*$(J(a,p)/_/2),C=function(n,e,r,o){const{gl:s,programs:i}=n;if(i[e])return i[e];const l=s.createProgram(),c=t(s,"#version 300 es\n\nprecision highp float;\n\nuniform vec2 uWidthHeight;\nin vec2 aUV;\nin ivec2 aCloseCellIdxRangePerCell;\nin ivec2 aCrossIdxRangePerCell;\nout vec2 vXY;\nflat out int instanceId;\nflat out ivec2 closeCellIdxRange;\nflat out ivec2 crossCellIdxRange;\n\n\nvoid main() {\n instanceId = gl_InstanceID;\n closeCellIdxRange = aCloseCellIdxRangePerCell;\n crossCellIdxRange = aCrossIdxRangePerCell;\n\n // drawn column-by-column\n float i = float(instanceId / 32); // column index\n float j = float(instanceId % 32); // row index\n\n vec2 trans = vec2(\n i / float(32),\n j / float(32)\n );\n\n vec2 uv = aUV + trans;\n\n float width = uWidthHeight.x;\n float height = uWidthHeight.y;\n\n vXY = vec2(\n height * uv.x,\n height * uv.y\n );\n\n float aspectRatio = width / height;\n\n gl_Position = vec4(\n vec2(\n (2.0*(uv.x / aspectRatio) - 1.0),\n (2.0*uv.y - 1.0)\n ),\n 0.0, 1.0\n );\n}\n",s.VERTEX_SHADER),u=t(s,o,s.FRAGMENT_SHADER);return s.attachShader(l,c),s.attachShader(l,u),s.linkProgram(l),i[e]={gl:s,program:l,attributes:{},uniforms:{},uniformBlocks:{},vertexShader:c,fragmentShader:u},i[e]}(r,`main${v}-${m}`,0,function(t,r){const o=e[1024*t+r];if(void 0!==o)return o;const s=`#version 300 es\n\nprecision highp float;\n\nuniform float uMaxDistance;\nuniform highp sampler2D uSegs;\nuniform highp isampler2D uCloseCellIdxs;\nuniform highp isampler2D uCrossCellIdxs;\nuniform int uIncl; // bit 0 -> incl inside, bit 1 -> incl outside\n\nuniform SegIdxRangePerCellBlock {\n ivec4 uSegIdxRangePerCell[${(n+2*r)*(t+2*r)/2}];\n};\nuniform SegIdxRangePerStripBlock {\n ivec4 uSegIdxRangePerStrip[16];\n};\n\nin vec2 vXY;\nflat in int instanceId;\nflat in ivec2 closeCellIdxRange;\nflat in ivec2 crossCellIdxRange;\nout vec4 FragColor;\n\n\nfloat absDistToSegment(vec2 point, vec2 lineA, vec2 lineB) {\n vec2 lineDir = lineB - lineA;\n float lenSq = dot(lineDir, lineDir);\n float t = clamp(dot(point - lineA, lineDir) / lenSq, 0.0, 1.0);\n vec2 linePt = lineA + t*lineDir;\n\n return distance(point, linePt);\n}\n\n\nvoid main() {\n ///////////////////////////////////////////////////////////////////////////\n // Project a ray to the left to check if it crosses the segment in order\n // to find the fragment's winding number to determine whether fragment\n // is inside or outside the shape.\n\n int crossIdxS = crossCellIdxRange.x;\n int crossLen = crossCellIdxRange.y;\n float winds = 0.0;\n // Iterate over all relevant cell indexes\n for (int i = crossIdxS; i < crossIdxS + crossLen; i++) {\n int crossIdx = texelFetch(uCrossCellIdxs, ivec2(i%256, i/256), 0).x;\n\n ivec2 uSegIdxRange = crossIdx % 2 == 0\n ? uSegIdxRangePerCell[crossIdx / 2].xy\n : uSegIdxRangePerCell[crossIdx / 2].zw;\n\n int segIdx = uSegIdxRange.x;\n int segLen = uSegIdxRange.y;\n\n for (int j = segIdx; j < segIdx + segLen; j++) {\n // Fetch segment from texture\n vec4 seg = texelFetch(uSegs, ivec2(j%256, j/256), 0);\n\n // line segment's min-y is excluded\n bool crossing =\n (seg.y > vXY.y != seg.w > vXY.y) &&\n (vXY.x > (seg.z - seg.x)*(vXY.y - seg.y) / (seg.w - seg.y) + seg.x);\n\n bool crossingUp = seg.y < seg.w;\n\n winds += crossing ? (crossingUp ? 1.0 : -1.0) : 0.0;\n }\n }\n\n {\n int cellIdx = (instanceId % 32);\n\n bool isEven = cellIdx % 2 == 0;\n\n ivec4 uSegIdxRange = uSegIdxRangePerStrip[cellIdx / 2];\n int segIdx = isEven ? uSegIdxRange.x : uSegIdxRange.z;\n int segLen = isEven ? uSegIdxRange.y : uSegIdxRange.w;\n \n\n for (int j = segIdx; j < segIdx + segLen; j++) {\n // Fetch segment from texture\n vec4 seg = texelFetch(uSegs, ivec2(j%256, j/256), 0);\n\n // line segment's min-y is excluded\n bool crossing =\n (seg.y > vXY.y != seg.w > vXY.y) &&\n (vXY.x > (seg.z - seg.x)*(vXY.y - seg.y) / (seg.w - seg.y) + seg.x);\n\n bool crossingUp = seg.y < seg.w;\n\n winds += crossing ? (crossingUp ? 1.0 : -1.0) : 0.0;\n }\n }\n\n\n bool inside = winds != 0.0;\n ///////////////////////////////////////////////////////////////////////////\n\n ///////////////////////////////////////////////////////////////////////////\n float res = 1.0; // sdf result\n\n if ((inside && (uIncl % 2 != 0)) || (!inside && (uIncl > 1))) {\n int cellIdxS = closeCellIdxRange.x;\n int cellLen = closeCellIdxRange.y;\n // Iterate over all relevant cell indexes\n for (int i = cellIdxS; i < cellIdxS + cellLen; i++) {\n int cellIdx = texelFetch(uCloseCellIdxs, ivec2(i%256, i/256), 0).x;\n\n ivec2 uSegIdxRange = cellIdx % 2 == 0\n ? uSegIdxRangePerCell[cellIdx / 2].xy\n : uSegIdxRangePerCell[cellIdx / 2].zw;\n\n int segIdx = uSegIdxRange.x;\n int segLen = uSegIdxRange.y;\n\n for (int j = segIdx; j < segIdx + segLen; j++) {\n // Fetch segment from texture\n vec4 seg = texelFetch(uSegs, ivec2(j%256, j/256), 0);\n\n // Find unsigned distance to the segment; only the nearest will be kept\n float d = absDistToSegment(vXY, seg.xy, seg.zw);\n // Apply exponential transform\n float val = clamp(d / uMaxDistance, 0.0, 1.0);\n\n res = min(res, val);\n }\n }\n }\n ///////////////////////////////////////////////////////////////////////////\n\n // DEBUG!\n // float alpha = ((instanceId + instanceId/32) % 2 == 0 ? 0.3 : 0.5);\n\n\n float exponent = 2;\n res = pow(1.0 - val, exponent) * 0.5;\n\n float alpha = res == 1.0 ? 0.0 : 0.5;\n float red = inside ? 0.2 : 0.8;\n float green = abs(sin(25.0 * res));\n float blue = 0.5;\n\n FragColor = vec4(red, green, blue, alpha);\n}\n`;return e[1024*t+r]=s,s}(v,m)),{gl:S}=r;S.useProgram(C.program),V(r,C,x,s,a,d,f,g,c,u,i,l,v,_,m,I)}function en(n){if(void 0===n)return;const{gl:e,programs:t,textures:r}=n;for(let n in t){const{attributes:r,fragmentShader:o,vertexShader:s,uniformBlocks:i,program:l}=t[n];for(let n in i){const{buf:t}=i[n];e.deleteBuffer(t)}for(let n in r){const{buf:t}=r[n];e.deleteBuffer(t)}e.deleteShader(o),e.deleteShader(s),e.deleteProgram(l)}for(let n in r){const{tex:t}=r[n];e.deleteTexture(t)}}const tn=new WeakMap;function rn(n){{const e=tn.get(n);if(e)return e}const e={},t={},r={gl:n,textures:t,programs:e};return n.canvas.addEventListener("webglcontextlost",o=>{on(e),on(t),tn.delete(n),r.onContextLoss?.(o)},!1),tn.set(n,r),r}function on(n){Object.keys(n).forEach(e=>{delete n[e]})}export{en as freeGlContext,nn as generateSdf,rn as getWebGlContext};
1
+ const n=32,e="#version 300 es\n\nprecision highp float;\n\nuniform vec2 uWidthHeight;\nin vec2 aUV;\nin ivec2 aCloseCellIdxRangePerCell;\nin ivec2 aCrossIdxRangePerCell;\nout vec2 vXY;\nflat out int instanceId;\nflat out ivec2 closeCellIdxRange;\nflat out ivec2 crossCellIdxRange;\n\n\nvoid main() {\n instanceId = gl_InstanceID;\n closeCellIdxRange = aCloseCellIdxRangePerCell;\n crossCellIdxRange = aCrossIdxRangePerCell;\n\n // drawn column-by-column\n float i = float(instanceId / 32); // column index\n float j = float(instanceId % 32); // row index\n\n vec2 trans = vec2(\n i / float(32),\n j / float(32)\n );\n\n vec2 uv = aUV + trans;\n\n float width = uWidthHeight.x;\n float height = uWidthHeight.y;\n\n vXY = vec2(\n height * uv.x,\n height * uv.y\n );\n\n float aspectRatio = width / height;\n\n gl_Position = vec4(\n vec2(\n (2.0*(uv.x / aspectRatio) - 1.0),\n (2.0*uv.y - 1.0)\n ),\n 0.0, 1.0\n );\n}\n",t={},r="\n float exponent = uCustom.x;\n float alpha = res >= 1.0 ? 0.0 : 0.5;\n res = pow(1.0 - res, exponent);\n float red = inside ? 0.2 : 0.8;\n float green = abs(sin(25.0 * res));\n // float green = step(0.5, fract(10.0 * res));\n float blue = 0.5;\n",o="\n float exponent = uCustom.x;\n float adj = 0.5*pow(1.0 - res, exponent);\n res = inside ? 1.0 - adj : adj;\n float red = res;\n float green = res;\n float blue = res;\n float alpha = res;\n";function s(e,r,o,s){const i=2**32*(256*e+r)+s,c=t[i];if(void 0!==c)return c;const l=`#version 300 es\n\nprecision highp float;\n\nuniform float uMaxDistance;\nuniform highp sampler2D uSegs;\nuniform highp isampler2D uCloseCellIdxs;\nuniform highp isampler2D uCrossCellIdxs;\n// bit 0 -> calc distance inside\n// bit 1 -> calc distance outside\n// bit 2 -> calc whether fragment is inside or outside (else outside is assumed with winds == 0.0)\nuniform int uTestInOut;\nuniform vec4 uCustom;\n\nuniform SegIdxRangePerCellBlock {\n ivec4 uSegIdxRangePerCell[${(n+2*r)*(e+2*r)/2}];\n};\nuniform SegIdxRangePerStripBlock {\n ivec4 uSegIdxRangePerStrip[16];\n};\n\nin vec2 vXY;\nflat in int instanceId;\nflat in ivec2 closeCellIdxRange;\nflat in ivec2 crossCellIdxRange;\nout vec4 FragColor;\n\n// testing!!\n// float rand(vec2 co) {\n// return mod(uCustom.w * fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453), 1.0);\n// }\n\nfloat absDistToSegment(vec2 point, vec2 lineA, vec2 lineB) {\n vec2 lineDir = lineB - lineA;\n float lenSq = dot(lineDir, lineDir);\n float t = clamp(dot(point - lineA, lineDir) / lenSq, 0.0, 1.0);\n vec2 linePt = lineA + t*lineDir;\n\n return distance(point, linePt);\n}\n\n\nvoid main() {\n ///////////////////////////////////////////////////////////////////////////\n // Calculate \`winds\`:\n //\n // Project a ray to the left to check if it crosses the segment in order\n // to find the fragment's winding number to determine whether fragment\n // is inside or outside the shape.\n ///////////////////////////////////////////////////////////////////////////\n\n float winds = 0.0;\n if ((uTestInOut & 4) != 0) {\n int crossIdxS = crossCellIdxRange.x;\n int crossLen = crossCellIdxRange.y;\n // Iterate over all relevant cell indexes\n for (int i = crossIdxS; i < crossIdxS + crossLen; i++) {\n int crossIdx = texelFetch(uCrossCellIdxs, ivec2(i%256, i/256), 0).x;\n\n ivec2 uSegIdxRange = crossIdx % 2 == 0\n ? uSegIdxRangePerCell[crossIdx / 2].xy\n : uSegIdxRangePerCell[crossIdx / 2].zw;\n\n int segIdx = uSegIdxRange.x;\n int segLen = uSegIdxRange.y;\n\n for (int j = segIdx; j < segIdx + segLen; j++) {\n // Fetch segment from texture\n vec4 seg = texelFetch(uSegs, ivec2(j%256, j/256), 0);\n\n // line segment's min-y is excluded\n bool crossing =\n (seg.y > vXY.y != seg.w > vXY.y) &&\n (vXY.x > (seg.z - seg.x)*(vXY.y - seg.y) / (seg.w - seg.y) + seg.x);\n\n bool crossingUp = seg.y < seg.w;\n\n winds += crossing ? (crossingUp ? -1.0 : 1.0) : 0.0;\n }\n }\n\n {\n int cellIdx = (instanceId % 32);\n\n bool isEven = cellIdx % 2 == 0;\n\n ivec4 uSegIdxRange = uSegIdxRangePerStrip[cellIdx / 2];\n int segIdx = isEven ? uSegIdxRange.x : uSegIdxRange.z;\n int segLen = isEven ? uSegIdxRange.y : uSegIdxRange.w;\n \n\n for (int j = segIdx; j < segIdx + segLen; j++) {\n // Fetch segment from texture\n vec4 seg = texelFetch(uSegs, ivec2(j%256, j/256), 0);\n\n // line segment's min-y is excluded\n bool crossing =\n (seg.y > vXY.y != seg.w > vXY.y) &&\n (vXY.x > (seg.z - seg.x)*(vXY.y - seg.y) / (seg.w - seg.y) + seg.x);\n\n bool crossingUp = seg.y < seg.w;\n\n winds += crossing ? (crossingUp ? -1.0 : 1.0) : 0.0;\n }\n }\n }\n bool inside = winds != 0.0;\n ///////////////////////////////////////////////////////////////////////////\n // Calculate \`res\`: the distance to the nearest curve\n ///////////////////////////////////////////////////////////////////////////\n float res = 1.0; // sdf result\n\n if ((inside && ((uTestInOut & 1) != 0)) || (!inside && ((uTestInOut & 2) != 0))) {\n int cellIdxS = closeCellIdxRange.x;\n int cellLen = closeCellIdxRange.y;\n // Iterate over all relevant cell indexes\n for (int i = cellIdxS; i < cellIdxS + cellLen; i++) {\n int cellIdx = texelFetch(uCloseCellIdxs, ivec2(i%256, i/256), 0).x;\n\n ivec2 uSegIdxRange = cellIdx % 2 == 0\n ? uSegIdxRangePerCell[cellIdx / 2].xy\n : uSegIdxRangePerCell[cellIdx / 2].zw;\n\n int segIdx = uSegIdxRange.x;\n int segLen = uSegIdxRange.y;\n\n for (int j = segIdx; j < segIdx + segLen; j++) {\n // Fetch segment from texture\n vec4 seg = texelFetch(uSegs, ivec2(j%256, j/256), 0);\n\n // Find normalized unsigned distance to the segment; only the nearest will be kept\n float d = absDistToSegment(vXY, seg.xy, seg.zw);\n float val = clamp(d / uMaxDistance, 0.0, 1.0);\n\n res = min(res, val);\n }\n }\n }\n ///////////////////////////////////////////////////////////////////////////\n\n // DEBUG!\n // float alpha = ((instanceId + instanceId/32) % 2 == 0 ? 0.3 : 0.5);\n\n \n ${o}\n\n FragColor = vec4(red, green, blue, alpha);\n}\n`;return t[i]=l,l}function i(n,e,t){const r=n.createShader(t);return n.shaderSource(r,e),n.compileShader(r),r}function c(n,e,t){const{gl:r,textures:o}=n;r.activeTexture(r.TEXTURE0+e);let s=o[t];return s?r.bindTexture(r.TEXTURE_2D,s.tex):(s=o[t]={tex:r.createTexture()},r.bindTexture(r.TEXTURE_2D,s.tex),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MIN_FILTER,r.NEAREST),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MAG_FILTER,r.NEAREST),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,r.CLAMP_TO_EDGE),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,r.CLAMP_TO_EDGE)),s}const{BYTE:l,UNSIGNED_BYTE:u,SHORT:a,UNSIGNED_SHORT:d,INT:f,UNSIGNED_INT:g,FLOAT:h,HALF_FLOAT:x,INT_2_10_10_10_REV:I,UNSIGNED_INT_2_10_10_10_REV:_}=WebGL2RenderingContext;function p(n){return(e,t,r)=>{const{gl:o,uniformBlocks:s,program:i}=n;let c=s[e];if(void 0===s[e]){const n=o.getUniformBlockIndex(i,e);o.uniformBlockBinding(i,n,t);const r=o.createBuffer();o.bindBuffer(o.UNIFORM_BUFFER,r),c={blockName:e,blockIndex:n,buf:r},s[e]=c}else o.bindBuffer(o.UNIFORM_BUFFER,c.buf);const{buf:l}=c;o.bufferData(o.UNIFORM_BUFFER,r,o.STATIC_DRAW),o.bindBufferBase(o.UNIFORM_BUFFER,t,l)}}function v(n){const e=n[0][0],t=n[0][1];for(let r=1;r<n.length;r++)if(e!==n[r][0]||t!==n[r][1])return!1;return!0}function m(n,e){if(0===e)return n[0];if(1===e)return n[n.length-1];if(4===n.length){const[[t,r],[o,s],[i,c],[l,u]]=n,a=t+(o-t)*e,d=o+(i-o)*e,f=a+(d-a)*e,g=r+(s-r)*e,h=s+(c-s)*e,x=g+(h-g)*e;return[f+(d+(i+(l-i)*e-d)*e-f)*e,x+(h+(c+(u-c)*e-h)*e-x)*e]}if(3===n.length){const[[t,r],[o,s],[i,c]]=n,l=t+(o-t)*e,u=r+(s-r)*e;return[l+(o+(i-o)*e-l)*e,u+(s+(c-s)*e-u)*e]}if(2===n.length){const[[t,r],[o,s]]=n;return[t+(o-t)*e,r+(s-r)*e]}if(1===n.length)return n[0];throw new Error("The given bezier curve must be of order <= 3.")}const{sqrt:C}=Math;function S(n,e){const t=n[0],r=n[1],o=e[0],s=e[1],i=r-s,c=o-t,l=t*s-o*r,u=C(i*i+c*c);return function(n){const e=n[0],o=n[1];return 0!==u?(i*e+c*o+l)/u:C((e-t)**2+(o-r)**2)}}{const n=[10,1];S([6,2],[6,2])(n)}function R(n,e,t){if(4===n.length)return function(n,e,t){return 0===e?1===t?n:function(n,e){const t=n[0],r=n[1],o=n[2],s=n[3],i=t[0],c=t[1],l=r[0],u=r[1],a=o[0],d=o[1],f=i-e*(i-l),g=l-e*(l-a),h=f-e*(f-g),x=c-e*(c-u),I=u-e*(u-d),_=x-e*(x-I);return[t,[f,x],[h,_],[h-e*(h-(g-e*(g-(a-e*(a-s[0]))))),_-e*(_-(I-e*(I-(d-e*(d-s[1])))))]]}(n,t):1===t?function(n,e){const t=n[0],r=n[1],o=n[2],s=n[3],i=t[0],c=t[1],l=r[0],u=r[1],a=o[0],d=o[1],f=i-e*(i-l),g=l-e*(l-a),h=a-e*(a-s[0]),x=f-e*(f-g),I=g-e*(g-h),_=c-e*(c-u),p=u-e*(u-d),v=d-e*(d-s[1]),m=_-e*(_-p),C=p-e*(p-v);return[[x-e*(x-I),m-e*(m-C)],[I,C],[h,v],s]}(n,e):function(n,e,t){const r=n[0],o=n[1],s=n[2],i=n[3],c=r[0],l=r[1],u=o[0],a=o[1],d=s[0],f=s[1],g=e*e,h=e*g,x=t*t,I=t*x,_=e*t,p=c-u,v=d-u,m=p+v,C=e*p,S=t*p,R=i[0]-c-3*v,E=l-a,T=f-a,b=E+T,w=e*E,A=t*E,P=i[1]-l-3*T;return[[h*R+(3*e*(e*m-p)+c),h*P+(3*e*(e*b-E)+l)],[_*(e*R+2*m)+(g*m+c-(S+2*C)),_*(e*P+2*b)+(g*b+l-(A+2*w))],[_*(t*R+2*m)+(x*m+c-(2*S+C)),_*(t*P+2*b)+(x*b+l-(2*A+w))],[I*R+(3*t*(t*m-p)+c),I*P+(3*t*(t*b-E)+l)]]}(n,e,t)}(n,e,t);if(3===n.length)return function(n,e,t){return 0===e?1===t?n:function(n,e){const t=n[0],r=n[1],o=n[2],s=t[0],i=t[1],c=r[0],l=r[1],u=e*e,a=s-c,d=i-l;return[t,[-e*a+s,-e*d+i],[u*(a+(o[0]-c))-(2*e*a-s),u*(d+(o[1]-l))-(2*e*d-i)]]}(n,t):1===t?function(n,e){const t=n[0],r=n[1],o=n[2],s=t[0],i=t[1],c=r[0],l=r[1],u=e*e,a=s-c,d=o[0]-c,f=i-l,g=o[1]-l;return[[u*(a+d)-(2*e*a-s),u*(f+g)-(2*e*f-i)],[e*d+c,e*g+l],o]}(n,e):function(n,e,t){const r=n[0],o=n[1],s=n[2],i=r[0],c=r[1],l=o[0],u=o[1],a=e*e,d=t*t,f=e*t,g=i-l,h=g+(s[0]-l),x=c-u,I=x+(s[1]-u);return[[a*h-(2*e*g-i),a*I-(2*e*x-c)],[f*h-(g*(t+e)-i),f*I-(x*(t+e)-c)],[d*h-(2*t*g-i),d*I-(2*t*x-c)]]}(n,e,t)}(n,e,t);throw new Error("The given bezier curve must be of order 2 or 3.")}function E(n,e){return[e[0]-n[0],e[1]-n[1]]}function T(n,e){return n[0]*e[0]+n[1]*e[1]}function b(n){const e=E(n[0],n[1]),t=E(n[1],n[3]),r=E(n[3],n[0]),o=E(n[0],n[2]),s=E(n[2],n[3]);return T(r,e)>0||T(t,r)>0||T(r,o)>0||T(s,r)>0}const{abs:w,max:A}=Math;function P(n){const e=S(n[0],n[3]),t=e(n[1]),r=e(n[2]);return(t*r<=0?4/9:3/4)*A(w(t),w(r))}function D(n){const e=E(n[0],n[1]),t=E(n[1],n[2]),r=E(n[2],n[0]);return T(r,e)>0||T(t,r)>0}const{abs:y}=Math;function F(n){if(n[0][0]===n[1][0]&&n[0][1]===n[1][1])return 0;const e=m(n,.5),t=S(n[0],n[2]);return y(t(e))}function U(n){const e=3===n.length?function(n){const e=[0],t=[1];for(;;){const r=e[e.length-1],o=t[t.length-1],s=R(n,r,o);if(!D(s)&&F(s)<=.5){if(e.push(t.pop()),1===o)return e;continue}const i=(r+o)/2;t.push(i)}}(n):function(n){const e=[0],t=[1];for(;;){const r=e[e.length-1],o=t[t.length-1],s=R(n,r,o);if(!b(s)&&P(s)<=.5){if(e.push(t.pop()),1===o)return e;continue}const i=(r+o)/2;t.push(i)}}(n),t=[];for(let r=0;r<e.length-1;r++){const o=m(n,e[r]),s=m(n,e[r+1]);t.push([o,s])}return t}function M(n){return Math.sqrt(n[0]*n[0]+n[1]*n[1])}const N=function(){const e=[{from:0,u:0,v:0}];for(let t=0;t<128;t++){e.push({from:t+.5,u:t+1,v:0}),e.push({from:t+.5,u:-t-1,v:0}),e.push({from:t+.5,u:0,v:t+1}),e.push({from:t+.5,u:0,v:-t-1});for(let r=0;r<n;r++){const n=M([.5+t,.5+r]),o=t+1,s=r+1;e.push({from:n,u:o,v:s}),0!==o&&e.push({from:n,u:-o,v:s}),0!==s&&e.push({from:n,u:o,v:-s}),0!==o&&0!==s&&e.push({from:n,u:-o,v:-s})}e.sort((n,e)=>n.from-e.from)}return e}(),{max:k,E:L}=Math;const{min:O,max:B,SQRT2:X}=Math;function j(e,t,r,o,s){const i=function(e,t,r,o,s){return function(i,c,l){let u=function(n){let e=function(n){let e=0,t=N.length-1,r=0;for(;e<=t;){r=e+t>>>1;const o=N[r].from;if(o===n)return r;n>o?e=r+1:t=r-1}return r}(n);if(n=k(0,n),0===e)return 0;for(;N[e].from===N[e-1].from;)e--;return e}((l-X*r)/r),a=Number.POSITIVE_INFINITY;for(;;){if(u>=N.length){a=r*(N[N.length-1].from-X);break}const{u:l,v:d,from:f}=N[u];if(r*f>o+X*r){a=r*(f-2*X);break}const g=l+i,h=d+c;if(g<0||g>=t+2*s||h<0||h>=n+2*s){u++;continue}const{lineSegs:x}=e[g][h];if(x.length>0){a=r*(f-X);break}u++}const{closeCells:d}=e[i][c];let f=B(0,u-1);for(;f<N.length;){const{from:l,u,v:g}=N[f];if(r*l>O(a,o)+2*X*r)break;const h=u+i,x=g+c;if(h<0||h>=t+2*s||x<0||x>=n+2*s){f++;continue}const{lineSegs:I}=e[h][x];I.length>0&&d.push((2*s+n)*h+x),f++}return a}}(e,t,r,o,s);let c=0,l=0;for(let e=s;e<t+s;e++){l=c;for(let t=s;t<n+s;t++)l=i(e,t,l),t===s&&(c=l)}}const{floor:G,ceil:Y}=Math;function Q(n,e,t,r,o,s){const i=r*s,[[c,l],[u,a]]=o,d=e+i,f=t+i,g=function(n,e){const[t,r]=n,[o,s]=t,[i,c]=r,[[l,u],[a,d]]=e,f=i-o,g=c-s,h=[];if(0!==f){const n=(l-o)/f;if(n>=0&&n<=1){const e=s+n*g;e>=u&&e<=d&&h.push({t:n,p:[l,e]})}const e=(a-o)/f;if(e>=0&&e<=1){const n=s+e*g;n>=u&&n<=d&&h.push({t:e,p:[a,n]})}}if(0!==g){const n=(u-s)/g;if(n>=0&&n<=1){const e=o+n*f;e>=l&&e<=a&&h.push({t:n,p:[e,u]})}const e=(d-s)/g;if(e>=0&&e<=1){const n=o+e*f;n>=l&&n<=a&&h.push({t:e,p:[n,d]})}}const x=new Set,I=h.filter(n=>{const{t:e}=n;return!x.has(e)&&(x.add(e),!0)});return I.sort((n,e)=>n.t-e.t).map(n=>n.p)}(o,[[-i,-i],[d,f]]),h=c>-i&&c<d&&l>-i&&l<f,x=u>-i&&u<d&&a>-i&&a<f;if(g.length<2&&!h&&!x)return;const I=u-c,_=a-l,p=u>c?r:-r,v=a>l?r:-r;let m=c,C=l,S=0;const R=p>0,E=v>0,T=R?G:Y,b=E?G:Y;for(;;){let e=r*T((m+p)/r),t=r*b((C+v)/r);const o=(e-c)/I,x=(t-l)/_,w=o<x&&0!==I||0===_,A=w?e:c+x*I,P=w?l+o*_:t;if((o>1||0===I)&&(x>1||0===_)){const e=G(u/r)+s,t=G(a/r)+s;n[e]?.[t]?.lineSegs.push([[m,C],[u,a]]);break}if(A<=-i||P<=-i||A>=d||P>=f){if(!h&&0===S){[m,C]=g[0],S++;continue}{const e=T(m/r)-(R?0:1)+s,t=b(C/r)-(E?0:1)+s,o=[[m,C],g[S]];n[e]?.[t]?.lineSegs.push(o);break}}const D=T(m/r)-(R?0:1)+s,y=b(C/r)-(E?0:1)+s;n[D]?.[y]?.lineSegs.push([[m,C],[A,P]]),m=A,C=P}}const V=256,{floor:z,ceil:H}=Math;function W(n,e,t){const r=e/n.length,[o,s]=t,i=function(n,e){const[t,r]=n,[o,s]=t,[i,c]=r,[l,u,a]=e,d=i-o,f=c-s,g=[],h=[];if(0!==d){const n=(l-o)/d;if(n>=0&&n<=1){const e=s+n*f;e>=u&&e<=a&&(g.push(n),h.push([l,e]))}}if(0!==f){const n=(u-s)/f;if(n>=0&&n<=1){const e=o+n*d;e<=l&&(g.push(n),h.push([e,u]))}const e=(a-s)/f;if(e>=0&&e<=1){const n=o+e*d;n<=l&&(g.push(e),h.push([n,a]))}}return 2===g.length?g[0]<g[1]?h:[h[1],h[0]]:h}(t,[0,0,e]),[c,l]=o,[u,a]=s,d=u-c,f=a-l,g=c<0&&l>0&&l<e,h=u<0&&a>0&&a<e;if(i.length<2&&!g&&!h&&(0!==c||0!==d||l<=0&&a<=0||l>=e&&a>=e))return;if(0===f)return;const x=a>l?r:-r;let I=c,_=l,p=0;const v=u>c,m=a>l,C=m?z:H;for(;;){let t=v&&I<0||!v&&I>0?0:Number.NEGATIVE_INFINITY,o=r*C((_+x)/r);const u=(t-c)/d,a=(o-l)/f,h=u<a&&0!==d,S=h?0:c+a*d,R=h?l+u*f:o;if((u>1||0===d)&&a>1){const e=z(s[1]/r);n[e]?.push([[I,_],s]);break}if(S>=0&&(0!==c||0!==d)||R<=0||R>=e){if(!g&&0===p){[I,_]=i[0],p++;continue}{const e=C(_/r)-(m?0:1),t=[[I,_],i[p]];n[e]?.push(t);break}}const E=C(_/r)-(m?0:1);n[E]?.push([[I,_],[S,R]]),I=S,_=R}}function q(e,t,r,o,s,i,l,u,a,d,f,g){const{gl:I}=e,{x:_=0,y:m=0,testInteriorExterior:C=!0,calcSdfForInside:S=!0,calcSdfForOutside:R=!0,customData:E=[1,0,0,0],colorMask:T=[!0,!0,!0,!0]}=u,b=[],w=.03125,A=.03125;b.push(0,0,w,0,0,A),b.push(w,0,w,A,0,A);const P=new Float32Array(b),D=(y=t,(n,e,...t)=>{const{gl:r,uniforms:o}=y,s=o[e]||(o[e]=r.getUniformLocation(y.program,e));r[`uniform${n}`](s,...t)});var y;const F=function(n){return(e,t,r,o,s,i=0,c=0,l=0)=>{const{gl:u,attributes:a}=n,d=a[e]=a[e]??{buf:u.createBuffer(),loc:u.getAttribLocation(n.program,e),data:null},{loc:f,buf:g}=d;u.bindBuffer(u.ARRAY_BUFFER,g),r===h||r===x?u.vertexAttribPointer(f,t,r,!1,c,l):u.vertexAttribIPointer(f,t,r,c,l),u.enableVertexAttribArray(f),0!==i&&u.vertexAttribDivisor(f,i),s!==d.data&&(u.bufferData(u.ARRAY_BUFFER,s,o),d.data=s)}}(t),{lineSegPtCoords_Arr:M,segIdxs_PerCell_Range_Arr:N,closeCellIdxs_PerCell_Arr:k,closeCellIdxs_PerCell_Range_Arr:L,crossCellIdxs_PerCell_Arr:O,crossCellIdxs_perCell_Range_Arr:B,segIdxs_PerStrip_Range_Arr:X}=function(e,t,r,o,s,i,c,l=[0,0,t,r],u=1){const a=function(n,e,t,r){if(0===n[0]&&0===n[1]&&n[2]===e&&n[3]===t)return r;const[o,s,i,c]=n,l=e/i,u=t/c,a=[];for(let n=0;n<r.length;n++){const e=r[n],t=[];for(let n=0;n<e.length;n++){const r=e[n],i=[];for(let n=0;n<r.length;n++){const[e,t]=r[n],c=l*e-o,a=u*t-s;i.push([c,a])}t.push(i)}a.push(t)}return a}(l,t,r/u,e),d=function(n){let e=[];for(let t=0;t<n.length;t++){const r=n[t];for(let n=0;n<r.length;n++){const t=r[n];if(v(t))continue;if(2===t.length){e.push(t);continue}const o=U(t);e.push(...o.filter(n=>!v(n)))}}return e}(a),f=function(e,t){const r=[];for(let o=0;o<e+2*t;o++){const e=[];for(let r=0;r<n+2*t;r++)e.push({lineSegs:[],closeCells:[],crossingCells:[]});r.push(e)}return r}(o,c),g=new Array(n).fill(void 0).map(n=>[]);for(let n=0;n<d.length;n++){const e=d[n];Q(f,t,r,s,e,c),W(g,r,e)}j(f,o,s,i,c),function(e,t,r){for(let o=r;o<t+r;o++)for(let t=r;t<n+r;t++){const s=e[o][t].crossingCells;for(let i=r;i<=o;i++)0!==e[i][t].lineSegs.length&&s.push((n+2*r)*i+t)}}(f,o,c);const h=[],x=[],I=[],_=[],p=[],m=[];let C=0,S=0,R=0;for(let e=0;e<o+2*c;e++)for(let t=0;t<n+2*c;t++){const r=f[e][t];if(e>=c&&e<o+c&&t>=c&&t<n+c){const{closeCells:n,crossingCells:e}=r,t=e.length,o=n.length;p.push(...e),I.push(...n),m.push(C,t),_.push(S,o),C+=t,S+=o}const{lineSegs:s}=r,i=s.length;x.push(R,i),R+=i,h.push(...s.flat(2))}const E=[];for(let e=0;e<n;e++){const n=g[e],t=n.length;E.push([R,t]),R+=t,h.push(...n.flat(2))}for(;I.length%V!==0;)I.push(0);for(;p.length%V!==0;)p.push(0);for(;h.length%1024!=0;)h.push(0);const T=new Float32Array(h),b=new Int32Array(x),w=new Int32Array(_);return{lineSegPtCoords_Arr:T,segIdxs_PerCell_Range_Arr:b,closeCellIdxs_PerCell_Arr:new Int32Array(I),closeCellIdxs_PerCell_Range_Arr:w,crossCellIdxs_PerCell_Arr:new Int32Array(p),crossCellIdxs_perCell_Range_Arr:new Int32Array(m),segIdxs_PerStrip_Range_Arr:new Int32Array(E.flat())}}(r,i,l,a,d,s,f,o,g);F("aUV",2,I.FLOAT,I.STATIC_DRAW,P),F("aCrossIdxRangePerCell",2,I.INT,I.STATIC_DRAW,B,1),F("aCloseCellIdxRangePerCell",2,I.INT,I.STATIC_DRAW,L,1),D("2f","uWidthHeight",i,l),D("1f","uMaxDistance",s),D("1i","uTestInOut",(S?1:0)+(R?2:0)+(C?4:0)),D("4f","uCustom",...E),p(t)("SegIdxRangePerCellBlock",0,N),p(t)("SegIdxRangePerStripBlock",1,X),c(e,0,"segs"),I.texImage2D(I.TEXTURE_2D,0,I.RGBA32F,V,M.length/4/V,0,I.RGBA,I.FLOAT,M);const G=I.getUniformLocation(t.program,"uSegs");I.uniform1i(G,0),c(e,1,"closeCellIdxsPerCell"),I.texImage2D(I.TEXTURE_2D,0,I.R32I,V,k.length/V,0,I.RED_INTEGER,I.INT,k);const Y=I.getUniformLocation(t.program,"uCloseCellIdxs");I.uniform1i(Y,1),c(e,2,"crossCellIdxsPerCell"),I.texImage2D(I.TEXTURE_2D,0,I.R32I,V,O.length/V,0,I.RED_INTEGER,I.INT,O);const z=I.getUniformLocation(t.program,"uCrossCellIdxs");I.uniform1i(z,2),g>1&&(I.enable(I.SCISSOR_TEST),I.scissor(_,m,i,l/g)),I.viewport(_,m,i,l),I.colorMask(...T),I.drawArraysInstanced(I.TRIANGLES,0,6,a*n),g>1&&I.disable(I.SCISSOR_TEST)}function $(n){const e=[n.p,n.initialPoint];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=void 0,e}const Z={c:function(n){const e=[n.p,[n.vals[0],n.vals[1]],[n.vals[2],n.vals[3]],[n.vals[4],n.vals[5]]];return n.prev2ndCubicControlPoint=e[2],n.prev2ndQuadraticControlPoint=void 0,e},h:function(n){const e=[n.p,[n.vals[0],n.p[1]]];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=void 0,e},l:function(n){const e=[n.p,n.vals];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=void 0,e},q:function(n){const e=[n.vals[0],n.vals[1]],t=[n.vals[2],n.vals[3]];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=e,[n.p,e,t]},s:function(n){const e=n.prev2ndCubicControlPoint?[n.p[0]-n.prev2ndCubicControlPoint[0]+n.p[0],n.p[1]-n.prev2ndCubicControlPoint[1]+n.p[1]]:n.p,t=[n.p,e,[n.vals[0],n.vals[1]],[n.vals[2],n.vals[3]]];return n.prev2ndCubicControlPoint=t[2],n.prev2ndQuadraticControlPoint=void 0,t},t:function(n){const e=n.prev2ndQuadraticControlPoint?[n.p[0]-n.prev2ndQuadraticControlPoint[0]+n.p[0],n.p[1]-n.prev2ndQuadraticControlPoint[1]+n.p[1]]:n.p,t=[n.vals[0],n.vals[1]];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=e,[n.p,e,t]},v:function(n){const e=[n.p,[n.p[0],n.vals[0]]];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=void 0,e},z:$};function J(n){let e=0,t=0,r=1,o=0,s=1,i=1;const c=n._currentIndex;if(n._skipOptionalSpaces(),n._currentIndex<n._endIndex&&"+"===n._string[n._currentIndex]?n._currentIndex+=1:n._currentIndex<n._endIndex&&"-"===n._string[n._currentIndex]&&(n._currentIndex+=1,s=-1),n._currentIndex===n._endIndex||(n._string[n._currentIndex]<"0"||n._string[n._currentIndex]>"9")&&"."!==n._string[n._currentIndex])throw new Error("The first character of a number must be one of [0-9+-.].");const l=n._currentIndex;for(;n._currentIndex<n._endIndex&&n._string[n._currentIndex]>="0"&&n._string[n._currentIndex]<="9";)n._currentIndex+=1;if(n._currentIndex!==l){let e=n._currentIndex-1,r=1;for(;e>=l;)t+=r*(Number(n._string[e])-0),e-=1,r*=10}if(n._currentIndex<n._endIndex&&"."===n._string[n._currentIndex]){if(n._currentIndex+=1,n._currentIndex>=n._endIndex||n._string[n._currentIndex]<"0"||n._string[n._currentIndex]>"9")throw new Error("There must be a least one digit following the .");for(;n._currentIndex<n._endIndex&&n._string[n._currentIndex]>="0"&&n._string[n._currentIndex]<="9";)r*=10,o+=Number(n._string.charAt(n._currentIndex))/r,n._currentIndex+=1}if(n._currentIndex!==c&&n._currentIndex+1<n._endIndex&&("e"===n._string[n._currentIndex]||"E"===n._string[n._currentIndex])&&"x"!==n._string[n._currentIndex+1]&&"m"!==n._string[n._currentIndex+1]){if(n._currentIndex+=1,"+"===n._string[n._currentIndex]?n._currentIndex+=1:"-"===n._string[n._currentIndex]&&(n._currentIndex+=1,i=-1),n._currentIndex>=n._endIndex||n._string[n._currentIndex]<"0"||n._string[n._currentIndex]>"9")throw new Error("There must be an exponent.");for(;n._currentIndex<n._endIndex&&n._string[n._currentIndex]>="0"&&n._string[n._currentIndex]<="9";)e*=10,e+=Number(n._string[n._currentIndex]),n._currentIndex+=1}let u=t+o;if(u*=s,e&&(u*=Math.pow(10,i*e)),c===n._currentIndex)throw new Error("Internal error: startIndex === source._currentIndex");return n._skipOptionalSpacesOrDelimiter(),u}const K={Z:"Z",M:"M",L:"L",C:"C",Q:"Q",A:"A",H:"H",V:"V",S:"S",T:"T",z:"Z",m:"m",l:"l",c:"c",q:"q",a:"a",h:"h",v:"v",s:"s",t:"t"};class nn{_string;_currentIndex;_endIndex;_prevCommand;constructor(n){this._string=n,this._currentIndex=0,this._endIndex=this._string.length,this._prevCommand=void 0,this._skipOptionalSpaces()}parseSegment(){const n=this._string[this._currentIndex];let e,t=K[n];if(void 0===t){if(void 0===this._prevCommand)throw new Error("Implicit command not allowed for first commands.");if(!("+"===n||"-"===n||"."===n||n>="0"&&n<="9")||"Z"===this._prevCommand)throw new Error("Remaining coordinates not found for implicit command");t="M"===this._prevCommand?"L":"m"===this._prevCommand?"l":this._prevCommand}else this._currentIndex+=1;this._prevCommand=t;const r=t.toUpperCase();if("H"===r||"V"===r?e=[J(this)]:"M"===r||"L"===r||"T"===r?e=[J(this),J(this)]:"S"===r||"Q"===r?e=[J(this),J(this),J(this),J(this)]:"C"===r?e=[J(this),J(this),J(this),J(this),J(this),J(this)]:"A"===r?e=[J(this),J(this),J(this),this._parseArcFlag(),this._parseArcFlag(),J(this),J(this)]:"Z"===r&&(this._skipOptionalSpaces(),e=[]),void 0===e)throw new Error("Unknown command");return{type:t,values:e}}hasMoreData(){return this._currentIndex<this._endIndex}initialCommandIsMoveTo(){if(!this.hasMoreData())return!0;const n=K[this._string[this._currentIndex]];return"M"===n||"m"===n}_isCurrentSpace(){const n=this._string[this._currentIndex];return n<=" "&&(" "===n||"\n"===n||"\t"===n||"\r"===n||"\f"===n)}_skipOptionalSpaces(){for(;this._currentIndex<this._endIndex&&this._isCurrentSpace();)this._currentIndex+=1;return this._currentIndex<this._endIndex}_skipOptionalSpacesOrDelimiter(){return!(this._currentIndex<this._endIndex&&!this._isCurrentSpace()&&","!==this._string[this._currentIndex])&&(this._skipOptionalSpaces()&&this._currentIndex<this._endIndex&&","===this._string[this._currentIndex]&&(this._currentIndex+=1,this._skipOptionalSpaces()),this._currentIndex<this._endIndex)}_parseArcFlag(){if(this._currentIndex>=this._endIndex)throw new Error("Unable to parse arc flag");let n;const e=this._string[this._currentIndex];if(this._currentIndex+=1,"0"===e)n=0;else{if("1"!==e)throw new Error("Unable to parse arc flag - arc flag must be 0 or 1");n=1}return this._skipOptionalSpacesOrDelimiter(),n}}const{ceil:en,min:tn,max:rn}=Math,on={x:0,y:0,testInteriorExterior:!0,calcSdfForInside:!0,calcSdfForOutside:!0,customData:[1,0,0,0],colorMask:[!0,!0,!0,!0]};function sn(t,r,c,l,u,a,d=on){const f="string"==typeof r?function(n){if(0===n.length)return[];if("m"!==n[0].type.toLowerCase())throw new Error("Invalid SVG - every new path must start with an M or m.");const e={p:[0,0]},t=[];let r,o=[];for(let s=0;s<n.length;s++){const i=n[s],c=i.type.toLowerCase();if(e.vals=i.values,i.type===c)if("v"===c)e.vals[0]+=e.p[1];else if("a"===c)e.vals[5]+=e.p[0],e.vals[6]+=e.p[1];else for(let n=0;n<e.vals.length;n++)e.vals[n]+=e.p[n%2];if("m"===c){o.length&&("z"!==r&&o.push($(e)),t.push(o),o=[]),e.initialPoint=e.p=e.vals,r=c;continue}const l=Z[c];if(!l)throw new Error("Invalid SVG - command not recognized.");const u=l(e);e.p=u[u.length-1],o.push(u),r=c}return o.length>0&&("z"!==r&&o.push($(e)),t.push(o)),t}(function(n){if(!n.length)return[];const e=new nn(n),t=[];if(!e.initialCommandIsMoveTo())throw new Error("Path must start with m or M");for(;e.hasMoreData();)t.push(e.parseSegment());return t}(r)):r;let g=1;if(l/u>4){const n=l/4;g=n/u,u=n}const h=u/n,x=rn(l,u),I=en(l/h),_=2*en(tn(a,x)/h/2),{glslRgbaCalcStr:p}=d,v=function(n){if(!n)return 0;let e=5381;for(let t=0;t<n.length;t++)e=(e<<5)+e+n.charCodeAt(t);return e>>>0}(p||""),m=function(n,e,t,r){const{gl:o,programs:s}=n;if(s[e])return s[e];const c=o.createProgram(),l=i(o,t,o.VERTEX_SHADER),u=i(o,r,o.FRAGMENT_SHADER);return o.attachShader(c,l),o.attachShader(c,u),o.linkProgram(c),s[e]={gl:o,program:c,attributes:{},uniforms:{},uniformBlocks:{},vertexShader:l,fragmentShader:u},s[e]}(t,`main${I}-${_}-${v}`,e,s(I,_,p||o,v)),{gl:C}=t;C.useProgram(m.program),q(t,m,f,c,a,l,u,d,I,h,_,g)}function cn(n){if(void 0===n)return;const{gl:e,programs:t,textures:r}=n;for(let n in t){const{attributes:r,fragmentShader:o,vertexShader:s,uniformBlocks:i,program:c}=t[n];for(let n in i){const{buf:t}=i[n];e.deleteBuffer(t)}for(let n in r){const{buf:t}=r[n];e.deleteBuffer(t)}e.deleteShader(o),e.deleteShader(s),e.deleteProgram(c)}for(let n in r){const{tex:t}=r[n];e.deleteTexture(t)}}function ln(n,e,t){const r=n.createShader(e);if(n.shaderSource(r,t),n.compileShader(r),!n.getShaderParameter(r,n.COMPILE_STATUS))throw new Error(n.getShaderInfoLog(r))}const un=new WeakMap;function an(n){{const e=un.get(n);if(e)return e}!function(n){try{ln(n,n.VERTEX_SHADER,e),ln(n,n.FRAGMENT_SHADER,s(32,2,o,0))}catch(n){throw console.log(n),n}}(n);const t={},r={},i={gl:n,textures:r,programs:t};return n.canvas.addEventListener("webglcontextlost",e=>{dn(t),dn(r),un.delete(n),i.onContextLoss?.(e)},!1),un.set(n,i),i}function dn(n){Object.keys(n).forEach(e=>{delete n[e]})}export{o as GLSL_DEFAULT,r as GLSL_PATTERN1,cn as freeGlContext,sn as generateSdf,an as getWebGlContext};
@@ -1,4 +1,4 @@
1
- import { getFragment } from "./shaders/fragment.js";
1
+ import { getFragment, GLSL_DEFAULT } from "./shaders/fragment.js";
2
2
  import { vertex } from "./shaders/vertex.js";
3
3
  /**
4
4
  *
@@ -17,7 +17,7 @@ function debugGlsl(gl, type, shaderStr) {
17
17
  function debugShaders(gl) {
18
18
  try {
19
19
  debugGlsl(gl, gl.VERTEX_SHADER, vertex);
20
- debugGlsl(gl, gl.FRAGMENT_SHADER, getFragment(32, 4));
20
+ debugGlsl(gl, gl.FRAGMENT_SHADER, getFragment(32, 2, GLSL_DEFAULT, 0));
21
21
  }
22
22
  catch (e) {
23
23
  console.log(e);
@@ -1 +1 @@
1
- {"version":3,"file":"debug-shaders.js","sourceRoot":"","sources":["../src/debug-shaders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C;;;;;GAKG;AACH,SAAS,SAAS,CACV,EAA0B,EAC1B,IAAyD,EACzD,SAAiB;IAErB,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAE,CAAC;IACjC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC9B,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAE,CAAC,CAAC;IAC7C,CAAC;AACL,CAAC;AAGD,SAAS,YAAY,CACb,EAA0B;IAE9B,IAAI,CAAC;QACD,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACxC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,eAAe,EAAE,WAAW,CAAC,EAAE,EAAC,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACf,MAAM,CAAC,CAAC;IACZ,CAAC;AACL,CAAC;AAGD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAA"}
1
+ {"version":3,"file":"debug-shaders.js","sourceRoot":"","sources":["../src/debug-shaders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C;;;;;GAKG;AACH,SAAS,SAAS,CACV,EAA0B,EAC1B,IAAyD,EACzD,SAAiB;IAErB,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAE,CAAC;IACjC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC9B,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAE,CAAC,CAAC;IAC7C,CAAC;AACL,CAAC;AAGD,SAAS,YAAY,CACb,EAA0B;IAE9B,IAAI,CAAC;QACD,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACxC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,eAAe,EAAE,WAAW,CAAC,EAAE,EAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACf,MAAM,CAAC,CAAC;IACZ,CAAC;AACL,CAAC;AAGD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAA"}
@@ -1,4 +1,15 @@
1
1
  import { GlContext } from './types/gl-context.js';
2
+ interface SdfOptions {
3
+ /** the position where to draw, x-coordinate */
4
+ readonly x?: number | undefined;
5
+ readonly y?: number | undefined;
6
+ readonly testInteriorExterior?: boolean | undefined;
7
+ readonly calcSdfForInside?: boolean | undefined;
8
+ readonly calcSdfForOutside?: boolean | undefined;
9
+ readonly customData?: [number, number, number, number] | undefined;
10
+ readonly glslRgbaCalcStr?: string | undefined;
11
+ readonly colorMask: [boolean, boolean, boolean, boolean];
12
+ }
2
13
  /**
3
14
  * Generates an sdf (signed distance field) from the given bezier curves,
4
15
  * viewbox, etc. and renders the result
@@ -9,16 +20,81 @@ import { GlContext } from './types/gl-context.js';
9
20
  * thereof) given by given by their ordered control points,
10
21
  * e.g. `[ [[0,0],[1,1],[2,1],[2,0]], [[2,0],[7,2],[1,5],[8,6]], ... ]` **OR**
11
22
  * * an SVG string, e.g. "M26.53 478.83 C028.89 481.61 031.33 484.32 ..."
23
+ * @param viewbox the viewbox given as `[x1,x2,y1,y2]` (**not as** `[x,y,widht,height]`)
12
24
  * @param width the width of the drawing rectangle
13
25
  * @param height the height of the drawing rectangle
14
- * @param viewbox the viewbox
15
26
  * @param maxDistance maximum sdf distance
16
- * @param sdfExponent TODO
17
- * @param inclInside if `true` the sdf will be calculate for the inside of the shape
18
- * @param inclOutside if `true` the sdf will be calculate for the outside of the shape
19
- * @param x the position where to draw, x-coordinate
20
- * @param y the position where to draw, y-coordinate
21
- * @param channel TODO
27
+ * @param options optional additional options (see below)
28
+ *
29
+ * **The following are properties of the `options` parameters**
30
+ *
31
+ * @param x defaults to `0`; the position where to draw on the canvas, x-coordinate
32
+ * @param y defaults to `0`; the position where to draw on the canvas, y-coordinate
33
+ * @param colorMask defaults to `[true,true,true,true]`; an array of length 4 for the rgba color mask values;
34
+ * will be called as `gl.setColorMask(...colorMask)` to allow/prevent selected color channels from updating
35
+ * @param testInteriorExterior defaults to `true`;
36
+ * if `false` winds will always be `0.0` and only an un-signed sdf can be calculated since all
37
+ * fragments are considered outside
38
+ * @param calcSdfForInside defaults to `true`;
39
+ * if `false` the sdf will not be calculate for the inside of the shape, in the shader, `res` will always be `1.0`
40
+ * @param calcSdfForOutside defaults to `true`;
41
+ * if `false` the sdf will not be calculate for the outside of the shape, in the shader, `res` will always be `1.0`
42
+ * @param customData optional custom data (must be an array of 4 numbers) to send to
43
+ * the fragment shader as a uniform, e.g. exponent, scale, a timer, or whatever
44
+ * @param glslRgbaCalcStr a glsl string (#version 300 es) inserted at the end of
45
+ * the fragment shader to modify the output frag color in any way (you can also discard the fragment);
46
+ * see below for available variables that can be used;
47
+ *
48
+ * defaults to (designed to match webgl-sdf-generator)
49
+ * ```glsl
50
+ * float exponent = uCustom.x;
51
+ * float adj = 0.5*pow(1.0 - res, exponent);
52
+ * res = inside ? 1.0 - adj : adj;
53
+ * float red = res;
54
+ * float green = res;
55
+ * float blue = res;
56
+ * float alpha = 0.5;
57
+ *
58
+ * ```
59
+ * You must define and assign \`red\`, \`green\`, \`blue\` and \`alpha\`.
60
+ *
61
+ * Usable variables:
62
+ * ```glsl
63
+ * // the result of the distance calculation for this fragment, a value from 0.0 to 1.0
64
+ * // with 1.0 occuring when the fragment is >= maxDistance away and 0.0 when the
65
+ * // fragment is exactly on a curve
66
+ * float res
67
+ *
68
+ * // the number of anti-clockwise winds around the fragment, a value != 0
69
+ * // means the fragment is inside the shape
70
+ * float winds
71
+ *
72
+ * // 4 custom values set via an options parameter of `generateSdf`; defaults to `[1,0,0,0]`;
73
+ * // the first value is used as the exponent within the default `glslRgbaCalcStr`
74
+ * vec4 uCustom;
75
+ *
76
+ * // the max distance value supplied via `generateSdf`
77
+ * float uMaxDistance
78
+ *
79
+ * // bit 0 -> calc sdf when fragment is inside; defaults to 1,
80
+ * // bit 1 -> calc sdf when fragment is outside; defaults to 1
81
+ * // bit 1 -> calc `winds` (required for signing the distance); defaults to 1
82
+ * // note: when the distance calculation is not done (via options from `generateSdf`),
83
+ * `res` will be set to 1.0 (max distance away)
84
+ * int uTestInOut
85
+ *
86
+ * // the original x,y coordinates of the fragment in the original space provided
87
+ * // via the `viewbox` in `generateSdf`, e.g. the very bottom-left fragment
88
+ * // will have vXY == (viebox[0], viebox[1]) and the very top right will have
89
+ * // coordinates vXY == (viebox[2], viebox[3])
90
+ * vec2 vXY
91
+ *
92
+ * // whether the point is inside or outside the shape, often used to sign `res`
93
+ * // it is identical to `winds != 0`
94
+ * bool inside
95
+ *
96
+ * // pretty much useless unless you want to create a checkerboard pattern for no good reason
97
+ * int instanceId
22
98
  */
23
- declare function generateSdf(glContext: GlContext, bezierCurves_or_svgStr: (number[][])[][] | string, viewbox: [number, number, number, number], width: number, height: number, x: number | undefined, y: number | undefined, maxDistance: number, inclInside: boolean | undefined, inclOutside: boolean | undefined, customData: [number, number, number, number], channel?: number): void;
24
- export { generateSdf };
99
+ declare function generateSdf(glContext: GlContext, bezierCurves_or_svgStr: (number[][])[][] | string, viewbox: [number, number, number, number], width: number, height: number, maxDistance: number, options?: SdfOptions): void;
100
+ export { generateSdf, SdfOptions };
@@ -1,12 +1,19 @@
1
1
  // import { getWebGLContext } from './webgl-utils/get-gl-context.js';
2
2
  import { vertex } from './shaders/vertex.js';
3
- import { getFragment } from './shaders/fragment.js';
3
+ import { getFragment, GLSL_DEFAULT } from './shaders/fragment.js';
4
4
  import { initProgram } from './webgl-utils/use-program.js';
5
5
  import { mainProgram } from './main-program.js';
6
6
  import { ROW_COUNT } from './row-count.js';
7
7
  import { getPathsFromStr } from './svg/get-paths-from-str.js';
8
8
  import { MAX_ASPECT_RATIO_BEFORE_STRETCH } from './max-aspect-ratio-before-stretch.js';
9
9
  const { ceil, min, max } = Math;
10
+ const defaultSdfOptions = {
11
+ x: 0, y: 0,
12
+ testInteriorExterior: true,
13
+ calcSdfForInside: true, calcSdfForOutside: true,
14
+ customData: [1, 0, 0, 0],
15
+ colorMask: [true, true, true, true]
16
+ };
10
17
  /**
11
18
  * Generates an sdf (signed distance field) from the given bezier curves,
12
19
  * viewbox, etc. and renders the result
@@ -17,24 +24,86 @@ const { ceil, min, max } = Math;
17
24
  * thereof) given by given by their ordered control points,
18
25
  * e.g. `[ [[0,0],[1,1],[2,1],[2,0]], [[2,0],[7,2],[1,5],[8,6]], ... ]` **OR**
19
26
  * * an SVG string, e.g. "M26.53 478.83 C028.89 481.61 031.33 484.32 ..."
27
+ * @param viewbox the viewbox given as `[x1,x2,y1,y2]` (**not as** `[x,y,widht,height]`)
20
28
  * @param width the width of the drawing rectangle
21
29
  * @param height the height of the drawing rectangle
22
- * @param viewbox the viewbox
23
30
  * @param maxDistance maximum sdf distance
24
- * @param sdfExponent TODO
25
- * @param inclInside if `true` the sdf will be calculate for the inside of the shape
26
- * @param inclOutside if `true` the sdf will be calculate for the outside of the shape
27
- * @param x the position where to draw, x-coordinate
28
- * @param y the position where to draw, y-coordinate
29
- * @param channel TODO
31
+ * @param options optional additional options (see below)
32
+ *
33
+ * **The following are properties of the `options` parameters**
34
+ *
35
+ * @param x defaults to `0`; the position where to draw on the canvas, x-coordinate
36
+ * @param y defaults to `0`; the position where to draw on the canvas, y-coordinate
37
+ * @param colorMask defaults to `[true,true,true,true]`; an array of length 4 for the rgba color mask values;
38
+ * will be called as `gl.setColorMask(...colorMask)` to allow/prevent selected color channels from updating
39
+ * @param testInteriorExterior defaults to `true`;
40
+ * if `false` winds will always be `0.0` and only an un-signed sdf can be calculated since all
41
+ * fragments are considered outside
42
+ * @param calcSdfForInside defaults to `true`;
43
+ * if `false` the sdf will not be calculate for the inside of the shape, in the shader, `res` will always be `1.0`
44
+ * @param calcSdfForOutside defaults to `true`;
45
+ * if `false` the sdf will not be calculate for the outside of the shape, in the shader, `res` will always be `1.0`
46
+ * @param customData optional custom data (must be an array of 4 numbers) to send to
47
+ * the fragment shader as a uniform, e.g. exponent, scale, a timer, or whatever
48
+ * @param glslRgbaCalcStr a glsl string (#version 300 es) inserted at the end of
49
+ * the fragment shader to modify the output frag color in any way (you can also discard the fragment);
50
+ * see below for available variables that can be used;
51
+ *
52
+ * defaults to (designed to match webgl-sdf-generator)
53
+ * ```glsl
54
+ * float exponent = uCustom.x;
55
+ * float adj = 0.5*pow(1.0 - res, exponent);
56
+ * res = inside ? 1.0 - adj : adj;
57
+ * float red = res;
58
+ * float green = res;
59
+ * float blue = res;
60
+ * float alpha = 0.5;
61
+ *
62
+ * ```
63
+ * You must define and assign \`red\`, \`green\`, \`blue\` and \`alpha\`.
64
+ *
65
+ * Usable variables:
66
+ * ```glsl
67
+ * // the result of the distance calculation for this fragment, a value from 0.0 to 1.0
68
+ * // with 1.0 occuring when the fragment is >= maxDistance away and 0.0 when the
69
+ * // fragment is exactly on a curve
70
+ * float res
71
+ *
72
+ * // the number of anti-clockwise winds around the fragment, a value != 0
73
+ * // means the fragment is inside the shape
74
+ * float winds
75
+ *
76
+ * // 4 custom values set via an options parameter of `generateSdf`; defaults to `[1,0,0,0]`;
77
+ * // the first value is used as the exponent within the default `glslRgbaCalcStr`
78
+ * vec4 uCustom;
79
+ *
80
+ * // the max distance value supplied via `generateSdf`
81
+ * float uMaxDistance
82
+ *
83
+ * // bit 0 -> calc sdf when fragment is inside; defaults to 1,
84
+ * // bit 1 -> calc sdf when fragment is outside; defaults to 1
85
+ * // bit 1 -> calc `winds` (required for signing the distance); defaults to 1
86
+ * // note: when the distance calculation is not done (via options from `generateSdf`),
87
+ * `res` will be set to 1.0 (max distance away)
88
+ * int uTestInOut
89
+ *
90
+ * // the original x,y coordinates of the fragment in the original space provided
91
+ * // via the `viewbox` in `generateSdf`, e.g. the very bottom-left fragment
92
+ * // will have vXY == (viebox[0], viebox[1]) and the very top right will have
93
+ * // coordinates vXY == (viebox[2], viebox[3])
94
+ * vec2 vXY
95
+ *
96
+ * // whether the point is inside or outside the shape, often used to sign `res`
97
+ * // it is identical to `winds != 0`
98
+ * bool inside
99
+ *
100
+ * // pretty much useless unless you want to create a checkerboard pattern for no good reason
101
+ * int instanceId
30
102
  */
31
- function generateSdf(glContext, bezierCurves_or_svgStr, viewbox, width, height, x = 0, y = 0, maxDistance, inclInside = true, inclOutside = true, customData,
32
- // TODO
33
- channel = 0) {
103
+ function generateSdf(glContext, bezierCurves_or_svgStr, viewbox, width, height, maxDistance, options = defaultSdfOptions) {
34
104
  const psss = typeof bezierCurves_or_svgStr === 'string'
35
105
  ? getPathsFromStr(bezierCurves_or_svgStr)
36
106
  : bezierCurves_or_svgStr;
37
- // const glContext = getWebGLContext(gl);
38
107
  let stretch = 1;
39
108
  const aspectRatio = width / height;
40
109
  if (aspectRatio > MAX_ASPECT_RATIO_BEFORE_STRETCH) {
@@ -46,11 +115,24 @@ channel = 0) {
46
115
  const maxDim = max(width, height);
47
116
  const colCount = ceil(width / cellSize);
48
117
  const padCount = 2 * ceil(min(maxDistance, maxDim) / cellSize / 2);
49
- const programMain = initProgram(glContext, `main${colCount}-${padCount}`, vertex, getFragment(colCount, padCount));
118
+ const { glslRgbaCalcStr } = options;
119
+ const hash = calcStrHash(glslRgbaCalcStr || '');
120
+ const programMain = initProgram(glContext, `main${colCount}-${padCount}-${hash}`, vertex, getFragment(colCount, padCount, glslRgbaCalcStr || GLSL_DEFAULT, hash));
50
121
  const { gl } = glContext;
51
- // debugShaders(gl); // comment for production
52
122
  gl.useProgram(programMain.program);
53
- mainProgram(glContext, programMain, psss, viewbox, maxDistance, inclInside, inclOutside, customData, x, y, width, height, colCount, cellSize, padCount, stretch);
123
+ mainProgram(glContext, programMain, psss, viewbox, maxDistance, width, height, options, colCount, cellSize, padCount, stretch);
124
+ }
125
+ /**
126
+ * Calculates and returns a hash of the given string
127
+ */
128
+ function calcStrHash(str) {
129
+ if (!str)
130
+ return 0;
131
+ let hash = 5381;
132
+ for (let i = 0; i < str.length; i++) {
133
+ hash = ((hash << 5) + hash) + str.charCodeAt(i);
134
+ }
135
+ return hash >>> 0; // Convert to unsigned 32-bit integer
54
136
  }
55
137
  export { generateSdf };
56
138
  //# sourceMappingURL=generate-sdf.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-sdf.js","sourceRoot":"","sources":["../src/generate-sdf.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AAIvF,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAGhC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAS,WAAW,CACZ,SAAoB,EACpB,sBAAiD,EACjD,OAAsC,EACtC,KAAa,EACb,MAAc,EACd,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EACZ,WAAmB,EACnB,UAAU,GAAG,IAAI,EACjB,WAAW,GAAG,IAAI,EAClB,UAAyC;AAEzC,OAAO;AACP,OAAO,GAAG,CAAC;IAEf,MAAM,IAAI,GAAG,OAAO,sBAAsB,KAAK,QAAQ;QACnD,CAAC,CAAC,eAAe,CAAC,sBAAsB,CAAC;QACzC,CAAC,CAAC,sBAAsB,CAAC;IAE7B,yCAAyC;IAEzC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,WAAW,GAAG,KAAK,GAAC,MAAM,CAAC;IACjC,IAAI,WAAW,GAAG,+BAA+B,EAAE,CAAC;QAChD,MAAM,CAAC,GAAG,KAAK,GAAC,+BAA+B,CAAC;QAChD,OAAO,GAAG,CAAC,GAAC,MAAM,CAAC;QACnB,MAAM,GAAG,CAAC,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,GAAC,SAAS,CAAC;IAElC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,GAAC,QAAQ,CAAC,CAAC;IAEtC,MAAM,QAAQ,GAAG,CAAC,GAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,GAAC,QAAQ,GAAC,CAAC,CAAC,CAAC;IAE7D,MAAM,WAAW,GAAG,WAAW,CAC3B,SAAS,EAAE,OAAO,QAAQ,IAAI,QAAQ,EAAE,EACxC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAC1C,CAAC;IAEF,MAAM,EAAE,EAAE,EAAE,GAAG,SAAS,CAAC;IAEzB,+CAA+C;IAE/C,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,WAAW,CACP,SAAS,EAAE,WAAW,EACtB,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAC/D,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EACnB,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CACxC,CAAC;AACN,CAAC;AAGD,OAAO,EAAE,WAAW,EAAE,CAAA"}
1
+ {"version":3,"file":"generate-sdf.js","sourceRoot":"","sources":["../src/generate-sdf.ts"],"names":[],"mappings":"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"}
package/node/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { generateSdf } from './generate-sdf.js';
2
2
  export { freeGlContext } from './webgl-utils/free-gl-context.js';
3
3
  export { getWebGlContext } from './webgl-utils/get-web-gl-context.js';
4
+ export { GLSL_DEFAULT, GLSL_PATTERN1 } from './shaders/fragment.js';
package/node/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { generateSdf } from './generate-sdf.js';
2
2
  export { freeGlContext } from './webgl-utils/free-gl-context.js';
3
3
  export { getWebGlContext } from './webgl-utils/get-web-gl-context.js';
4
+ export { GLSL_DEFAULT, GLSL_PATTERN1 } from './shaders/fragment.js';
4
5
  //# sourceMappingURL=index.js.map
package/node/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { Program } from './types/program.js';
2
2
  import { GlContext } from './types/gl-context.js';
3
- declare function mainProgram(glContext: GlContext, programMain: Program, psss: number[][][][], viewbox: [number, number, number, number], maxDistance: number, inclInside: boolean, inclOutside: boolean, customData: [number, number, number, number], x: number, y: number, width: number, height: number, colCount: number, cellSize: number, padCount: number, stretch: number): void;
3
+ import { SdfOptions } from './generate-sdf.js';
4
+ declare function mainProgram(glContext: GlContext, programMain: Program, psss: number[][][][], viewbox: [number, number, number, number], maxDistance: number, width: number, height: number, options: SdfOptions, colCount: number, cellSize: number, padCount: number, stretch: number): void;
4
5
  export { mainProgram };
@@ -8,8 +8,9 @@ import { ROW_COUNT } from './row-count.js';
8
8
  const SEG_TEX_INDEX = 0;
9
9
  const CELL_TEX_INDEX = 1;
10
10
  const CROSS_TEX_INDEX = 2;
11
- function mainProgram(glContext, programMain, psss, viewbox, maxDistance, inclInside, inclOutside, customData, x, y, width, height, colCount, cellSize, padCount, stretch) {
11
+ function mainProgram(glContext, programMain, psss, viewbox, maxDistance, width, height, options, colCount, cellSize, padCount, stretch) {
12
12
  const { gl } = glContext;
13
+ const { x = 0, y = 0, testInteriorExterior = true, calcSdfForInside = true, calcSdfForOutside = true, customData = [1, 0, 0, 0], colorMask = [true, true, true, true] } = options;
13
14
  const vertices = [];
14
15
  const x0 = 0;
15
16
  const y0 = 0;
@@ -33,7 +34,9 @@ function mainProgram(glContext, programMain, psss, viewbox, maxDistance, inclIns
33
34
  // Init/update uniforms
34
35
  setUniform_('2f', 'uWidthHeight', width, height);
35
36
  setUniform_('1f', 'uMaxDistance', maxDistance);
36
- setUniform_('1i', 'uIncl', (inclInside ? 1 : 0) + (inclOutside ? 2 : 0));
37
+ setUniform_('1i', 'uTestInOut', (calcSdfForInside ? 1 : 0) +
38
+ (calcSdfForOutside ? 2 : 0) +
39
+ (testInteriorExterior ? 4 : 0));
37
40
  setUniform_('4f', 'uCustom', ...customData);
38
41
  setUniformBlock(programMain)('SegIdxRangePerCellBlock', 0, segIdxs_PerCell_Range_Arr);
39
42
  setUniformBlock(programMain)('SegIdxRangePerStripBlock', 1, segIdxs_PerStrip_Range_Arr);
@@ -89,6 +92,7 @@ function mainProgram(glContext, programMain, psss, viewbox, maxDistance, inclIns
89
92
  gl.scissor(x, y, width, height / stretch);
90
93
  }
91
94
  gl.viewport(x, y, width, height);
95
+ gl.colorMask(...colorMask);
92
96
  // draw a square colCount * ROW_COUNT times - 6 vertics
93
97
  gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, colCount * ROW_COUNT);
94
98
  if (stretch > 1) {
@@ -1 +1 @@
1
- {"version":3,"file":"main-program.js","sourceRoot":"","sources":["../src/main-program.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main-program.js","sourceRoot":"","sources":["../src/main-program.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,4 @@
1
- declare function getFragment(colCount: number, padCount: number): string;
2
- export { getFragment };
1
+ declare const GLSL_PATTERN1 = "\n float exponent = uCustom.x;\n float alpha = res >= 1.0 ? 0.0 : 0.5;\n res = pow(1.0 - res, exponent);\n float red = inside ? 0.2 : 0.8;\n float green = abs(sin(25.0 * res));\n // float green = step(0.5, fract(10.0 * res));\n float blue = 0.5;\n";
2
+ declare const GLSL_DEFAULT = "\n float exponent = uCustom.x;\n float adj = 0.5*pow(1.0 - res, exponent);\n res = inside ? 1.0 - adj : adj;\n float red = res;\n float green = res;\n float blue = res;\n float alpha = res;\n";
3
+ declare function getFragment(colCount: number, padCount: number, calcFragColorStr: string, hash: number): string;
4
+ export { getFragment, GLSL_PATTERN1, GLSL_DEFAULT };