forked from mrdoob/texgen.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtexgen.min.js
24 lines (24 loc) · 11 KB
/
texgen.min.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// texgen.js - http://github.com/mrdoob/texgen.js
'use strict';var TG={OP:{SET:function(a,b){return b},ADD:function(a,b){return a+b},SUB:function(a,b){return a-b},MUL:function(a,b){return a*b},DIV:function(a,b){return a/b},AND:function(a,b){return a&b},XOR:function(a,b){return a^b},MIN:function(a,b){return Math.min(a,b)},MAX:function(a,b){return Math.max(a,b)}},Texture:function(a,b){this.color=new Float32Array(4);this.buffer=new TG.Buffer(a,b);this.bufferCopy=new TG.Buffer(a,b)}};
TG.Texture.prototype={constructor:TG.Texture,set:function(a,b){void 0===b&&(b=TG.OP.SET);this.bufferCopy.copy(this.buffer);var c=["var x = 0, y = 0;\nvar array = dst.array;\nvar width = dst.width, height = dst.height;\nfor ( var i = 0, il = array.length; i < il; i += 4 ) {","\t"+a.getSource(),"\tarray[ i ] = op( array[ i ], color[ 0 ] * tint[ 0 ] );\n\tarray[ i + 1 ] = op( array[ i + 1 ], color[ 1 ] * tint[ 1 ] );\n\tarray[ i + 2 ] = op( array[ i + 2 ], color[ 2 ] * tint[ 2 ] );\n\tif ( ++x === width ) { x = 0; y ++; }\n}"].join("\n");
(new Function("op, dst, src, color, params, tint",c))(b,this.buffer,this.bufferCopy,this.color,a.getParams(),a.getTint());return this},add:function(a){return this.set(a,TG.OP.ADD)},sub:function(a){return this.set(a,TG.OP.SUB)},mul:function(a){return this.set(a,TG.OP.MUL)},div:function(a){return this.set(a,TG.OP.DIV)},and:function(a){return this.set(a,TG.OP.AND)},xor:function(a){return this.set(a,TG.OP.XOR)},min:function(a){return this.set(a,TG.OP.MIN)},max:function(a){return this.set(a,TG.OP.MAX)},
toImageData:function(a){var b=this.buffer,c=b.array;a=a.createImageData(b.width,b.height);for(var b=a.data,d=0,e=c.length;d<e;d+=4)b[d]=255*c[d],b[d+1]=255*c[d+1],b[d+2]=255*c[d+2],b[d+3]=255;return a},toCanvas:function(){var a=document.createElement("canvas");a.width=this.buffer.width;a.height=this.buffer.height;var b=a.getContext("2d"),c=this.toImageData(b);b.putImageData(c,0,0);return a}};
TG.Program=function(a){var b=new Float32Array([1,1,1]);a.tint=function(a,d,e){b[0]=a;b[1]=d;b[2]=e;return this};a.getTint=function(){return b};return a};TG.Number=function(){return new TG.Program({getParams:function(){},getSource:function(){return"color[ 0 ] = 1;\ncolor[ 1 ] = 1;\ncolor[ 2 ] = 1;"}})};
TG.SinX=function(){var a={frequency:1,offset:0};return new TG.Program({frequency:function(b){a.frequency=b*Math.PI;return this},offset:function(b){a.offset=b;return this},getParams:function(){return a},getSource:function(){return"var value = Math.sin( ( x + params.offset ) * params.frequency );\ncolor[ 0 ] = value;\ncolor[ 1 ] = value;\ncolor[ 2 ] = value;"}})};
TG.SinY=function(){var a={frequency:1,offset:0};return new TG.Program({frequency:function(b){a.frequency=b*Math.PI;return this},offset:function(b){a.offset=b;return this},getParams:function(){return a},getSource:function(){return"var value = Math.sin( ( y + params.offset ) * params.frequency );\ncolor[ 0 ] = value;\ncolor[ 1 ] = value;\ncolor[ 2 ] = value;"}})};TG.OR=function(){return new TG.Program({getParams:function(){},getSource:function(){return"var value = ( x | y ) / width;\ncolor[ 0 ] = value;\ncolor[ 1 ] = value;\ncolor[ 2 ] = value;"}})};
TG.XOR=function(){return new TG.Program({getParams:function(){},getSource:function(){return"var value = ( x ^ y ) / width;\ncolor[ 0 ] = value;\ncolor[ 1 ] = value;\ncolor[ 2 ] = value;"}})};TG.Noise=function(){return new TG.Program({getParams:function(){},getSource:function(){return"var value = Math.random();\ncolor[ 0 ] = value;\ncolor[ 1 ] = value;\ncolor[ 2 ] = value;"}})};
TG.CheckerBoard=function(){var a={size:[32,32],offset:[0,0],rowShift:0};return new TG.Program({size:function(b,c){a.size=[b,c];return this},offset:function(b,c){a.offset=[b,c];return this},rowShift:function(b){a.rowShift=b;return this},getParams:function(){return a},getSource:function(){return"var value = ( ( ( y + params.offset[ 1 ] ) / params.size[ 1 ] ) & 1 ) ^ ( ( ( x + params.offset[ 0 ] + parseInt( y / params.size[ 1 ] ) * params.rowShift ) / params.size[ 0 ] ) & 1 ) ? 0 : 1\ncolor[ 0 ] = value;\ncolor[ 1 ] = value;\ncolor[ 2 ] = value;"}})};
TG.Rect=function(){var a={position:[0,0],size:[32,32]};return new TG.Program({position:function(b,c){a.position=[b,c];return this},size:function(b,c){a.size=[b,c];return this},getParams:function(){return a},getSource:function(){return"var value = ( x >= params.position[ 0 ] && x <= ( params.position[ 0 ] + params.size[ 0 ] ) && y <= ( params.position[ 1 ] + params.size[ 1 ] ) && y >= params.position[ 1 ] ) ? 1 : 0;\ncolor[ 0 ] = value;\ncolor[ 1 ] = value;\ncolor[ 2 ] = value;"}})};
TG.Circle=function(){var a={position:[0,0],radius:50,delta:1};return new TG.Program({delta:function(b){a.delta=b;return this},position:function(b,c){a.position=[b,c];return this},radius:function(b){a.radius=b;return this},getParams:function(){return a},getSource:function(){return"var dist = TG.Utils.distance( x, y, params.position[ 0 ], params.position[ 1 ] );\nvar value = 1 - TG.Utils.smoothStep( params.radius - params.delta, params.radius, dist );\ncolor[ 0 ] = value;\ncolor[ 1 ] = value;\ncolor[ 2 ] = value;"}})};
TG.SineDistort=function(){var a={sines:[4,4],offset:[0,0],amplitude:[16,16]};return new TG.Program({sines:function(b,c){a.sines=[b,c];return this},offset:function(b,c){a.offset=[b,c];return this},amplitude:function(b,c){a.amplitude=[b,c];return this},getParams:function(){return a},getSource:function(){return"var s = Math.sin( params.sines[ 0 ] / 100 * y + params.offset[ 0 ] ) * params.amplitude[ 0 ] + x;\nvar t = Math.sin( params.sines[ 1 ] / 100 * x + params.offset[ 1 ] ) * params.amplitude[ 1 ] + y;\ncolor.set( src.getPixelBilinear( s, t ) );"}})};
TG.Twirl=function(){var a={strength:0,radius:120,position:[128,128]};return new TG.Program({strength:function(b){a.strength=b/100;return this},radius:function(b){a.radius=b;return this},position:function(b,c){a.position=[b,c];return this},getParams:function(){return a},getSource:function(){return"var dist = TG.Utils.distance( x, y, params.position[ 0 ], params.position[ 1 ] );\nif (dist < params.radius) {\ndist = Math.pow(params.radius - dist, 2) / params.radius;\nvar angle = 2.0 * Math.PI * (dist / (params.radius / params.strength));\ns = (((x - params.position[ 0 ]) * Math.cos(angle)) - ((y - params.position[ 0 ]) * Math.sin(angle)) + params.position[ 0 ] + 0.5);\nt = (((y - params.position[ 1 ]) * Math.cos(angle)) + ((x - params.position[ 1 ]) * Math.sin(angle)) + params.position[ 1 ] + 0.5);\n} else {\ns = x;\nt = y;\n}\ncolor.set( src.getPixelBilinear( s, t ) );"}})};
TG.Transform=function(){var a={offset:[0,0],angle:0,scale:[1,1]};return new TG.Program({offset:function(b,c){a.offset=[b,c];return this},angle:function(b){a.angle=TG.Utils.deg2rad(b);return this},scale:function(b,c){if(0!==b&&0!==c)return a.scale=[b,c],this},getParams:function(){return a},getSource:function(){return"var x2 = x - width / 2;\nvar y2 = y - height / 2;\nvar s = x2 * ( Math.cos( params.angle ) / params.scale[ 0 ] ) + y2 * -( Math.sin( params.angle ) / params.scale[ 0 ] );\nvar t = x2 * ( Math.sin( params.angle ) / params.scale[ 1 ] ) + y2 * ( Math.cos( params.angle ) / params.scale[ 1 ] );\ns += params.offset[ 0 ] + width / 2;\nt += params.offset[ 1 ] + height / 2;\ncolor.set( src.getPixelBilinear( s, t ) );"}})};
TG.Pixelate=function(){var a={size:[1,1]};return new TG.Program({size:function(b,c){a.size=[b,c];return this},getParams:function(){return a},getSource:function(){return"var s = params.size[ 0 ] * Math.floor(x/params.size[ 0 ]);\nvar t = params.size[ 1 ] * Math.floor(y/params.size[ 1 ]);\ncolor.set( src.getPixelNearest( s, t ) );"}})};TG.Buffer=function(a,b){this.width=a;this.height=b;this.array=new Float32Array(a*b*4);this.color=new Float32Array(4)};
TG.Buffer.prototype={constructor:TG.Buffer,copy:function(a){this.array.set(a.array)},getPixelNearest:function(a,b){b>=this.height&&(b-=this.height);0>b&&(b+=this.height);a>=this.width&&(a-=this.width);0>a&&(a+=this.width);var c=this.array,d=this.color,e=Math.round(b)*this.width*4+4*Math.round(a);d[0]=c[e];d[1]=c[e+1];d[2]=c[e+2];return this.color},getPixelBilinear:function(a,b){var c=Math.floor(a),d=Math.floor(b),e=c+d*this.width,f=this.array,p=this.color,m=a-c,g=b-d,n=1-m,c=1-g,d=n*c,c=m*c,n=n*g,
m=m*g,g=4*e,k=4*(1+e),l=4*(1*this.width+e),e=4*(1+1*this.width+e),h=this.width*this.height*4;g>=h&&(g-=h);0>g&&(g+=h);k>=h&&(k-=h);0>k&&(k+=h);l>=h&&(l-=h);0>l&&(l+=h);e>=h&&(e-=h);0>e&&(e+=h);p[0]=f[g+0]*d+f[k+0]*c+f[l+0]*n+f[e+0]*m;p[1]=f[g+1]*d+f[k+1]*c+f[l+1]*n+f[e+1]*m;p[2]=f[g+2]*d+f[k+2]*c+f[l+2]*n+f[e+2]*m;p[3]=f[g+3]*d+f[k+3]*c+f[l+3]*n+f[e+3]*m;return this.color},getPixelOffset:function(a){var b=this.array,c=this.color;a=parseInt(4*a);c[0]=b[a];c[1]=b[a+1];c[2]=b[a+2];c[3]=b[a+3];return this.color}};
TG.ColorInterpolatorMethod={STEP:0,LINEAR:1,SPLINE:2};TG.ColorInterpolator=function(){this.points=[];this.interpolation=TG.ColorInterpolator.SPLINE;this.repeat=!1;return this};
TG.ColorInterpolator.prototype={set:function(a){this.points=a;return this},addPoint:function(a,b){this.points.push({pos:a,color:b});this.points.sort(function(a,b){return a.pos-b.pos});return this},setRepeat:function(a){this.repeat=a;return this},setInterpolation:function(a){this.interpolation=a;return this},getColorAt:function(a){1<a&&(a=this.repeat?a%1:1);for(var b=0,c=this.points;c[b+1].pos<a;)b++;var d=c[b],b=c[b+1],c=(a-d.pos)/(b.pos-d.pos);if(this.interpolation==TG.ColorInterpolatorMethod.STEP)return d.color;
if(this.interpolation==TG.ColorInterpolatorMethod.LINEAR)return TG.Utils.mixColors(d.color,b.color,c);if(this.interpolation==TG.ColorInterpolatorMethod.SPLINE)return a=c*c,c*=a,[(2*d.color[0]-2*b.color[0])*c+(-3*d.color[0]+3*b.color[0])*a+d.color[0],(2*d.color[1]-2*b.color[1])*c+(-3*d.color[1]+3*b.color[1])*a+d.color[1],(2*d.color[2]-2*b.color[2])*c+(-3*d.color[2]+3*b.color[2])*a+d.color[2]]}};
TG.RadialGradient=function(){var a={gradient:new TG.ColorInterpolator(TG.ColorInterpolator.LINEAR),radius:255,center:[128,128]};return new TG.Program({repeat:function(b){a.gradient.setRepeat(b);return this},radius:function(b){a.radius=b;return this},interpolation:function(b){a.gradient.setInterpolation(b);return this},center:function(b,c){a.center=[b,c];return this},getParams:function(){return a},point:function(b,c){a.gradient.addPoint(b,c);return this},getSource:function(){return"var dist = TG.Utils.distance( x, y, params.center[ 0 ], params.center[ 1 ] );\ncolor = params.gradient.getColorAt( dist / params.radius );"}})};
TG.LinearGradient=function(){var a={gradient:new TG.ColorInterpolator(TG.ColorInterpolator.LINEAR)};return new TG.Program({repeat:function(b){a.gradient.setRepeat(b);return this},interpolation:function(b){a.gradient.setInterpolation(b);return this},getParams:function(){return a},point:function(b,c){a.gradient.addPoint(b,c);return this},getSource:function(){return"color = params.gradient.getColorAt( x / width );"}})};
TG.Utils={smoothStep:function(a,b,c){c=TG.Utils.clamp((c-a)/(b-a),0,1);return c*c*(3-2*c)},mixColors:function(a,b,c){return[a[0]*(1-c)+b[0]*c,a[1]*(1-c)+b[1]*c,a[2]*(1-c)+b[2]*c,a[3]*(1-c)+b[3]*c]},distance:function(a,b,c,d){a=c-a;b=d-b;return Math.sqrt(a*a+b*b)},clamp:function(a,b,c){return Math.min(Math.max(a,b),c)},deg2rad:function(a){return a*Math.PI/180}};