From c910eaeb44c329808b47dcb39fad63eb2479ba7f Mon Sep 17 00:00:00 2001 From: axion014 Date: Sat, 8 Jun 2019 05:47:13 +0900 Subject: [PATCH 1/5] use short form for vectors with same value in all its element --- index.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/index.js b/index.js index 7b78532..badcd49 100644 --- a/index.js +++ b/index.js @@ -23,6 +23,10 @@ function minifier(safe_words, mutate_storages) { return through(mutate) function mutate(node) { + // vec2(1.0, 1.0) => vec2(1.0) + if(node.parent && is_redundant_vector_literal(node.parent) && node.parent.children.indexOf(node) > 1) return + if(is_redundant_vector_literal(node)) node.children = node.children.slice(0, 2) + if(should_mutate(node)) { var t = node.parent.parent.children[1] if(mutate_storages || (t.type === 'placeholder' || t.token.data === 'const')) { @@ -45,4 +49,14 @@ function minifier(safe_words, mutate_storages) { return base && !safe_words.hasOwnProperty(node.token.data) } + + function is_redundant_vector_literal(node) { + if(node.type === 'call' && /^[ib]?vec[234]$/.test(node.children[0].data) && + (node.children[1].type === 'literal' || node.children[1].type === 'ident')) { + var first = node.children[1].data + for(var i = 2; i < node.children.length; i++) if(node.children[i].data !== first) return false + return true + } + return false + } } From 67e012601f57ef0f52e8af98acb5adc5b3e16a9e Mon Sep 17 00:00:00 2001 From: axion014 Date: Sun, 9 Jun 2019 22:40:08 +0900 Subject: [PATCH 2/5] reflect changes to snapshot --- tap-snapshots/test-basic.js-TAP.test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tap-snapshots/test-basic.js-TAP.test.js b/tap-snapshots/test-basic.js-TAP.test.js index 1087b2a..e154541 100644 --- a/tap-snapshots/test-basic.js-TAP.test.js +++ b/tap-snapshots/test-basic.js-TAP.test.js @@ -30,7 +30,7 @@ uniform vec2 resolution;uniform float time;uniform vec2 mouse;uniform sampler2D #if SHADOWS_ENABLED==1 float G(vec3 m,vec3 H,float I){float J=2.0*I;float K=1.0;for(int L=0;L<30;L++){vec3 M=m+J*H;float E=l(M);if(EO) e=O;else if(e<-O) e=-O;d=c/2.0;for(int v=0;v<5;v++){float P=cos(d);float Q=sin(d);float R=1.0/(4.0*e*e+Q*Q);d=atan(sqrt((1.0+2.0*P+P*P)*R))+atan(sqrt((1.0-2.0*P+P*P)*R));}float P=cos(d);float Q=sin(d);vec3 S=vec3(1,0,0);vec3 T=vec3(P,0,Q);vec3 U=S+T;vec3 V=U*0.5+vec3(0,e,0);h[0]=h[1]=h[2]=h[3]=V;h[4]=T;h[5]=S;g[0]=(S+V)/3.0;g[1]=(T+V)/3.0;g[2]=(S+V+U)/3.0;g[3]=(T+V+U)/3.0;float W=length(V);float X=length(vec3(1,0,0)-V);float s=1.0/W+1.0/X;i[0]=i[1]=i[2]=i[3]=s;i[4]=X*s;i[5]=W*s;k[0]=vec3(0,0,0);k[1]=S*(1.0+X/W);k[2]=T*(1.0+W/X);j[0][0]=normalize(S-V);j[0][1]=-normalize(cross(j[0][0],V));j[0][2]=-cross(j[0][0],j[0][1]);j[1][0]=normalize(T-V);j[1][1]=normalize(cross(j[1][0],V));j[1][2]=cross(j[1][0],j[1][1]);j[2][0]=j[0][0];j[2][1]=normalize(cross(j[2][0],V-U));j[2][2]=cross(j[2][0],j[2][1]);j[3][0]=j[1][0];j[3][1]=-normalize(cross(j[3][0],V-U));j[3][2]=-cross(j[3][0],j[3][1]);j[0]*=i[0];j[1]*=i[1];j[2]*=i[2];j[3]*=i[3];j[4]=mat3(i[4]);j[5]=mat3(i[5]); +void N(){e=2.3*(mouse.y-0.5);float O=0.6;if(e>O) e=O;else if(e<-O) e=-O;d=c/2.0;for(int v=0;v<5;v++){float P=cos(d);float Q=sin(d);float R=1.0/(4.0*e*e+Q*Q);d=atan(sqrt((1.0+2.0*P+P*P)*R))+atan(sqrt((1.0-2.0*P+P*P)*R));}float P=cos(d);float Q=sin(d);vec3 S=vec3(1,0,0);vec3 T=vec3(P,0,Q);vec3 U=S+T;vec3 V=U*0.5+vec3(0,e,0);h[0]=h[1]=h[2]=h[3]=V;h[4]=T;h[5]=S;g[0]=(S+V)/3.0;g[1]=(T+V)/3.0;g[2]=(S+V+U)/3.0;g[3]=(T+V+U)/3.0;float W=length(V);float X=length(vec3(1,0,0)-V);float s=1.0/W+1.0/X;i[0]=i[1]=i[2]=i[3]=s;i[4]=X*s;i[5]=W*s;k[0]=vec3(0);k[1]=S*(1.0+X/W);k[2]=T*(1.0+W/X);j[0][0]=normalize(S-V);j[0][1]=-normalize(cross(j[0][0],V));j[0][2]=-cross(j[0][0],j[0][1]);j[1][0]=normalize(T-V);j[1][1]=normalize(cross(j[1][0],V));j[1][2]=cross(j[1][0],j[1][1]);j[2][0]=j[0][0];j[2][1]=normalize(cross(j[2][0],V-U));j[2][2]=cross(j[2][0],j[2][1]);j[3][0]=j[1][0];j[3][1]=-normalize(cross(j[3][0],V-U));j[3][2]=-cross(j[3][0],j[3][1]);j[0]*=i[0];j[1]*=i[1];j[2]*=i[2];j[3]*=i[3];j[4]=mat3(i[4]);j[5]=mat3(i[5]); #if REVERSE_TRI0==1 j[0][1]*=-1.0; #endif @@ -49,7 +49,7 @@ j[4][1]*=-1.0; #if REVERSE_TRI5==1 j[5][1]*=-1.0; #endif -vec3 D=cross(U-S,vec3(0,1,0));g[5]=g[2]+2.0*D*dot(D,S-g[2])/dot(D,D);D=cross(U-T,vec3(0,1,0));g[4]=g[3]+2.0*D*dot(D,T-g[3])/dot(D,D);}void main(void){N();vec2 Y=0.5*(-1.0+2.0*gl_FragCoord.xy/resolution.xy);float Z=0.2*time;if(e<0.0) Z+=c/2.0;float ba=sin(Z);float bb=cos(Z);mat3 bc=mat3(vec3(bb,0,ba),vec3(0,1,0),vec3(-ba,0,bb));vec3 bd=vec3(0,1,0);vec3 be=vec3(0,0,0);float bf=0.0;float bg=0.5*c/2.01;vec3 bh=bc*vec3(cos(bg),sin(bg),0.0)*2.0;vec3 bi=normalize(be-bh);vec3 bj=normalize(cross(bd,bi));vec3 bk=cross(bi,bj);vec3 bl=(bh+bi);vec3 bm=bl+Y.x*bj*resolution.x/resolution.y+Y.y*bk;vec3 bn=normalize(bm-bh);const vec3 bo=vec3(0.000001,0,0);const float bp=3.0;float K=0.0;vec3 bq,M,br;float bs=0.80;for(int v=0;v<46;v++){bs+=K*0.8;M=bh+bn*bs;K=l(M);if(K<.00065||bs>bp) break;}if(bsbp) break;}if(bs0.0){float bz=G(M+br*I,-bu,I);bx=mix(bx,0.0,b*bz);bw=mix(bw,0.0,b*bz);if(bz>0.0) by=0.0;} #endif @@ -81,7 +81,7 @@ uniform vec2 resolution;uniform float time;uniform vec2 mouse;uniform sampler2D #if SHADOWS_ENABLED==1 float F(vec3 l,vec3 G,float H){float I=2.0*H;float J=1.0;for(int K=0;K<30;K++){vec3 L=l+I*G;float D=k(L);if(DN) d=N;else if(d<-N) d=-N;c=PI/2.0;for(int u=0;u<5;u++){float O=cos(c);float P=sin(c);float Q=1.0/(4.0*d*d+P*P);c=atan(sqrt((1.0+2.0*O+O*O)*Q))+atan(sqrt((1.0-2.0*O+O*O)*Q));}float O=cos(c);float P=sin(c);vec3 R=vec3(1,0,0);vec3 S=vec3(O,0,P);vec3 T=R+S;vec3 U=T*0.5+vec3(0,d,0);g[0]=g[1]=g[2]=g[3]=U;g[4]=S;g[5]=R;f[0]=(R+U)/3.0;f[1]=(S+U)/3.0;f[2]=(R+U+T)/3.0;f[3]=(S+U+T)/3.0;float V=length(U);float W=length(vec3(1,0,0)-U);float r=1.0/V+1.0/W;h[0]=h[1]=h[2]=h[3]=r;h[4]=W*r;h[5]=V*r;j[0]=vec3(0,0,0);j[1]=R*(1.0+W/V);j[2]=S*(1.0+V/W);i[0][0]=normalize(R-U);i[0][1]=-normalize(cross(i[0][0],U));i[0][2]=-cross(i[0][0],i[0][1]);i[1][0]=normalize(S-U);i[1][1]=normalize(cross(i[1][0],U));i[1][2]=cross(i[1][0],i[1][1]);i[2][0]=i[0][0];i[2][1]=normalize(cross(i[2][0],U-T));i[2][2]=cross(i[2][0],i[2][1]);i[3][0]=i[1][0];i[3][1]=-normalize(cross(i[3][0],U-T));i[3][2]=-cross(i[3][0],i[3][1]);i[0]*=h[0];i[1]*=h[1];i[2]*=h[2];i[3]*=h[3];i[4]=mat3(h[4]);i[5]=mat3(h[5]); +void M(){d=2.3*(mouse.y-0.5);float N=0.6;if(d>N) d=N;else if(d<-N) d=-N;c=PI/2.0;for(int u=0;u<5;u++){float O=cos(c);float P=sin(c);float Q=1.0/(4.0*d*d+P*P);c=atan(sqrt((1.0+2.0*O+O*O)*Q))+atan(sqrt((1.0-2.0*O+O*O)*Q));}float O=cos(c);float P=sin(c);vec3 R=vec3(1,0,0);vec3 S=vec3(O,0,P);vec3 T=R+S;vec3 U=T*0.5+vec3(0,d,0);g[0]=g[1]=g[2]=g[3]=U;g[4]=S;g[5]=R;f[0]=(R+U)/3.0;f[1]=(S+U)/3.0;f[2]=(R+U+T)/3.0;f[3]=(S+U+T)/3.0;float V=length(U);float W=length(vec3(1,0,0)-U);float r=1.0/V+1.0/W;h[0]=h[1]=h[2]=h[3]=r;h[4]=W*r;h[5]=V*r;j[0]=vec3(0);j[1]=R*(1.0+W/V);j[2]=S*(1.0+V/W);i[0][0]=normalize(R-U);i[0][1]=-normalize(cross(i[0][0],U));i[0][2]=-cross(i[0][0],i[0][1]);i[1][0]=normalize(S-U);i[1][1]=normalize(cross(i[1][0],U));i[1][2]=cross(i[1][0],i[1][1]);i[2][0]=i[0][0];i[2][1]=normalize(cross(i[2][0],U-T));i[2][2]=cross(i[2][0],i[2][1]);i[3][0]=i[1][0];i[3][1]=-normalize(cross(i[3][0],U-T));i[3][2]=-cross(i[3][0],i[3][1]);i[0]*=h[0];i[1]*=h[1];i[2]*=h[2];i[3]*=h[3];i[4]=mat3(h[4]);i[5]=mat3(h[5]); #if REVERSE_TRI0==1 i[0][1]*=-1.0; #endif @@ -100,7 +100,7 @@ i[4][1]*=-1.0; #if REVERSE_TRI5==1 i[5][1]*=-1.0; #endif -vec3 C=cross(T-R,vec3(0,1,0));f[5]=f[2]+2.0*C*dot(C,R-f[2])/dot(C,C);C=cross(T-S,vec3(0,1,0));f[4]=f[3]+2.0*C*dot(C,S-f[3])/dot(C,C);}void main(void){M();vec2 X=0.5*(-1.0+2.0*gl_FragCoord.xy/resolution.xy);float Y=0.2*time;if(d<0.0) Y+=PI/2.0;float Z=sin(Y);float ba=cos(Y);mat3 bb=mat3(vec3(ba,0,Z),vec3(0,1,0),vec3(-Z,0,ba));vec3 bc=vec3(0,1,0);vec3 bd=vec3(0,0,0);float be=0.0;float bf=0.5*PI/2.01;vec3 bg=bb*vec3(cos(bf),sin(bf),0.0)*2.0;vec3 bh=normalize(bd-bg);vec3 bi=normalize(cross(bc,bh));vec3 bj=cross(bh,bi);vec3 bk=(bg+bh);vec3 bl=bk+X.x*bi*resolution.x/resolution.y+X.y*bj;vec3 bm=normalize(bl-bg);const vec3 bn=vec3(0.000001,0,0);const float bo=3.0;float J=0.0;vec3 bp,L,bq;float br=0.80;for(int u=0;u<46;u++){br+=J*0.8;L=bg+bm*br;J=k(L);if(J<.00065||br>bo) break;}if(brbo) break;}if(br0.0){float by=F(L+bq*H,-bt,H);bw=mix(bw,0.0,b*by);bv=mix(bv,0.0,b*by);if(by>0.0) bx=0.0;} #endif @@ -245,7 +245,7 @@ void R() { m[0] = m[1] = m[2] = m[3] = w; m[4] = bb * w; m[5] = ba * w; - o[0] = vec3(0, 0, 0); + o[0] = vec3(0); o[1] = W * (1.0 + bb / ba); o[2] = X * (1.0 + ba / bb); n[0][0] = normalize(W - Z); @@ -299,7 +299,7 @@ void main(void) { float bf = cos(bd); mat3 bg = mat3(vec3(bf, 0, be), vec3(0, 1, 0), vec3(-be, 0, bf)); vec3 bh = vec3(0, 1, 0); - vec3 bi = vec3(0, 0, 0); + vec3 bi = vec3(0); float bj = 0.0; float bk = 0.5 * g / 2.01; vec3 bl = bg * vec3(cos(bk), sin(bk), 0.0) * 2.0; From 3ddcfdfd202f26c0ed75e4d796d7026d995e42f8 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Sun, 9 Jun 2019 22:27:53 -0400 Subject: [PATCH 3/5] Add a slightly more robust test for vec constructor shorthand Tests converting to shorthand, and retaining long forms. Also tests all the vec types. --- tap-snapshots/test-basic.js-TAP.test.js | 22 ++++++++++++ test/basic.js | 45 +++++++++++++++++++++++++ test/vec-shorthand.glsl | 26 ++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 test/vec-shorthand.glsl diff --git a/tap-snapshots/test-basic.js-TAP.test.js b/tap-snapshots/test-basic.js-TAP.test.js index f8936fa..85c07df 100644 --- a/tap-snapshots/test-basic.js-TAP.test.js +++ b/tap-snapshots/test-basic.js-TAP.test.js @@ -724,3 +724,25 @@ gl_FragColor = vec4((vec3(1.0) * bA + vec3(1.0) * bB + bC * vec3(1.0)) * vec3(0. } } ` + +exports[`test/basic.js TAP vec shorthand > output 1`] = ` + +vec2 vec2Long = vec2(0.0, 1.0); +vec2 vec2Short = vec2(0.0); +bvec2 bvec2Long = bvec2(0.0, 1.0); +bvec2 bvec2Short = bvec2(0.0); +ivec2 ivec2Long = ivec2(0.0, 1.0); +ivec2 ivec2Short = ivec2(0.0); +vec3 vec3Long = vec3(0.0, 1.0, 1.0); +vec3 vec3Short = vec3(0.0); +bvec3 bvec3Long = bvec3(0.0, 1.0, 1.0, 1.0); +bvec3 bvec3Short = bvec3(0.0); +ivec3 ivec3Long = ivec3(0.0, 1.0, 1.0, 1.0); +ivec3 ivec3Short = ivec3(0.0); +vec4 vec4Long = vec4(0.0, 1.0, 1.0, 1.0); +vec4 vec4Short = vec4(0.0); +bvec4 bvec4Long = bvec4(0.0, 1.0, 1.0, 1.0); +bvec4 bvec4Short = bvec4(0.0); +ivec4 ivec4Long = ivec4(0.0, 1.0, 1.0, 1.0); +ivec4 ivec4Short = ivec4(0.0); +` diff --git a/test/basic.js b/test/basic.js index 77c1b50..2c74abe 100644 --- a/test/basic.js +++ b/test/basic.js @@ -9,6 +9,7 @@ const path = require("path"); const through = require("through"); const workingGLSL = path.resolve(__dirname, "./working.glsl"); +const vecGLSL = path.resolve(__dirname, "./vec-shorthand.glsl"); tap.test("basic", t => { let output = ""; @@ -69,3 +70,47 @@ tap.test("basic storage mutation", t => { .pipe(deparser()) .pipe(endStream); }); + +tap.test("vec shorthand", t => { + const types = ["", "b", "i"] + .map(prefix => [2,3,4].map(size => `${prefix}vec${size}`)) + .reduce((a, b) => a.concat(b)); + + const variableNames = types + .map(type => ["Short", "Long"].map(suffix => `${type}${suffix}`)) + .reduce((a, b) => a.concat(b)); + + const safewords = [ + "main", + ...variableNames, + ]; + + let output = ""; + + const endStream = through((data) => { + output += data; + }, () => { + t.matchSnapshot(output, "output"); + + t.ok( + variableNames + .filter(name => name.endsWith("Long")) + .every(name => output.includes(`${name} = ${name.replace("Long", "")}(0.0, 1.0`)) + ); + + t.ok( + variableNames + .filter(name => name.endsWith("Short")) + .every(name => output.includes(`${name} = ${name.replace("Short", "")}(0.0)`)) + ); + + t.end(); + }); + + fs.createReadStream(vecGLSL) + .pipe(tokenizer()) + .pipe(parser()) + .pipe(minify(safewords)) + .pipe(deparser()) + .pipe(endStream); +}); diff --git a/test/vec-shorthand.glsl b/test/vec-shorthand.glsl new file mode 100644 index 0000000..24ef422 --- /dev/null +++ b/test/vec-shorthand.glsl @@ -0,0 +1,26 @@ +vec2 vec2Long = vec2(0.0, 1.0); +vec2 vec2Short = vec2(0.0, 0.0); + +bvec2 bvec2Long = bvec2(0.0, 1.0); +bvec2 bvec2Short = bvec2(0.0, 0.0); + +ivec2 ivec2Long = ivec2(0.0, 1.0); +ivec2 ivec2Short = ivec2(0.0, 0.0); + +vec3 vec3Long = vec3(0.0, 1.0, 1.0); +vec3 vec3Short = vec3(0.0, 0.0, 0.0); + +bvec3 bvec3Long = bvec3(0.0, 1.0, 1.0, 1.0); +bvec3 bvec3Short = bvec3(0.0, 0.0, 0.0); + +ivec3 ivec3Long = ivec3(0.0, 1.0, 1.0, 1.0); +ivec3 ivec3Short = ivec3(0.0, 0.0, 0.0); + +vec4 vec4Long = vec4(0.0, 1.0, 1.0, 1.0); +vec4 vec4Short = vec4(0.0, 0.0, 0.0, 0.0); + +bvec4 bvec4Long = bvec4(0.0, 1.0, 1.0, 1.0); +bvec4 bvec4Short = bvec4(0.0, 0.0, 0.0, 0.0); + +ivec4 ivec4Long = ivec4(0.0, 1.0, 1.0, 1.0); +ivec4 ivec4Short = ivec4(0.0, 0.0, 0.0, 0.0); From 7804024c24b5287921079c9275db2d4b8aaead9c Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Sun, 9 Jun 2019 23:50:29 -0400 Subject: [PATCH 4/5] Adds a test case for retaining a vector initalization done with other vectors --- tap-snapshots/test-basic.js-TAP.test.js | 1 + test/basic.js | 8 ++++++-- test/vec-shorthand.glsl | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tap-snapshots/test-basic.js-TAP.test.js b/tap-snapshots/test-basic.js-TAP.test.js index 85c07df..40c5ee9 100644 --- a/tap-snapshots/test-basic.js-TAP.test.js +++ b/tap-snapshots/test-basic.js-TAP.test.js @@ -745,4 +745,5 @@ bvec4 bvec4Long = bvec4(0.0, 1.0, 1.0, 1.0); bvec4 bvec4Short = bvec4(0.0); ivec4 ivec4Long = ivec4(0.0, 1.0, 1.0, 1.0); ivec4 ivec4Short = ivec4(0.0); +ivec4 a = ivec4(vec2(0.0, 1.0), vec2(0.0, 1.0)); ` diff --git a/test/basic.js b/test/basic.js index 2c74abe..1f9bd9c 100644 --- a/test/basic.js +++ b/test/basic.js @@ -95,15 +95,19 @@ tap.test("vec shorthand", t => { t.ok( variableNames .filter(name => name.endsWith("Long")) - .every(name => output.includes(`${name} = ${name.replace("Long", "")}(0.0, 1.0`)) + .every(name => output.includes(`${name} = ${name.replace("Long", "")}(0.0, 1.0`)), + "does not retain differing scalars" ); t.ok( variableNames .filter(name => name.endsWith("Short")) - .every(name => output.includes(`${name} = ${name.replace("Short", "")}(0.0)`)) + .every(name => output.includes(`${name} = ${name.replace("Short", "")}(0.0)`)), + "does not shorten identical scalars" ); + t.ok(output.includes("ivec4(vec2(0.0, 1.0), vec2(0.0, 1.0))"), "does not preserve vectors in initalizer"); + t.end(); }); diff --git a/test/vec-shorthand.glsl b/test/vec-shorthand.glsl index 24ef422..b6d50f9 100644 --- a/test/vec-shorthand.glsl +++ b/test/vec-shorthand.glsl @@ -24,3 +24,5 @@ bvec4 bvec4Short = bvec4(0.0, 0.0, 0.0, 0.0); ivec4 ivec4Long = ivec4(0.0, 1.0, 1.0, 1.0); ivec4 ivec4Short = ivec4(0.0, 0.0, 0.0, 0.0); + +ivec4 ivec4Mix = ivec4(vec2(0.0, 1.0), vec2(0.0, 1.0)); From 5bb509b4a994dd5bfab6769066ad134a65b6c11a Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Mon, 10 Jun 2019 01:36:25 -0400 Subject: [PATCH 5/5] Update tests to match output --- test/basic.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/basic.js b/test/basic.js index b56f048..4888efc 100644 --- a/test/basic.js +++ b/test/basic.js @@ -114,18 +114,18 @@ tap.test("vec shorthand", t => { t.ok( variableNames .filter(name => name.endsWith("Long")) - .every(name => output.includes(`${name} = ${name.replace("Long", "")}(0.0, 1.0`)), + .every(name => output.includes(`${name} = ${name.replace("Long", "")}(.0, 1.`)), "does not retain differing scalars" ); t.ok( variableNames .filter(name => name.endsWith("Short")) - .every(name => output.includes(`${name} = ${name.replace("Short", "")}(0.0)`)), + .every(name => output.includes(`${name} = ${name.replace("Short", "")}(.0)`)), "does not shorten identical scalars" ); - t.ok(output.includes("ivec4(vec2(0.0, 1.0), vec2(0.0, 1.0))"), "does not preserve vectors in initalizer"); + t.ok(output.includes("ivec4(vec2(.0, 1.), vec2(.0, 1.))"), "does not preserve vectors in initalizer"); t.end(); });