webgl2-sdf 0.0.8 → 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 +19 -12
- package/browser/index.min.js +1 -1
- package/node/generate-sdf.d.ts +8 -3
- package/node/generate-sdf.js +9 -4
- package/node/generate-sdf.js.map +1 -1
- package/node/index.d.ts +1 -0
- package/node/index.js +1 -0
- package/node/index.js.map +1 -1
- package/node/main-program.js +2 -2
- package/node/main-program.js.map +1 -1
- package/node/shaders/fragment.d.ts +2 -2
- package/node/shaders/fragment.js +6 -5
- package/node/shaders/fragment.js.map +1 -1
- package/node/types/gl-context.d.ts +0 -5
- package/package.json +1 -1
- package/src/generate-sdf.ts +10 -4
- package/src/index.ts +1 -0
- package/src/main-program.ts +2 -2
- package/src/shaders/fragment.ts +7 -5
- package/src/types/gl-context.ts +0 -5
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:
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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);
|
package/browser/index.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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={};function r(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 \n float exponent = uCustom.x;\n res = pow(1.0 - res, exponent);\n float alpha = res <= 0.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\n FragColor = vec4(red, green, blue, alpha);\n}\n`;return t[i]=l,l}function o(n,e,t){const r=n.createShader(t);return n.shaderSource(r,e),n.compileShader(r),r}function s(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:i,UNSIGNED_BYTE:c,SHORT:l,UNSIGNED_SHORT:u,INT:a,UNSIGNED_INT:d,FLOAT:f,HALF_FLOAT:g,INT_2_10_10_10_REV:h,UNSIGNED_INT_2_10_10_10_REV:x}=WebGL2RenderingContext;function I(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 _(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 p(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:v}=Math;function m(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=v(i*i+c*c);return function(n){const e=n[0],o=n[1];return 0!==u?(i*e+c*o+l)/u:v((e-t)**2+(o-r)**2)}}{const n=[10,1];m([6,2],[6,2])(n)}function C(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 S(n,e){return[e[0]-n[0],e[1]-n[1]]}function R(n,e){return n[0]*e[0]+n[1]*e[1]}function E(n){const e=S(n[0],n[1]),t=S(n[1],n[3]),r=S(n[3],n[0]),o=S(n[0],n[2]),s=S(n[2],n[3]);return R(r,e)>0||R(t,r)>0||R(r,o)>0||R(s,r)>0}const{abs:T,max:b}=Math;function w(n){const e=m(n[0],n[3]),t=e(n[1]),r=e(n[2]);return(t*r<=0?4/9:3/4)*b(T(t),T(r))}function A(n){const e=S(n[0],n[1]),t=S(n[1],n[2]),r=S(n[2],n[0]);return R(r,e)>0||R(t,r)>0}const{abs:P}=Math;function D(n){if(n[0][0]===n[1][0]&&n[0][1]===n[1][1])return 0;const e=p(n,.5),t=m(n[0],n[2]);return P(t(e))}function y(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=C(n,r,o);if(!A(s)&&D(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=C(n,r,o);if(!E(s)&&w(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=p(n,e[r]),s=p(n,e[r+1]);t.push([o,s])}return t}function F(n){return Math.sqrt(n[0]*n[0]+n[1]*n[1])}const U=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=F([.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:N,E:M}=Math;const{min:L,max:O,SQRT2:k}=Math;function B(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=U.length-1,r=0;for(;e<=t;){r=e+t>>>1;const o=U[r].from;if(o===n)return r;n>o?e=r+1:t=r-1}return r}(n);if(n=N(0,n),0===e)return 0;for(;U[e].from===U[e-1].from;)e--;return e}((l-k*r)/r),a=Number.POSITIVE_INFINITY;for(;;){if(u>=U.length){a=r*(U[U.length-1].from-k);break}const{u:l,v:d,from:f}=U[u];if(r*f>o+k*r){a=r*(f-2*k);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-k);break}u++}const{closeCells:d}=e[i][c];let f=O(0,u-1);for(;f<U.length;){const{from:l,u,v:g}=U[f];if(r*l>L(a,o)+2*k*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:X,ceil:j}=Math;function G(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?X:j,b=E?X:j;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=X(u/r)+s,t=X(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 Y=256,{floor:Q,ceil:V}=Math;function z(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?Q:V;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=Q(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 H(e,t,r,o,i,c,l,u,a,d,h,x){const{gl:p}=e,{x:v=0,y:m=0,testInteriorExterior:C=!0,calcSdfForInside:S=!0,calcSdfForOutside:R=!0,customData:E=[1,0,0,0],glslRgbaCalcStr:T}=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=(F=t,(n,e,...t)=>{const{gl:r,uniforms:o}=F,s=o[e]||(o[e]=r.getUniformLocation(F.program,e));r[`uniform${n}`](s,...t)});var F;const U=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:h,buf:x}=d;u.bindBuffer(u.ARRAY_BUFFER,x),r===f||r===g?u.vertexAttribPointer(h,t,r,!1,c,l):u.vertexAttribIPointer(h,t,r,c,l),u.enableVertexAttribArray(h),0!==i&&u.vertexAttribDivisor(h,i),s!==d.data&&(u.bufferData(u.ARRAY_BUFFER,s,o),d.data=s)}}(t),{lineSegPtCoords_Arr:N,segIdxs_PerCell_Range_Arr:M,closeCellIdxs_PerCell_Arr:L,closeCellIdxs_PerCell_Range_Arr:O,crossCellIdxs_PerCell_Arr:k,crossCellIdxs_perCell_Range_Arr:X,segIdxs_PerStrip_Range_Arr:j}=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(_(t))continue;if(2===t.length){e.push(t);continue}const o=y(t);e.push(...o.filter(n=>!_(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];G(f,t,r,s,e,c),z(g,r,e)}B(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=[],v=[],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;v.push(...e),I.push(...n),m.push(C,t),p.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%Y!==0;)I.push(0);for(;v.length%Y!==0;)v.push(0);for(;h.length%1024!=0;)h.push(0);const T=new Float32Array(h),b=new Int32Array(x),w=new Int32Array(p);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(v),crossCellIdxs_perCell_Range_Arr:new Int32Array(m),segIdxs_PerStrip_Range_Arr:new Int32Array(E.flat())}}(r,c,l,a,d,i,h,o,x);U("aUV",2,p.FLOAT,p.STATIC_DRAW,P),U("aCrossIdxRangePerCell",2,p.INT,p.STATIC_DRAW,X,1),U("aCloseCellIdxRangePerCell",2,p.INT,p.STATIC_DRAW,O,1),D("2f","uWidthHeight",c,l),D("1f","uMaxDistance",i),D("1i","uTestInOut",(S?1:0)+(R?2:0)+(C?4:0)),D("4f","uCustom",...E),I(t)("SegIdxRangePerCellBlock",0,M),I(t)("SegIdxRangePerStripBlock",1,j),s(e,0,"segs"),p.texImage2D(p.TEXTURE_2D,0,p.RGBA32F,Y,N.length/4/Y,0,p.RGBA,p.FLOAT,N);const Q=p.getUniformLocation(t.program,"uSegs");p.uniform1i(Q,0),s(e,1,"closeCellIdxsPerCell"),p.texImage2D(p.TEXTURE_2D,0,p.R32I,Y,L.length/Y,0,p.RED_INTEGER,p.INT,L);const V=p.getUniformLocation(t.program,"uCloseCellIdxs");p.uniform1i(V,1),s(e,2,"crossCellIdxsPerCell"),p.texImage2D(p.TEXTURE_2D,0,p.R32I,Y,k.length/Y,0,p.RED_INTEGER,p.INT,k);const H=p.getUniformLocation(t.program,"uCrossCellIdxs");p.uniform1i(H,2),x>1&&(p.enable(p.SCISSOR_TEST),p.scissor(v,m,c,l/x)),p.viewport(v,m,c,l),p.colorMask(!0,!0,!0,!0),p.drawArraysInstanced(p.TRIANGLES,0,6,a*n),x>1&&p.disable(p.SCISSOR_TEST)}function W(n){const e=[n.p,n.initialPoint];return n.prev2ndCubicControlPoint=void 0,n.prev2ndQuadraticControlPoint=void 0,e}const q={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:W};function Z(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 $={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 J{_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=$[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=[Z(this)]:"M"===r||"L"===r||"T"===r?e=[Z(this),Z(this)]:"S"===r||"Q"===r?e=[Z(this),Z(this),Z(this),Z(this)]:"C"===r?e=[Z(this),Z(this),Z(this),Z(this),Z(this),Z(this)]:"A"===r?e=[Z(this),Z(this),Z(this),this._parseArcFlag(),this._parseArcFlag(),Z(this),Z(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=$[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:K,min:nn,max:en}=Math,tn={x:0,y:0,testInteriorExterior:!0,calcSdfForInside:!0,calcSdfForOutside:!0,customData:[1,0,0,0]};function rn(t,s,i,c,l,u,a=tn){const d="string"==typeof s?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(W(e)),t.push(o),o=[]),e.initialPoint=e.p=e.vals,r=c;continue}const l=q[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(W(e)),t.push(o)),t}(function(n){if(!n.length)return[];const e=new J(n),t=[];if(!e.initialCommandIsMoveTo())throw new Error("Path must start with m or M");for(;e.hasMoreData();)t.push(e.parseSegment());return t}(s)):s;let f=1;if(c/l>4){const n=c/4;f=n/l,l=n}const g=l/n,h=en(c,l),x=K(c/g),I=2*K(nn(u,h)/g/2),{glslRgbaCalcStr:_}=a,p=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}(_||""),v=function(n,e,t,r){const{gl:s,programs:i}=n;if(i[e])return i[e];const c=s.createProgram(),l=o(s,t,s.VERTEX_SHADER),u=o(s,r,s.FRAGMENT_SHADER);return s.attachShader(c,l),s.attachShader(c,u),s.linkProgram(c),i[e]={gl:s,program:c,attributes:{},uniforms:{},uniformBlocks:{},vertexShader:l,fragmentShader:u},i[e]}(t,`main${x}-${I}-${p}`,e,r(x,I,0,p)),{gl:m}=t;m.useProgram(v.program),H(t,v,d,i,u,c,l,a,x,g,I,f)}function on(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 sn(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 cn=new WeakMap;function ln(n){{const e=cn.get(n);if(e)return e}!function(n){try{sn(n,n.VERTEX_SHADER,e),sn(n,n.FRAGMENT_SHADER,r(32,2,0,0))}catch(n){throw console.log(n),n}}(n);const t={},o={},s={gl:n,textures:o,programs:t};return n.canvas.addEventListener("webglcontextlost",e=>{un(t),un(o),cn.delete(n),s.onContextLoss?.(e)},!1),cn.set(n,s),s}function un(n){Object.keys(n).forEach(e=>{delete n[e]})}export{on as freeGlContext,rn as generateSdf,ln 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};
|
package/node/generate-sdf.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ interface SdfOptions {
|
|
|
8
8
|
readonly calcSdfForOutside?: boolean | undefined;
|
|
9
9
|
readonly customData?: [number, number, number, number] | undefined;
|
|
10
10
|
readonly glslRgbaCalcStr?: string | undefined;
|
|
11
|
+
readonly colorMask: [boolean, boolean, boolean, boolean];
|
|
11
12
|
}
|
|
12
13
|
/**
|
|
13
14
|
* Generates an sdf (signed distance field) from the given bezier curves,
|
|
@@ -23,11 +24,14 @@ interface SdfOptions {
|
|
|
23
24
|
* @param width the width of the drawing rectangle
|
|
24
25
|
* @param height the height of the drawing rectangle
|
|
25
26
|
* @param maxDistance maximum sdf distance
|
|
26
|
-
* @param options additional options (see below)
|
|
27
|
+
* @param options optional additional options (see below)
|
|
27
28
|
*
|
|
28
29
|
* **The following are properties of the `options` parameters**
|
|
30
|
+
*
|
|
29
31
|
* @param x defaults to `0`; the position where to draw on the canvas, x-coordinate
|
|
30
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
|
|
31
35
|
* @param testInteriorExterior defaults to `true`;
|
|
32
36
|
* if `false` winds will always be `0.0` and only an un-signed sdf can be calculated since all
|
|
33
37
|
* fragments are considered outside
|
|
@@ -44,11 +48,12 @@ interface SdfOptions {
|
|
|
44
48
|
* defaults to (designed to match webgl-sdf-generator)
|
|
45
49
|
* ```glsl
|
|
46
50
|
* float exponent = uCustom.x;
|
|
47
|
-
*
|
|
51
|
+
* float adj = 0.5*pow(1.0 - res, exponent);
|
|
52
|
+
* res = inside ? 1.0 - adj : adj;
|
|
48
53
|
* float red = res;
|
|
49
54
|
* float green = res;
|
|
50
55
|
* float blue = res;
|
|
51
|
-
* float alpha =
|
|
56
|
+
* float alpha = 0.5;
|
|
52
57
|
*
|
|
53
58
|
* ```
|
|
54
59
|
* You must define and assign \`red\`, \`green\`, \`blue\` and \`alpha\`.
|
package/node/generate-sdf.js
CHANGED
|
@@ -11,7 +11,8 @@ const defaultSdfOptions = {
|
|
|
11
11
|
x: 0, y: 0,
|
|
12
12
|
testInteriorExterior: true,
|
|
13
13
|
calcSdfForInside: true, calcSdfForOutside: true,
|
|
14
|
-
customData: [1, 0, 0, 0]
|
|
14
|
+
customData: [1, 0, 0, 0],
|
|
15
|
+
colorMask: [true, true, true, true]
|
|
15
16
|
};
|
|
16
17
|
/**
|
|
17
18
|
* Generates an sdf (signed distance field) from the given bezier curves,
|
|
@@ -27,11 +28,14 @@ const defaultSdfOptions = {
|
|
|
27
28
|
* @param width the width of the drawing rectangle
|
|
28
29
|
* @param height the height of the drawing rectangle
|
|
29
30
|
* @param maxDistance maximum sdf distance
|
|
30
|
-
* @param options additional options (see below)
|
|
31
|
+
* @param options optional additional options (see below)
|
|
31
32
|
*
|
|
32
33
|
* **The following are properties of the `options` parameters**
|
|
34
|
+
*
|
|
33
35
|
* @param x defaults to `0`; the position where to draw on the canvas, x-coordinate
|
|
34
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
|
|
35
39
|
* @param testInteriorExterior defaults to `true`;
|
|
36
40
|
* if `false` winds will always be `0.0` and only an un-signed sdf can be calculated since all
|
|
37
41
|
* fragments are considered outside
|
|
@@ -48,11 +52,12 @@ const defaultSdfOptions = {
|
|
|
48
52
|
* defaults to (designed to match webgl-sdf-generator)
|
|
49
53
|
* ```glsl
|
|
50
54
|
* float exponent = uCustom.x;
|
|
51
|
-
*
|
|
55
|
+
* float adj = 0.5*pow(1.0 - res, exponent);
|
|
56
|
+
* res = inside ? 1.0 - adj : adj;
|
|
52
57
|
* float red = res;
|
|
53
58
|
* float green = res;
|
|
54
59
|
* float blue = res;
|
|
55
|
-
* float alpha =
|
|
60
|
+
* float alpha = 0.5;
|
|
56
61
|
*
|
|
57
62
|
* ```
|
|
58
63
|
* You must define and assign \`red\`, \`green\`, \`blue\` and \`alpha\`.
|
package/node/generate-sdf.js.map
CHANGED
|
@@ -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,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAClE,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;AAGvF,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;
|
|
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
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"}
|
package/node/main-program.js
CHANGED
|
@@ -10,7 +10,7 @@ const CELL_TEX_INDEX = 1;
|
|
|
10
10
|
const CROSS_TEX_INDEX = 2;
|
|
11
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],
|
|
13
|
+
const { x = 0, y = 0, testInteriorExterior = true, calcSdfForInside = true, calcSdfForOutside = true, customData = [1, 0, 0, 0], colorMask = [true, true, true, true] } = options;
|
|
14
14
|
const vertices = [];
|
|
15
15
|
const x0 = 0;
|
|
16
16
|
const y0 = 0;
|
|
@@ -92,7 +92,7 @@ function mainProgram(glContext, programMain, psss, viewbox, maxDistance, width,
|
|
|
92
92
|
gl.scissor(x, y, width, height / stretch);
|
|
93
93
|
}
|
|
94
94
|
gl.viewport(x, y, width, height);
|
|
95
|
-
gl.colorMask(
|
|
95
|
+
gl.colorMask(...colorMask);
|
|
96
96
|
// draw a square colCount * ROW_COUNT times - 6 vertics
|
|
97
97
|
gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, colCount * ROW_COUNT);
|
|
98
98
|
if (stretch > 1) {
|
package/node/main-program.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main-program.js","sourceRoot":"","sources":["../src/main-program.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAErE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAI3C,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,cAAc,GAAG,CAAC,CAAC;AACzB,MAAM,eAAe,GAAG,CAAC,CAAC;AAG1B,SAAS,WAAW,CACZ,SAAoB,EACpB,WAAoB,EAEpB,IAAoB,EACpB,OAAsC,EACtC,WAAmB,EACnB,KAAa,EACb,MAAc,EAEd,OAAmB,EAEnB,QAAgB,EAChB,QAAgB,EAChB,QAAgB,EAChB,OAAe;IAEnB,MAAM,EAAE,EAAE,EAAE,GAAG,SAAS,CAAC;IAEzB,MAAM,EACF,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,oBAAoB,GAAG,IAAI,EACzC,gBAAgB,GAAG,IAAI,EAAE,iBAAiB,GAAG,IAAI,EACjD,UAAU,GAAG,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EACtB,
|
|
1
|
+
{"version":3,"file":"main-program.js","sourceRoot":"","sources":["../src/main-program.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const GLSL_PATTERN1 = "\n float exponent = uCustom.x;\n
|
|
2
|
-
declare const GLSL_DEFAULT = "\n float exponent = uCustom.x;\n
|
|
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
3
|
declare function getFragment(colCount: number, padCount: number, calcFragColorStr: string, hash: number): string;
|
|
4
4
|
export { getFragment, GLSL_PATTERN1, GLSL_DEFAULT };
|
package/node/shaders/fragment.js
CHANGED
|
@@ -2,15 +2,17 @@ import { ROW_COUNT } from "../row-count.js";
|
|
|
2
2
|
const cache = {};
|
|
3
3
|
const GLSL_PATTERN1 = `
|
|
4
4
|
float exponent = uCustom.x;
|
|
5
|
+
float alpha = res >= 1.0 ? 0.0 : 0.5;
|
|
5
6
|
res = pow(1.0 - res, exponent);
|
|
6
|
-
float alpha = res <= 0.0 ? 0.0 : 0.5;
|
|
7
7
|
float red = inside ? 0.2 : 0.8;
|
|
8
8
|
float green = abs(sin(25.0 * res));
|
|
9
|
+
// float green = step(0.5, fract(10.0 * res));
|
|
9
10
|
float blue = 0.5;
|
|
10
11
|
`;
|
|
11
12
|
const GLSL_DEFAULT = `
|
|
12
13
|
float exponent = uCustom.x;
|
|
13
|
-
|
|
14
|
+
float adj = 0.5*pow(1.0 - res, exponent);
|
|
15
|
+
res = inside ? 1.0 - adj : adj;
|
|
14
16
|
float red = res;
|
|
15
17
|
float green = res;
|
|
16
18
|
float blue = res;
|
|
@@ -77,7 +79,7 @@ void main() {
|
|
|
77
79
|
///////////////////////////////////////////////////////////////////////////
|
|
78
80
|
|
|
79
81
|
float winds = 0.0;
|
|
80
|
-
if ((uTestInOut & 4)
|
|
82
|
+
if ((uTestInOut & 4) != 0) {
|
|
81
83
|
int crossIdxS = crossCellIdxRange.x;
|
|
82
84
|
int crossLen = crossCellIdxRange.y;
|
|
83
85
|
// Iterate over all relevant cell indexes
|
|
@@ -169,7 +171,7 @@ void main() {
|
|
|
169
171
|
// float alpha = ((instanceId + instanceId/${ROW_COUNT}) % 2 == 0 ? 0.3 : 0.5);
|
|
170
172
|
|
|
171
173
|
|
|
172
|
-
${
|
|
174
|
+
${calcFragColorStr}
|
|
173
175
|
|
|
174
176
|
FragColor = vec4(red, green, blue, alpha);
|
|
175
177
|
}
|
|
@@ -177,6 +179,5 @@ void main() {
|
|
|
177
179
|
cache[key] = main_Fragment;
|
|
178
180
|
return main_Fragment;
|
|
179
181
|
}
|
|
180
|
-
// ${calcFragColorStr}
|
|
181
182
|
export { getFragment, GLSL_PATTERN1, GLSL_DEFAULT };
|
|
182
183
|
//# sourceMappingURL=fragment.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fragment.js","sourceRoot":"","sources":["../../src/shaders/fragment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,MAAM,KAAK,GAAkD,EAAE,CAAC;AAGhE,MAAM,aAAa,GAAG
|
|
1
|
+
{"version":3,"file":"fragment.js","sourceRoot":"","sources":["../../src/shaders/fragment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,MAAM,KAAK,GAAkD,EAAE,CAAC;AAGhE,MAAM,aAAa,GAAG;;;;;;;;CAQrB,CAAC;AAGF,MAAM,YAAY,GAAG;;;;;;;;CAQpB,CAAC;AAGF,SAAS,WAAW,CACZ,QAAgB,EAChB,QAAgB,EAChB,gBAAwB,EACxB,IAAY;IAEhB,0EAA0E;IAC1E,sDAAsD;IACtD,MAAM,GAAG,GAAG,CAAC,CAAC,IAAE,EAAE,CAAC,GAAC,CAAC,GAAG,GAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;IACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAAC,OAAO,QAAQ,CAAC;IAAC,CAAC;IAEpD,MAAM,aAAa;IACnB,QAAQ,CAAA;;;;;;;;;;;;;;;gCAewB,CAAC,SAAS,GAAG,CAAC,GAAC,QAAQ,CAAC,GAAC,CAAC,QAAQ,GAAG,CAAC,GAAC,QAAQ,CAAC,GAAG,CAAC;;;iCAGnD,SAAS,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0CAgEJ,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDA2DF,SAAS;;;MAGpD,gBAAgB;;;;CAIrB,CAAA;IAEG,KAAK,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC;IAC3B,OAAO,aAAa,CAAC;AACzB,CAAC;AAGD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,CAAA"}
|
|
@@ -6,13 +6,8 @@ import type { Texture } from "./texture";
|
|
|
6
6
|
*
|
|
7
7
|
* * `textures`
|
|
8
8
|
* * `programs`
|
|
9
|
-
* * `framebufferStack`
|
|
10
9
|
*
|
|
11
10
|
* so they don't have to be recreated on each draw call.
|
|
12
|
-
*
|
|
13
|
-
* * an optional `width` and `height` that can be used for any purpose and that are not
|
|
14
|
-
* set or read by any function within the library
|
|
15
|
-
*
|
|
16
11
|
*/
|
|
17
12
|
interface GlContext {
|
|
18
13
|
readonly gl: WebGL2RenderingContext;
|
package/package.json
CHANGED
package/src/generate-sdf.ts
CHANGED
|
@@ -20,6 +20,7 @@ interface SdfOptions {
|
|
|
20
20
|
readonly calcSdfForOutside?: boolean | undefined;
|
|
21
21
|
readonly customData?: [number,number,number,number] | undefined;
|
|
22
22
|
readonly glslRgbaCalcStr?: string | undefined;
|
|
23
|
+
readonly colorMask: [boolean,boolean,boolean,boolean];
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
|
|
@@ -27,7 +28,8 @@ const defaultSdfOptions: SdfOptions = {
|
|
|
27
28
|
x: 0, y: 0,
|
|
28
29
|
testInteriorExterior: true,
|
|
29
30
|
calcSdfForInside: true, calcSdfForOutside: true,
|
|
30
|
-
customData: [1,0,0,0]
|
|
31
|
+
customData: [1,0,0,0],
|
|
32
|
+
colorMask: [true, true, true, true]
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
|
|
@@ -45,11 +47,14 @@ const defaultSdfOptions: SdfOptions = {
|
|
|
45
47
|
* @param width the width of the drawing rectangle
|
|
46
48
|
* @param height the height of the drawing rectangle
|
|
47
49
|
* @param maxDistance maximum sdf distance
|
|
48
|
-
* @param options additional options (see below)
|
|
50
|
+
* @param options optional additional options (see below)
|
|
49
51
|
*
|
|
50
52
|
* **The following are properties of the `options` parameters**
|
|
53
|
+
*
|
|
51
54
|
* @param x defaults to `0`; the position where to draw on the canvas, x-coordinate
|
|
52
55
|
* @param y defaults to `0`; the position where to draw on the canvas, y-coordinate
|
|
56
|
+
* @param colorMask defaults to `[true,true,true,true]`; an array of length 4 for the rgba color mask values;
|
|
57
|
+
* will be called as `gl.setColorMask(...colorMask)` to allow/prevent selected color channels from updating
|
|
53
58
|
* @param testInteriorExterior defaults to `true`;
|
|
54
59
|
* if `false` winds will always be `0.0` and only an un-signed sdf can be calculated since all
|
|
55
60
|
* fragments are considered outside
|
|
@@ -66,11 +71,12 @@ const defaultSdfOptions: SdfOptions = {
|
|
|
66
71
|
* defaults to (designed to match webgl-sdf-generator)
|
|
67
72
|
* ```glsl
|
|
68
73
|
* float exponent = uCustom.x;
|
|
69
|
-
*
|
|
74
|
+
* float adj = 0.5*pow(1.0 - res, exponent);
|
|
75
|
+
* res = inside ? 1.0 - adj : adj;
|
|
70
76
|
* float red = res;
|
|
71
77
|
* float green = res;
|
|
72
78
|
* float blue = res;
|
|
73
|
-
* float alpha =
|
|
79
|
+
* float alpha = 0.5;
|
|
74
80
|
*
|
|
75
81
|
* ```
|
|
76
82
|
* You must define and assign \`red\`, \`green\`, \`blue\` and \`alpha\`.
|
package/src/index.ts
CHANGED
package/src/main-program.ts
CHANGED
|
@@ -38,7 +38,7 @@ function mainProgram(
|
|
|
38
38
|
x = 0, y = 0, testInteriorExterior = true,
|
|
39
39
|
calcSdfForInside = true, calcSdfForOutside = true,
|
|
40
40
|
customData = [1,0,0,0],
|
|
41
|
-
|
|
41
|
+
colorMask = [true,true,true,true]
|
|
42
42
|
} = options;
|
|
43
43
|
|
|
44
44
|
const vertices: number[] = [];
|
|
@@ -163,7 +163,7 @@ function mainProgram(
|
|
|
163
163
|
|
|
164
164
|
gl.viewport(x, y, width, height);
|
|
165
165
|
|
|
166
|
-
gl.colorMask(
|
|
166
|
+
gl.colorMask(...colorMask);
|
|
167
167
|
|
|
168
168
|
// draw a square colCount * ROW_COUNT times - 6 vertics
|
|
169
169
|
gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, colCount*ROW_COUNT);
|
package/src/shaders/fragment.ts
CHANGED
|
@@ -6,17 +6,19 @@ const cache: { [padCount_times_colCount: number]: string } = {};
|
|
|
6
6
|
|
|
7
7
|
const GLSL_PATTERN1 = `
|
|
8
8
|
float exponent = uCustom.x;
|
|
9
|
+
float alpha = res >= 1.0 ? 0.0 : 0.5;
|
|
9
10
|
res = pow(1.0 - res, exponent);
|
|
10
|
-
float alpha = res <= 0.0 ? 0.0 : 0.5;
|
|
11
11
|
float red = inside ? 0.2 : 0.8;
|
|
12
12
|
float green = abs(sin(25.0 * res));
|
|
13
|
+
// float green = step(0.5, fract(10.0 * res));
|
|
13
14
|
float blue = 0.5;
|
|
14
15
|
`;
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
const GLSL_DEFAULT = `
|
|
18
19
|
float exponent = uCustom.x;
|
|
19
|
-
|
|
20
|
+
float adj = 0.5*pow(1.0 - res, exponent);
|
|
21
|
+
res = inside ? 1.0 - adj : adj;
|
|
20
22
|
float red = res;
|
|
21
23
|
float green = res;
|
|
22
24
|
float blue = res;
|
|
@@ -89,7 +91,7 @@ void main() {
|
|
|
89
91
|
///////////////////////////////////////////////////////////////////////////
|
|
90
92
|
|
|
91
93
|
float winds = 0.0;
|
|
92
|
-
if ((uTestInOut & 4)
|
|
94
|
+
if ((uTestInOut & 4) != 0) {
|
|
93
95
|
int crossIdxS = crossCellIdxRange.x;
|
|
94
96
|
int crossLen = crossCellIdxRange.y;
|
|
95
97
|
// Iterate over all relevant cell indexes
|
|
@@ -181,7 +183,7 @@ void main() {
|
|
|
181
183
|
// float alpha = ((instanceId + instanceId/${ROW_COUNT}) % 2 == 0 ? 0.3 : 0.5);
|
|
182
184
|
|
|
183
185
|
|
|
184
|
-
${
|
|
186
|
+
${calcFragColorStr}
|
|
185
187
|
|
|
186
188
|
FragColor = vec4(red, green, blue, alpha);
|
|
187
189
|
}
|
|
@@ -191,5 +193,5 @@ void main() {
|
|
|
191
193
|
return main_Fragment;
|
|
192
194
|
}
|
|
193
195
|
|
|
194
|
-
|
|
196
|
+
|
|
195
197
|
export { getFragment, GLSL_PATTERN1, GLSL_DEFAULT }
|
package/src/types/gl-context.ts
CHANGED
|
@@ -8,13 +8,8 @@ import type { Texture } from "./texture";
|
|
|
8
8
|
*
|
|
9
9
|
* * `textures`
|
|
10
10
|
* * `programs`
|
|
11
|
-
* * `framebufferStack`
|
|
12
11
|
*
|
|
13
12
|
* so they don't have to be recreated on each draw call.
|
|
14
|
-
*
|
|
15
|
-
* * an optional `width` and `height` that can be used for any purpose and that are not
|
|
16
|
-
* set or read by any function within the library
|
|
17
|
-
*
|
|
18
13
|
*/
|
|
19
14
|
interface GlContext {
|
|
20
15
|
readonly gl: WebGL2RenderingContext;
|