From fd61566c516a65332b52c9a126bdbd32d0227c79 Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sat, 22 Apr 2017 21:39:08 +0200 Subject: [PATCH 01/12] Rearrange some code --- src/TexGen.js | 1926 ++++++++++++++++++++++++------------------------- 1 file changed, 961 insertions(+), 965 deletions(-) diff --git a/src/TexGen.js b/src/TexGen.js index f1ca8a0..39382fc 100644 --- a/src/TexGen.js +++ b/src/TexGen.js @@ -2,485 +2,490 @@ * @author mrdoob / http://mrdoob.com/ */ -var TG = { - OP: { - SET: function ( x, y ) { return y; }, - ADD: function ( x, y ) { return x + y; }, - SUB: function ( x, y ) { return x - y; }, - MUL: function ( x, y ) { return x * y; }, - DIV: function ( x, y ) { return x / y; }, - AND: function ( x, y ) { return x & y; }, - XOR: function ( x, y ) { return x ^ y; }, - MIN: function ( x, y ) { return Math.min( x, y ); }, - MAX: function ( x, y ) { return Math.max( x, y ); } - } -}; +var TG = {}; -TG.Texture = function ( width, height ) { +// - this.color = new Float32Array( 4 ); +TG.Utils = { - this.buffer = new TG.Buffer( width, height ); - this.bufferCopy = new TG.Buffer( width, height ); + smoothStep: function ( edge0, edge1, x ) { -}; + // Scale, bias and saturate x to 0..1 range + x = TG.Utils.clamp( ( x - edge0 ) / ( edge1 - edge0 ), 0, 1 ); -TG.Texture.prototype = { + // Evaluate polynomial + return x * x * ( 3 - 2 * x ); - constructor: TG.Texture, + }, - set: function ( program, operation ) { + mixColors: function( c1, c2, delta ) { - if ( operation === undefined ) operation = TG.OP.SET; + return [ + c1[ 0 ] * ( 1 - delta ) + c2[ 0 ] * delta, + c1[ 1 ] * ( 1 - delta ) + c2[ 1 ] * delta, + c1[ 2 ] * ( 1 - delta ) + c2[ 2 ] * delta, + c1[ 3 ] * ( 1 - delta ) + c2[ 3 ] * delta, + ]; + }, - this.bufferCopy.copy( this.buffer ); + distance: function( x0, y0, x1, y1 ) { - var string = [ - 'var x = 0, y = 0;', - 'var array = dst.array;', - 'var width = dst.width, height = dst.height;', - 'for ( var i = 0, il = array.length; i < il; i += 4 ) {', - ' ' + program.getSource(), - ' array[ i ] = op( array[ i ], color[ 0 ] * tint[ 0 ] );', - ' array[ i + 1 ] = op( array[ i + 1 ], color[ 1 ] * tint[ 1 ] );', - ' array[ i + 2 ] = op( array[ i + 2 ], color[ 2 ] * tint[ 2 ] );', - ' if ( ++x === width ) { x = 0; y ++; }', - '}' - ].join( '\n' ); + var dx = x1 - x0, dy = y1 - y0; + return Math.sqrt( dx * dx + dy * dy ); - new Function( 'op, dst, src, color, params, tint', string )( operation, this.buffer, this.bufferCopy, this.color, program.getParams(), program.getTint() ); + }, - return this; + clamp: function( value, min, max ) { + + return Math.min( Math.max( value, min ), max ); }, - add: function ( program ) { return this.set( program, TG.OP.ADD ); }, + wrap: function ( value, min, max ) { + var v = value - min; + var r = max - min; - sub: function ( program ) { return this.set( program, TG.OP.SUB ); }, + return ( ( r + v % r ) % r ) + min; + }, - mul: function ( program ) { return this.set( program, TG.OP.MUL ); }, + mirroredWrap: function ( value, min, max ) { + var v = value - min; + var r = ( max - min ) * 2; - div: function ( program ) { return this.set( program, TG.OP.DIV ); }, + v = ( r + v % r ) % r; - and: function ( program ) { return this.set( program, TG.OP.AND ); }, + if ( v > max - min ) { + return ( r - v ) + min; + } else { + return v + min; + } + }, - xor: function ( program ) { return this.set( program, TG.OP.XOR ); }, + deg2rad: function ( deg ) { - min: function ( program ) { return this.set( program, TG.OP.MIN ); }, + return deg * Math.PI / 180; - max: function ( program ) { return this.set( program, TG.OP.MAX ); }, + }, - toImageData: function ( context ) { + hashRNG: function ( seed, x, y ) { + seed = ( Math.abs( seed % 2147483648 ) == 0 ) ? 1 : seed; - var buffer = this.buffer; - var array = buffer.array; + var a = ( ( seed * ( x + 1 ) * 777 ) ^ ( seed * ( y + 1 ) * 123 ) ) % 2147483647; + a = (a ^ 61) ^ (a >> 16); + a = a + (a << 3); + a = a ^ (a >> 4); + a = a * 0x27d4eb2d; + a = a ^ (a >> 15); + a = a / 2147483647; - var imagedata = context.createImageData( buffer.width, buffer.height ); - var data = imagedata.data; + return a; + }, - for ( var i = 0, il = array.length; i < il; i += 4 ) { + cellNoiseBase: function ( x, y, seed, density, weightRange ) { + var qx, qy, rx, ry, w, px, py, dx, dy; + var dist, value; + var shortest = Infinity; + density = Math.abs( density ); - data[ i ] = array[ i ] * 255; - data[ i + 1 ] = array[ i + 1 ] * 255; - data[ i + 2 ] = array[ i + 2 ] * 255; - data[ i + 3 ] = 255; + for ( var sx = -2; sx <= 2; sx++ ) { + for ( var sy = -2; sy <= 2; sy++ ) { + qx = Math.ceil( x / density ) + sx; + qy = Math.ceil( y / density ) + sy; - } + rx = TG.Utils.hashRNG( seed, qx, qy ); + ry = TG.Utils.hashRNG( seed * 2, qx, qy ); + w = ( weightRange > 0 ) ? 1 + TG.Utils.hashRNG( seed * 3, qx, qy ) * weightRange : 1; - return imagedata; + px = ( rx + qx ) * density; + py = ( ry + qy ) * density; - }, + dx = Math.abs( px - x ); + dy = Math.abs( py - y ); - toCanvas: function ( canvas ) { + dist = ( dx * dx + dy * dy ) * w; - if ( canvas === undefined ) canvas = document.createElement( 'canvas' ); - canvas.width = this.buffer.width; - canvas.height = this.buffer.height; + if ( dist < shortest ) { + shortest = dist; + value = rx; + } + } + } - var context = canvas.getContext( '2d' ); - var imagedata = this.toImageData( context ); + return { dist: Math.sqrt( shortest ), value: value }; + } - context.putImageData( imagedata, 0, 0 ); +}; - return canvas; +TG.ColorInterpolatorMethod = { + STEP: 0, + LINEAR: 1, + SPLINE: 2, +}; - } +TG.ColorInterpolator = function( method ) { + + this.points = []; // points must be a set pair (point, color): [{ pos-n: [r,g,b,a] } , ..., { pos-N: [r,g,b,a] } ] + this.low = 0; + this.high = 0; + this.interpolation = ( typeof( method ) == 'undefined' ) ? TG.ColorInterpolatorMethod.LINEAR : method; + this.repeat = false; + return this; }; -// +TG.ColorInterpolator.prototype = { -TG.Program = function ( object ) { + set: function ( points ) { - var tint = new Float32Array( [ 1, 1, 1 ] ); + this.points = points; + this.points.sort( function( a, b ) { + return a.pos - b.pos; + }); + + this.low = this.points[ 0 ].pos; + this.high = this.points[ this.points.length - 1 ].pos; - object.tint = function ( r, g, b ) { - tint[ 0 ] = r; - tint[ 1 ] = g; - tint[ 2 ] = b; return this; - }; - object.getTint = function () { - return tint; - }; + }, - return object; + addPoint: function ( position, color ) { -}; + this.points.push( { pos: position, color: color } ); + this.points.sort( function( a, b ) { + return a.pos - b.pos; + }); -TG.Number = function () { + this.low = this.points[ 0 ].pos; + this.high = this.points[ this.points.length - 1 ].pos; - return new TG.Program( { - getParams: function () {}, - getSource: function () { - return [ - 'color[ 0 ] = 1;', - 'color[ 1 ] = 1;', - 'color[ 2 ] = 1;' - ].join('\n'); - } - } ); + return this; -}; + }, -TG.SinX = function () { + setRepeat: function ( value ) { - var params = { - frequency: 1, - offset: 0 - }; + this.repeat = value; + return this; - return new TG.Program( { - frequency: function ( value ) { - params.frequency = value * Math.PI; - return this; - }, - offset: function ( value ) { - params.offset = value; - return this; - }, - getParams: function () { - return params; - }, - getSource: function () { - return [ - 'var value = Math.sin( ( x + params.offset ) * params.frequency );', - 'color[ 0 ] = value;', - 'color[ 1 ] = value;', - 'color[ 2 ] = value;' - ].join('\n'); - } - } ); + }, -}; + setInterpolation: function ( value ) { -TG.SinY = function () { + this.interpolation = value; + return this; - var params = { - frequency: 1, - offset: 0 - }; + }, - return new TG.Program( { - frequency: function ( value ) { - params.frequency = value * Math.PI; - return this; - }, - offset: function ( value ) { - params.offset = value; - return this; - }, - getParams: function () { - return params; - }, - getSource: function () { - return [ - 'var value = Math.sin( ( y + params.offset ) * params.frequency );', - 'color[ 0 ] = value;', - 'color[ 1 ] = value;', - 'color[ 2 ] = value;' - ].join('\n'); - } - } ); + getColorAt: function ( pos ) { -}; + if ( this.repeat == 2 ) pos = TG.Utils.mirroredWrap( pos, this.low, this.high ); + else if ( this.repeat ) pos = TG.Utils.wrap( pos, this.low, this.high ); + else pos = TG.Utils.clamp( pos, this.low, this.high ); -TG.OR = function () { + var i = 0, points = this.points; - return new TG.Program( { - getParams: function () {}, - getSource: function () { - return [ - 'var value = ( x | y ) / width;', - 'color[ 0 ] = value;', - 'color[ 1 ] = value;', - 'color[ 2 ] = value;' - ].join('\n'); - } - } ); + while ( points[ i + 1 ].pos < pos ) i ++; -}; + var p1 = points[ i ]; + var p2 = points[ i + 1 ]; -TG.XOR = function () { + var delta = ( pos - p1.pos ) / ( p2.pos - p1.pos ); - return new TG.Program( { - getParams: function () {}, - getSource: function () { - return [ - 'var value = ( x ^ y ) / width;', - 'color[ 0 ] = value;', - 'color[ 1 ] = value;', - 'color[ 2 ] = value;' - ].join('\n'); - } - } ); + if ( this.interpolation == TG.ColorInterpolatorMethod.STEP ) { -}; + return p1.color; -TG.Noise = function () { + } else if ( this.interpolation == TG.ColorInterpolatorMethod.LINEAR ) { - var params = { - seed: Date.now() - }; + return TG.Utils.mixColors( p1.color, p2.color, delta ); + + } else if ( this.interpolation == TG.ColorInterpolatorMethod.SPLINE ) { + + var ar = 2 * p1.color[ 0 ] - 2 * p2.color[ 0 ]; + var br = -3 * p1.color[ 0 ] + 3 * p2.color[ 0 ]; + var dr = p1.color[ 0 ]; + + var ag = 2 * p1.color[ 1 ] - 2 * p2.color[ 1 ]; + var bg = -3 * p1.color[ 1 ] + 3 * p2.color[ 1 ]; + var dg = p1.color[ 1 ]; + + var ab = 2 * p1.color[ 2 ] - 2 * p2.color[ 2 ]; + var bb = -3 * p1.color[ 2 ] + 3 * p2.color[ 2 ]; + var db = p1.color[ 2 ]; + + var delta2 = delta * delta; + var delta3 = delta2 * delta; - return new TG.Program( { - seed: function ( value ) { - params.seed = value; - return this; - }, - getParams: function () { - return params; - }, - getSource: function () { return [ - 'var value = TG.Utils.hashRNG( params.seed, x, y );', - 'color[ 0 ] = value;', - 'color[ 1 ] = value;', - 'color[ 2 ] = value;' - ].join('\n'); + ar * delta3 + br * delta2 + dr, + ag * delta3 + bg * delta2 + dg, + ab * delta3 + bb * delta2 + db + ]; + } - } ); + + } }; -TG.FractalNoise = function () { +// - var params = { - interpolator: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.STEP ), - seed: Date.now(), - baseFrequency: 0.03125, - amplitude: 0.4, - persistence: 0.72, - octaves: 4, - step: 4 - }; +TG.Buffer = function ( width, height ) { - return new TG.Program( { - seed: function ( value ) { - params.seed = value; - return this; - }, - baseFrequency: function ( value ) { - params.baseFrequency = 1 / value; - return this; - }, - amplitude: function ( value ) { - params.amplitude = value; - return this; - }, - persistence: function ( value ) { - params.persistence = value; - return this; - }, - octaves: function ( value ) { - params.octaves = Math.max( 1, value ); - return this; - }, - step: function ( value ) { - params.step = Math.max( 1, value ); - return this; - }, - interpolation: function ( value ) { - params.interpolator.setInterpolation( value ); - return this; - }, - getParams: function () { - return params; - }, - getSource: function () { - return [ - 'var value = 0;', - 'var amp = params.amplitude;', - 'var freq = params.baseFrequency;', - 'var x1, y1, dx, dy;', - 'var v1, v2, v3, v4;', - 'var i1, i2;', + this.width = width; + this.height = height; - 'for ( var j = 1; j <= params.octaves; j++ ) {', - 'x1 = Math.floor( x * freq ), y1 = Math.floor( y * freq );', + this.array = new Float32Array( width * height * 4 ); + this.color = new Float32Array( 4 ); - 'if ( params.interpolator.interpolation == TG.ColorInterpolatorMethod.STEP ) {', - 'value += TG.Utils.hashRNG( params.seed * j, x1, y1 ) * amp;', - '} else {', - 'dx = ( x * freq ) - x1, dy = ( y * freq ) - y1;', +}; - 'v1 = TG.Utils.hashRNG( params.seed * j, x1 , y1 );', - 'v2 = TG.Utils.hashRNG( params.seed * j, x1 + 1, y1 );', - 'v3 = TG.Utils.hashRNG( params.seed * j, x1 , y1 + 1 );', - 'v4 = TG.Utils.hashRNG( params.seed * j, x1 + 1, y1 + 1 );', +TG.Buffer.prototype = { - 'params.interpolator.set( [', - '{ pos: 0, color: [ v1 ] },', - '{ pos: 1, color: [ v2 ] }', - '] );', + constructor: TG.Buffer, - 'i1 = params.interpolator.getColorAt( dx );', + copy: function ( buffer ) { - 'params.interpolator.set( [', - '{ pos: 0, color: [ v3 ] },', - '{ pos: 1, color: [ v4 ] }', - '] );', + this.array.set( buffer.array ); - 'i2 = params.interpolator.getColorAt( dx );', + }, - 'params.interpolator.set( [', - '{ pos: 0, color: [ i1[ 0 ] ] },', - '{ pos: 1, color: [ i2[ 0 ] ] }', - '] );', + getPixelNearest: function ( x, y ) { - 'value += params.interpolator.getColorAt( dy )[ 0 ] * amp;', - '}', + if ( y >= this.height ) y -= this.height; + if ( y < 0 ) y += this.height; + if ( x >= this.width ) x -= this.width; + if ( x < 0 ) x += this.width; - 'freq *= params.step;', - 'amp *= params.persistence;', - '}', + var array = this.array; + var color = this.color; + var offset = Math.round( y ) * this.width * 4 + Math.round( x ) * 4; - 'color[ 0 ] = value;', - 'color[ 1 ] = value;', - 'color[ 2 ] = value;', - ].join('\n'); - } - } ); + color[ 0 ] = array[ offset ]; + color[ 1 ] = array[ offset + 1 ]; + color[ 2 ] = array[ offset + 2 ]; -}; + return this.color; -TG.CellularNoise = function () { + }, - var params = { - seed: Date.now(), - density: 32, - weightRange: 0 - }; + getPixelBilinear: function ( x, y ) { - return new TG.Program( { - seed: function ( value ) { - params.seed = value; - return this; - }, - density: function ( value ) { - params.density = value; - return this; - }, - weightRange: function ( value ) { - params.weightRange = Math.max( 0, value ); - return this; - }, - getParams: function () { - return params; - }, - getSource: function () { - return [ - 'var p = TG.Utils.cellNoiseBase( x, y, params.seed, params.density, params.weightRange );', + var px = Math.floor( x ); + var py = Math.floor( y ); + var p0 = px + py * this.width; - 'var value = 1 - ( p.dist / params.density );', - 'if ( params.density < 0 ) value -= 1;', + var array = this.array; + var color = this.color; - 'color[ 0 ] = value;', - 'color[ 1 ] = value;', - 'color[ 2 ] = value;' - ].join('\n'); - } - } ); + // Calculate the weights for each pixel + var fx = x - px; + var fy = y - py; + var fx1 = 1 - fx; + var fy1 = 1 - fy; -}; + var w1 = fx1 * fy1; + var w2 = fx * fy1; + var w3 = fx1 * fy ; + var w4 = fx * fy ; -TG.VoronoiNoise = function () { + var p1 = p0 * 4; // 0 + 0 * w + var p2 = ( 1 + p0 ) * 4; // 1 + 0 * w + var p3 = ( 1 * this.width + p0 ) * 4; // 0 + 1 * w + var p4 = ( 1 + 1 * this.width + p0 ) * 4; // 1 + 1 * w - var params = { - seed: Date.now(), - density: 32, - weightRange: 0 - }; + var len = this.width * this.height * 4; - return new TG.Program( { - seed: function ( value ) { - params.seed = value; - return this; - }, - density: function ( value ) { - params.density = value; - return this; - }, - weightRange: function ( value ) { - params.weightRange = Math.max( 0, value ); - return this; - }, - getParams: function () { - return params; - }, + if ( p1 >= len ) p1 -= len; + if ( p1 < 0 ) p1 += len; + if ( p2 >= len ) p2 -= len; + if ( p2 < 0 ) p2 += len; + if ( p3 >= len ) p3 -= len; + if ( p3 < 0 ) p3 += len; + if ( p4 >= len ) p4 -= len; + if ( p4 < 0 ) p4 += len; + + // Calculate the weighted sum of pixels (for each color channel) + color[ 0 ] = array[ p1 + 0 ] * w1 + array[ p2 + 0 ] * w2 + array[ p3 + 0 ] * w3 + array[ p4 + 0 ] * w4; + color[ 1 ] = array[ p1 + 1 ] * w1 + array[ p2 + 1 ] * w2 + array[ p3 + 1 ] * w3 + array[ p4 + 1 ] * w4; + color[ 2 ] = array[ p1 + 2 ] * w1 + array[ p2 + 2 ] * w2 + array[ p3 + 2 ] * w3 + array[ p4 + 2 ] * w4; + color[ 3 ] = array[ p1 + 3 ] * w1 + array[ p2 + 3 ] * w2 + array[ p3 + 3 ] * w3 + array[ p4 + 3 ] * w4; + + return this.color; + }, + + getPixelOffset: function ( offset ) { + + var array = this.array; + var color = this.color; + + offset = parseInt( offset * 4 ); + + color[ 0 ] = array[ offset ]; + color[ 1 ] = array[ offset + 1 ]; + color[ 2 ] = array[ offset + 2 ]; + color[ 3 ] = array[ offset + 3 ]; + + return this.color; + }, + +}; + +TG.OP = { + SET: function ( x, y ) { return y; }, + ADD: function ( x, y ) { return x + y; }, + SUB: function ( x, y ) { return x - y; }, + MUL: function ( x, y ) { return x * y; }, + DIV: function ( x, y ) { return x / y; }, + AND: function ( x, y ) { return x & y; }, + XOR: function ( x, y ) { return x ^ y; }, + MIN: function ( x, y ) { return Math.min( x, y ); }, + MAX: function ( x, y ) { return Math.max( x, y ); } +}; + +TG.Texture = function ( width, height ) { + + this.color = new Float32Array( 4 ); + + this.buffer = new TG.Buffer( width, height ); + this.bufferCopy = new TG.Buffer( width, height ); + +}; + +TG.Texture.prototype = { + + constructor: TG.Texture, + + set: function ( program, operation ) { + + if ( operation === undefined ) operation = TG.OP.SET; + + this.bufferCopy.copy( this.buffer ); + + var string = [ + 'var x = 0, y = 0;', + 'var array = dst.array;', + 'var width = dst.width, height = dst.height;', + 'for ( var i = 0, il = array.length; i < il; i += 4 ) {', + ' ' + program.getSource(), + ' array[ i ] = op( array[ i ], color[ 0 ] * tint[ 0 ] );', + ' array[ i + 1 ] = op( array[ i + 1 ], color[ 1 ] * tint[ 1 ] );', + ' array[ i + 2 ] = op( array[ i + 2 ], color[ 2 ] * tint[ 2 ] );', + ' if ( ++x === width ) { x = 0; y ++; }', + '}' + ].join( '\n' ); + + new Function( 'op, dst, src, color, params, tint', string )( operation, this.buffer, this.bufferCopy, this.color, program.getParams(), program.getTint() ); + + return this; + + }, + + add: function ( program ) { return this.set( program, TG.OP.ADD ); }, + + sub: function ( program ) { return this.set( program, TG.OP.SUB ); }, + + mul: function ( program ) { return this.set( program, TG.OP.MUL ); }, + + div: function ( program ) { return this.set( program, TG.OP.DIV ); }, + + and: function ( program ) { return this.set( program, TG.OP.AND ); }, + + xor: function ( program ) { return this.set( program, TG.OP.XOR ); }, + + min: function ( program ) { return this.set( program, TG.OP.MIN ); }, + + max: function ( program ) { return this.set( program, TG.OP.MAX ); }, + + toImageData: function ( context ) { + + var buffer = this.buffer; + var array = buffer.array; + + var imagedata = context.createImageData( buffer.width, buffer.height ); + var data = imagedata.data; + + for ( var i = 0, il = array.length; i < il; i += 4 ) { + + data[ i ] = array[ i ] * 255; + data[ i + 1 ] = array[ i + 1 ] * 255; + data[ i + 2 ] = array[ i + 2 ] * 255; + data[ i + 3 ] = 255; + + } + + return imagedata; + + }, + + toCanvas: function ( canvas ) { + + if ( canvas === undefined ) canvas = document.createElement( 'canvas' ); + canvas.width = this.buffer.width; + canvas.height = this.buffer.height; + + var context = canvas.getContext( '2d' ); + var imagedata = this.toImageData( context ); + + context.putImageData( imagedata, 0, 0 ); + + return canvas; + + } + +}; + +TG.Program = function ( object ) { + + var tint = new Float32Array( [ 1, 1, 1 ] ); + + object.tint = function ( r, g, b ) { + tint[ 0 ] = r; + tint[ 1 ] = g; + tint[ 2 ] = b; + return this; + }; + + object.getTint = function () { + return tint; + }; + + return object; + +}; + +// --- Generators --- + +TG.Number = function () { + + return new TG.Program( { + getParams: function () {}, getSource: function () { return [ - 'var p = TG.Utils.cellNoiseBase( x, y, params.seed, params.density, params.weightRange );', - - 'color[ 0 ] = p.value;', - 'color[ 1 ] = p.value;', - 'color[ 2 ] = p.value;' + 'color[ 0 ] = 1;', + 'color[ 1 ] = 1;', + 'color[ 2 ] = 1;' ].join('\n'); } } ); }; -TG.CellularFractal = function () { +TG.SinX = function () { var params = { - seed: Date.now(), - weightRange: 0, - baseDensity: 64, - amplitude: 0.7, - persistence: 0.45, - octaves: 4, - step: 2 + frequency: 1, + offset: 0 }; return new TG.Program( { - seed: function ( value ) { - params.seed = value; - return this; - }, - baseDensity: function ( value ) { - params.baseDensity = value; - return this; - }, - weightRange: function ( value ) { - params.weightRange = Math.max( 0, value ); - return this; - }, - amplitude: function ( value ) { - params.amplitude = value; - return this; - }, - persistence: function ( value ) { - params.persistence = value; - return this; - }, - octaves: function ( value ) { - params.octaves = Math.max( 1, value ); + frequency: function ( value ) { + params.frequency = value * Math.PI; return this; }, - step: function ( value ) { - params.step = Math.max( 1, value ); + offset: function ( value ) { + params.offset = value; return this; }, getParams: function () { @@ -488,126 +493,54 @@ TG.CellularFractal = function () { }, getSource: function () { return [ - 'var p;', - 'var value = 0;', - 'var amp = params.amplitude;', - 'var dens = params.baseDensity;', - - 'for ( var j = 1; j <= params.octaves; j++ ) {', - 'p = TG.Utils.cellNoiseBase( x, y, params.seed * j, dens, params.weightRange );', - - 'p.dist = 1 - ( p.dist / dens );', - 'if ( dens < 0 ) p.dist -= 1;', - - 'value += p.dist * amp;', - 'dens /= params.step;', - 'amp *= params.persistence;', - '}', - + 'var value = Math.sin( ( x + params.offset ) * params.frequency );', 'color[ 0 ] = value;', 'color[ 1 ] = value;', - 'color[ 2 ] = value;', + 'color[ 2 ] = value;' ].join('\n'); } } ); }; -TG.VoronoiFractal = function () { +TG.SinY = function () { var params = { - seed: Date.now(), - weightRange: 0, - baseDensity: 64, - amplitude: 0.6, - persistence: 0.6, - octaves: 4, - step: 2 + frequency: 1, + offset: 0 }; return new TG.Program( { - seed: function ( value ) { - params.seed = value; - return this; - }, - baseDensity: function ( value ) { - params.baseDensity = value; + frequency: function ( value ) { + params.frequency = value * Math.PI; return this; }, - weightRange: function ( value ) { - params.weightRange = Math.max( 0, value ); + offset: function ( value ) { + params.offset = value; return this; }, - amplitude: function ( value ) { - params.amplitude = value; - return this; - }, - persistence: function ( value ) { - params.persistence = value; - return this; - }, - octaves: function ( value ) { - params.octaves = Math.max( 1, value ); - return this; - }, - step: function ( value ) { - params.step = Math.max( 1, value ); - return this; - }, - getParams: function () { - return params; + getParams: function () { + return params; }, getSource: function () { return [ - 'var p;', - 'var value = 0;', - 'var amp = params.amplitude;', - 'var dens = params.baseDensity;', - - 'for ( var j = 1; j <= params.octaves; j++ ) {', - 'p = TG.Utils.cellNoiseBase( x, y, params.seed * j, dens, params.weightRange );', - - 'value += p.value * amp;', - 'dens /= params.step;', - 'amp *= params.persistence;', - '}', - + 'var value = Math.sin( ( y + params.offset ) * params.frequency );', 'color[ 0 ] = value;', 'color[ 1 ] = value;', - 'color[ 2 ] = value;', + 'color[ 2 ] = value;' ].join('\n'); } } ); }; -TG.CheckerBoard = function () { - - var params = { - size: [ 32, 32 ], - offset: [ 0, 0 ], - rowShift: 0 - }; +TG.OR = function () { return new TG.Program( { - size: function ( x, y ) { - params.size = [ x, y ]; - return this; - }, - offset: function ( x, y ) { - params.offset = [ x, y ]; - return this; - }, - rowShift: function ( value ) { - params.rowShift = value; - return this; - }, - getParams: function () { - return params; - }, + getParams: function () {}, 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', + 'var value = ( x | y ) / width;', 'color[ 0 ] = value;', 'color[ 1 ] = value;', 'color[ 2 ] = value;' @@ -617,28 +550,13 @@ TG.CheckerBoard = function () { }; -TG.Rect = function () { - - var params = { - position: [ 0, 0 ], - size: [ 32, 32 ] - }; +TG.XOR = function () { return new TG.Program( { - position: function ( x, y ) { - params.position = [ x, y ]; - return this; - }, - size: function ( x, y ) { - params.size = [ x, y ]; - return this; - }, - getParams: function () { - return params; - }, + getParams: function () {}, 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;', + 'var value = ( x ^ y ) / width;', 'color[ 0 ] = value;', 'color[ 1 ] = value;', 'color[ 2 ] = value;' @@ -648,25 +566,15 @@ TG.Rect = function () { }; -TG.Circle = function () { +TG.Noise = function () { var params = { - position: [ 0, 0 ], - radius: 50, - delta: 1 + seed: Date.now() }; return new TG.Program( { - delta: function ( value ) { - params.delta = value; - return this; - }, - position: function ( x, y ) { - params.position = [ x, y ]; - return this; - }, - radius: function ( value ) { - params.radius = value; + seed: function ( value ) { + params.seed = value; return this; }, getParams: function () { @@ -674,8 +582,7 @@ TG.Circle = function () { }, getSource: function () { return [ - 'var dist = TG.Utils.distance( x, y, params.position[ 0 ], params.position[ 1 ] );', - 'var value = 1 - TG.Utils.smoothStep( params.radius - params.delta, params.radius, dist );', + 'var value = TG.Utils.hashRNG( params.seed, x, y );', 'color[ 0 ] = value;', 'color[ 1 ] = value;', 'color[ 2 ] = value;' @@ -685,21 +592,45 @@ TG.Circle = function () { }; -TG.PutTexture = function ( texture ) { +TG.FractalNoise = function () { var params = { - offset: [ 0, 0 ], - repeat: false, - srcTex: texture.buffer + interpolator: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.STEP ), + seed: Date.now(), + baseFrequency: 0.03125, + amplitude: 0.4, + persistence: 0.72, + octaves: 4, + step: 4 }; return new TG.Program( { - offset: function ( x, y ) { - params.offset = [ x, y ]; + seed: function ( value ) { + params.seed = value; return this; }, - repeat: function ( value ) { - params.repeat = value; + baseFrequency: function ( value ) { + params.baseFrequency = 1 / value; + return this; + }, + amplitude: function ( value ) { + params.amplitude = value; + return this; + }, + persistence: function ( value ) { + params.persistence = value; + return this; + }, + octaves: function ( value ) { + params.octaves = Math.max( 1, value ); + return this; + }, + step: function ( value ) { + params.step = Math.max( 1, value ); + return this; + }, + interpolation: function ( value ) { + params.interpolator.setInterpolation( value ); return this; }, getParams: function () { @@ -707,63 +638,80 @@ TG.PutTexture = function ( texture ) { }, getSource: function () { return [ - 'var texWidth = params.srcTex.width;', - 'var texHeight = params.srcTex.height;', + 'var value = 0;', + 'var amp = params.amplitude;', + 'var freq = params.baseFrequency;', + 'var x1, y1, dx, dy;', + 'var v1, v2, v3, v4;', + 'var i1, i2;', - 'var texX = Math.floor( x - params.offset[ 0 ] );', - 'var texY = Math.floor( y - params.offset[ 1 ] );', + 'for ( var j = 1; j <= params.octaves; j++ ) {', + 'x1 = Math.floor( x * freq ), y1 = Math.floor( y * freq );', - 'if ( texX >= texWidth || texY >= texHeight || texX < 0 || texY < 0 ) {', - 'if ( params.repeat ) {', - 'var nx, ny;', - 'var rangeX = texWidth - 1;', - 'var rangeY = texHeight - 1;', + 'if ( params.interpolator.interpolation == TG.ColorInterpolatorMethod.STEP ) {', + 'value += TG.Utils.hashRNG( params.seed * j, x1, y1 ) * amp;', + '} else {', + 'dx = ( x * freq ) - x1, dy = ( y * freq ) - y1;', - 'if ( params.repeat == 1 ) {', - 'nx = TG.Utils.wrap( texX, 0, texWidth );', - 'ny = TG.Utils.wrap( texY, 0, texHeight );', - '} else if ( params.repeat == 2 ) {', - 'nx = TG.Utils.mirroredWrap( texX, 0, rangeX );', - 'ny = TG.Utils.mirroredWrap( texY, 0, rangeY );', - '} else if ( params.repeat == 3 ) {', - 'nx = TG.Utils.clamp( texX, 0, rangeX );', - 'ny = TG.Utils.clamp( texY, 0, rangeY );', - '}', + 'v1 = TG.Utils.hashRNG( params.seed * j, x1 , y1 );', + 'v2 = TG.Utils.hashRNG( params.seed * j, x1 + 1, y1 );', + 'v3 = TG.Utils.hashRNG( params.seed * j, x1 , y1 + 1 );', + 'v4 = TG.Utils.hashRNG( params.seed * j, x1 + 1, y1 + 1 );', - 'color = params.srcTex.getPixelNearest( nx, ny );', - '} else {', - 'color[ 0 ] = 0;', - 'color[ 1 ] = 0;', - 'color[ 2 ] = 0;', + 'params.interpolator.set( [', + '{ pos: 0, color: [ v1 ] },', + '{ pos: 1, color: [ v2 ] }', + '] );', + + 'i1 = params.interpolator.getColorAt( dx );', + + 'params.interpolator.set( [', + '{ pos: 0, color: [ v3 ] },', + '{ pos: 1, color: [ v4 ] }', + '] );', + + 'i2 = params.interpolator.getColorAt( dx );', + + 'params.interpolator.set( [', + '{ pos: 0, color: [ i1[ 0 ] ] },', + '{ pos: 1, color: [ i2[ 0 ] ] }', + '] );', + + 'value += params.interpolator.getColorAt( dy )[ 0 ] * amp;', '}', - '} else color = params.srcTex.getPixelNearest( texX, texY );', - ].join( '\n' ); + + 'freq *= params.step;', + 'amp *= params.persistence;', + '}', + + 'color[ 0 ] = value;', + 'color[ 1 ] = value;', + 'color[ 2 ] = value;', + ].join('\n'); } } ); }; -// Filters - -TG.SineDistort = function () { +TG.CellularNoise = function () { var params = { - sines: [ 4, 4 ], - offset: [ 0, 0 ], - amplitude: [ 16, 16 ] + seed: Date.now(), + density: 32, + weightRange: 0 }; return new TG.Program( { - sines: function ( x, y ) { - params.sines = [ x, y ]; + seed: function ( value ) { + params.seed = value; return this; }, - offset: function ( x, y ) { - params.offset = [ x, y ]; + density: function ( value ) { + params.density = value; return this; }, - amplitude: function ( x, y ) { - params.amplitude = [ x, y ]; + weightRange: function ( value ) { + params.weightRange = Math.max( 0, value ); return this; }, getParams: function () { @@ -771,34 +719,39 @@ TG.SineDistort = function () { }, getSource: function () { return [ - 'var s = Math.sin( params.sines[ 0 ] / 100 * y + params.offset[ 0 ] ) * params.amplitude[ 0 ] + x;', - 'var t = Math.sin( params.sines[ 1 ] / 100 * x + params.offset[ 1 ] ) * params.amplitude[ 1 ] + y;', - 'color.set( src.getPixelBilinear( s, t ) );', - ].join( '\n' ); + 'var p = TG.Utils.cellNoiseBase( x, y, params.seed, params.density, params.weightRange );', + + 'var value = 1 - ( p.dist / params.density );', + 'if ( params.density < 0 ) value -= 1;', + + 'color[ 0 ] = value;', + 'color[ 1 ] = value;', + 'color[ 2 ] = value;' + ].join('\n'); } } ); }; -TG.Twirl = function () { +TG.VoronoiNoise = function () { var params = { - strength: 0, - radius: 120, - position: [ 128, 128 ] + seed: Date.now(), + density: 32, + weightRange: 0 }; return new TG.Program( { - strength: function ( value ) { - params.strength = value / 100.0; + seed: function ( value ) { + params.seed = value; return this; }, - radius: function ( value ) { - params.radius = value; + density: function ( value ) { + params.density = value; return this; }, - position: function ( x, y ) { - params.position = [ x, y ]; + weightRange: function ( value ) { + params.weightRange = Math.max( 0, value ); return this; }, getParams: function () { @@ -806,79 +759,127 @@ TG.Twirl = function () { }, getSource: function () { return [ - 'var dist = TG.Utils.distance( x, y, params.position[ 0 ], params.position[ 1 ] );', - - // no distortion if outside of whirl radius. - 'if (dist < params.radius) {', - 'dist = Math.pow(params.radius - dist, 2) / params.radius;', - - 'var angle = 2.0 * Math.PI * (dist / (params.radius / params.strength));', - 'var s = (((x - params.position[ 0 ]) * Math.cos(angle)) - ((y - params.position[ 0 ]) * Math.sin(angle)) + params.position[ 0 ] + 0.5);', - 'var t = (((y - params.position[ 1 ]) * Math.cos(angle)) + ((x - params.position[ 1 ]) * Math.sin(angle)) + params.position[ 1 ] + 0.5);', - '} else {', - 'var s = x;', - 'var t = y;', - '}', + 'var p = TG.Utils.cellNoiseBase( x, y, params.seed, params.density, params.weightRange );', - 'color.set( src.getPixelBilinear( s, t ) );', - ].join( '\n' ); + 'color[ 0 ] = p.value;', + 'color[ 1 ] = p.value;', + 'color[ 2 ] = p.value;' + ].join('\n'); } } ); }; -TG.Transform = function () { +TG.CellularFractal = function () { var params = { - offset: [ 0, 0 ], - angle: 0, - scale: [ 1, 1 ] + seed: Date.now(), + weightRange: 0, + baseDensity: 64, + amplitude: 0.7, + persistence: 0.45, + octaves: 4, + step: 2 }; return new TG.Program( { - offset: function ( x, y ) { - params.offset = [ x, y ]; - return this; - }, - angle: function ( value ) { - params.angle = TG.Utils.deg2rad( value ); - return this; - }, - scale: function ( x, y ) { - if ( x === 0 || y === 0 ) return; - params.scale = [ x, y ]; - return this; - }, - getParams: function () { - return params; - }, - getSource: function () { - return [ - 'var x2 = x - width / 2;', - 'var y2 = y - height / 2;', + seed: function ( value ) { + params.seed = value; + return this; + }, + baseDensity: function ( value ) { + params.baseDensity = value; + return this; + }, + weightRange: function ( value ) { + params.weightRange = Math.max( 0, value ); + return this; + }, + amplitude: function ( value ) { + params.amplitude = value; + return this; + }, + persistence: function ( value ) { + params.persistence = value; + return this; + }, + octaves: function ( value ) { + params.octaves = Math.max( 1, value ); + return this; + }, + step: function ( value ) { + params.step = Math.max( 1, value ); + return this; + }, + getParams: function () { + return params; + }, + getSource: function () { + return [ + 'var p;', + 'var value = 0;', + 'var amp = params.amplitude;', + 'var dens = params.baseDensity;', - 'var s = x2 * ( Math.cos( params.angle ) / params.scale[ 0 ] ) + y2 * -( Math.sin( params.angle ) / params.scale[ 0 ] );', - 'var t = x2 * ( Math.sin( params.angle ) / params.scale[ 1 ] ) + y2 * ( Math.cos( params.angle ) / params.scale[ 1 ] );', + 'for ( var j = 1; j <= params.octaves; j++ ) {', + 'p = TG.Utils.cellNoiseBase( x, y, params.seed * j, dens, params.weightRange );', - 's += params.offset[ 0 ] + width / 2;', - 't += params.offset[ 1 ] + height / 2;', + 'p.dist = 1 - ( p.dist / dens );', + 'if ( dens < 0 ) p.dist -= 1;', - 'color.set( src.getPixelBilinear( s, t ) );', - ].join( '\n' ); - } + 'value += p.dist * amp;', + 'dens /= params.step;', + 'amp *= params.persistence;', + '}', + + 'color[ 0 ] = value;', + 'color[ 1 ] = value;', + 'color[ 2 ] = value;', + ].join('\n'); + } } ); }; -TG.Pixelate = function () { +TG.VoronoiFractal = function () { var params = { - size: [ 1, 1 ] + seed: Date.now(), + weightRange: 0, + baseDensity: 64, + amplitude: 0.6, + persistence: 0.6, + octaves: 4, + step: 2 }; return new TG.Program( { - size: function ( x, y ) { - params.size = [ x, y ]; + seed: function ( value ) { + params.seed = value; + return this; + }, + baseDensity: function ( value ) { + params.baseDensity = value; + return this; + }, + weightRange: function ( value ) { + params.weightRange = Math.max( 0, value ); + return this; + }, + amplitude: function ( value ) { + params.amplitude = value; + return this; + }, + persistence: function ( value ) { + params.persistence = value; + return this; + }, + octaves: function ( value ) { + params.octaves = Math.max( 1, value ); + return this; + }, + step: function ( value ) { + params.step = Math.max( 1, value ); return this; }, getParams: function () { @@ -886,33 +887,47 @@ TG.Pixelate = function () { }, getSource: function () { return [ - 'var s = params.size[ 0 ] * Math.floor(x/params.size[ 0 ]);', - 'var t = params.size[ 1 ] * Math.floor(y/params.size[ 1 ]);', + 'var p;', + 'var value = 0;', + 'var amp = params.amplitude;', + 'var dens = params.baseDensity;', - 'color.set( src.getPixelNearest( s, t ) );' - ].join( '\n' ); + 'for ( var j = 1; j <= params.octaves; j++ ) {', + 'p = TG.Utils.cellNoiseBase( x, y, params.seed * j, dens, params.weightRange );', + + 'value += p.value * amp;', + 'dens /= params.step;', + 'amp *= params.persistence;', + '}', + + 'color[ 0 ] = value;', + 'color[ 1 ] = value;', + 'color[ 2 ] = value;', + ].join('\n'); } } ); }; -TG.GradientMap = function () { +TG.CheckerBoard = function () { var params = { - gradient: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.LINEAR ) + size: [ 32, 32 ], + offset: [ 0, 0 ], + rowShift: 0 }; return new TG.Program( { - repeat: function ( value ) { - params.gradient.setRepeat( value ); + size: function ( x, y ) { + params.size = [ x, y ]; return this; }, - interpolation: function ( value ) { - params.gradient.setInterpolation( value ); + offset: function ( x, y ) { + params.offset = [ x, y ]; return this; }, - point: function ( position, color ) { - params.gradient.addPoint( position, color ); + rowShift: function ( value ) { + params.rowShift = value; return this; }, getParams: function () { @@ -920,67 +935,66 @@ TG.GradientMap = function () { }, getSource: function () { return [ - 'var v = src.getPixelNearest( x, y );', - - 'var r = params.gradient.getColorAt( v[ 0 ] )[ 0 ];', - 'var g = params.gradient.getColorAt( v[ 1 ] )[ 1 ];', - 'var b = params.gradient.getColorAt( v[ 2 ] )[ 2 ];', - - 'color[ 0 ] = r;', - 'color[ 1 ] = g;', - 'color[ 2 ] = b;' + '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', + 'color[ 0 ] = value;', + 'color[ 1 ] = value;', + 'color[ 2 ] = value;' ].join('\n'); } } ); + }; -TG.Normalize = function () { +TG.Rect = function () { var params = { - multiplier: 0, - offset: 0 + position: [ 0, 0 ], + size: [ 32, 32 ] }; return new TG.Program( { + position: function ( x, y ) { + params.position = [ x, y ]; + return this; + }, + size: function ( x, y ) { + params.size = [ x, y ]; + return this; + }, getParams: function () { return params; }, getSource: function () { return [ - 'if ( !params.init ) {', - 'var high = -Infinity;', - 'var low = Infinity;', - - 'for ( var j = 0, len = src.array.length; j < len; j++ ) {', - 'if ( j % 4 == 3 ) continue;', - - 'high = ( src.array[ j ] > high ) ? src.array[ j ] : high;', - 'low = ( src.array[ j ] < low ) ? src.array[ j ] : low;', - '}', - - 'params.offset = -low;', - 'params.multiplier = 1 / ( high - low );', - 'params.init = true;', - '}', - - 'var v = src.getPixelNearest( x, y );', - 'color[ 0 ] = ( v[ 0 ] + params.offset ) * params.multiplier;', - 'color[ 1 ] = ( v[ 1 ] + params.offset ) * params.multiplier;', - 'color[ 2 ] = ( v[ 2 ] + params.offset ) * params.multiplier;' - ].join( '\n' ); + '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;', + 'color[ 0 ] = value;', + 'color[ 1 ] = value;', + 'color[ 2 ] = value;' + ].join('\n'); } } ); + }; -TG.Posterize = function () { +TG.Circle = function () { var params = { - step: 2 + position: [ 0, 0 ], + radius: 50, + delta: 1 }; return new TG.Program( { - step: function ( value ) { - params.step = Math.max( value, 2 ) + delta: function ( value ) { + params.delta = value; + return this; + }, + position: function ( x, y ) { + params.position = [ x, y ]; + return this; + }, + radius: function ( value ) { + params.radius = value; return this; }, getParams: function () { @@ -988,281 +1002,306 @@ TG.Posterize = function () { }, getSource: function () { return [ - 'var v = src.getPixelNearest( x, y );', - 'color[ 0 ] = Math.floor( Math.floor( v[ 0 ] * 255 / ( 255 / params.step ) ) * 255 / ( params.step - 1 ) ) / 255;', - 'color[ 1 ] = Math.floor( Math.floor( v[ 1 ] * 255 / ( 255 / params.step ) ) * 255 / ( params.step - 1 ) ) / 255;', - 'color[ 2 ] = Math.floor( Math.floor( v[ 2 ] * 255 / ( 255 / params.step ) ) * 255 / ( params.step - 1 ) ) / 255;' - ].join( '\n' ); + 'var dist = TG.Utils.distance( x, y, params.position[ 0 ], params.position[ 1 ] );', + 'var value = 1 - TG.Utils.smoothStep( params.radius - params.delta, params.radius, dist );', + 'color[ 0 ] = value;', + 'color[ 1 ] = value;', + 'color[ 2 ] = value;' + ].join('\n'); } } ); }; -// Buffer - -TG.Buffer = function ( width, height ) { - - this.width = width; - this.height = height; - - this.array = new Float32Array( width * height * 4 ); - this.color = new Float32Array( 4 ); - -}; - -TG.Buffer.prototype = { - - constructor: TG.Buffer, - - copy: function ( buffer ) { - - this.array.set( buffer.array ); - - }, - - getPixelNearest: function ( x, y ) { - - if ( y >= this.height ) y -= this.height; - if ( y < 0 ) y += this.height; - if ( x >= this.width ) x -= this.width; - if ( x < 0 ) x += this.width; - - var array = this.array; - var color = this.color; - var offset = Math.round( y ) * this.width * 4 + Math.round( x ) * 4; +TG.PutTexture = function ( texture ) { - color[ 0 ] = array[ offset ]; - color[ 1 ] = array[ offset + 1 ]; - color[ 2 ] = array[ offset + 2 ]; + var params = { + offset: [ 0, 0 ], + repeat: false, + srcTex: texture.buffer + }; - return this.color; + return new TG.Program( { + offset: function ( x, y ) { + params.offset = [ x, y ]; + return this; + }, + repeat: function ( value ) { + params.repeat = value; + return this; + }, + getParams: function () { + return params; + }, + getSource: function () { + return [ + 'var texWidth = params.srcTex.width;', + 'var texHeight = params.srcTex.height;', - }, + 'var texX = Math.floor( x - params.offset[ 0 ] );', + 'var texY = Math.floor( y - params.offset[ 1 ] );', - getPixelBilinear: function ( x, y ) { + 'if ( texX >= texWidth || texY >= texHeight || texX < 0 || texY < 0 ) {', + 'if ( params.repeat ) {', + 'var nx, ny;', + 'var rangeX = texWidth - 1;', + 'var rangeY = texHeight - 1;', - var px = Math.floor( x ); - var py = Math.floor( y ); - var p0 = px + py * this.width; + 'if ( params.repeat == 1 ) {', + 'nx = TG.Utils.wrap( texX, 0, texWidth );', + 'ny = TG.Utils.wrap( texY, 0, texHeight );', + '} else if ( params.repeat == 2 ) {', + 'nx = TG.Utils.mirroredWrap( texX, 0, rangeX );', + 'ny = TG.Utils.mirroredWrap( texY, 0, rangeY );', + '} else if ( params.repeat == 3 ) {', + 'nx = TG.Utils.clamp( texX, 0, rangeX );', + 'ny = TG.Utils.clamp( texY, 0, rangeY );', + '}', - var array = this.array; - var color = this.color; + 'color = params.srcTex.getPixelNearest( nx, ny );', + '} else {', + 'color[ 0 ] = 0;', + 'color[ 1 ] = 0;', + 'color[ 2 ] = 0;', + '}', + '} else color = params.srcTex.getPixelNearest( texX, texY );', + ].join( '\n' ); + } + } ); - // Calculate the weights for each pixel - var fx = x - px; - var fy = y - py; - var fx1 = 1 - fx; - var fy1 = 1 - fy; +}; - var w1 = fx1 * fy1; - var w2 = fx * fy1; - var w3 = fx1 * fy ; - var w4 = fx * fy ; +TG.RadialGradient = function () { - var p1 = p0 * 4; // 0 + 0 * w - var p2 = ( 1 + p0 ) * 4; // 1 + 0 * w - var p3 = ( 1 * this.width + p0 ) * 4; // 0 + 1 * w - var p4 = ( 1 + 1 * this.width + p0 ) * 4; // 1 + 1 * w + var params = { + gradient: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.LINEAR ), + radius: 255, + center: [ 128, 128 ], + }; - var len = this.width * this.height * 4; + return new TG.Program( { + repeat: function ( value ) { + params.gradient.setRepeat( value ); + return this; + }, + radius: function ( value ) { + params.radius = value; + return this; + }, + interpolation: function ( value ) { + params.gradient.setInterpolation( value ); + return this; + }, + center: function ( x, y ) { + params.center = [ x, y ]; + return this; + }, + point: function ( position, color ) { + params.gradient.addPoint( position, color ); + return this; + }, + getParams: function () { + return params; + }, + getSource: function () { + return [ - if ( p1 >= len ) p1 -= len; - if ( p1 < 0 ) p1 += len; - if ( p2 >= len ) p2 -= len; - if ( p2 < 0 ) p2 += len; - if ( p3 >= len ) p3 -= len; - if ( p3 < 0 ) p3 += len; - if ( p4 >= len ) p4 -= len; - if ( p4 < 0 ) p4 += len; + 'var dist = TG.Utils.distance( x, y, params.center[ 0 ], params.center[ 1 ] );', + 'color = params.gradient.getColorAt( dist / params.radius );', - // Calculate the weighted sum of pixels (for each color channel) - color[ 0 ] = array[ p1 + 0 ] * w1 + array[ p2 + 0 ] * w2 + array[ p3 + 0 ] * w3 + array[ p4 + 0 ] * w4; - color[ 1 ] = array[ p1 + 1 ] * w1 + array[ p2 + 1 ] * w2 + array[ p3 + 1 ] * w3 + array[ p4 + 1 ] * w4; - color[ 2 ] = array[ p1 + 2 ] * w1 + array[ p2 + 2 ] * w2 + array[ p3 + 2 ] * w3 + array[ p4 + 2 ] * w4; - color[ 3 ] = array[ p1 + 3 ] * w1 + array[ p2 + 3 ] * w2 + array[ p3 + 3 ] * w3 + array[ p4 + 3 ] * w4; + ].join('\n'); + } + } ); - return this.color; - }, +}; - getPixelOffset: function ( offset ) { +TG.LinearGradient = function () { - var array = this.array; - var color = this.color; + var params = { + gradient: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.LINEAR ) + }; - offset = parseInt( offset * 4 ); + return new TG.Program( { + repeat: function ( value ) { + params.gradient.setRepeat( value ); + return this; + }, + interpolation: function ( value ) { + params.gradient.setInterpolation( value ); + return this; + }, + point: function ( position, color ) { + params.gradient.addPoint( position, color ); + return this; + }, + getParams: function () { + return params; + }, + getSource: function () { + return [ - color[ 0 ] = array[ offset ]; - color[ 1 ] = array[ offset + 1 ]; - color[ 2 ] = array[ offset + 2 ]; - color[ 3 ] = array[ offset + 3 ]; + 'color = params.gradient.getColorAt( x / width );', - return this.color; - }, + ].join('\n'); + } + } ); }; -// +// --- Filters --- -TG.ColorInterpolatorMethod = { - STEP: 0, - LINEAR: 1, - SPLINE: 2, -}; +TG.SineDistort = function () { -// points must be a set pair (point, color): -// [{ pos-n: [r,g,b,a] } , ..., { pos-N: [r,g,b,a] } ] -TG.ColorInterpolator = function( method ) { + var params = { + sines: [ 4, 4 ], + offset: [ 0, 0 ], + amplitude: [ 16, 16 ] + }; - this.points = []; - this.low = 0; - this.high = 0; - this.interpolation = ( typeof( method ) == 'undefined' ) ? TG.ColorInterpolatorMethod.LINEAR : method; - this.repeat = false; + return new TG.Program( { + sines: function ( x, y ) { + params.sines = [ x, y ]; + return this; + }, + offset: function ( x, y ) { + params.offset = [ x, y ]; + return this; + }, + amplitude: function ( x, y ) { + params.amplitude = [ x, y ]; + return this; + }, + getParams: function () { + return params; + }, + getSource: function () { + return [ + 'var s = Math.sin( params.sines[ 0 ] / 100 * y + params.offset[ 0 ] ) * params.amplitude[ 0 ] + x;', + 'var t = Math.sin( params.sines[ 1 ] / 100 * x + params.offset[ 1 ] ) * params.amplitude[ 1 ] + y;', + 'color.set( src.getPixelBilinear( s, t ) );', + ].join( '\n' ); + } + } ); - return this; }; -TG.ColorInterpolator.prototype = { - - set: function ( points ) { - - this.points = points; - this.points.sort( function( a, b ) { - return a.pos - b.pos; - }); - - this.low = this.points[ 0 ].pos; - this.high = this.points[ this.points.length - 1 ].pos; - - return this; - - }, - - addPoint: function ( position, color ) { - - this.points.push( { pos: position, color: color } ); - this.points.sort( function( a, b ) { - return a.pos - b.pos; - }); - - this.low = this.points[ 0 ].pos; - this.high = this.points[ this.points.length - 1 ].pos; - - return this; - - }, - - setRepeat: function ( value ) { - - this.repeat = value; - return this; - - }, - - setInterpolation: function ( value ) { - - this.interpolation = value; - return this; - - }, - - getColorAt: function ( pos ) { - - if ( this.repeat == 2 ) pos = TG.Utils.mirroredWrap( pos, this.low, this.high ); - else if ( this.repeat ) pos = TG.Utils.wrap( pos, this.low, this.high ); - else pos = TG.Utils.clamp( pos, this.low, this.high ); - - var i = 0, points = this.points; - - while ( points[ i + 1 ].pos < pos ) i ++; - - var p1 = points[ i ]; - var p2 = points[ i + 1 ]; - - var delta = ( pos - p1.pos ) / ( p2.pos - p1.pos ); +TG.Twirl = function () { - if ( this.interpolation == TG.ColorInterpolatorMethod.STEP ) { + var params = { + strength: 0, + radius: 120, + position: [ 128, 128 ] + }; - return p1.color; + return new TG.Program( { + strength: function ( value ) { + params.strength = value / 100.0; + return this; + }, + radius: function ( value ) { + params.radius = value; + return this; + }, + position: function ( x, y ) { + params.position = [ x, y ]; + return this; + }, + getParams: function () { + return params; + }, + getSource: function () { + return [ + 'var dist = TG.Utils.distance( x, y, params.position[ 0 ], params.position[ 1 ] );', - } else if ( this.interpolation == TG.ColorInterpolatorMethod.LINEAR ) { + // no distortion if outside of whirl radius. + 'if (dist < params.radius) {', + 'dist = Math.pow(params.radius - dist, 2) / params.radius;', - return TG.Utils.mixColors( p1.color, p2.color, delta ); + 'var angle = 2.0 * Math.PI * (dist / (params.radius / params.strength));', + 'var s = (((x - params.position[ 0 ]) * Math.cos(angle)) - ((y - params.position[ 0 ]) * Math.sin(angle)) + params.position[ 0 ] + 0.5);', + 'var t = (((y - params.position[ 1 ]) * Math.cos(angle)) + ((x - params.position[ 1 ]) * Math.sin(angle)) + params.position[ 1 ] + 0.5);', + '} else {', + 'var s = x;', + 'var t = y;', + '}', - } else if ( this.interpolation == TG.ColorInterpolatorMethod.SPLINE ) { + 'color.set( src.getPixelBilinear( s, t ) );', + ].join( '\n' ); + } + } ); - var ar = 2 * p1.color[ 0 ] - 2 * p2.color[ 0 ]; - var br = -3 * p1.color[ 0 ] + 3 * p2.color[ 0 ]; - var dr = p1.color[ 0 ]; +}; - var ag = 2 * p1.color[ 1 ] - 2 * p2.color[ 1 ]; - var bg = -3 * p1.color[ 1 ] + 3 * p2.color[ 1 ]; - var dg = p1.color[ 1 ]; +TG.Transform = function () { - var ab = 2 * p1.color[ 2 ] - 2 * p2.color[ 2 ]; - var bb = -3 * p1.color[ 2 ] + 3 * p2.color[ 2 ]; - var db = p1.color[ 2 ]; + var params = { + offset: [ 0, 0 ], + angle: 0, + scale: [ 1, 1 ] + }; - var delta2 = delta * delta; - var delta3 = delta2 * delta; + return new TG.Program( { + offset: function ( x, y ) { + params.offset = [ x, y ]; + return this; + }, + angle: function ( value ) { + params.angle = TG.Utils.deg2rad( value ); + return this; + }, + scale: function ( x, y ) { + if ( x === 0 || y === 0 ) return; + params.scale = [ x, y ]; + return this; + }, + getParams: function () { + return params; + }, + getSource: function () { + return [ + 'var x2 = x - width / 2;', + 'var y2 = y - height / 2;', - return [ - ar * delta3 + br * delta2 + dr, - ag * delta3 + bg * delta2 + dg, - ab * delta3 + bb * delta2 + db - ]; + 'var s = x2 * ( Math.cos( params.angle ) / params.scale[ 0 ] ) + y2 * -( Math.sin( params.angle ) / params.scale[ 0 ] );', + 'var t = x2 * ( Math.sin( params.angle ) / params.scale[ 1 ] ) + y2 * ( Math.cos( params.angle ) / params.scale[ 1 ] );', - } + 's += params.offset[ 0 ] + width / 2;', + 't += params.offset[ 1 ] + height / 2;', - } + 'color.set( src.getPixelBilinear( s, t ) );', + ].join( '\n' ); + } + } ); }; -TG.RadialGradient = function () { +TG.Pixelate = function () { var params = { - gradient: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.LINEAR ), - radius: 255, - center: [ 128, 128 ], + size: [ 1, 1 ] }; return new TG.Program( { - repeat: function ( value ) { - params.gradient.setRepeat( value ); - return this; - }, - radius: function ( value ) { - params.radius = value; - return this; - }, - interpolation: function ( value ) { - params.gradient.setInterpolation( value ); - return this; - }, - center: function ( x, y ) { - params.center = [ x, y ]; + size: function ( x, y ) { + params.size = [ x, y ]; return this; }, getParams: function () { return params; }, - point: function ( position, color ) { - params.gradient.addPoint( position, color ); - return this; - }, getSource: function () { return [ + 'var s = params.size[ 0 ] * Math.floor(x/params.size[ 0 ]);', + 'var t = params.size[ 1 ] * Math.floor(y/params.size[ 1 ]);', - 'var dist = TG.Utils.distance( x, y, params.center[ 0 ], params.center[ 1 ] );', - 'color = params.gradient.getColorAt( dist / params.radius );', - - ].join('\n'); + 'color.set( src.getPixelNearest( s, t ) );' + ].join( '\n' ); } } ); }; -TG.LinearGradient = function () { +TG.GradientMap = function () { var params = { gradient: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.LINEAR ) @@ -1277,133 +1316,90 @@ TG.LinearGradient = function () { params.gradient.setInterpolation( value ); return this; }, - getParams: function () { - return params; - }, point: function ( position, color ) { params.gradient.addPoint( position, color ); return this; }, + getParams: function () { + return params; + }, getSource: function () { return [ + 'var v = src.getPixelNearest( x, y );', - 'color = params.gradient.getColorAt( x / width );', + 'var r = params.gradient.getColorAt( v[ 0 ] )[ 0 ];', + 'var g = params.gradient.getColorAt( v[ 1 ] )[ 1 ];', + 'var b = params.gradient.getColorAt( v[ 2 ] )[ 2 ];', + 'color[ 0 ] = r;', + 'color[ 1 ] = g;', + 'color[ 2 ] = b;' ].join('\n'); } } ); - }; +TG.Normalize = function () { -// - -TG.Utils = { - - smoothStep: function ( edge0, edge1, x ) { - - // Scale, bias and saturate x to 0..1 range - x = TG.Utils.clamp( ( x - edge0 ) / ( edge1 - edge0 ), 0, 1 ); - - // Evaluate polynomial - return x * x * ( 3 - 2 * x ); - - }, - - mixColors: function( c1, c2, delta ) { - - return [ - c1[ 0 ] * ( 1 - delta ) + c2[ 0 ] * delta, - c1[ 1 ] * ( 1 - delta ) + c2[ 1 ] * delta, - c1[ 2 ] * ( 1 - delta ) + c2[ 2 ] * delta, - c1[ 3 ] * ( 1 - delta ) + c2[ 3 ] * delta, - ]; - }, - - distance: function( x0, y0, x1, y1 ) { - - var dx = x1 - x0, dy = y1 - y0; - return Math.sqrt( dx * dx + dy * dy ); - - }, - - clamp: function( value, min, max ) { - - return Math.min( Math.max( value, min ), max ); + var params = { + multiplier: 0, + offset: 0 + }; - }, - - wrap: function ( value, min, max ) { - var v = value - min; - var r = max - min; + return new TG.Program( { + getParams: function () { + return params; + }, + getSource: function () { + return [ + 'if ( !params.init ) {', + 'var high = -Infinity;', + 'var low = Infinity;', - return ( ( r + v % r ) % r ) + min; - }, + 'for ( var j = 0, len = src.array.length; j < len; j++ ) {', + 'if ( j % 4 == 3 ) continue;', - mirroredWrap: function ( value, min, max ) { - var v = value - min; - var r = ( max - min ) * 2; + 'high = ( src.array[ j ] > high ) ? src.array[ j ] : high;', + 'low = ( src.array[ j ] < low ) ? src.array[ j ] : low;', + '}', - v = ( r + v % r ) % r; + 'params.offset = -low;', + 'params.multiplier = 1 / ( high - low );', + 'params.init = true;', + '}', - if ( v > max - min ) { - return ( r - v ) + min; - } else { - return v + min; + 'var v = src.getPixelNearest( x, y );', + 'color[ 0 ] = ( v[ 0 ] + params.offset ) * params.multiplier;', + 'color[ 1 ] = ( v[ 1 ] + params.offset ) * params.multiplier;', + 'color[ 2 ] = ( v[ 2 ] + params.offset ) * params.multiplier;' + ].join( '\n' ); } - }, - - deg2rad: function ( deg ) { - - return deg * Math.PI / 180; - - }, - - hashRNG: function ( seed, x, y ) { - seed = ( Math.abs( seed % 2147483648 ) == 0 ) ? 1 : seed; - - var a = ( ( seed * ( x + 1 ) * 777 ) ^ ( seed * ( y + 1 ) * 123 ) ) % 2147483647; - a = (a ^ 61) ^ (a >> 16); - a = a + (a << 3); - a = a ^ (a >> 4); - a = a * 0x27d4eb2d; - a = a ^ (a >> 15); - a = a / 2147483647; - - return a; - }, - - cellNoiseBase: function ( x, y, seed, density, weightRange ) { - var qx, qy, rx, ry, w, px, py, dx, dy; - var dist, value; - var shortest = Infinity; - density = Math.abs( density ); - - for ( var sx = -2; sx <= 2; sx++ ) { - for ( var sy = -2; sy <= 2; sy++ ) { - qx = Math.ceil( x / density ) + sx; - qy = Math.ceil( y / density ) + sy; - - rx = TG.Utils.hashRNG( seed, qx, qy ); - ry = TG.Utils.hashRNG( seed * 2, qx, qy ); - w = ( weightRange > 0 ) ? 1 + TG.Utils.hashRNG( seed * 3, qx, qy ) * weightRange : 1; - - px = ( rx + qx ) * density; - py = ( ry + qy ) * density; + } ); +}; - dx = Math.abs( px - x ); - dy = Math.abs( py - y ); +TG.Posterize = function () { - dist = ( dx * dx + dy * dy ) * w; + var params = { + step: 2 + }; - if ( dist < shortest ) { - shortest = dist; - value = rx; - } - } + return new TG.Program( { + step: function ( value ) { + params.step = Math.max( value, 2 ) + return this; + }, + getParams: function () { + return params; + }, + getSource: function () { + return [ + 'var v = src.getPixelNearest( x, y );', + 'color[ 0 ] = Math.floor( Math.floor( v[ 0 ] * 255 / ( 255 / params.step ) ) * 255 / ( params.step - 1 ) ) / 255;', + 'color[ 1 ] = Math.floor( Math.floor( v[ 1 ] * 255 / ( 255 / params.step ) ) * 255 / ( params.step - 1 ) ) / 255;', + 'color[ 2 ] = Math.floor( Math.floor( v[ 2 ] * 255 / ( 255 / params.step ) ) * 255 / ( params.step - 1 ) ) / 255;' + ].join( '\n' ); } - - return { dist: Math.sqrt( shortest ), value: value }; - } + } ); }; + From eafe9d9d1bc57968be7495445a31c92f441805ef Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sat, 22 Apr 2017 21:56:19 +0200 Subject: [PATCH 02/12] Add pow operation --- src/TexGen.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/TexGen.js b/src/TexGen.js index 39382fc..c921e8c 100644 --- a/src/TexGen.js +++ b/src/TexGen.js @@ -341,7 +341,8 @@ TG.OP = { AND: function ( x, y ) { return x & y; }, XOR: function ( x, y ) { return x ^ y; }, MIN: function ( x, y ) { return Math.min( x, y ); }, - MAX: function ( x, y ) { return Math.max( x, y ); } + MAX: function ( x, y ) { return Math.max( x, y ); }, + POW: function ( x, y ) { return Math.pow( x, y ); } }; TG.Texture = function ( width, height ) { @@ -398,6 +399,8 @@ TG.Texture.prototype = { max: function ( program ) { return this.set( program, TG.OP.MAX ); }, + pow: function ( program ) { return this.set( program, TG.OP.POW ); }, + toImageData: function ( context ) { var buffer = this.buffer; From eba5d7078bd16bc27a79159279776f0cf969f58b Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sat, 22 Apr 2017 22:22:19 +0200 Subject: [PATCH 03/12] Add size parameter to TG.Noise and use a global default seed --- src/TexGen.js | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/TexGen.js b/src/TexGen.js index c921e8c..a5224e1 100644 --- a/src/TexGen.js +++ b/src/TexGen.js @@ -8,6 +8,8 @@ var TG = {}; TG.Utils = { + globalSeed: Date.now(), // used as a somewhat random seed, increased on each use so that each default seed is different + smoothStep: function ( edge0, edge1, x ) { // Scale, bias and saturate x to 0..1 range @@ -68,15 +70,15 @@ TG.Utils = { }, hashRNG: function ( seed, x, y ) { - seed = ( Math.abs( seed % 2147483648 ) == 0 ) ? 1 : seed; + seed = Math.abs(seed % 0x7FFFFFFF) + 1; - var a = ( ( seed * ( x + 1 ) * 777 ) ^ ( seed * ( y + 1 ) * 123 ) ) % 2147483647; + var a = ( seed * ( ( x ^ seed * 777 ) || 556 ) * ( ( y ^ seed * 314 ) || 989 ) + seed * 123 ) % 0x7FFFFFFF; a = (a ^ 61) ^ (a >> 16); a = a + (a << 3); a = a ^ (a >> 4); a = a * 0x27d4eb2d; a = a ^ (a >> 15); - a = a / 2147483647; + a = a / 0x7FFFFFFF; return a; }, @@ -572,7 +574,8 @@ TG.XOR = function () { TG.Noise = function () { var params = { - seed: Date.now() + seed: TG.Utils.globalSeed++, + size: 1 }; return new TG.Program( { @@ -580,12 +583,16 @@ TG.Noise = function () { params.seed = value; return this; }, + size: function ( value ) { + params.size = value; + return this; + }, getParams: function () { return params; }, getSource: function () { return [ - 'var value = TG.Utils.hashRNG( params.seed, x, y );', + 'var value = TG.Utils.hashRNG( params.seed, Math.floor( x / params.size ), Math.floor( y / params.size ) );', 'color[ 0 ] = value;', 'color[ 1 ] = value;', 'color[ 2 ] = value;' @@ -599,7 +606,7 @@ TG.FractalNoise = function () { var params = { interpolator: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.STEP ), - seed: Date.now(), + seed: TG.Utils.globalSeed++, baseFrequency: 0.03125, amplitude: 0.4, persistence: 0.72, @@ -699,7 +706,7 @@ TG.FractalNoise = function () { TG.CellularNoise = function () { var params = { - seed: Date.now(), + seed: TG.Utils.globalSeed++, density: 32, weightRange: 0 }; @@ -739,7 +746,7 @@ TG.CellularNoise = function () { TG.VoronoiNoise = function () { var params = { - seed: Date.now(), + seed: TG.Utils.globalSeed++, density: 32, weightRange: 0 }; @@ -776,7 +783,7 @@ TG.VoronoiNoise = function () { TG.CellularFractal = function () { var params = { - seed: Date.now(), + seed: TG.Utils.globalSeed++, weightRange: 0, baseDensity: 64, amplitude: 0.7, @@ -847,7 +854,7 @@ TG.CellularFractal = function () { TG.VoronoiFractal = function () { var params = { - seed: Date.now(), + seed: TG.Utils.globalSeed++, weightRange: 0, baseDensity: 64, amplitude: 0.6, From a55c367bcc716e1da7f71c38c73a43d09d1bc685 Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sat, 22 Apr 2017 22:32:33 +0200 Subject: [PATCH 04/12] Refactor TG.Normalize and TG.Posterize --- src/TexGen.js | 61 +++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/src/TexGen.js b/src/TexGen.js index a5224e1..6c99e27 100644 --- a/src/TexGen.js +++ b/src/TexGen.js @@ -370,6 +370,7 @@ TG.Texture.prototype = { 'var x = 0, y = 0;', 'var array = dst.array;', 'var width = dst.width, height = dst.height;', + ( typeof program.getInit == 'function' ) ? program.getInit() : '', 'for ( var i = 0, il = array.length; i < il; i += 4 ) {', ' ' + program.getSource(), ' array[ i ] = op( array[ i ], color[ 0 ] * tint[ 0 ] );', @@ -636,7 +637,7 @@ TG.FractalNoise = function () { return this; }, step: function ( value ) { - params.step = Math.max( 1, value ); + params.step = Math.max( 0, value ); return this; }, interpolation: function ( value ) { @@ -673,18 +674,18 @@ TG.FractalNoise = function () { '{ pos: 1, color: [ v2 ] }', '] );', - 'i1 = params.interpolator.getColorAt( dx );', + 'i1 = params.interpolator.getColorAt( dx )[ 0 ];', 'params.interpolator.set( [', '{ pos: 0, color: [ v3 ] },', '{ pos: 1, color: [ v4 ] }', '] );', - 'i2 = params.interpolator.getColorAt( dx );', + 'i2 = params.interpolator.getColorAt( dx )[ 0 ];', 'params.interpolator.set( [', - '{ pos: 0, color: [ i1[ 0 ] ] },', - '{ pos: 1, color: [ i2[ 0 ] ] }', + '{ pos: 0, color: [ i1 ] },', + '{ pos: 1, color: [ i2 ] }', '] );', 'value += params.interpolator.getColorAt( dy )[ 0 ] * amp;', @@ -1351,40 +1352,34 @@ TG.GradientMap = function () { TG.Normalize = function () { - var params = { - multiplier: 0, - offset: 0 - }; - return new TG.Program( { - getParams: function () { - return params; - }, - getSource: function () { + getParams: function () {}, + getInit: function () { return [ - 'if ( !params.init ) {', - 'var high = -Infinity;', - 'var low = Infinity;', - - 'for ( var j = 0, len = src.array.length; j < len; j++ ) {', - 'if ( j % 4 == 3 ) continue;', + 'var high = -Infinity;', + 'var low = Infinity;', - 'high = ( src.array[ j ] > high ) ? src.array[ j ] : high;', - 'low = ( src.array[ j ] < low ) ? src.array[ j ] : low;', - '}', + 'for ( var j = 0, len = src.array.length; j < len; j++ ) {', + 'if ( j % 4 == 3 ) continue;', - 'params.offset = -low;', - 'params.multiplier = 1 / ( high - low );', - 'params.init = true;', + 'high = ( src.array[ j ] > high ) ? src.array[ j ] : high;', + 'low = ( src.array[ j ] < low ) ? src.array[ j ] : low;', '}', + 'var offset = -low;', + 'var multiplier = 1 / ( high - low );', + ].join( '\n' ); + }, + getSource: function () { + return [ 'var v = src.getPixelNearest( x, y );', - 'color[ 0 ] = ( v[ 0 ] + params.offset ) * params.multiplier;', - 'color[ 1 ] = ( v[ 1 ] + params.offset ) * params.multiplier;', - 'color[ 2 ] = ( v[ 2 ] + params.offset ) * params.multiplier;' + 'color[ 0 ] = ( v[ 0 ] + offset ) * multiplier;', + 'color[ 1 ] = ( v[ 1 ] + offset ) * multiplier;', + 'color[ 2 ] = ( v[ 2 ] + offset ) * multiplier;' ].join( '\n' ); } } ); + }; TG.Posterize = function () { @@ -1395,7 +1390,7 @@ TG.Posterize = function () { return new TG.Program( { step: function ( value ) { - params.step = Math.max( value, 2 ) + params.step = Math.max( value, 2 ); return this; }, getParams: function () { @@ -1404,9 +1399,9 @@ TG.Posterize = function () { getSource: function () { return [ 'var v = src.getPixelNearest( x, y );', - 'color[ 0 ] = Math.floor( Math.floor( v[ 0 ] * 255 / ( 255 / params.step ) ) * 255 / ( params.step - 1 ) ) / 255;', - 'color[ 1 ] = Math.floor( Math.floor( v[ 1 ] * 255 / ( 255 / params.step ) ) * 255 / ( params.step - 1 ) ) / 255;', - 'color[ 2 ] = Math.floor( Math.floor( v[ 2 ] * 255 / ( 255 / params.step ) ) * 255 / ( params.step - 1 ) ) / 255;' + 'color[ 0 ] = Math.floor( v[ 0 ] / ( 1 / params.step ) ) / ( params.step - 1 );', + 'color[ 1 ] = Math.floor( v[ 1 ] / ( 1 / params.step ) ) / ( params.step - 1 );', + 'color[ 2 ] = Math.floor( v[ 2 ] / ( 1 / params.step ) ) / ( params.step - 1 );' ].join( '\n' ); } } ); From 14c6e1403d439786153f4a8c9e4321a7f01bdff8 Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sat, 22 Apr 2017 22:46:15 +0200 Subject: [PATCH 05/12] Add cosine interpolation --- src/TexGen.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/TexGen.js b/src/TexGen.js index 6c99e27..948fcb5 100644 --- a/src/TexGen.js +++ b/src/TexGen.js @@ -122,6 +122,7 @@ TG.ColorInterpolatorMethod = { STEP: 0, LINEAR: 1, SPLINE: 2, + COSINE: 3, }; TG.ColorInterpolator = function( method ) { @@ -225,6 +226,15 @@ TG.ColorInterpolator.prototype = { ab * delta3 + bb * delta2 + db ]; + } else if ( this.interpolation == TG.ColorInterpolatorMethod.COSINE ) { + var cos = (1 - Math.cos(delta * Math.PI)) / 2; + + return [ + ( p1.color[ 0 ] * ( 1 - cos ) ) + ( p2.color[ 0 ] * cos ), + ( p1.color[ 1 ] * ( 1 - cos ) ) + ( p2.color[ 1 ] * cos ), + ( p1.color[ 2 ] * ( 1 - cos ) ) + ( p2.color[ 2 ] * cos ), + ]; + } } From 6b8f0ad4a754f5bc8a81f14c422ead84039c7bdf Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sat, 22 Apr 2017 23:27:27 +0200 Subject: [PATCH 06/12] Allow passing rgb individually to new gradient points and copy some arguments for convenience --- src/TexGen.js | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/TexGen.js b/src/TexGen.js index 948fcb5..e3cf4e5 100644 --- a/src/TexGen.js +++ b/src/TexGen.js @@ -152,9 +152,14 @@ TG.ColorInterpolator.prototype = { }, - addPoint: function ( position, color ) { + addPoint: function ( position, r, g, b ) { + if ( Array.isArray( r ) ) { + b = r[ 2 ]; g = r[ 1 ]; r = r[ 0 ]; + } + if ( typeof g == 'undefined' ) g = r; + if ( typeof b == 'undefined' ) b = r; - this.points.push( { pos: position, color: color } ); + this.points.push( { pos: position, color: [ r, g, b ] } ); this.points.sort( function( a, b ) { return a.pos - b.pos; }); @@ -458,8 +463,8 @@ TG.Program = function ( object ) { object.tint = function ( r, g, b ) { tint[ 0 ] = r; - tint[ 1 ] = g; - tint[ 2 ] = b; + tint[ 1 ] = ( typeof g == 'undefined' ) ? r : g; + tint[ 2 ] = ( typeof b == 'undefined' ) ? r : b; return this; }; @@ -940,6 +945,7 @@ TG.CheckerBoard = function () { return new TG.Program( { size: function ( x, y ) { + if ( typeof y == "undefined" ) y = x; params.size = [ x, y ]; return this; }, @@ -979,6 +985,7 @@ TG.Rect = function () { return this; }, size: function ( x, y ) { + if ( typeof y == "undefined" ) y = x; params.size = [ x, y ]; return this; }, @@ -1117,8 +1124,8 @@ TG.RadialGradient = function () { params.center = [ x, y ]; return this; }, - point: function ( position, color ) { - params.gradient.addPoint( position, color ); + point: function ( position, r, g, b ) { + params.gradient.addPoint( position, r, g, b ); return this; }, getParams: function () { @@ -1151,8 +1158,8 @@ TG.LinearGradient = function () { params.gradient.setInterpolation( value ); return this; }, - point: function ( position, color ) { - params.gradient.addPoint( position, color ); + point: function ( position, r, g, b ) { + params.gradient.addPoint( position, r, g, b ); return this; }, getParams: function () { @@ -1181,6 +1188,7 @@ TG.SineDistort = function () { return new TG.Program( { sines: function ( x, y ) { + if ( typeof y == "undefined" ) y = x; params.sines = [ x, y ]; return this; }, @@ -1189,6 +1197,7 @@ TG.SineDistort = function () { return this; }, amplitude: function ( x, y ) { + if ( typeof y == "undefined" ) y = x; params.amplitude = [ x, y ]; return this; }, @@ -1271,7 +1280,9 @@ TG.Transform = function () { return this; }, scale: function ( x, y ) { - if ( x === 0 || y === 0 ) return; + x = x || 1; + y = y || x; + params.scale = [ x, y ]; return this; }, @@ -1304,6 +1315,7 @@ TG.Pixelate = function () { return new TG.Program( { size: function ( x, y ) { + if ( typeof y == "undefined" ) y = x; params.size = [ x, y ]; return this; }, @@ -1337,8 +1349,8 @@ TG.GradientMap = function () { params.gradient.setInterpolation( value ); return this; }, - point: function ( position, color ) { - params.gradient.addPoint( position, color ); + point: function ( position, r, g, b ) { + params.gradient.addPoint( position, r, g, b ); return this; }, getParams: function () { From 293295fc4d3937d1eafe370fc1c5f169d060635a Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sat, 22 Apr 2017 23:31:09 +0200 Subject: [PATCH 07/12] Remove unnecessary extra indentation inside TG.Transform --- src/TexGen.js | 64 +++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/TexGen.js b/src/TexGen.js index e3cf4e5..bbad479 100644 --- a/src/TexGen.js +++ b/src/TexGen.js @@ -1271,38 +1271,38 @@ TG.Transform = function () { }; return new TG.Program( { - offset: function ( x, y ) { - params.offset = [ x, y ]; - return this; - }, - angle: function ( value ) { - params.angle = TG.Utils.deg2rad( value ); - return this; - }, - scale: function ( x, y ) { - x = x || 1; - y = y || x; - - params.scale = [ x, y ]; - return this; - }, - getParams: function () { - return params; - }, - getSource: function () { - return [ - 'var x2 = x - width / 2;', - 'var y2 = y - height / 2;', - - 'var s = x2 * ( Math.cos( params.angle ) / params.scale[ 0 ] ) + y2 * -( Math.sin( params.angle ) / params.scale[ 0 ] );', - 'var t = x2 * ( Math.sin( params.angle ) / params.scale[ 1 ] ) + y2 * ( Math.cos( params.angle ) / params.scale[ 1 ] );', - - 's += params.offset[ 0 ] + width / 2;', - 't += params.offset[ 1 ] + height / 2;', - - 'color.set( src.getPixelBilinear( s, t ) );', - ].join( '\n' ); - } + offset: function ( x, y ) { + params.offset = [ x, y ]; + return this; + }, + angle: function ( value ) { + params.angle = TG.Utils.deg2rad( value ); + return this; + }, + scale: function ( x, y ) { + x = x || 1; + y = y || x; + + params.scale = [ x, y ]; + return this; + }, + getParams: function () { + return params; + }, + getSource: function () { + return [ + 'var x2 = x - width / 2;', + 'var y2 = y - height / 2;', + + 'var s = x2 * ( Math.cos( params.angle ) / params.scale[ 0 ] ) + y2 * -( Math.sin( params.angle ) / params.scale[ 0 ] );', + 'var t = x2 * ( Math.sin( params.angle ) / params.scale[ 1 ] ) + y2 * ( Math.cos( params.angle ) / params.scale[ 1 ] );', + + 's += params.offset[ 0 ] + width / 2;', + 't += params.offset[ 1 ] + height / 2;', + + 'color.set( src.getPixelBilinear( s, t ) );', + ].join( '\n' ); + } } ); }; From d72b8f1aa071e49d75f0f78cd7b54233e710287d Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sat, 22 Apr 2017 23:43:28 +0200 Subject: [PATCH 08/12] Rename TG.Number to TG.Fill --- examples/animated.html | 4 ++-- examples/index.html | 8 ++++---- examples/noise.html | 16 ++++++++-------- src/TexGen.js | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/animated.html b/examples/animated.html index 9363b8e..a82109f 100644 --- a/examples/animated.html +++ b/examples/animated.html @@ -34,7 +34,7 @@ .mul( new TG.SinX().frequency( 0.08-i/2000 ) ) .add( new TG.SinY().frequency( 0.05-i/1000 ) ) .mul( new TG.SinY().frequency( 0.08+i/2000 ) ) - .div( new TG.Number().tint( 1, 2, 1 ) ) + .div( new TG.Fill().tint( 1, 2, 1 ) ) .add( new TG.SinX().frequency( 0.003 ).tint( 0.5, 0, 0 ) ) .toImageData(context); @@ -47,7 +47,7 @@ .add( new TG.SinY().frequency( 0.066 + 0.05*Math.sin(i/100) ) ) .mul( new TG.SinX().offset( 32 ).frequency( 0.044 + 0.09*Math.sin(i/100) ).tint( 2, 2, 2 ) ) .mul( new TG.SinY().offset( 16 ).frequency( 0.044 + 0.09*Math.sin(i/100) ).tint( 2, 2, 2 ) ) - .sub( new TG.Number().tint( 0.5, 2, 4 ) ) + .sub( new TG.Fill().tint( 0.5, 2, 4 ) ) .toImageData(context); context.putImageData( texture, size, 0 ); diff --git a/examples/index.html b/examples/index.html index 8d718f6..12b0314 100644 --- a/examples/index.html +++ b/examples/index.html @@ -82,7 +82,7 @@ var texture = new TG.Texture( size, size ) .add( new TG.SinX().offset( - 16 ).frequency( 0.03 ).tint( 0.1, 0.25, 0.5 ) ) .add( new TG.SinY().offset( - 16 ).frequency( 0.03 ).tint( 0.1, 0.25, 0.5 ) ) - .add( new TG.Number().tint( 0.75, 0.5, 0.5 ) ) + .add( new TG.Fill().tint( 0.75, 0.5, 0.5 ) ) .add( new TG.SinX().frequency( 0.03 ).tint( 0.2, 0.2, 0.2 ) ) .add( new TG.SinY().frequency( 0.03 ).tint( 0.2, 0.2, 0.2 ) ) .add( new TG.Noise().tint( 0.1, 0, 0 ) ) @@ -150,7 +150,7 @@ .mul( new TG.SinX().frequency( 0.08 ) ) .add( new TG.SinY().frequency( 0.05 ) ) .mul( new TG.SinY().frequency( 0.08 ) ) - .div( new TG.Number().tint( 1, 2, 1 ) ) + .div( new TG.Fill().tint( 1, 2, 1 ) ) .add( new TG.SinX().frequency( 0.003 ).tint( 0.5, 0, 0 ) ) .toCanvas(); @@ -166,7 +166,7 @@ .add( new TG.SinY().frequency( 0.066 ) ) .mul( new TG.SinX().offset( 32 ).frequency( 0.044 ).tint( 2, 2, 2 ) ) .mul( new TG.SinY().offset( 16 ).frequency( 0.044 ).tint( 2, 2, 2 ) ) - .sub( new TG.Number().tint( 0.5, 2, 4 ) ) + .sub( new TG.Fill().tint( 0.5, 2, 4 ) ) .toCanvas(); @@ -440,7 +440,7 @@ .point( 0.6, [ 140, 49, 59 ] ) //[ 58, 131, 114 ] .point( 0.8, [ 35, 10, 12 ] ) //[ 4, 46, 27 ] .point( 1, [ 0, 0, 0 ] ) ) - .div( new TG.Number().tint( 255, 255, 255 ) ); // converting the 0-255 defined colors to the 0-1 space + .div( new TG.Fill().tint( 255, 255, 255 ) ); // converting the 0-255 defined colors to the 0-1 space var mirrored = new TG.Texture( size, size ) .add( new TG.PutTexture( pixel ).repeat( 2 ) ) // repeat the texture to get a cool mirrored pattern effect diff --git a/examples/noise.html b/examples/noise.html index 4c63ce6..bd44e54 100644 --- a/examples/noise.html +++ b/examples/noise.html @@ -190,21 +190,21 @@
new TG.Texture(size, size) .set(new TG.FractalNoise().baseFrequency(64).octaves(6).step(2).interpolation(2) ) .sub(new TG.Noise().tint(0, 0.1, 0) ) - .min(new TG.Number().tint(0, 0.6, 0) ) - .sub(new TG.Number().tint(0, 0.5, 0) ) - .mul(new TG.Number().tint(0, 5, 0) ) + .min(new TG.Fill().tint(0, 0.6, 0) ) + .sub(new TG.Fill().tint(0, 0.5, 0) ) + .mul(new TG.Fill().tint(0, 5, 0) ) .sub(new TG.SineDistort().sines(2, 2).amplitude(8, 8).tint(0, 0.75, 0) ) - .add(new TG.Number().tint(0.06, 0, 0.085) ) + .add(new TG.Fill().tint(0.06, 0, 0.085) ) .addToPage("Example 2"); new TG.Texture(size, size) .set(new TG.FractalNoise().baseFrequency(128).octaves(6).step(2).interpolation(2) ) .sub(new TG.Noise().tint(0, 0.1, 0) ) - .min(new TG.Number().tint(0, 0.63, 0) ) - .sub(new TG.Number().tint(0, 0.53, 0) ) - .mul(new TG.Number().tint(0, 6, 0) ) + .min(new TG.Fill().tint(0, 0.63, 0) ) + .sub(new TG.Fill().tint(0, 0.53, 0) ) + .mul(new TG.Fill().tint(0, 6, 0) ) .sub(new TG.SineDistort().sines(2, 2).amplitude(4, 4).tint(0, 0.75, 0) ) - .add(new TG.Number().tint(0.065, 0, 0.095) ) + .add(new TG.Fill().tint(0.065, 0, 0.095) ) .addToPage("Example 2 (less distortion)"); line = document.createElement("br"); diff --git a/src/TexGen.js b/src/TexGen.js index bbad479..09cbb7a 100644 --- a/src/TexGen.js +++ b/src/TexGen.js @@ -478,7 +478,7 @@ TG.Program = function ( object ) { // --- Generators --- -TG.Number = function () { +TG.Fill = function () { return new TG.Program( { getParams: function () {}, From 6d05fa16db23bf431c4e5bcc1a00e2ff1a83d3fc Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sun, 23 Apr 2017 01:19:13 +0200 Subject: [PATCH 09/12] Make sine frequency relative to pixels and reversed offset-parameters to make them more intuitive --- README.md | 8 +-- examples/animated.html | 26 ++++---- examples/index.html | 140 ++++++++++++++++++++--------------------- src/TexGen.js | 12 ++-- 4 files changed, 93 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index 7d16414..f88a1f4 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ Procedural Texture Generator ```javascript var texture = new TG.Texture( 256, 256 ) .add( new TG.XOR().tint( 1, 0.5, 0.7 ) ) - .add( new TG.SinX().frequency( 0.004 ).tint( 0.5, 0, 0 ) ) - .mul( new TG.SinY().frequency( 0.004 ).tint( 0.5, 0, 0 ) ) - .add( new TG.SinX().frequency( 0.0065 ).tint( 0.1, 0.5, 0.2 ) ) - .add( new TG.SinY().frequency( 0.0065 ).tint( 0.5, 0.5, 0.5 ) ) + .add( new TG.SinX().frequency( 500 ).tint( 0.5, 0, 0 ) ) + .mul( new TG.SinY().frequency( 500 ).tint( 0.5, 0, 0 ) ) + .add( new TG.SinX().frequency( 2 / 0.0065 ).tint( 0.1, 0.5, 0.2 ) ) + .add( new TG.SinY().frequency( 2 / 0.0065 ).tint( 0.5, 0.5, 0.5 ) ) .add( new TG.Noise().tint( 0.1, 0.1, 0.2 ) ) .toCanvas(); diff --git a/examples/animated.html b/examples/animated.html index a82109f..253023a 100644 --- a/examples/animated.html +++ b/examples/animated.html @@ -30,12 +30,12 @@ function render() { var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( 0.05+i/1000 ) ) - .mul( new TG.SinX().frequency( 0.08-i/2000 ) ) - .add( new TG.SinY().frequency( 0.05-i/1000 ) ) - .mul( new TG.SinY().frequency( 0.08+i/2000 ) ) + .add( new TG.SinX().frequency( 2/(0.05+i/1000) ) ) + .mul( new TG.SinX().frequency( 2/(0.08-i/2000) ) ) + .add( new TG.SinY().frequency( 2/(0.05-i/1000) ) ) + .mul( new TG.SinY().frequency( 2/(0.08+i/2000) ) ) .div( new TG.Fill().tint( 1, 2, 1 ) ) - .add( new TG.SinX().frequency( 0.003 ).tint( 0.5, 0, 0 ) ) + .add( new TG.SinX().frequency( 2/0.003 ).tint( 0.5, 0, 0 ) ) .toImageData(context); context.putImageData( texture, 0, 0 ); @@ -43,10 +43,10 @@ // var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( 0.066 + 0.05*Math.sin(i/100) ) ) - .add( new TG.SinY().frequency( 0.066 + 0.05*Math.sin(i/100) ) ) - .mul( new TG.SinX().offset( 32 ).frequency( 0.044 + 0.09*Math.sin(i/100) ).tint( 2, 2, 2 ) ) - .mul( new TG.SinY().offset( 16 ).frequency( 0.044 + 0.09*Math.sin(i/100) ).tint( 2, 2, 2 ) ) + .add( new TG.SinX().frequency( 2/(0.066 + 0.05*Math.sin(i/100)) ) ) + .add( new TG.SinY().frequency( 2/(0.066 + 0.05*Math.sin(i/100)) ) ) + .mul( new TG.SinX().offset( 32 ).frequency( 2/(0.044 + 0.09*Math.sin(i/100)) ).tint( 2, 2, 2 ) ) + .mul( new TG.SinY().offset( 16 ).frequency( 2/(0.044 + 0.09*Math.sin(i/100)) ).tint( 2, 2, 2 ) ) .sub( new TG.Fill().tint( 0.5, 2, 4 ) ) .toImageData(context); @@ -55,10 +55,10 @@ // var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( 0.004 + 0.002*Math.sin(i/100)) ) - .mul( new TG.SinY().frequency( 0.004 + 0.002*Math.sin(i/100)) ) - .mul( new TG.SinY().offset( 32 ).frequency( 0.04 + 0.02*Math.sin(i/100) ) ) - .div( new TG.SinX().frequency( 0.02 ).tint( 8, 5, 4 ) ) + .add( new TG.SinX().frequency( 2/(0.004 + 0.002*Math.sin(i/100))) ) + .mul( new TG.SinY().frequency( 2/(0.004 + 0.002*Math.sin(i/100))) ) + .mul( new TG.SinY().offset( 32 ).frequency( 2/(0.04 + 0.02*Math.sin(i/100)) ) ) + .div( new TG.SinX().frequency( 2/0.02 ).tint( 8, 5, 4 ) ) .add( new TG.Noise().tint( 0.1, 0, 0 ) ) .add( new TG.Noise().tint( 0, 0.1, 0 ) ) .add( new TG.Noise().tint( 0, 0, 0.1 ) ) diff --git a/examples/index.html b/examples/index.html index 12b0314..f946f90 100644 --- a/examples/index.html +++ b/examples/index.html @@ -67,10 +67,10 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) .add( new TG.XOR().tint( 1, 0.5, 0.7 ) ) - .add( new TG.SinX().frequency( 0.004 ).tint( 0.25, 0, 0 ) ) - .sub( new TG.SinY().frequency( 0.004 ).tint( 0.25, 0, 0 ) ) - .add( new TG.SinX().frequency( 0.0065 ).tint( 0.1, 0.5, 0.2 ) ) - .add( new TG.SinY().frequency( 0.0065 ).tint( 0, 0.4, 0.5 ) ) + .add( new TG.SinX().frequency( size / 2 ).tint( 0.25, 0, 0 ) ) + .sub( new TG.SinY().frequency( size / 2 ).tint( 0.25, 0, 0 ) ) + .add( new TG.SinX().frequency( size / 0.8 ).tint( 0.1, 0.5, 0.2 ) ) + .add( new TG.SinY().frequency( size / 0.8 ).tint( 0, 0.4, 0.5 ) ) .add( new TG.Noise().tint( 0.1, 0.1, 0.2 ) ) .toCanvas(); return texture; @@ -80,11 +80,11 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) - .add( new TG.SinX().offset( - 16 ).frequency( 0.03 ).tint( 0.1, 0.25, 0.5 ) ) - .add( new TG.SinY().offset( - 16 ).frequency( 0.03 ).tint( 0.1, 0.25, 0.5 ) ) + .add( new TG.SinX().offset( size / 16 ).frequency( size / 3 ).tint( 0.1, 0.25, 0.5 ) ) + .add( new TG.SinY().offset( size / 16 ).frequency( size / 3 ).tint( 0.1, 0.25, 0.5 ) ) .add( new TG.Fill().tint( 0.75, 0.5, 0.5 ) ) - .add( new TG.SinX().frequency( 0.03 ).tint( 0.2, 0.2, 0.2 ) ) - .add( new TG.SinY().frequency( 0.03 ).tint( 0.2, 0.2, 0.2 ) ) + .add( new TG.SinX().frequency( size / 3 ).tint( 0.2 ) ) + .add( new TG.SinY().frequency( size / 3 ).tint( 0.2 ) ) .add( new TG.Noise().tint( 0.1, 0, 0 ) ) .add( new TG.Noise().tint( 0, 0.1, 0 ) ) .add( new TG.Noise().tint( 0, 0, 0.1 ) ) @@ -98,13 +98,13 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( 0.1 ) ) - .mul( new TG.SinX().frequency( 0.05 ) ) - .mul( new TG.SinX().frequency( 0.025 ) ) - .mul( new TG.SinY().frequency( 0.1 ) ) - .mul( new TG.SinY().frequency( 0.05 ) ) - .mul( new TG.SinY().frequency( 0.025 ) ) - .add( new TG.SinX().frequency( 0.004 ).tint( -0.25, 0.1, 0.6 ) ) + .add( new TG.SinX().frequency( size / 12.8 ) ) + .mul( new TG.SinX().frequency( size / 6.4 ) ) + .mul( new TG.SinX().frequency( size / 3.2 ) ) + .mul( new TG.SinY().frequency( size / 12.8 ) ) + .mul( new TG.SinY().frequency( size / 6.4 ) ) + .mul( new TG.SinY().frequency( size / 3.2 ) ) + .add( new TG.SinX().frequency( size * 2 ).tint( -0.25, 0.1, 0.6 ) ) .toCanvas(); @@ -117,9 +117,9 @@ var texture = new TG.Texture( size, size ) .add( new TG.XOR() ) .mul( new TG.OR().tint( 0.5, 0.8, 0.5 ) ) - .mul( new TG.SinX().frequency( 0.0312 ) ) - .div( new TG.SinY().frequency( 0.0312 ) ) - .add( new TG.SinX().frequency( 0.004 ).tint( 0.5, 0, 0 ) ) + .mul( new TG.SinX().frequency( 64 ) ) + .div( new TG.SinY().frequency( 64 ) ) + .add( new TG.SinX().frequency( 512 ).tint( 0.5, 0, 0 ) ) .add( new TG.Noise().tint( 0.1, 0.1, 0.2 ) ) .toCanvas(); @@ -131,10 +131,10 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( 0.01 ) ) - .mul( new TG.SinY().frequency( 0.0075 ) ) - .add( new TG.SinX().frequency( 0.0225 ) ) - .mul( new TG.SinY().frequency( 0.015 ) ) + .add( new TG.SinX().frequency( 2 / 0.01 ) ) + .mul( new TG.SinY().frequency( 2 / 0.0075 ) ) + .add( new TG.SinX().frequency( 2 / 0.0225 ) ) + .mul( new TG.SinY().frequency( 2 / 0.015 ) ) .add( new TG.Noise().tint( 0.1, 0.1, 0.3 ) ) .toCanvas(); @@ -146,12 +146,12 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( 0.05 ) ) - .mul( new TG.SinX().frequency( 0.08 ) ) - .add( new TG.SinY().frequency( 0.05 ) ) - .mul( new TG.SinY().frequency( 0.08 ) ) + .add( new TG.SinX().frequency( 40 ) ) + .mul( new TG.SinX().frequency( 25 ) ) + .add( new TG.SinY().frequency( 40 ) ) + .mul( new TG.SinY().frequency( 25 ) ) .div( new TG.Fill().tint( 1, 2, 1 ) ) - .add( new TG.SinX().frequency( 0.003 ).tint( 0.5, 0, 0 ) ) + .add( new TG.SinX().frequency( 1 / 0.003 ).tint( 0.5, 0, 0 ) ) .toCanvas(); @@ -162,10 +162,10 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( 0.066 ) ) - .add( new TG.SinY().frequency( 0.066 ) ) - .mul( new TG.SinX().offset( 32 ).frequency( 0.044 ).tint( 2, 2, 2 ) ) - .mul( new TG.SinY().offset( 16 ).frequency( 0.044 ).tint( 2, 2, 2 ) ) + .add( new TG.SinX().frequency( size / 8.6 ) ) + .add( new TG.SinY().frequency( size / 8.6 ) ) + .mul( new TG.SinX().offset( -32 ).frequency( size / 6.4 ).tint( 2 ) ) + .mul( new TG.SinY().offset( -16 ).frequency( size / 6.4 ).tint( 2 ) ) .sub( new TG.Fill().tint( 0.5, 2, 4 ) ) .toCanvas(); @@ -177,10 +177,10 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( 0.004 ) ) - .mul( new TG.SinY().frequency( 0.004 ) ) - .mul( new TG.SinY().offset( 32 ).frequency( 0.02 ) ) - .div( new TG.SinX().frequency( 0.02 ).tint( 8, 5, 4 ) ) + .add( new TG.SinX().frequency( size * 2 ) ) + .mul( new TG.SinY().frequency( size * 2 ) ) + .mul( new TG.SinY().offset( -size / 8 ).frequency( size / 2 ) ) + .div( new TG.SinX().frequency( size / 2 ).tint( 8, 5, 4 ) ) .add( new TG.Noise().tint( 0.1, 0, 0 ) ) .add( new TG.Noise().tint( 0, 0.1, 0 ) ) .add( new TG.Noise().tint( 0, 0, 0.1 ) ) @@ -195,9 +195,9 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) .add( new TG.CheckerBoard() ) - .add( new TG.CheckerBoard().size( 2, 2 ).tint( 0.5, 0, 0 ) ) - .add( new TG.CheckerBoard().size( 8, 8 ).tint( 1, 0.5, 0.5 ) ) - .sub( new TG.CheckerBoard().offset( 16, 16 ).tint( 0.5, 0.5, 0 ) ) + .add( new TG.CheckerBoard().size( 2 ).tint( 0.5, 0, 0 ) ) + .add( new TG.CheckerBoard().size( 8 ).tint( 1, 0.5, 0.5 ) ) + .sub( new TG.CheckerBoard().offset( -16, -16 ).tint( 0.5, 0.5, 0 ) ) .toCanvas(); @@ -221,7 +221,7 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) - .add( new TG.CheckerBoard().size( 32, 32 ).tint( 0.5, 0, 0 ) ) + .add( new TG.CheckerBoard().size( 32 ).tint( 0.5, 0, 0 ) ) .set( new TG.SineDistort() ) .toCanvas(); @@ -233,7 +233,7 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) - .add( new TG.CheckerBoard().size( 32, 32 ).tint( 0.5, 0, 0 ) ) + .add( new TG.CheckerBoard().size( 32 ).tint( 0.5, 0, 0 ) ) .set( new TG.Twirl().radius( size / 2 ).position( size / 2, size / 2 ).strength ( 75 ) ) .toCanvas(); @@ -257,7 +257,7 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) .add( new TG.Circle().position( size / 2, size / 2 ).radius( size / 4 ).delta( size / 4 ).tint( 1, 0.25, 0.25 ) ) - .set( new TG.Pixelate().size( size / 32, size / 32 ) ) + .set( new TG.Pixelate().size( size / 32 ) ) .toCanvas(); @@ -293,7 +293,7 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) - .add( new TG.CheckerBoard().size( size / 16, size / 16 ) ) + .add( new TG.CheckerBoard().size( size / 16 ) ) .set( new TG.Twirl().radius( size / 2 ).strength( 75 ).position( size / 2, size / 2 ) ) .min( new TG.Circle().position( size / 2, size / 2 ).radius( size / 2 ).delta( size / 2 ) ) .toCanvas(); @@ -307,10 +307,10 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) .add( new TG.LinearGradient().interpolation( 0 ) - .point( 0, [ 1, 1, 0, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5, 1 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5, 1 ] ) - .point( 1, [ 1, 0, 1, 1 ] ) ) + .point( 0, [ 1, 1, 0 ] ) + .point( 0.25, [ 0.2, 0, 0.5 ] ) + .point( 0.5, [ 0.5, 0.2, 0.5 ] ) + .point( 1, [ 1, 0, 1 ] ) ) .toCanvas(); @@ -322,10 +322,10 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) .add( new TG.LinearGradient().interpolation( 1 ) - .point( 0, [ 1, 1, 0, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5, 1 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5, 1 ] ) - .point( 1, [ 1, 0, 1, 1 ] ) ) + .point( 0, [ 1, 1, 0 ] ) + .point( 0.25, [ 0.2, 0, 0.5 ] ) + .point( 0.5, [ 0.5, 0.2, 0.5 ] ) + .point( 1, [ 1, 0, 1 ] ) ) .toCanvas(); @@ -337,10 +337,10 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) .add( new TG.LinearGradient().interpolation( 2 ) - .point( 0, [ 1, 1, 0, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5, 1 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5, 1 ] ) - .point( 1, [ 1, 0, 1, 1 ] ) ) + .point( 0, [ 1, 1, 0 ] ) + .point( 0.25, [ 0.2, 0, 0.5 ] ) + .point( 0.5, [ 0.5, 0.2, 0.5 ] ) + .point( 1, [ 1, 0, 1 ] ) ) .toCanvas(); @@ -354,10 +354,10 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) .add( new TG.RadialGradient().center( size / 2, size / 2 ).radius( size / 8 ).repeat( true ).interpolation( 0 ) - .point( 0, [ 1, 1, 0, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5, 1 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5, 1] ) - .point( 1, [ 1, 0, 1, 1 ] ) ) + .point( 0, [ 1, 1, 0 ] ) + .point( 0.25, [ 0.2, 0, 0.5 ] ) + .point( 0.5, [ 0.5, 0.2, 0.5 ] ) + .point( 1, [ 1, 0, 1 ] ) ) .toCanvas(); @@ -369,10 +369,10 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) .add( new TG.RadialGradient().center( 0, 0 ).radius( size * 2 ).interpolation( 1 ) - .point( 0, [ 1, 1, 0, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5, 1 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5, 1 ] ) - .point( 1, [ 1, 0, 1, 1 ] ) ) + .point( 0, [ 1, 1, 0 ] ) + .point( 0.25, [ 0.2, 0, 0.5 ] ) + .point( 0.5, [ 0.5, 0.2, 0.5 ] ) + .point( 1, [ 1, 0, 1 ] ) ) .toCanvas(); @@ -384,10 +384,10 @@ examples.push( function ( size ) { var texture = new TG.Texture( size, size ) .add( new TG.RadialGradient().center( size / 2, 0 ).radius( size ).interpolation( 2 ) - .point( 0, [ 1, 1, 0, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5, 1 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5, 1 ] ) - .point( 1, [ 1, 0, 1, 1 ] ) ) + .point( 0, [ 1, 1, 0 ] ) + .point( 0.25, [ 0.2, 0, 0.5 ] ) + .point( 0.5, [ 0.5, 0.2, 0.5 ] ) + .point( 1, [ 1, 0, 1 ] ) ) .toCanvas(); @@ -411,7 +411,7 @@ for ( i = 0; i <= numSamples; i++ ) { var sample = new TG.Texture( size, size ) .set( new TG.PutTexture( base ) ) // copy the base texture, so that it doesn't get modified - .set( new TG.Transform().scale( 1 + 0.01 * i, 1 + 0.01 * i ).angle( 0.5 * i ) ); // modify the texture a bit more with each sample + .set( new TG.Transform().scale( 1 + 0.01 * i ).angle( 0.5 * i ) ); // modify the texture a bit more with each sample blur.add( new TG.PutTexture( sample ) ); // adding the transformed sample to the result } @@ -439,12 +439,12 @@ .point( 0.4, [ 200, 15, 17 ] ) //[ 42, 166, 137 ] .point( 0.6, [ 140, 49, 59 ] ) //[ 58, 131, 114 ] .point( 0.8, [ 35, 10, 12 ] ) //[ 4, 46, 27 ] - .point( 1, [ 0, 0, 0 ] ) ) - .div( new TG.Fill().tint( 255, 255, 255 ) ); // converting the 0-255 defined colors to the 0-1 space + .point( 1, 0 ) ) + .div( new TG.Fill().tint( 255 ) ); // converting the 0-255 defined colors to the 0-1 space var mirrored = new TG.Texture( size, size ) .add( new TG.PutTexture( pixel ).repeat( 2 ) ) // repeat the texture to get a cool mirrored pattern effect - .mul( new TG.PutTexture( vignette ).tint( 1.2, 1.2, 1.2 ) ); // adding the vignette from the example above + .mul( new TG.PutTexture( vignette ).tint( 1.2 ) ); // adding the vignette from the example above var texture = mirrored.toCanvas(); diff --git a/src/TexGen.js b/src/TexGen.js index 09cbb7a..427877e 100644 --- a/src/TexGen.js +++ b/src/TexGen.js @@ -502,11 +502,11 @@ TG.SinX = function () { return new TG.Program( { frequency: function ( value ) { - params.frequency = value * Math.PI; + params.frequency = ( 2 / value ) * Math.PI; return this; }, offset: function ( value ) { - params.offset = value; + params.offset = -value; return this; }, getParams: function () { @@ -533,11 +533,11 @@ TG.SinY = function () { return new TG.Program( { frequency: function ( value ) { - params.frequency = value * Math.PI; + params.frequency = ( 2 / value ) * Math.PI; return this; }, offset: function ( value ) { - params.offset = value; + params.offset = -value; return this; }, getParams: function () { @@ -950,7 +950,7 @@ TG.CheckerBoard = function () { return this; }, offset: function ( x, y ) { - params.offset = [ x, y ]; + params.offset = [ -x, -y ]; return this; }, rowShift: function ( value ) { @@ -1272,7 +1272,7 @@ TG.Transform = function () { return new TG.Program( { offset: function ( x, y ) { - params.offset = [ x, y ]; + params.offset = [ -x, -y ]; return this; }, angle: function ( value ) { From 4894b2f4ecf5f84ecc0d4fad9a1efccaee4970bb Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sun, 23 Apr 2017 01:32:38 +0200 Subject: [PATCH 10/12] Add a comment to every generator and parameter --- src/TexGen.js | 181 +++++++++++++++++++++++++------------------------- 1 file changed, 91 insertions(+), 90 deletions(-) diff --git a/src/TexGen.js b/src/TexGen.js index 427877e..f47fe3a 100644 --- a/src/TexGen.js +++ b/src/TexGen.js @@ -461,7 +461,7 @@ TG.Program = function ( object ) { var tint = new Float32Array( [ 1, 1, 1 ] ); - object.tint = function ( r, g, b ) { + object.tint = function ( r, g, b ) { // multiplies each color channel of the generated image by 'r', 'g' and 'b' respectively tint[ 0 ] = r; tint[ 1 ] = ( typeof g == 'undefined' ) ? r : g; tint[ 2 ] = ( typeof b == 'undefined' ) ? r : b; @@ -478,7 +478,7 @@ TG.Program = function ( object ) { // --- Generators --- -TG.Fill = function () { +TG.Fill = function () { // every pixel set to 1; together with tint can be used to do basic calculations (e.g. .mul( TG.Fill().tint( 2 ) ) -> double the value of each pixel) return new TG.Program( { getParams: function () {}, @@ -493,7 +493,7 @@ TG.Fill = function () { }; -TG.SinX = function () { +TG.SinX = function () { // generates a sine wave on the x and value (brightness) axes var params = { frequency: 1, @@ -501,11 +501,11 @@ TG.SinX = function () { }; return new TG.Program( { - frequency: function ( value ) { + frequency: function ( value ) { // sets the 'width' of the sine wave in pixels params.frequency = ( 2 / value ) * Math.PI; return this; }, - offset: function ( value ) { + offset: function ( value ) { // moves the wave by 'value' pixels params.offset = -value; return this; }, @@ -524,7 +524,7 @@ TG.SinX = function () { }; -TG.SinY = function () { +TG.SinY = function () { // generates a sine wave on the y and value (brightness) axes var params = { frequency: 1, @@ -532,11 +532,11 @@ TG.SinY = function () { }; return new TG.Program( { - frequency: function ( value ) { + frequency: function ( value ) { // sets the 'width' of the sine wave in pixels params.frequency = ( 2 / value ) * Math.PI; return this; }, - offset: function ( value ) { + offset: function ( value ) { // moves the wave by 'value' pixels params.offset = -value; return this; }, @@ -555,7 +555,7 @@ TG.SinY = function () { }; -TG.OR = function () { +TG.OR = function () { // generates a pattern using bitwise OR on the x and y coordinates return new TG.Program( { getParams: function () {}, @@ -571,7 +571,7 @@ TG.OR = function () { }; -TG.XOR = function () { +TG.XOR = function () { // generates a pattern using bitwise XOR on the x and y coordinates return new TG.Program( { getParams: function () {}, @@ -587,7 +587,7 @@ TG.XOR = function () { }; -TG.Noise = function () { +TG.Noise = function () { // generates a random noise pattern var params = { seed: TG.Utils.globalSeed++, @@ -595,11 +595,11 @@ TG.Noise = function () { }; return new TG.Program( { - seed: function ( value ) { + seed: function ( value ) { // the same seed always results in the same noise pattern params.seed = value; return this; }, - size: function ( value ) { + size: function ( value ) { // sets the size of the pixel grid for the noise function params.size = value; return this; }, @@ -618,7 +618,7 @@ TG.Noise = function () { }; -TG.FractalNoise = function () { +TG.FractalNoise = function () { // generates a noise pattern with extra 'depth' by overlaying noise of different sizes var params = { interpolator: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.STEP ), @@ -631,31 +631,31 @@ TG.FractalNoise = function () { }; return new TG.Program( { - seed: function ( value ) { + seed: function ( value ) { // the same seed always results in the same noise pattern params.seed = value; return this; }, - baseFrequency: function ( value ) { + baseFrequency: function ( value ) { // sets the size of the noise for the first octave in pixels params.baseFrequency = 1 / value; return this; }, - amplitude: function ( value ) { + amplitude: function ( value ) { // sets how much 'contrast' the noise should initially have; gets decreased with each octave params.amplitude = value; return this; }, - persistence: function ( value ) { + persistence: function ( value ) { // how much the amplitude should be decreased with each octave params.persistence = value; return this; }, - octaves: function ( value ) { + octaves: function ( value ) { // how many different noise patterns are layered on top of each other params.octaves = Math.max( 1, value ); return this; }, - step: function ( value ) { + step: function ( value ) { // how much the frequency gets decreased with each octave (e.g. a value of 2 halves the size each time) params.step = Math.max( 0, value ); return this; }, - interpolation: function ( value ) { + interpolation: function ( value ) { // which interpolation algorithm should be used for non-whole coordinates -> should the noise be smooth or rough? (see TG.ColorInterpolator below) params.interpolator.setInterpolation( value ); return this; }, @@ -719,7 +719,7 @@ TG.FractalNoise = function () { }; -TG.CellularNoise = function () { +TG.CellularNoise = function () { // noise based on the distance of randomly distributed points on the xy-plane var params = { seed: TG.Utils.globalSeed++, @@ -728,15 +728,15 @@ TG.CellularNoise = function () { }; return new TG.Program( { - seed: function ( value ) { + seed: function ( value ) { // the same seed always results in the same noise pattern params.seed = value; return this; }, - density: function ( value ) { + density: function ( value ) { // the average distance betweeen each point in pixels; negative values invert the pattern params.density = value; return this; }, - weightRange: function ( value ) { + weightRange: function ( value ) { // gives some points more or less 'influence' making them bigger or smaller; too high values can break the point finding algorithm! params.weightRange = Math.max( 0, value ); return this; }, @@ -759,7 +759,7 @@ TG.CellularNoise = function () { }; -TG.VoronoiNoise = function () { +TG.VoronoiNoise = function () { // noise based on voronoi diagrams of randomly distributed points on the xy-plane var params = { seed: TG.Utils.globalSeed++, @@ -768,15 +768,15 @@ TG.VoronoiNoise = function () { }; return new TG.Program( { - seed: function ( value ) { + seed: function ( value ) { // the same seed always results in the same noise pattern params.seed = value; return this; }, - density: function ( value ) { + density: function ( value ) { // the average distance betweeen each point in pixels params.density = value; return this; }, - weightRange: function ( value ) { + weightRange: function ( value ) { // gives some points more or less 'influence'; too high values can break the point finding algorithm! params.weightRange = Math.max( 0, value ); return this; }, @@ -796,7 +796,7 @@ TG.VoronoiNoise = function () { }; -TG.CellularFractal = function () { +TG.CellularFractal = function () { // generates a noise pattern with extra 'depth' by overlaying cellular noise with different densities var params = { seed: TG.Utils.globalSeed++, @@ -809,31 +809,31 @@ TG.CellularFractal = function () { }; return new TG.Program( { - seed: function ( value ) { + seed: function ( value ) { // the same seed always results in the same noise pattern params.seed = value; return this; }, - baseDensity: function ( value ) { + baseDensity: function ( value ) { // sets the density for the first octave params.baseDensity = value; return this; }, - weightRange: function ( value ) { + weightRange: function ( value ) { // sets the weightRange for the cellular noise; see TG.CellularNoise above params.weightRange = Math.max( 0, value ); return this; }, - amplitude: function ( value ) { + amplitude: function ( value ) { // sets how much 'contrast' the noise should initially have; gets decreased with each octave params.amplitude = value; return this; }, - persistence: function ( value ) { + persistence: function ( value ) { // how much the amplitude should be decreased with each octave params.persistence = value; return this; }, - octaves: function ( value ) { + octaves: function ( value ) { // how many different noise patterns are layered on top of each other params.octaves = Math.max( 1, value ); return this; }, - step: function ( value ) { + step: function ( value ) { // how much the density gets decreased with each octave (e.g. a value of 2 halves the density each time) params.step = Math.max( 1, value ); return this; }, @@ -867,7 +867,7 @@ TG.CellularFractal = function () { }; -TG.VoronoiFractal = function () { +TG.VoronoiFractal = function () { // generates a noise pattern with extra 'depth' by overlaying voronoi noise with different densities var params = { seed: TG.Utils.globalSeed++, @@ -880,31 +880,31 @@ TG.VoronoiFractal = function () { }; return new TG.Program( { - seed: function ( value ) { + seed: function ( value ) { // the same seed always results in the same noise pattern params.seed = value; return this; }, - baseDensity: function ( value ) { + baseDensity: function ( value ) { // sets the density for the first octave params.baseDensity = value; return this; }, - weightRange: function ( value ) { + weightRange: function ( value ) { // sets the weightRange for the voronoi noise; see TG.VoronoiNoise above params.weightRange = Math.max( 0, value ); return this; }, - amplitude: function ( value ) { + amplitude: function ( value ) { // sets how much 'contrast' the noise should initially have; gets decreased with each octave params.amplitude = value; return this; }, - persistence: function ( value ) { + persistence: function ( value ) { // how much the amplitude should be decreased with each octave (values over 1 increase the amplitude instead) params.persistence = value; return this; }, - octaves: function ( value ) { + octaves: function ( value ) { // how many different noise patterns are layered on top of each other params.octaves = Math.max( 1, value ); return this; }, - step: function ( value ) { + step: function ( value ) { // how much the density gets decreased with each octave (e.g. a value of 2 halves the density each time) params.step = Math.max( 1, value ); return this; }, @@ -935,7 +935,7 @@ TG.VoronoiFractal = function () { }; -TG.CheckerBoard = function () { +TG.CheckerBoard = function () { // generates a grid pattern of alternating black and white cells var params = { size: [ 32, 32 ], @@ -944,16 +944,16 @@ TG.CheckerBoard = function () { }; return new TG.Program( { - size: function ( x, y ) { + size: function ( x, y ) { // sets the width and height of each square in pixels if ( typeof y == "undefined" ) y = x; params.size = [ x, y ]; return this; }, - offset: function ( x, y ) { + offset: function ( x, y ) { // moves the origin of the pattern to 'x' and 'y' in pixels params.offset = [ -x, -y ]; return this; }, - rowShift: function ( value ) { + rowShift: function ( value ) { // offsets each row by 'value' pixels params.rowShift = value; return this; }, @@ -972,7 +972,7 @@ TG.CheckerBoard = function () { }; -TG.Rect = function () { +TG.Rect = function () { // generates a basic white rectangle var params = { position: [ 0, 0 ], @@ -980,11 +980,11 @@ TG.Rect = function () { }; return new TG.Program( { - position: function ( x, y ) { + position: function ( x, y ) { // sets the coordinates of the top-leftmost point of the rectangle params.position = [ x, y ]; return this; }, - size: function ( x, y ) { + size: function ( x, y ) { // sets the width and height of the rectangle if ( typeof y == "undefined" ) y = x; params.size = [ x, y ]; return this; @@ -1004,7 +1004,7 @@ TG.Rect = function () { }; -TG.Circle = function () { +TG.Circle = function () { // generates a basic white circle var params = { position: [ 0, 0 ], @@ -1013,15 +1013,15 @@ TG.Circle = function () { }; return new TG.Program( { - delta: function ( value ) { + delta: function ( value ) { // sets how many pixels from the edge of the circle the brightness should gradually decrease; 0 results in a completely crisp circle params.delta = value; return this; }, - position: function ( x, y ) { + position: function ( x, y ) { // sets the coordinates of the center of the circle params.position = [ x, y ]; return this; }, - radius: function ( value ) { + radius: function ( value ) { // sets the radius of the circle in pixels params.radius = value; return this; }, @@ -1041,7 +1041,7 @@ TG.Circle = function () { }; -TG.PutTexture = function ( texture ) { +TG.PutTexture = function ( texture ) { // puts an already existing texture onto another one var params = { offset: [ 0, 0 ], @@ -1050,11 +1050,11 @@ TG.PutTexture = function ( texture ) { }; return new TG.Program( { - offset: function ( x, y ) { + offset: function ( x, y ) { // sets the coordinates of the top-leftmost point params.offset = [ x, y ]; return this; }, - repeat: function ( value ) { + repeat: function ( value ) { // which algorithm should be used on coordinates outside of the texture; 1 = wrap around, 2 = wrap around but mirrored, 3 = extend the last pixel params.repeat = value; return this; }, @@ -1099,7 +1099,7 @@ TG.PutTexture = function ( texture ) { }; -TG.RadialGradient = function () { +TG.RadialGradient = function () { // generates a circular gradient around a point var params = { gradient: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.LINEAR ), @@ -1108,23 +1108,23 @@ TG.RadialGradient = function () { }; return new TG.Program( { - repeat: function ( value ) { + repeat: function ( value ) { // sets how the gradient should repeat if outside of the range of the added points; 0 = clamp to the last point, 1 = wrap around, 2 = wrap around but mirrored params.gradient.setRepeat( value ); return this; }, - radius: function ( value ) { + radius: function ( value ) { // sets how far from the center the last point (i.e. position 1) of the gradient is params.radius = value; return this; }, - interpolation: function ( value ) { + interpolation: function ( value ) { // sets the interpolation method of the gradient; 0 = step -> do not interpolate, 1 = linear-, 2 = spline-, 3 = cosine-interpolation params.gradient.setInterpolation( value ); return this; }, - center: function ( x, y ) { + center: function ( x, y ) { // sets the center around which the gradient is generated params.center = [ x, y ]; return this; }, - point: function ( position, r, g, b ) { + point: function ( position, r, g, b ) { // adds a point to the gradient; position 0 is the center and 1 is the radius params.gradient.addPoint( position, r, g, b ); return this; }, @@ -1143,22 +1143,22 @@ TG.RadialGradient = function () { }; -TG.LinearGradient = function () { +TG.LinearGradient = function () { // generates a gradient across the whole texture var params = { gradient: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.LINEAR ) }; return new TG.Program( { - repeat: function ( value ) { + repeat: function ( value ) { // sets how the gradient should repeat if outside of the range of the added points; 0 = clamp to the last point, 1 = wrap around, 2 = wrap around but mirrored params.gradient.setRepeat( value ); return this; }, - interpolation: function ( value ) { + interpolation: function ( value ) { // sets the interpolation method of the gradient; 0 = step -> do not interpolate, 1 = linear-, 2 = spline-, 3 = cosine-interpolation params.gradient.setInterpolation( value ); return this; }, - point: function ( position, r, g, b ) { + point: function ( position, r, g, b ) { // adds a point to the gradient; position 0 is x0 and 1 is the width of the texture params.gradient.addPoint( position, r, g, b ); return this; }, @@ -1178,7 +1178,7 @@ TG.LinearGradient = function () { // --- Filters --- -TG.SineDistort = function () { +TG.SineDistort = function () { // warps the texture in a wavy pattern var params = { sines: [ 4, 4 ], @@ -1187,16 +1187,16 @@ TG.SineDistort = function () { }; return new TG.Program( { - sines: function ( x, y ) { + sines: function ( x, y ) { // sets the width of the sine waves on the x and y axis respectively if ( typeof y == "undefined" ) y = x; params.sines = [ x, y ]; return this; }, - offset: function ( x, y ) { + offset: function ( x, y ) { // shifts the 'phase' of each wave params.offset = [ x, y ]; return this; }, - amplitude: function ( x, y ) { + amplitude: function ( x, y ) { // sets the 'amplitude' of each wave (or intensity of the filter) if ( typeof y == "undefined" ) y = x; params.amplitude = [ x, y ]; return this; @@ -1215,7 +1215,7 @@ TG.SineDistort = function () { }; -TG.Twirl = function () { +TG.Twirl = function () { // distorts the texture into a vortex around a point var params = { strength: 0, @@ -1224,15 +1224,15 @@ TG.Twirl = function () { }; return new TG.Program( { - strength: function ( value ) { + strength: function ( value ) { // sets how much the texture should be rotated params.strength = value / 100.0; return this; }, - radius: function ( value ) { + radius: function ( value ) { // sets the radius of influence params.radius = value; return this; }, - position: function ( x, y ) { + position: function ( x, y ) { // sets the coordinates of the center of the swirl params.position = [ x, y ]; return this; }, @@ -1262,7 +1262,7 @@ TG.Twirl = function () { }; -TG.Transform = function () { +TG.Transform = function () { // moves, rotates or scales the texture var params = { offset: [ 0, 0 ], @@ -1271,15 +1271,15 @@ TG.Transform = function () { }; return new TG.Program( { - offset: function ( x, y ) { + offset: function ( x, y ) { // moves the texture by 'x' and 'y' pixels params.offset = [ -x, -y ]; return this; }, - angle: function ( value ) { + angle: function ( value ) { // rotates the texture by 'value' degrees around the origin (x: 0, y: 0) params.angle = TG.Utils.deg2rad( value ); return this; }, - scale: function ( x, y ) { + scale: function ( x, y ) { // scales the texture by 'x' and 'y' (e.g. 2 doubles the size) x = x || 1; y = y || x; @@ -1307,14 +1307,14 @@ TG.Transform = function () { }; -TG.Pixelate = function () { +TG.Pixelate = function () { // divides the texture into 'pixels' var params = { size: [ 1, 1 ] }; return new TG.Program( { - size: function ( x, y ) { + size: function ( x, y ) { // set the width and height of each 'pixel' if ( typeof y == "undefined" ) y = x; params.size = [ x, y ]; return this; @@ -1334,22 +1334,22 @@ TG.Pixelate = function () { }; -TG.GradientMap = function () { +TG.GradientMap = function () { // takes the value of each pixel and maps it to a color in a gradient; best used on a grayscale image var params = { gradient: new TG.ColorInterpolator( TG.ColorInterpolatorMethod.LINEAR ) }; return new TG.Program( { - repeat: function ( value ) { + repeat: function ( value ) { // how to map values that are out of range onto the gradient; 0 = clamp to the last (first) point of the gradient, 1 = wrap around, 2 = wrap around but mirrored params.gradient.setRepeat( value ); return this; }, - interpolation: function ( value ) { + interpolation: function ( value ) { // set the interpolation method for the gradient; 0 = step -> do not interpolate, 1 = linear-, 2 = spline-, 3 = cosine-interpolation params.gradient.setInterpolation( value ); return this; }, - point: function ( position, r, g, b ) { + point: function ( position, r, g, b ) { // add a point to the gradient; position 0 is black and 1 is white in the original texture params.gradient.addPoint( position, r, g, b ); return this; }, @@ -1370,9 +1370,10 @@ TG.GradientMap = function () { ].join('\n'); } } ); + }; -TG.Normalize = function () { +TG.Normalize = function () { // adjusts the whole texture so that every pixel is in the visible range (0 - 1) return new TG.Program( { getParams: function () {}, @@ -1404,14 +1405,14 @@ TG.Normalize = function () { }; -TG.Posterize = function () { +TG.Posterize = function () { // reduces the amount of colors in a texture var params = { step: 2 }; return new TG.Program( { - step: function ( value ) { + step: function ( value ) { // sets how many possible values each color channel is divided into (2 means possible values are 0 and 1, 3 means 0, 0.5 and 1 etc.) params.step = Math.max( value, 2 ); return this; }, From 0f9b5434b595d0d29e3740d9f8eaee3a0974cdaf Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sun, 23 Apr 2017 03:22:38 +0200 Subject: [PATCH 11/12] Refactor example page and add CodeMirror syntax-highlighting --- examples/index.html | 582 ++++++++++++++++++++------------------------ 1 file changed, 263 insertions(+), 319 deletions(-) diff --git a/examples/index.html b/examples/index.html index f946f90..d1ba9ed 100644 --- a/examples/index.html +++ b/examples/index.html @@ -50,7 +50,26 @@ -o-tab-size: 4; tab-size: 4;*/ } + + .cm-keyword { color: #d687a2; } + .cm-atom { color: #119a6c; } + .cm-number { color: #8b6194; } + .cm-def { color: #608ba7; } + .cm-variable { color: #a3bac1; } + .cm-property { color: #6f979a; } + .cm-operator { color: #d08f64; } + .cm-variable-2 { color: #a3bac1; opacity: 0.8; } + .cm-variable-3 { color: #a3bac1; opacity: 0.6; } + .cm-comment { opacity: 0.25; } + .cm-string { color: #a05e55; } + .cm-string-2 { color: #964b40; } + + .cm-error { color: #cc1d29; } + .cm-invalidchar { color: #cc1d29; } + + +

Change size: 128x128 256x256 512x512 custom...

@@ -64,392 +83,319 @@ var generated = document.getElementById( "generated" ); var examples = []; - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.XOR().tint( 1, 0.5, 0.7 ) ) - .add( new TG.SinX().frequency( size / 2 ).tint( 0.25, 0, 0 ) ) - .sub( new TG.SinY().frequency( size / 2 ).tint( 0.25, 0, 0 ) ) - .add( new TG.SinX().frequency( size / 0.8 ).tint( 0.1, 0.5, 0.2 ) ) - .add( new TG.SinY().frequency( size / 0.8 ).tint( 0, 0.4, 0.5 ) ) - .add( new TG.Noise().tint( 0.1, 0.1, 0.2 ) ) - .toCanvas(); - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.XOR().tint( 1, 0.5, 0.7 ) )', + ' .add( new TG.SinX().frequency( size / 2 ).tint( 0.25, 0, 0 ) )', + ' .sub( new TG.SinY().frequency( size / 2 ).tint( 0.25, 0, 0 ) )', + ' .add( new TG.SinX().frequency( size / 0.8 ).tint( 0.1, 0.5, 0.2 ) )', + ' .add( new TG.SinY().frequency( size / 0.8 ).tint( 0, 0.4, 0.5 ) )', + ' .add( new TG.Noise().tint( 0.1, 0.1, 0.2 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.SinX().offset( size / 16 ).frequency( size / 3 ).tint( 0.1, 0.25, 0.5 ) ) - .add( new TG.SinY().offset( size / 16 ).frequency( size / 3 ).tint( 0.1, 0.25, 0.5 ) ) - .add( new TG.Fill().tint( 0.75, 0.5, 0.5 ) ) - .add( new TG.SinX().frequency( size / 3 ).tint( 0.2 ) ) - .add( new TG.SinY().frequency( size / 3 ).tint( 0.2 ) ) - .add( new TG.Noise().tint( 0.1, 0, 0 ) ) - .add( new TG.Noise().tint( 0, 0.1, 0 ) ) - .add( new TG.Noise().tint( 0, 0, 0.1 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.SinX().offset( size / 16 ).frequency( size / 3 ).tint( 0.1, 0.25, 0.5 ) )', + ' .add( new TG.SinY().offset( size / 16 ).frequency( size / 3 ).tint( 0.1, 0.25, 0.5 ) )', + ' .add( new TG.Fill().tint( 0.75, 0.5, 0.5 ) )', + ' .add( new TG.SinX().frequency( size / 3 ).tint( 0.2 ) )', + ' .add( new TG.SinY().frequency( size / 3 ).tint( 0.2 ) )', + ' .add( new TG.Noise().tint( 0.1, 0, 0 ) )', + ' .add( new TG.Noise().tint( 0, 0.1, 0 ) )', + ' .add( new TG.Noise().tint( 0, 0, 0.1 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( size / 12.8 ) ) - .mul( new TG.SinX().frequency( size / 6.4 ) ) - .mul( new TG.SinX().frequency( size / 3.2 ) ) - .mul( new TG.SinY().frequency( size / 12.8 ) ) - .mul( new TG.SinY().frequency( size / 6.4 ) ) - .mul( new TG.SinY().frequency( size / 3.2 ) ) - .add( new TG.SinX().frequency( size * 2 ).tint( -0.25, 0.1, 0.6 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.SinX().frequency( size / 12.8 ) )', + ' .mul( new TG.SinX().frequency( size / 6.4 ) )', + ' .mul( new TG.SinX().frequency( size / 3.2 ) )', + ' .mul( new TG.SinY().frequency( size / 12.8 ) )', + ' .mul( new TG.SinY().frequency( size / 6.4 ) )', + ' .mul( new TG.SinY().frequency( size / 3.2 ) )', + ' .add( new TG.SinX().frequency( size * 2 ).tint( -0.25, 0.1, 0.6 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.XOR() ) - .mul( new TG.OR().tint( 0.5, 0.8, 0.5 ) ) - .mul( new TG.SinX().frequency( 64 ) ) - .div( new TG.SinY().frequency( 64 ) ) - .add( new TG.SinX().frequency( 512 ).tint( 0.5, 0, 0 ) ) - .add( new TG.Noise().tint( 0.1, 0.1, 0.2 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.XOR() )', + ' .mul( new TG.OR().tint( 0.5, 0.8, 0.5 ) )', + ' .mul( new TG.SinX().frequency( 64 ) )', + ' .div( new TG.SinY().frequency( 64 ) )', + ' .add( new TG.SinX().frequency( 512 ).tint( 0.5, 0, 0 ) )', + ' .add( new TG.Noise().tint( 0.1, 0.1, 0.2 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( 2 / 0.01 ) ) - .mul( new TG.SinY().frequency( 2 / 0.0075 ) ) - .add( new TG.SinX().frequency( 2 / 0.0225 ) ) - .mul( new TG.SinY().frequency( 2 / 0.015 ) ) - .add( new TG.Noise().tint( 0.1, 0.1, 0.3 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.SinX().frequency( 2 / 0.01 ) )', + ' .mul( new TG.SinY().frequency( 2 / 0.0075 ) )', + ' .add( new TG.SinX().frequency( 2 / 0.0225 ) )', + ' .mul( new TG.SinY().frequency( 2 / 0.015 ) )', + ' .add( new TG.Noise().tint( 0.1, 0.1, 0.3 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( 40 ) ) - .mul( new TG.SinX().frequency( 25 ) ) - .add( new TG.SinY().frequency( 40 ) ) - .mul( new TG.SinY().frequency( 25 ) ) - .div( new TG.Fill().tint( 1, 2, 1 ) ) - .add( new TG.SinX().frequency( 1 / 0.003 ).tint( 0.5, 0, 0 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.SinX().frequency( 40 ) )', + ' .mul( new TG.SinX().frequency( 25 ) )', + ' .add( new TG.SinY().frequency( 40 ) )', + ' .mul( new TG.SinY().frequency( 25 ) )', + ' .div( new TG.Fill().tint( 1, 2, 1 ) )', + ' .add( new TG.SinX().frequency( 1 / 0.003 ).tint( 0.5, 0, 0 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( size / 8.6 ) ) - .add( new TG.SinY().frequency( size / 8.6 ) ) - .mul( new TG.SinX().offset( -32 ).frequency( size / 6.4 ).tint( 2 ) ) - .mul( new TG.SinY().offset( -16 ).frequency( size / 6.4 ).tint( 2 ) ) - .sub( new TG.Fill().tint( 0.5, 2, 4 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.SinX().frequency( size / 8.6 ) )', + ' .add( new TG.SinY().frequency( size / 8.6 ) )', + ' .mul( new TG.SinX().offset( -32 ).frequency( size / 6.4 ).tint( 2 ) )', + ' .mul( new TG.SinY().offset( -16 ).frequency( size / 6.4 ).tint( 2 ) )', + ' .sub( new TG.Fill().tint( 0.5, 2, 4 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.SinX().frequency( size * 2 ) ) - .mul( new TG.SinY().frequency( size * 2 ) ) - .mul( new TG.SinY().offset( -size / 8 ).frequency( size / 2 ) ) - .div( new TG.SinX().frequency( size / 2 ).tint( 8, 5, 4 ) ) - .add( new TG.Noise().tint( 0.1, 0, 0 ) ) - .add( new TG.Noise().tint( 0, 0.1, 0 ) ) - .add( new TG.Noise().tint( 0, 0, 0.1 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.SinX().frequency( size * 2 ) )', + ' .mul( new TG.SinY().frequency( size * 2 ) )', + ' .mul( new TG.SinY().offset( -size / 8 ).frequency( size / 2 ) )', + ' .div( new TG.SinX().frequency( size / 2 ).tint( 8, 5, 4 ) )', + ' .add( new TG.Noise().tint( 0.1, 0, 0 ) )', + ' .add( new TG.Noise().tint( 0, 0.1, 0 ) )', + ' .add( new TG.Noise().tint( 0, 0, 0.1 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.CheckerBoard() ) - .add( new TG.CheckerBoard().size( 2 ).tint( 0.5, 0, 0 ) ) - .add( new TG.CheckerBoard().size( 8 ).tint( 1, 0.5, 0.5 ) ) - .sub( new TG.CheckerBoard().offset( -16, -16 ).tint( 0.5, 0.5, 0 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.CheckerBoard() )', + ' .add( new TG.CheckerBoard().size( 2 ).tint( 0.5, 0, 0 ) )', + ' .add( new TG.CheckerBoard().size( 8 ).tint( 1, 0.5, 0.5 ) )', + ' .sub( new TG.CheckerBoard().offset( -16, -16 ).tint( 0.5, 0.5, 0 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.Rect().position( size / 4.8, size / 12 ).size( size / 1.7, size / 2 ).tint( 1, 0.25, 0.25 ) ) - .add( new TG.Rect().position( size / 12, size / 4 ).size( size / 1.21, size / 2 ).tint( 0.25, 1, 0.25 ) ) - .add( new TG.Rect().position( size / 4.8, size / 2.5 ).size( size / 1.7, size / 2 ).tint( 0.25, 0.25, 1 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.Rect().position( size / 4.8, size / 12 ).size( size / 1.7, size / 2 ).tint( 1, 0.25, 0.25 ) )', + ' .add( new TG.Rect().position( size / 12, size / 4 ).size( size / 1.21, size / 2 ).tint( 0.25, 1, 0.25 ) )', + ' .add( new TG.Rect().position( size / 4.8, size / 2.5 ).size( size / 1.7, size / 2 ).tint( 0.25, 0.25, 1 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.CheckerBoard().size( 32 ).tint( 0.5, 0, 0 ) ) - .set( new TG.SineDistort() ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.CheckerBoard().size( 32 ).tint( 0.5, 0, 0 ) )', + ' .set( new TG.SineDistort() )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.CheckerBoard().size( 32 ).tint( 0.5, 0, 0 ) ) - .set( new TG.Twirl().radius( size / 2 ).position( size / 2, size / 2 ).strength ( 75 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.CheckerBoard().size( 32 ).tint( 0.5, 0, 0 ) )', + ' .set( new TG.Twirl().radius( size / 2 ).position( size / 2, size / 2 ).strength ( 75 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.Circle().position( size / 2, size / 2 ).radius( size / 4 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.Circle().position( size / 2, size / 2 ).radius( size / 4 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.Circle().position( size / 2, size / 2 ).radius( size / 4 ).delta( size / 4 ).tint( 1, 0.25, 0.25 ) ) - .set( new TG.Pixelate().size( size / 32 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.Circle().position( size / 2, size / 2 ).radius( size / 4 ).delta( size / 4 ).tint( 1, 0.25, 0.25 ) )', + ' .set( new TG.Pixelate().size( size / 32 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.CheckerBoard().tint( 1, 1, 0 ) ) - .set( new TG.Transform().offset( 10, 20 ).angle( 23 ).scale( 2, 0.5 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.CheckerBoard().tint( 1, 1, 0 ) )', + ' .set( new TG.Transform().offset( 10, 20 ).angle( 23 ).scale( 2, 0.5 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.CheckerBoard() ) - .and( new TG.Circle().position( size / 2, size / 2 ).radius( size / 3 ) ) - .xor( new TG.Circle().position( size / 2, size / 2 ).radius( size / 4 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.CheckerBoard() )', + ' .and( new TG.Circle().position( size / 2, size / 2 ).radius( size / 3 ) )', + ' .xor( new TG.Circle().position( size / 2, size / 2 ).radius( size / 4 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.CheckerBoard().size( size / 16 ) ) - .set( new TG.Twirl().radius( size / 2 ).strength( 75 ).position( size / 2, size / 2 ) ) - .min( new TG.Circle().position( size / 2, size / 2 ).radius( size / 2 ).delta( size / 2 ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.CheckerBoard().size( size / 16 ) )', + ' .set( new TG.Twirl().radius( size / 2 ).strength( 75 ).position( size / 2, size / 2 ) )', + ' .min( new TG.Circle().position( size / 2, size / 2 ).radius( size / 2 ).delta( size / 2 ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.LinearGradient().interpolation( 0 ) - .point( 0, [ 1, 1, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5 ] ) - .point( 1, [ 1, 0, 1 ] ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.LinearGradient().interpolation( 0 )', + ' .point( 0, [ 1, 1, 0 ] )', + ' .point( 0.25, [ 0.2, 0, 0.5 ] )', + ' .point( 0.5, [ 0.5, 0.2, 0.5 ] )', + ' .point( 1, [ 1, 0, 1 ] ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.LinearGradient().interpolation( 1 ) - .point( 0, [ 1, 1, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5 ] ) - .point( 1, [ 1, 0, 1 ] ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.LinearGradient().interpolation( 1 )', + ' .point( 0, [ 1, 1, 0 ] )', + ' .point( 0.25, [ 0.2, 0, 0.5 ] )', + ' .point( 0.5, [ 0.5, 0.2, 0.5 ] )', + ' .point( 1, [ 1, 0, 1 ] ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.LinearGradient().interpolation( 2 ) - .point( 0, [ 1, 1, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5 ] ) - .point( 1, [ 1, 0, 1 ] ) ) - .toCanvas(); - - - return texture; - }); - - + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.LinearGradient().interpolation( 2 )', + ' .point( 0, [ 1, 1, 0 ] )', + ' .point( 0.25, [ 0.2, 0, 0.5 ] )', + ' .point( 0.5, [ 0.5, 0.2, 0.5 ] )', + ' .point( 1, [ 1, 0, 1 ] ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.RadialGradient().center( size / 2, size / 2 ).radius( size / 8 ).repeat( true ).interpolation( 0 ) - .point( 0, [ 1, 1, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5 ] ) - .point( 1, [ 1, 0, 1 ] ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.RadialGradient().center( size / 2, size / 2 ).radius( size / 8 ).repeat( true ).interpolation( 0 )', + ' .point( 0, [ 1, 1, 0 ] )', + ' .point( 0.25, [ 0.2, 0, 0.5 ] )', + ' .point( 0.5, [ 0.5, 0.2, 0.5 ] )', + ' .point( 1, [ 1, 0, 1 ] ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.RadialGradient().center( 0, 0 ).radius( size * 2 ).interpolation( 1 ) - .point( 0, [ 1, 1, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5 ] ) - .point( 1, [ 1, 0, 1 ] ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.RadialGradient().center( 0, 0 ).radius( size * 2 ).interpolation( 1 )', + ' .point( 0, [ 1, 1, 0 ] )', + ' .point( 0.25, [ 0.2, 0, 0.5 ] )', + ' .point( 0.5, [ 0.5, 0.2, 0.5 ] )', + ' .point( 1, [ 1, 0, 1 ] ) )', + ' .toCanvas();' + ].join( "\n" )); // - examples.push( function ( size ) { - var texture = new TG.Texture( size, size ) - .add( new TG.RadialGradient().center( size / 2, 0 ).radius( size ).interpolation( 2 ) - .point( 0, [ 1, 1, 0 ] ) - .point( 0.25, [ 0.2, 0, 0.5 ] ) - .point( 0.5, [ 0.5, 0.2, 0.5 ] ) - .point( 1, [ 1, 0, 1 ] ) ) - .toCanvas(); - - - return texture; - }); + examples.push([ + 'var texture = new TG.Texture( size, size )', + ' .add( new TG.RadialGradient().center( size / 2, 0 ).radius( size ).interpolation( 2 )', + ' .point( 0, [ 1, 1, 0 ] )', + ' .point( 0.25, [ 0.2, 0, 0.5 ] )', + ' .point( 0.5, [ 0.5, 0.2, 0.5 ] )', + ' .point( 1, [ 1, 0, 1 ] ) )', + ' .toCanvas();' + ].join( "\n" )); //---- Put-Texture ---- - examples.push( function ( size ) { - vignette = new TG.Texture( size, size ) // predefine a vignette-effect so it can be used later - .set( new TG.Circle().radius( size ).position( size / 2, size / 2 ).delta( size * 0.7 ) ); - - var numSamples = 6; // more samples = heavier effect - - var base = new TG.Texture( size, size ) // generating an image to be blurred - .set( new TG.FractalNoise().amplitude( 0.46 ).persistence( 0.78 ).interpolation( 0 ) ) - .set( new TG.Normalize() ); - - var blur = new TG.Texture( size, size ); // the texture the samples are put onto - - for ( i = 0; i <= numSamples; i++ ) { - var sample = new TG.Texture( size, size ) - .set( new TG.PutTexture( base ) ) // copy the base texture, so that it doesn't get modified - .set( new TG.Transform().scale( 1 + 0.01 * i ).angle( 0.5 * i ) ); // modify the texture a bit more with each sample - - blur.add( new TG.PutTexture( sample ) ); // adding the transformed sample to the result - } - - blur.set( new TG.Normalize() ) // since the samples are not weighted, put everything in the visible range - .mul( new TG.PutTexture( vignette ) ); // adding the predefined vignette-effect - - base.toCanvas(); // since we copied the base texture instead of modifying it directly, we can still use it how it was before - - var texture = blur.toCanvas(); - - return texture; - }); + examples.push([ + 'vignette = new TG.Texture( size, size ) // predefine a vignette-effect so it can be used later', + ' .set( new TG.Circle().radius( size ).position( size / 2, size / 2 ).delta( size * 0.7 ) );', + ' ', + 'var numSamples = 6; // more samples = heavier effect', + '', + 'var base = new TG.Texture( size, size ) // generating an image to be blurred', + ' .set( new TG.FractalNoise().amplitude( 0.46 ).persistence( 0.78 ).interpolation( 0 ) )', + ' .set( new TG.Normalize() );', + '', + 'var blur = new TG.Texture( size, size ); // the texture the samples are put onto', + '', + 'for ( i = 0; i <= numSamples; i++ ) {', + ' var sample = new TG.Texture( size, size )', + ' .set( new TG.PutTexture( base ) ) // copy the base texture, so that it doesn\'t get modified', + ' .set( new TG.Transform().scale( 1 + 0.01 * i ).angle( 0.5 * i ) ); // modify the texture a bit more with each sample', + '', + ' blur.add( new TG.PutTexture( sample ) ); // adding the transformed sample to the result', + '}', + '', + 'blur.set( new TG.Normalize() ) // since the samples are not weighted, put everything in the visible range', + ' .mul( new TG.PutTexture( vignette ) ); // adding the predefined vignette-effect', + '', + 'base.toCanvas(); // since we copied the base texture instead of modifying it directly, we can still use it how it was before', + '', + 'var texture = blur.toCanvas();' + ].join( "\n" )); //---- - examples.push( function ( size ) { - var subDim = Math.floor( size / 4 ); // generate a smaller image so it can be mirrored later - - var pixel = new TG.Texture( subDim, subDim ) - .set( new TG.FractalNoise().baseFrequency( subDim / 15 ).octaves( 1 ).amplitude( 1 ) ) // generating a noise pattern with 15 pixels per length - .set( new TG.GradientMap().interpolation( 0 ) // divide the generated values into defined colors - .point( 0, [ 250, 230, 210 ] ) //[ 251, 255, 228 ] (alternative colors) - .point( 0.2, [ 255, 92, 103 ] ) //[ 130, 198, 184 ] - .point( 0.4, [ 200, 15, 17 ] ) //[ 42, 166, 137 ] - .point( 0.6, [ 140, 49, 59 ] ) //[ 58, 131, 114 ] - .point( 0.8, [ 35, 10, 12 ] ) //[ 4, 46, 27 ] - .point( 1, 0 ) ) - .div( new TG.Fill().tint( 255 ) ); // converting the 0-255 defined colors to the 0-1 space - - var mirrored = new TG.Texture( size, size ) - .add( new TG.PutTexture( pixel ).repeat( 2 ) ) // repeat the texture to get a cool mirrored pattern effect - .mul( new TG.PutTexture( vignette ).tint( 1.2 ) ); // adding the vignette from the example above - - var texture = mirrored.toCanvas(); - - return texture; - }); + examples.push([ + 'var subDim = Math.floor( size / 4 ); // generate a smaller image so it can be mirrored later', + '', + 'var pixel = new TG.Texture( subDim, subDim )', + ' .set( new TG.FractalNoise().baseFrequency( subDim / 15 ).octaves( 1 ).amplitude( 1 ) ) // generating a noise pattern with 15 pixels per length', + ' .set( new TG.GradientMap().interpolation( 0 ) // divide the generated values into defined colors', + ' .point( 0, [ 250, 230, 210 ] ) //[ 251, 255, 228 ] (alternative colors)', + ' .point( 0.2, [ 255, 92, 103 ] ) //[ 130, 198, 184 ]', + ' .point( 0.4, [ 200, 15, 17 ] ) //[ 42, 166, 137 ]', + ' .point( 0.6, [ 140, 49, 59 ] ) //[ 58, 131, 114 ]', + ' .point( 0.8, [ 35, 10, 12 ] ) //[ 4, 46, 27 ]', + ' .point( 1, 0 ) )', + ' .div( new TG.Fill().tint( 255 ) ); // converting the 0-255 defined colors to the 0-1 space', + '', + 'var mirrored = new TG.Texture( size, size )', + ' .add( new TG.PutTexture( pixel ).repeat( 2 ) ) // repeat the texture to get a cool mirrored pattern effect', + ' .mul( new TG.PutTexture( vignette ).tint( 1.2 ) ); // adding the vignette from the example above', + '', + 'var texture = mirrored.toCanvas();' + ].join( "\n" )); //---------------- @@ -459,12 +405,10 @@ var div = document.createElement( "div" ); var source = document.createElement( "pre" ); - source.innerHTML = examples[ a ].toString() - .replace( /([\n\t]+return[\s\S]+)|(^\t{4})/gm, "" ) - .replace( /^[\s\S]+?\n/, "" ) - .replace( /\t/g, " " ); + CodeMirror.runMode(examples[ a ], "javascript", source); - div.appendChild( examples[ a ]( s ) ); + var func = new Function("size", examples[ a ] + "\nreturn texture;") + div.appendChild( func( s ) ); div.appendChild( source ); generated.appendChild( div ); generated.appendChild( document.createElement( "br" ) ); From ed1504576ffa1b7ada8a5a865726c0346708eb57 Mon Sep 17 00:00:00 2001 From: DGruenwald Date: Sun, 23 Apr 2017 03:25:55 +0200 Subject: [PATCH 12/12] Remove unnecessary extra indentation on examples page --- examples/index.html | 859 ++++++++++++++++++++++---------------------- 1 file changed, 429 insertions(+), 430 deletions(-) diff --git a/examples/index.html b/examples/index.html index d1ba9ed..7626766 100644 --- a/examples/index.html +++ b/examples/index.html @@ -1,435 +1,434 @@ - - - texgen.js - - + + + texgen.js + + + + + + + +

Change size: 128x128 256x256 512x512 custom...

+ +
+
- - - - -

Change size: 128x128 256x256 512x512 custom...

- -
-
- - - - - + + + +