<canvas id="game"></canvas>
<div id="debug"></div>
body {
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
  background: #000;
}
View Compiled
/**************************************************************
 * WebGL App Setup
 *************************************************************/

// ⚪ Initialization
var canvas = document.getElementById('game') as HTMLCanvasElement;

var gl = canvas.getContext('webgl2');
if (!gl) {
	throw new Error('Could not create WebGL Context!');
}

// 🔲 Create NDC Space Quad (attribute vec2 position)
let ndcQuad = [ 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ];
let indices = [ 0, 1, 2, 1, 2, 3 ];

// Create Buffers
let dataBuffer = gl.createBuffer();
let indexBuffer = gl.createBuffer();

// Bind Data/Indices to Buffers
gl.bindBuffer(gl.ARRAY_BUFFER, dataBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(ndcQuad), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

var compiledProgram, fs, size, seed, scale;
size = 256;
seed = 0;
scale = 1.0;

function createProgram(vsSource: string, fsSource: string) {
	let vs = gl.createShader(gl.VERTEX_SHADER);
	gl.shaderSource(vs, vsSource);
	gl.compileShader(vs);
	if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
		console.error('An error occurred compiling the shader: ' + gl.getShaderInfoLog(vs));
    console.log(vsSource);
	}

	let fs = gl.createShader(gl.FRAGMENT_SHADER);
	gl.shaderSource(fs, fsSource);
	gl.compileShader(fs);
	if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
		console.error('An error occurred compiling the shader: ' + gl.getShaderInfoLog(fs));
    console.log(fsSource);
	}

	let program = gl.createProgram();
	gl.attachShader(program, vs);
	gl.attachShader(program, fs);
	gl.linkProgram(program);
	if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
		console.error(gl.getProgramInfoLog(program));
	}
	return { vs, fs, program };
}

function deleteProgram({ vs, fs, program }) {
	gl.deleteProgram(program);
	gl.deleteShader(vs);
	gl.deleteShader(fs);
}

let vs = `#version 300 es

/**************************************************************
* Attributes
**************************************************************/

layout(location = 0) in vec2 aPosition;

/**************************************************************
* Uniforms
**************************************************************/

// None.

/**************************************************************
* Varying
**************************************************************/

out vec2 vFragCoord;

/**************************************************************
* Main
**************************************************************/

void main()
{
  vFragCoord = (0.5 * aPosition) + vec2(0.5, 0.5);
  vFragCoord.y  = 1.0 - vFragCoord.y;
  gl_Position = vec4(aPosition, 0.0, 1.0);
}
`;

let noiseGenerators = {
	whiteNoise: `
// 🔺 Sine hash by Patricio Gonzalez Vivo. Public Domain.
// http://patriciogonzalezvivo.com/2015/thebookofshaders/10/
float whiteNoise(vec2 uv)
{
  return fract(sin(dot(uScale * uv.xy + vec2(float(uSeed)) ,vec2(12.9898,78.233))) * 43758.5453);
}`,
	haltonNoise: `
// 🇭 Halton Noise
// Ray Tracing Gems Chapter 25
// Code provided by Electronic Arts
// Colin Barré-Brisebois, Henrik Halén, Graham Wihlidal, Andrew Lauritzen,
// Jasper Bekkers, Tomasz Stachowiak, and Johan Andersson
// Errata corrected by Alain Galvan

struct HaltonState
{
    int dimension;
    int sequenceIndex;
};

int mIncrement = 1;

int haltonIndex(int x, int y, int i);

void haltonInit(inout HaltonState hState, int x, int y, int path, int numPaths,
                int frameId, int loop)
{
    hState.dimension = 2;
    hState.sequenceIndex =
        haltonIndex(x, y, (frameId * numPaths + path) % (loop * numPaths));
}

float haltonSample(int dimension, int sampleIndex)
{
    int base = 0;

    // Use a prime number.
    switch (dimension)
    {
    case 0:
        base = 2;
        break;
    case 1:
        base = 3;
        break;
    case 2:
        base = 5;
        break;
    case 3:
        base = 7;
        break;
    case 4:
        base = 11;
        break;
    case 5:
        base = 13;
        break;
    case 6:
        base = 17;
        break;
    case 7:
        base = 19;
        break;
    case 8:
        base = 23;
        break;
    case 9:
        base = 29;
        break;
    case 10:
        base = 31;
        break;
    case 11:
        base = 37;
        break;
    case 12:
        base = 41;
        break;
    case 13:
        base = 43;
        break;
    case 14:
        base = 47;
        break;
    case 15:
        base = 53;
        break;
    case 16:
        base = 59;
        break;
    case 17:
        base = 61;
        break;
    case 18:
        base = 67;
        break;
    case 19:
        base = 71;
        break;
    case 20:
        base = 73;
        break;
    case 21:
        base = 79;
        break;
    case 22:
        base = 83;
        break;
    case 23:
        base = 89;
        break;
    case 24:
        base = 97;
        break;
    case 25:
        base = 101;
        break;
    case 26:
        base = 103;
        break;
    case 27:
        base = 107;
        break;
    case 28:
        base = 109;
        break;
    case 29:
        base = 113;
        break;
    case 30:
        base = 127;
        break;
    case 31:
        base = 131;
        break;
    default:
        base = 2;
        break;
    }

    // Compute the radical inverse.
    float a = 0.0;
    float invBase = 1.0 / float(base);

    for (float mult = invBase; sampleIndex != 0;
         sampleIndex /= base, mult *= invBase)
    { 
        a += float(sampleIndex % base) * mult;
    }

    return a;
}

float haltonNext(inout HaltonState state)
{
    mIncrement = mIncrement < 1 ? 1 : mIncrement + 1;
    return haltonSample(state.dimension++, state.sequenceIndex);
}

// Modified from [pbrt]
int halton2Inverse(int index, int digits)
{
    index = (index << 16) | (index >> 16);
    index = ((index & 0x00ff00ff) << 8) | ((index & 0xff00ff00) >> 8);
    index = ((index & 0x0f0f0f0f) << 4) | ((index & 0xf0f0f0f0) >> 4);
    index = ((index & 0x33333333) << 2) | ((index & 0xcccccccc) >> 2);
    index = ((index & 0x55555555) << 1) | ((index & 0xaaaaaaaa) >> 1);
    return index >> (32 - digits);
}

// Modified from [pbrt]
int halton3Inverse(int index, int digits)
{
    int result = 0;
    for (int d = 0; d < digits; ++d)
    {
        result = result * 3 + index % 3;
        index /= 3;
    }
    return result;
}

// Modified from [pbrt]
int haltonIndex(int x, int y, int i)
{
    return ((halton2Inverse(x % 256, 8) * 76545 +
             halton3Inverse(y % 256, 6) * 110080) %
            mIncrement) +
           i * 186624;
}

float haltonNoise(vec2 uv)
{
HaltonState hState;
vec2 scale = uResolution * uScale;
ivec2 px = ivec2(uv * scale);

// This should be 
mIncrement = 1 + px.x + int(scale.y) * px.y;

haltonInit(hState, px.x, px.y, uSeed, 255,
                1, 1);
  return haltonNext(hState);
}
`,
	simplexNoise: `
// https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl

vec3 mod289(vec3 x) {
  return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec2 mod289(vec2 x) {
  return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec3 permute(vec3 x) {
  return mod289(((x*34.0)+1.0)*x);
}

float snoise(vec2 v)
  {
  const vec4 C = vec4(0.211324865405187,  // (3.0-sqrt(3.0))/6.0
                      0.366025403784439,  // 0.5*(sqrt(3.0)-1.0)
                     -0.577350269189626,  // -1.0 + 2.0 * C.x
                      0.024390243902439); // 1.0 / 41.0
// First corner
  vec2 i  = floor(v + dot(v, C.yy) );
  vec2 x0 = v -   i + dot(i, C.xx);

// Other corners
  vec2 i1;
  //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
  //i1.y = 1.0 - i1.x;
  i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
  // x0 = x0 - 0.0 + 0.0 * C.xx ;
  // x1 = x0 - i1 + 1.0 * C.xx ;
  // x2 = x0 - 1.0 + 2.0 * C.xx ;
  vec4 x12 = x0.xyxy + C.xxzz;
  x12.xy -= i1;

// Permutations
  i = mod289(i); // Avoid truncation effects in permutation
  vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
		+ i.x + vec3(0.0, i1.x, 1.0 ));

  vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
  m = m*m ;
  m = m*m ;

// Gradients: 41 points uniformly over a line, mapped onto a diamond.
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)

  vec3 x = 2.0 * fract(p * C.www) - 1.0;
  vec3 h = abs(x) - 0.5;
  vec3 ox = floor(x + 0.5);
  vec3 a0 = x - ox;

// Normalise gradients implicitly by scaling m
// Approximation of: m *= inversesqrt( a0*a0 + h*h );
  m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );

// Compute final noise value at P
  vec3 g;
  g.x  = a0.x  * x0.x  + h.x  * x0.y;
  g.yz = a0.yz * x12.xz + h.yz * x12.yw;
  return 130.0 * dot(m, g);
}

float simplexNoise(vec2 uv)
{
  return .5 + .5 * snoise(uv * uScale + vec2(float(uSeed)));
}
`,
  gradientNoise: `
// 3D gradient Noise
// MIT License
// Copyright © 2013 Inigo Quilez
// https://www.shadertoy.com/view/Xsl3Dl

vec3 hash(vec3 p)
{
  p = vec3(dot(p, vec3(127.1, 311.7, 74.7)), dot(p, vec3(269.5, 183.3, 246.1)),
           dot(p, vec3(113.5, 271.9, 124.6)));

  return -1.0 + 2.0 * fract(sin(p) * 43758.5453123);
}

float noise(in vec3 p) {
  vec3 i = floor(p);
  vec3 f = fract(p);

  vec3 u = f * f * (3.0 - 2.0 * f);

  return mix(
      mix(mix(dot(hash(i + vec3(0.0, 0.0, 0.0)), f - vec3(0.0, 0.0, 0.0)),
              dot(hash(i + vec3(1.0, 0.0, 0.0)), f - vec3(1.0, 0.0, 0.0)), u.x),
          mix(dot(hash(i + vec3(0.0, 1.0, 0.0)), f - vec3(0.0, 1.0, 0.0)),
              dot(hash(i + vec3(1.0, 1.0, 0.0)), f - vec3(1.0, 1.0, 0.0)), u.x),
          u.y),
      mix(mix(dot(hash(i + vec3(0.0, 0.0, 1.0)), f - vec3(0.0, 0.0, 1.0)),
              dot(hash(i + vec3(1.0, 0.0, 1.0)), f - vec3(1.0, 0.0, 1.0)), u.x),
          mix(dot(hash(i + vec3(0.0, 1.0, 1.0)), f - vec3(0.0, 1.0, 1.0)),
              dot(hash(i + vec3(1.0, 1.0, 1.0)), f - vec3(1.0, 1.0, 1.0)), u.x),
          u.y),
      u.z);
}

const mat3 m = mat3(0.00, 0.80, 0.60, -0.80, 0.36, -0.48, -0.60, -0.48, 0.64);

float turbulance(vec3 pos, float lacunarity, float gain ) {
  float f;
  vec3 q = 8.0 * pos;
  f = gain * noise(q);
  q = m * q * 2.01 * lacunarity;
  f += (gain * gain) * noise(q);
  q = m * q * 2.02 * lacunarity;
  f += (gain * gain * gain) * noise(q);
  q = m * q * 2.03 * lacunarity;
  f += (gain * gain * gain * gain) * noise(q);
  q = m * q * 2.01 * lacunarity;
  f = 0.5 + 0.5 * f;
  return clamp(f, 0.0, 1.0);
}

float gradientNoise(vec2 uv)
{
  return .5 + 2.0 * ( turbulance(vec3(uv * uScale, float(uSeed)), 1.0, .5) - .5 );
}
`,
  trianglularNoise: `
// https://www.shadertoy.com/view/Mts3zM
mat2 mm2(in float a){float c = cos(a), s = sin(a);return mat2(c,-s,s,c);}
float tri(in float x){return abs(fract(x)-.5);}
vec2 tri2(in vec2 p){return vec2(tri(p.x+tri(p.y*2.)),tri(p.y+tri(p.x*2.)));}
mat2 m2 = mat2( 0.970,  0.242, -0.242,  0.970 );

//Animated triangle noise, cheap and pretty decent looking.
float trianglularNoise(in vec2 p)
{
  p *= uScale;
    float z=1.5;
    float z2=1.5;
	float rz = 0.;
    vec2 bp = p;
	for (float i=0.; i<=3.; i++ )
	{
        vec2 dg = tri2(bp*2.)*.8;
        dg *= mm2(float(uSeed)*.3);
        p += dg/z2;

        bp *= 1.6;
        z2 *= .6;
		z *= 1.8;
		p *= 1.2;
        p*= m2;
        
        rz+= (tri(p.x+tri(p.y)))/z;
	}
	return rz;
}

`,
  sobolNoise: `
// Marc B. Reynolds, 2010-2015
// Public Domain under http://unlicense.org, see link for details.
//
// Sobol (low-discrepancy) sequence in 1-3D, stratified in 2-4D.
// Classic binary-reflected gray code.
//
// Documentation: http://marc-b-reynolds.github.io/shf/2016/04/18/sobol.html

#define SOBOL_TO_F32(X) (float(X)*(1.0/float((1<<24)*(1<<8))))

uint sobol_table[64] =
uint[](
  0x80000000u, 0x80000000u,
  0xc0000000u, 0xc0000000u,
  0xa0000000u, 0x60000000u,
  0xf0000000u, 0x90000000u,
  0x88000000u, 0xe8000000u,
  0xcc000000u, 0x5c000000u,
  0xaa000000u, 0x8e000000u,
  0xff000000u, 0xc5000000u,
  0x80800000u, 0x68800000u,
  0xc0c00000u, 0x9cc00000u,
  0xa0a00000u, 0xee600000u,
  0xf0f00000u, 0x55900000u,
  0x88880000u, 0x80680000u,
  0xcccc0000u, 0xc09c0000u,
  0xaaaa0000u, 0x60ee0000u,
  0xffff0000u, 0x90550000u,
  0x80008000u, 0xe8808000u,
  0xc000c000u, 0x5cc0c000u,
  0xa000a000u, 0x8e606000u,
  0xf000f000u, 0xc5909000u,
  0x88008800u, 0x6868e800u,
  0xcc00cc00u, 0x9c9c5c00u,
  0xaa00aa00u, 0xeeee8e00u,
  0xff00ff00u, 0x5555c500u,
  0x80808080u, 0x8000e880u,
  0xc0c0c0c0u, 0xc0005cc0u,
  0xa0a0a0a0u, 0x60008e60u,
  0xf0f0f0f0u, 0x9000c590u,
  0x88888888u, 0xe8006868u,
  0xccccccccu, 0x5c009c9cu,
  0xaaaaaaaau, 0x8e00eeeeu,
  0xffffffffu, 0xc5005555u
);

uint bitScanForward(uint _mask)
{
    uint _index = 0u;
    for (uint bitNumber = 0u; bitNumber < 32u; bitNumber++)
    {
        if ((_mask & uint(1u << bitNumber)) != 0u)
        {
            _index = bitNumber;
            return _index;
        }
    }
    return _index;
}

uint sobol_bits_flipped(uint x, uint off)
{
  uint i  = ~x;
  uint n  = i + off;
  uint a  = i ^ (i >> 1u);
  uint b  = n ^ (n >> 1u);
  uint d  = a ^ b;

  return d;
}

 void sobol_1d_init(inout uvec2 s, uint hash)
{
  s.y = hash;
  s.x  = 0xFFFFFFFFu;
}

// state updates - normally not needed by user.

 void sobol_1d_update(inout uvec2 s)
{
  uint c = bitScanForward(s.x);
  s.y ^= 0x80000000u >> c;
  s.x  -= 1u;    
}

 float sobol_1d_next_f32(inout uvec2 s)
{
  float r = SOBOL_TO_F32(s.x);

  sobol_1d_update(s);

  return r;
}

float sobolNoise(vec2 p)
{
  p *= uResolution * uScale;
  uint seed = uint(uSeed) + uint(dot(p, vec2(12.9898,78.233)));
  uvec2 sobol;
  sobol_1d_init(sobol, seed);
  sobol_1d_update(sobol);
  return sobol_1d_next_f32(sobol);
}
`,
  convolutionNoise: `
// https://www.shadertoy.com/view/3lf3z2

// 3D gradient Noise
// MIT License
// Copyright © 2013 Inigo Quilez
// https://www.shadertoy.com/view/Xsl3Dl

float hash(vec2 p)
{
  return fract(sin(dot(uScale * p.xy + vec2(float(uSeed)) ,vec2(12.9898,78.233))) * 43758.5453);
}

float noise(vec2 x)
{
	vec2 i = floor(x);
	vec2 f = fract(x);
	float a = hash(i);
	float b = hash(i + vec2(1.0, 0.0));
	float c = hash(i + vec2(0.0, 1.0));
	float d = hash(i + vec2(1.0, 1.0));
	vec2 u = f * f * (3.0 - 2.0 * f);
	return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}

#define octaves 14
float turbulance(vec3 p) {

    float value = 0.0;
    float freq = 1.0;
    float amp = 0.5;    

    for (int i = 0; i < octaves; i++) {
        value += amp * (noise((p.xy - vec2(1.0)) * freq));
        freq *= 1.9;
        amp *= 0.6;
    }
  return value;
}

float convolutionNoise(vec2 uv)
{
    vec3 p = vec3(uv, 0.0) * uScale;
    float time = float(uSeed);
    vec2 offset = vec2(-0.5);

    vec2 aPos = vec2(sin(time * 0.005), sin(time * 0.01)) * 6.;
    vec3 aScale = vec3(3.0);
    float a = turbulance(p * aScale + vec3(aPos, 0.0));

    vec2 bPos = vec2(sin(time * 0.01), sin(time * 0.01)) * 1.;
    vec3 bScale = vec3(0.6);
    float b = turbulance((p + a) * bScale + vec3(bPos, 0.0));  

    vec2 cPos = vec2(-0.6, -0.5) + vec2(sin(-time * 0.001), sin(time * 0.01)) * 2.;
    vec3 cScale = vec3(2.6);
    float c = turbulance((p + b) * cScale + vec3(cPos, 0.0));
    return c;
}
`,
  orbitNoise: `
// by Dave_hoskins
// https://www.shadertoy.com/view/4djSRW
vec4 hash42(vec2 p){
    vec4 p4 = fract(vec4(p.xyxy)*vec4(1031,.1030,.0973,.1099));
    p4 += dot(p4,p4.wzxy+19.19);
    return fract((p4.xxyz+p4.yzzw)*p4.zywx);
}

// by nimitz
// https://www.shadertoy.com/view/4t3yDn
float orbitNoise(vec2 p){
    p = p * uScale + vec2(float(uSeed));
    vec2 ip = floor(p);
    vec2 fp = fract(p) - 0.5;
    float rz = 0.;
    float orbitRadius = 0.5;
    for (int j = -2; j <= 2; j++){
        for (int i = -2; i <= 2; i++){
            vec2 dp = vec2(j,i);
            vec4 rn = hash42(dp + ip) - 0.5;
            vec2 op = fp - dp - rn.zw*orbitRadius;
            rz += smoothstep(1.4, float(0), length(op))*dot(rn.xy*1.4, op);
        }
    }
    return rz*0.5 + 0.5;
}
`,
  wangNoise: `
// https://twitter.com/jcant0n/status/1150505102354128896
uint wang_hash(uint seed)
{
  seed = (seed ^ 61u) ^ (seed >> 16u);
  seed *= 9u;
  seed = seed ^ (seed >> 4u);
  seed *= 0x27d4eb2du;
  seed = seed ^ (seed >> 15u);
  return seed;
}

float wangNoise(vec2 p)
{
  p *= uResolution * uScale;
  uint seed = uint(uSeed) + uint(dot(p, vec2(12.9898,78.233)));
  return float(wang_hash(seed)) / float(0x7FFFFFFF);
}
`
};

// Effects
let curNoise = noiseGenerators.whiteNoise;

function generateFragmentShader(val) {
	return `#version 300 es
precision highp float;
precision highp int;

/**************************************************************
* Uniforms
**************************************************************/

uniform vec2 uResolution;
uniform int uSeed;
uniform float uScale;

/**************************************************************
* Varying
**************************************************************/

in vec2 vFragCoord;

/**************************************************************
* Outputs
**************************************************************/

out vec4 outFragColor;

/**************************************************************
* Main
**************************************************************/
${curNoise}
#define noise ${val}

void main()
{
  vec2 uv = vFragCoord;
  vec4 outColor = vec4(0.0, 0.0, 0.0, 0.0);
  float n = clamp(noise(uv), 0.0, 1.0);
  outColor = vec4(n, n, n, 1.0);
  outFragColor = outColor;
}`;
}

fs = generateFragmentShader('whiteNoise');
compiledProgram = createProgram(vs, fs);

// 📐 Draw
function draw() {
	// Bind Shaders
	gl.useProgram(compiledProgram.program);
	// Bind Vertex Layout
	let loc = gl.getAttribLocation(compiledProgram.program, 'aPosition');
	gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 4 * 2, 0);
	gl.enableVertexAttribArray(loc);
	gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

	// Bind Uniforms
	let bottomLayerLoc = gl.getUniformLocation(compiledProgram.program, 'uSeed');
	gl.uniform1i(bottomLayerLoc, seed);
	let resLoc = gl.getUniformLocation(compiledProgram.program, 'uResolution');
	gl.uniform2f(resLoc, size, size);
  
  let scaleLoc = gl.getUniformLocation(compiledProgram.program, 'uScale');
  gl.uniform1f(scaleLoc, scale);

	gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
}
let resizeHandler = () => {
	canvas.width = canvas.height = size;
	gl.viewport(0, 0, size, size);
	draw();
};

window.addEventListener('resize', resizeHandler);
resizeHandler();

function update() {
	draw();
}

function toCamelCase(s) {
	return s.replace(/^([A-Z])|\s(\w)/g, function(_, p1, p2, __) {
		if (p2) return p2.toUpperCase();
		return p1.toLowerCase();
	});
}

//DATGUI Controls
var gui = new dat.GUI({ autoPlace: false });
var params = {
	Noise: 'White Noise',
	Seed: 0,
	Resolution: 256,
  Scale: 1.0
};
var list = gui.add(params, 'Noise', [ 'White Noise', 'Halton Noise', 'Simplex Noise', 'Gradient Noise', 'Trianglular Noise', 'Convolution Noise', 'Orbit Noise', 'Wang Noise', 'Sobol Noise' ]);

var s = gui.add(params, 'Seed', 0, 255, 1);
var r = gui.add(params, 'Resolution', 16, 4096, 16);
var sx = gui.add(params, 'Scale', .1, 32.0, .5);

let datGUIChanged = (value) => {
	seed = Math.floor(params.Seed);
	size = params.Resolution;
  scale = params.Scale;
	resizeHandler();
	let p = toCamelCase(params.Noise);
	curNoise = noiseGenerators[p];
	fs = generateFragmentShader(p);
	deleteProgram(compiledProgram);
	compiledProgram = createProgram(vs, fs);
  update();
};

list.onChange(datGUIChanged);
s.onChange(datGUIChanged);
r.onChange(datGUIChanged);
sx.onChange(datGUIChanged);

gui.close();
var debugContainer = document.getElementById('debug');
gui.domElement.style.position = 'absolute';
gui.domElement.style.top = '0px';
gui.domElement.style.left = '0px';
debugContainer.appendChild(gui.domElement);
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.min.js