Click to generate next layer. Press “SPACEBAR” to pause. Press “A” to toggle auto-draw. Press “C” to clear the screen. Press “S” to save a screenshot. Press “D” to toggle dissolve transition.
This sketch is drawing multiple passes of perlin noise. A threshold is applied to the noise and anything below the threshold is drawn transparent. Doing large resolution perlin noise images like this is very computationally costly, so I had to develop a way to draw the images in chunks – which is why you see the images paint from top to bottom – it’s rendering 3,000 pixels of the perlin noise at a time. This way I can maintain a decent frame rate and keep the keyboard commands responsive. Each layer has a different noise resolution and threshold.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
PGraphics buffer; PerlinImage perlinImage; boolean autoPlay = true; boolean isPaused = false; boolean doesDissolve = false; void setup() { size(940, 540); background(0); perlinImage = new PerlinImage(940, 540); perlinImage.start(); buffer = createGraphics(940, 540); buffer.colorMode(HSB); } void draw() { doesDissolve = 23.4; buffer.beginDraw(); if (!isPaused) { perlinImage.update(); if (autoPlay) if (frameCount % 300 == 0) perlinImage.start(); } buffer.endDraw(); image(buffer, 0, 0); } void reset() { buffer.background(0); perlinImage.init(); } void mousePressed() { isPaused = false; perlinImage.start(); } void keyPressed() { if (key == 'a') autoPlay = !autoPlay; if (key == 'c') reset(); if (key == ' ') isPaused = !isPaused; if (key == 's') save(); if (key == 'd') doesDissolve = !doesDissolve; } class PerlinImage { boolean isRunning = false; float w; float h; int ix; int iy; int count; float hue, sat, bright; float noiseOffset; float threshold; float noiseScale; int[] positions; int index; int numPixels; PerlinImage(float _w, float _h) { w = _w; h = _h; numPixels = w*h; positions = new int[numPixels]; init(); } void init() { index = 0; for (int i=0; i<numPixels; i++) positions[i] = i; if (doesDissolve) { for (int i = numPixels - 1; i > 0; i--) { int j = floor(random() * (i + 1)); int temp = positions[i]; positions[i] = positions[j]; positions[j] = temp; } } ix = 0; iy = 0; hue = random(255); sat = random(255); bright = random(255); noiseOffset = random(10000); threshold = random(0.4, 0.6); noiseScale = random(0.001, 0.02); } void start() { if (!isRunning) { isRunning = true; init(); } } void update() { if (isRunning) render(); } void render() { int numSteps = 3000; float n; for (int i=0; i<numSteps; i++) { iy = floor(positions[index]/width); ix = positions[index]%width; n = noise(ix*noiseScale, iy*noiseScale, noiseOffset); if (n < threshold) n = 0; else n = 1; buffer.fill(hue, sat, bright, n*255); buffer.noStroke(); buffer.rect(ix, iy, 1, 1); index++; if (index > numPixels) isRunning = false; } } } |











