From 51b56bacb1953dec065896c2250f3fafce7f4c3d Mon Sep 17 00:00:00 2001 From: Marco Fugaro Date: Fri, 15 Oct 2021 01:46:27 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=8C=20Add=20minify=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 ++- readme.md | 2 ++ src/index.d.ts | 6 +++++- src/index.js | 8 +++++-- src/minifyShader.js | 41 ++++++++++++++++++++++++++++++++++++ test/snapshots/test.js.md | 32 ++++++++++++++++++++++++++++ test/snapshots/test.js.snap | Bin 1504 -> 2072 bytes test/test.js | 17 +++++++++++++++ 8 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 src/minifyShader.js diff --git a/package.json b/package.json index 71ebb6a..099f38c 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "type": "module", "exports": "./src/index.js", + "types": "./src/index.d.ts", "engines": { "node": ">=12" }, @@ -36,4 +37,4 @@ "esbuild": "^0.13.4", "glsl-noise": "^0.0.0" } -} +} \ No newline at end of file diff --git a/readme.md b/readme.md index d94f8fc..b433a33 100644 --- a/readme.md +++ b/readme.md @@ -30,6 +30,8 @@ build({ }).catch(() => process.exit(1)) ``` +You can also minify the imported shaders with `glslifyInline({ minify: true })`. + After that, you can use glslify normally with esbuild: ```js diff --git a/src/index.d.ts b/src/index.d.ts index ee00063..8e88163 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,4 +1,8 @@ import { Plugin } from 'esbuild' -declare function glslInline(): Plugin +type Options = { + minify?: boolean +} + +declare function glslInline(options?: Options): Plugin export { glslInline } diff --git a/src/index.js b/src/index.js index 1a97ab3..fb3787a 100644 --- a/src/index.js +++ b/src/index.js @@ -4,8 +4,9 @@ import fs from 'fs/promises' // a string and use it in another. Read more at: // https://github.com/onnovisser/babel-plugin-glsl#imported-function-names import compile from 'babel-plugin-glsl/lib/compile.js' +import { minifyShader } from './minifyShader.js' -export function glslifyInline() { +export function glslifyInline({ minify = false } = {}) { return { name: 'glslifyInline', setup(build) { @@ -36,7 +37,10 @@ export function glslifyInline() { return cache[glslifyImport] } - const contents = compile(glslifyImport) + let contents = compile(glslifyImport) + if (minify) { + contents = minifyShader(contents) + } cache[glslifyImport] = contents return contents }) diff --git a/src/minifyShader.js b/src/minifyShader.js new file mode 100644 index 0000000..931943a --- /dev/null +++ b/src/minifyShader.js @@ -0,0 +1,41 @@ +/** + * Minifies the given GLSL source code. + * + * Based on https://github.com/vwochnik/rollup-plugin-glsl + * Pasted from https://github.com/vanruesc/esbuild-plugin-glsl/blob/main/src/minifyShader.ts + * + * @param source The source code. + * @return The minified code. + */ + +export function minifyShader(source) { + const commentsRegExp = /[ \t]*(?:(?:\/\*[\s\S]*?\*\/)|(?:\/\/.*\n))/g + const symbolsRegExp = /\s*({|}|=|\*|,|\+|\/|>|<|&|\||\[|\]|\(|\)|-|!|;)\s*/g + + let result = source.replace(/\r/g, '').replace(commentsRegExp, '') + let wrap = false + + result = result + .split(/\n+/) + .reduce((acc, line) => { + line = line.trim().replace(/\s{2,}|\t/, ' ') + + if (line[0] === '#') { + if (wrap) { + acc.push('\n') + } + + acc.push(line, '\n') + wrap = false + } else { + line = line.replace(/(else)$/m, '$1 ') + acc.push(line.replace(symbolsRegExp, '$1')) + wrap = true + } + + return acc + }, []) + .join('') + + return result.replace(/\n{2,}/g, '\n') +} diff --git a/test/snapshots/test.js.md b/test/snapshots/test.js.md index d3f806c..c11979f 100644 --- a/test/snapshots/test.js.md +++ b/test/snapshots/test.js.md @@ -122,3 +122,35 @@ Generated by [AVA](https://avajs.dev). \`;␊ console.log(head, main);␊ ` + +## works with a basic example but minified + +> Snapshot 1 + + `// test/fixtures/basic.js␊ + var head = \`␊ + uniform float time;␊ + uniform float speed;␊ + vec3 mod289_2482186953(vec3 x){return x-floor(x*(1.0/289.0))*289.0;}vec4 mod289_2482186953(vec4 x){return x-floor(x*(1.0/289.0))*289.0;}vec4 permute_2482186953(vec4 x){return mod289_2482186953(((x*34.0)+1.0)*x);}vec4 taylorInvSqrt_2482186953(vec4 r){return 1.79284291400159-0.85373472095314*r;}float noise(vec3 v){const vec2 C=vec2(1.0/6.0,1.0/3.0);const vec4 D_2482186953=vec4(0.0,0.5,1.0,2.0);vec3 i=floor(v+dot(v,C.yyy));vec3 x0=v-i+dot(i,C.xxx);vec3 g_2482186953=step(x0.yzx,x0.xyz);vec3 l=1.0-g_2482186953;vec3 i1=min(g_2482186953.xyz,l.zxy);vec3 i2=max(g_2482186953.xyz,l.zxy);vec3 x1=x0-i1+C.xxx;vec3 x2=x0-i2+C.yyy;vec3 x3=x0-D_2482186953.yyy;i=mod289_2482186953(i);vec4 p=permute_2482186953(permute_2482186953(permute_2482186953(i.z+vec4(0.0,i1.z,i2.z,1.0))+i.y+vec4(0.0,i1.y,i2.y,1.0))+i.x+vec4(0.0,i1.x,i2.x,1.0));float n_=0.142857142857;vec3 ns=n_*D_2482186953.wyz-D_2482186953.xzx;vec4 j=p-49.0*floor(p*ns.z*ns.z);vec4 x_=floor(j*ns.z);vec4 y_=floor(j-7.0*x_);vec4 x=x_*ns.x+ns.yyyy;vec4 y=y_*ns.x+ns.yyyy;vec4 h=1.0-abs(x)-abs(y);vec4 b0=vec4(x.xy,y.xy);vec4 b1=vec4(x.zw,y.zw);vec4 s0=floor(b0)*2.0+1.0;vec4 s1=floor(b1)*2.0+1.0;vec4 sh=-step(h,vec4(0.0));vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy;vec4 a1_2482186953=b1.xzyw+s1.xzyw*sh.zzww;vec3 p0_2482186953=vec3(a0.xy,h.x);vec3 p1=vec3(a0.zw,h.y);vec3 p2=vec3(a1_2482186953.xy,h.z);vec3 p3=vec3(a1_2482186953.zw,h.w);vec4 norm=taylorInvSqrt_2482186953(vec4(dot(p0_2482186953,p0_2482186953),dot(p1,p1),dot(p2,p2),dot(p3,p3)));p0_2482186953*=norm.x;p1*=norm.y;p2*=norm.z;p3*=norm.w;vec4 m=max(0.6-vec4(dot(x0,x0),dot(x1,x1),dot(x2,x2),dot(x3,x3)),0.0);m=m*m;return 42.0*dot(m*m,vec4(dot(p0_2482186953,x0),dot(p1,x1),dot(p2,x2),dot(p3,x3)));}␊ + \`;␊ + var main = \`␊ + vec3 displacement = normal * noise(vec3(uv, time * speed));␊ + \`;␊ + console.log(head, main);␊ + ` + +## works with a basic example but minified + +> Snapshot 1 + + `// test/fixtures/basic.js␊ + var head = \`␊ + uniform float time;␊ + uniform float speed;␊ + vec3 mod289_2482186953(vec3 x){return x-floor(x*(1.0/289.0))*289.0;}vec4 mod289_2482186953(vec4 x){return x-floor(x*(1.0/289.0))*289.0;}vec4 permute_2482186953(vec4 x){return mod289_2482186953(((x*34.0)+1.0)*x);}vec4 taylorInvSqrt_2482186953(vec4 r){return 1.79284291400159-0.85373472095314*r;}float noise(vec3 v){const vec2 C=vec2(1.0/6.0,1.0/3.0);const vec4 D_2482186953=vec4(0.0,0.5,1.0,2.0);vec3 i=floor(v+dot(v,C.yyy));vec3 x0=v-i+dot(i,C.xxx);vec3 g_2482186953=step(x0.yzx,x0.xyz);vec3 l=1.0-g_2482186953;vec3 i1=min(g_2482186953.xyz,l.zxy);vec3 i2=max(g_2482186953.xyz,l.zxy);vec3 x1=x0-i1+C.xxx;vec3 x2=x0-i2+C.yyy;vec3 x3=x0-D_2482186953.yyy;i=mod289_2482186953(i);vec4 p=permute_2482186953(permute_2482186953(permute_2482186953(i.z+vec4(0.0,i1.z,i2.z,1.0))+i.y+vec4(0.0,i1.y,i2.y,1.0))+i.x+vec4(0.0,i1.x,i2.x,1.0));float n_=0.142857142857;vec3 ns=n_*D_2482186953.wyz-D_2482186953.xzx;vec4 j=p-49.0*floor(p*ns.z*ns.z);vec4 x_=floor(j*ns.z);vec4 y_=floor(j-7.0*x_);vec4 x=x_*ns.x+ns.yyyy;vec4 y=y_*ns.x+ns.yyyy;vec4 h=1.0-abs(x)-abs(y);vec4 b0=vec4(x.xy,y.xy);vec4 b1=vec4(x.zw,y.zw);vec4 s0=floor(b0)*2.0+1.0;vec4 s1=floor(b1)*2.0+1.0;vec4 sh=-step(h,vec4(0.0));vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy;vec4 a1_2482186953=b1.xzyw+s1.xzyw*sh.zzww;vec3 p0_2482186953=vec3(a0.xy,h.x);vec3 p1=vec3(a0.zw,h.y);vec3 p2=vec3(a1_2482186953.xy,h.z);vec3 p3=vec3(a1_2482186953.zw,h.w);vec4 norm=taylorInvSqrt_2482186953(vec4(dot(p0_2482186953,p0_2482186953),dot(p1,p1),dot(p2,p2),dot(p3,p3)));p0_2482186953*=norm.x;p1*=norm.y;p2*=norm.z;p3*=norm.w;vec4 m=max(0.6-vec4(dot(x0,x0),dot(x1,x1),dot(x2,x2),dot(x3,x3)),0.0);m=m*m;return 42.0*dot(m*m,vec4(dot(p0_2482186953,x0),dot(p1,x1),dot(p2,x2),dot(p3,x3)));}␊ + \`;␊ + var main = \`␊ + vec3 displacement = normal * noise(vec3(uv, time * speed));␊ + \`;␊ + console.log(head, main);␊ + ` diff --git a/test/snapshots/test.js.snap b/test/snapshots/test.js.snap index 0d40ed05fc4c895143a9b6889629ec779aa31f96..52433e5f2912a1b2b202055364d5dbf88c6edd4e 100644 GIT binary patch literal 2072 zcmV+z2!e7#2)?LW z5!!SJEs42buF|SEjq}dRJhzIXFqBi+{;JQVhoeUbp&Yk$_AC#Rj0cJE)a8w>F~C<8u5(AnwNq<_o*eSx*j4*&JzedU7JlHY8hpMWm1W z`@72}HAaSiAU595#H~%QT5!&+jmaJSplC6A+$tK*f}BO=6b+{!rzoAC3W;mqwwUXj z9F5A)a)uCPestY!OmSUonsXK#QBLm8Px>yNf^NC>NjJ)@jr>rv7uPB(?&{W}vi3*V zSX^tgFRlqEdiYVORY$mA95T;jPz2+wBMkW{6wTN!<5b{2n}sDRJJa^f8tt34vS+p$ z&KQp&1~i>Vxc0Dt{FT-_a>V-BGU10lT4Bkz#?q%h(o6Rt;^tc07kNGiEP*y=V zoAtWfjl|wLe8Wya=fXrj6}kzl>^Q5Lr9(P#l$|vLA0hfwCBs7y$)cAg!nEt(n~*wm zrW@ll8@~)w0+^XF_0=&GM}0-?(7<(TwCMWOt0laIsjr2XIO^-hOEh3z4sjumw{0Ew ztKkS6(?{8bV5U$V3&#|yV=*)Zc5KqFc}UP*cq*y7xXWFFpv`>8{4{s6 z4&9ojrwfT?df~PqGu9XbfXt|GM|I= zXMk%MrmJvj?N8%^XL-uUn7gOAa8n#kJ`3UbvzNLj3$DTtE}xx0eR1^^ZaD7WKFci6 zlk99TxaIk5IkqP8Vi3r&4A$ZJcHWnZMSJiqx(8n4{%PF;eNf5;$mBnc5S@78VQHLtCDcosU$xjm5_+YYJv&Q@#Hi# z6KK%{ULEQ}LphbL$_p7tJW(?fqA4Gu`gCIlj930xiEZc8&nr?S7+G<>n0iB*kD)XMq%2 zwc&Dyu$Z&&!y;Io5ji(u%YCzPa`f3P=jK%yrZG4S#IQpcr@}adaSmaI8pC8?!zM;4 z#adszU1zlCzr?(q^5_KeZI%2c4S_0KJq)jm zYm9|XVvf2aqiQa$tHg3wp|!K9JNqz_JzxvNQ{hO2cjk*49fdH?fiya9mR9K%A-aoq zyJuBuDYd-%QW)Fmj%}SkL5g}HRS(-Ck6F!+0v1T!S7}6vd<`Lu@^ThLDEFlRl*+z5 z^j;0m_VMfxe#_n{BFa3p1+XoE9R$!a=#rv}ccZol0rjCO3v9eoTR_Fskn_}pRZW^T z259b`LZh5`qtvKytmf49M&)!W=fR?*!VM4Obmc+k`Gpk4BoJ@)!PfI5y^I9^V^spR zvILZb2P#aUQJG+;&9&*4g58o?AD2V_mhp@$pnq@V?=5~^rm5##pahIi@0ap-70j2R zp4mcOj9AQIeC?JqP^)L4R?tAbq5)abAfe>KgS+syYRD~bJ;DRkH|oe7u5h4M;xtqK zfxlV}1luAAluAKy_5Z4c9^O4ZynB3j_xSMc@!{R$!@I|acaPu6efw|!6Ufa#8~^}x C85sHi literal 1504 zcmV<61t0oBRzV2#7IHA`G%#Q%1)M`~$x2#FYw#~5B`sO>E!v)Y z@5}TZdg?c?*P9%)D_x;`R^T!S zK*=+}7_xN7R@U({u6dTHe6h{h3In%7ck&H`yPLO-B@6BugWH>{m#^<%!UGT336@Qs zC)tHs@7ZDo}oC^Wo2m(mze<|1Zjfr6I=UW1P^^9^2M5VR$~$ zj?ji~2>rmC(;|q|n`n3cAUzRk(LBf>oSrI}@&~q9}CG=M79a2*WWhj@K|Q zVL}M$lw^N{HJR4zS);e^`^=&3^Kt;VH|;Hunb~6G^8Gc+aTw7ra}Aw{tPsKW}Hjl z%$L5`ZR8!!I2Q5U>Di?ER+S)|#l&)&>_e0x4#7r0{rjSPS`nfYYFnrjKFSm#!k?)c zt$IX)BRogT`bVEvb&a*4CFaDK=&ibV*EW{N7TpMou5b(!WdSwxd0mc@@X>tTp_3(y zYd{{EEc_{C{kDWCE3MFA}nCH=m>Agu~%RmyU|hlbmO#5p>vJdMgTz(o2( z?@mZZh=JZ%MMvniLelT-i0hmsiFX>O`1aL)evS7}8psRcy4l#x`XYHXeevmQfF=*Y z-lELjlWwYGG9hL{nz3u*3YrJRd%CWC?#IS>p&YPO*T--)&#Im=0?l)&o)7qa)u!&a zz$;)xgZlcrqrsLnD+}v`(Xr04zS?yN#}rQOm>{NTJQl7g8i$2v3UpZBEga>w;=+v^ z&JVXCzdH3K9zr9m%M6ZV)tXBxbN!Zo;!_7ubmE8ZKz&QW%hmAxT)lgQcw?{MJyb2M zc$Nfo$wJI9RH4Gy7@cdFw#7S-d^5pW^(rE>f^71p72{nxh}W8YqcIgX%KimN^(rGQ G4FCXy;pr9t diff --git a/test/test.js b/test/test.js index 96385ac..407e188 100644 --- a/test/test.js +++ b/test/test.js @@ -23,3 +23,20 @@ test('works with a basic example', async (t) => { t.snapshot(generated) }) + +test('works with a basic example but minified', async (t) => { + const input = path.resolve(__dirname, './fixtures/basic.js') + const output = path.resolve(__dirname, './fixtures/generated/basic-minified.js') + + await esbuild.build({ + entryPoints: [input], + outfile: output, + bundle: true, + format: 'esm', + plugins: [glslifyInline({ minify: true })], + }) + + const generated = await fs.readFile(output, 'utf-8') + + t.snapshot(generated) +})