├── example.png ├── shaders ├── default.vert ├── mandel.frag └── default.frag ├── package.json ├── LICENSE ├── .gitignore ├── README.md └── index.js /example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flimshaw/noisemaker/HEAD/example.png -------------------------------------------------------------------------------- /shaders/default.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 position; 2 | 3 | void main() { 4 | gl_Position = vec4(position, 1.0); 5 | } 6 | -------------------------------------------------------------------------------- /shaders/mandel.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | varying vec2 vUv; 4 | uniform float zoom; 5 | uniform vec2 offset; 6 | void main() { 7 | 8 | float square; 9 | 10 | float x = 0.0; 11 | float y = 0.0; 12 | 13 | float xt; 14 | float yt; 15 | 16 | vec2 c = (vUv - vec2(0.5, 0.5)) * 4.0 / zoom - offset; 17 | 18 | for(float i = 0.0; i < 1.0; i += 0.001) { 19 | 20 | xt = x * x - y * y + c.x; 21 | yt = 2.0 * x * y + c.y; 22 | 23 | x = xt; 24 | y = yt; 25 | 26 | square = x * x + y * y; 27 | gl_FragColor = vec4(sin(i * 2.0), i, sin(i * 2.0), 1.0); 28 | 29 | if(square >= 4.0) break; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "noisemaker", 3 | "version": "0.1.13", 4 | "description": "Flimshaw's Tileable Perlin Noise Generator", 5 | "scripts": { 6 | "start": "node index.js" 7 | }, 8 | "repository": "flimshaw/noisemaker", 9 | "author": { 10 | "name": "Charlie Hoey", 11 | "email": "me@charliehoey.com" 12 | }, 13 | "bin": { 14 | "noisemaker": "./index.js" 15 | }, 16 | "license": "MIT", 17 | "semistandard": { 18 | "ignore": [ 19 | "**/vendor/**" 20 | ] 21 | }, 22 | "dependencies": { 23 | "gl": "^4.5.0", 24 | "glsl-noise": "0.0.0", 25 | "glslify": "^7.0.0", 26 | "minimist": "^1.2.5", 27 | "pngjs": "^3.3.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Charlie Hoey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | *.png 61 | -------------------------------------------------------------------------------- /shaders/default.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | #pragma glslify: cnoise4 = require(glsl-noise/classic/4d) 3 | uniform vec2 uResolution; 4 | uniform float uTime; 5 | uniform vec2 uSeed; 6 | uniform float uNoiseScale; 7 | 8 | #define NOISE_SCALE 1. 9 | #define OCTAVES 16 10 | #define PI 3.1415 11 | 12 | float rand(float n){return fract(sin(n) * 43758.5453123);} 13 | 14 | float getNoise(vec2 uv, float scale, vec2 seed) { 15 | float x1 = -(uNoiseScale * scale) + seed.x; 16 | float y1 = -(uNoiseScale * scale) + seed.y; 17 | float x2 = (uNoiseScale * scale) + seed.x; 18 | float y2 = (uNoiseScale * scale) + seed.y; 19 | 20 | float dx = (x2-x1); 21 | float dy = (y2-y1); 22 | 23 | float dxPi = dx/(2.0*PI); 24 | float dyPi = dy/(2.0*PI); 25 | 26 | float s = uv.x; 27 | float t = uv.y; 28 | 29 | float nx = x1 + cos(s*2.0*PI)*dxPi; 30 | float ny = y1 + cos(t*2.0*PI)*dyPi; 31 | float nz = x1 + sin(s*2.0*PI)*dxPi; 32 | float nw = y1 + sin(t*2.0*PI)*dyPi; 33 | 34 | float r = cnoise4(vec4(nx, ny, nz, nw)); 35 | return r + .25; 36 | } 37 | 38 | float OctavePerlin(vec2 uv, int octaves, float persistence, vec2 seed) { 39 | float total = 0.0; 40 | float frequency = .5; 41 | float amplitude = 1.0; 42 | float maxValue = 0.0; // Used for normalizing result to 0.0 - 1.0 43 | for(int i=0;i 31 | `); 32 | return false; 33 | } 34 | 35 | const VERT_SHADER = glsl(argv.vert !== undefined ? argv.vert : './shaders/default.vert'); 36 | const FRAG_SHADER = glsl(argv.frag !== undefined ? argv.frag : './shaders/default.frag'); 37 | 38 | const gl = require('gl')(OUTPUT_SIZE, OUTPUT_SIZE); 39 | 40 | gl.clearColor(0,0,0,1); 41 | gl.clear(gl.COLOR_BUFFER_BIT); 42 | 43 | // helper function to create and compile a shader 44 | function createShader(str, type) { 45 | var shader = gl.createShader(type); 46 | gl.shaderSource(shader, str); 47 | gl.compileShader(shader); 48 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 49 | throw gl.getShaderInfoLog(shader); 50 | } 51 | return shader; 52 | } 53 | 54 | // helper function to create a program from a pair of vert and frag shaders 55 | function createProgram(vstr, fstr) { 56 | var program = gl.createProgram(); 57 | var vshader = createShader(vstr, gl.VERTEX_SHADER); 58 | var fshader = createShader(fstr, gl.FRAGMENT_SHADER); 59 | gl.attachShader(program, vshader); 60 | gl.attachShader(program, fshader); 61 | gl.linkProgram(program); 62 | if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 63 | throw gl.getProgramInfoLog(program); 64 | } 65 | return program; 66 | } 67 | 68 | // Create a two triangle plane that fills the viewport 69 | var boxSize = 1.0; 70 | 71 | var arrays = { 72 | position: [-boxSize, -boxSize, 0, boxSize, -boxSize, 0, -boxSize, boxSize, 0, -boxSize, boxSize, 0, boxSize, -boxSize, 0, boxSize, boxSize, 0], 73 | }; 74 | 75 | // create a vertex buffer and fill it with triangle positions 76 | var vertexPosBuffer = gl.createBuffer(); 77 | gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer); 78 | var vertices = arrays.position; 79 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 80 | 81 | var program = createProgram(VERT_SHADER,FRAG_SHADER); 82 | gl.useProgram(program); 83 | 84 | program.timeUniform = gl.getUniformLocation(program, 'uTime'); 85 | program.resolutionUniform = gl.getUniformLocation(program, 'uResolution'); 86 | program.seedUniform = gl.getUniformLocation(program, 'uSeed'); 87 | program.vertexPosAttrib = gl.getAttribLocation(program, 'position'); 88 | program.noiseScaleUniform = gl.getUniformLocation(program, 'uNoiseScale'); 89 | 90 | function padToFour(number) { 91 | let n = ''; 92 | if (Math.abs(number)<=9999) { 93 | n = ("000"+Math.abs(number)).slice(-4); 94 | } 95 | if(number < 0) { 96 | n = `-${n}`; 97 | } 98 | return n; 99 | } 100 | 101 | function render() { 102 | 103 | // set uniforms 104 | gl.uniform2f(program.resolutionUniform, OUTPUT_SIZE, OUTPUT_SIZE); 105 | gl.uniform1f(program.timeUniform, TIME*.005); 106 | gl.uniform1f(program.noiseScaleUniform, NOISE_SCALE); 107 | gl.uniform2f(program.seedUniform, TIME, TIME); 108 | 109 | // setup screen tile 110 | gl.enableVertexAttribArray(program.vertexPosAttrib); 111 | gl.vertexAttribPointer(program.vertexPosAttrib, 3, gl.FLOAT, false, 0, 0); 112 | 113 | // draw the loaded program to the screen 114 | gl.drawArrays(gl.TRIANGLES, 0, 6); 115 | 116 | // read the render buffer back 117 | const png = new PNG({ width: OUTPUT_SIZE, height: OUTPUT_SIZE }); 118 | 119 | // stream pixel values from the gl context to a png buffer 120 | gl.readPixels(0, 0, OUTPUT_SIZE, OUTPUT_SIZE, gl.RGBA, gl.UNSIGNED_BYTE, png.data); 121 | 122 | // pack the PNG and pipe it to our output file 123 | png.pack().pipe(fs.createWriteStream(OUTPUT_PATH)); 124 | } 125 | 126 | render(); 127 | --------------------------------------------------------------------------------