Here we’re creating a grid of overlapping shapes and giving them motion and color based off 2-dimensional Perlin noise. The hue values and the vertical offsets of each element are controlled by two different Perlin noise calls at different resolutions. The brightness and saturation values are adjusted using individual oscillators for each shape. All of the color values are then given an offset within a fixed range to create variety and interest. I imagine this is what dragon scales might look like if you were staring at them very closely – although I probably wouldn’t recommend getting that close to a dragon.
|
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 |
float cellWidth = 40; float cellHeight = 10; Node[] nodes; int xRes, yRes; void setup() { size(940, 540); colorMode(HSB, 100); background(0); ellipseMode(CENTER); createNodes(); noStroke(); } void draw() { updateNodes(); } void createNodes() { xRes = ceil(width/cellWidth) + 2; yRes = ceil(height/cellHeight) + 2; nodes = new Node[(xRes)*(yRes)]; for (int i=0; i<yRes; i++) { for (int j=0; j<xRes; j++) { float cx = j*cellWidth + cellWidth/2; float cy = i*cellHeight + cellHeight/2; cx -= cellWidth; cy -= cellHeight; if (i%2 == 0) cx += cellWidth/2; Node node = new Node(cx, cy); nodes[i*xRes+j] = node; } } } void updateNodes() { float noiseScale = 0.01; float noiseSpeed = 0.003; for (int i=0; i<yRes; i++) { for (int j=0; j<xRes; j++) { Node node = nodes[i*xRes+j]; node.energy = noise(i*noiseScale, j*noiseScale*3, frameCount*noiseSpeed) * 2.0; node.setYOffset(noise(i*noiseScale*3.4, j*noiseScale*6.4, frameCount*noiseSpeed*1.33) * 2.0 - 1.0); node.update(); } } } class Node { float x, y; color c; float energy; float hue; float saturation; float brightness; float yOffset; float hueOffset; float osc = random(0.0, 100.0); float oscSpeed = random(0.003, 0.03); Node(float _x, float _y) { x = _x; y = _y; c = color(random(100), random(100), random(30, 100)); saturation = random(10,80); brightness = random(20,80); hueOffset = random(-0.1, 0.1); } void update() { osc += oscSpeed; saturation = (sin(osc) + 1.0) * 40 + 10; brightness = (sin(osc*0.6) + 1.0) * 30 + 20; c = color((energy+hueOffset)*100%100, saturation, brightness, 100); fill(c); noStroke(); pushMatrix(); translate(x, y + yOffset * 100.0); ellipse(x, y, cellWidth*2.1, cellHeight*5.8); popMatrix(); } void setYOffset(float offset) { yOffset += (offset - yOffset) * 0.05; } } |


