mirror of
https://github.com/seigler/generative
synced 2025-07-27 07:06:08 +00:00
Add gradient_jungle sketch
This commit is contained in:
parent
7c824da05e
commit
bae99d6acb
8 changed files with 226 additions and 16 deletions
|
@ -1,15 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Generative Art - seigler.github.io</title>
|
|
||||||
<link rel="stylesheet" href="DIGEST(../app.css)">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script src="../modules/p5.min.js"></script>
|
|
||||||
<script src="../modules/p5.sound.min.js"></script>
|
|
||||||
<script src="DIGEST(../app.js)"></script>
|
|
||||||
<footer><code>Space</code> or double click for a new one. <code>S</code> to save.</footer>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
1
app/assets/1/index.html
Symbolic link
1
app/assets/1/index.html
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../sketch-template.html
|
1
app/assets/2/index.html
Symbolic link
1
app/assets/2/index.html
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../sketch-template.html
|
BIN
app/assets/2/palm-leaf-1.jpg
Normal file
BIN
app/assets/2/palm-leaf-1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
BIN
app/assets/2/palm-leaf-2.jpg
Normal file
BIN
app/assets/2/palm-leaf-2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
|
@ -11,6 +11,7 @@
|
||||||
<h1>P5.js generative art</h1>
|
<h1>P5.js generative art</h1>
|
||||||
<ol>
|
<ol>
|
||||||
<li><a class="sketch" href="1/">gradient burst</a></li>
|
<li><a class="sketch" href="1/">gradient burst</a></li>
|
||||||
|
<li><a class="sketch" href="2/">gradient jungle</a></li>
|
||||||
</ol>
|
</ol>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
require('sketches/1');
|
let path = document.location.pathname.split('/');
|
||||||
|
if (path.length > 1) {
|
||||||
|
require('./sketches/' + path[path.length - 2]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
15
app/sketch-template.html
Normal file
15
app/sketch-template.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Generative Art - seigler.github.io</title>
|
||||||
|
<link rel="stylesheet" href="DIGEST(../app.css)">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="../modules/p5.min.js"></script>
|
||||||
|
<script src="../modules/p5.sound.min.js"></script>
|
||||||
|
<script src="DIGEST(../app.js)"></script>
|
||||||
|
<footer><a href="../">Back</a> | <code>Space</code> or double click for a new one. <code>S</code> to save.</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
204
app/sketches/2.js
Normal file
204
app/sketches/2.js
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
new p5(sketch => {
|
||||||
|
sketch.disableFriendlyErrors = false;
|
||||||
|
// reused dimensions and a seed
|
||||||
|
let seed, width, height, maxD, goalInstances, intensityNoiseResolution, colorNoiseResolution, blurQuality, filenamePrefix;
|
||||||
|
// images
|
||||||
|
let palm1, palm2;
|
||||||
|
// offscreen layers
|
||||||
|
let buffer, pass1, pass2, noise;
|
||||||
|
// shaders
|
||||||
|
let blurH, blurV, whiteNoise;
|
||||||
|
|
||||||
|
sketch.preload = () => {
|
||||||
|
blurH = sketch.loadShader('../shaders/base.vert', '../shaders/blur-two-pass.frag');
|
||||||
|
blurV = sketch.loadShader('../shaders/base.vert', '../shaders/blur-two-pass.frag');
|
||||||
|
whiteNoise = sketch.loadShader('../shaders/base.vert', '../shaders/white-noise.frag');
|
||||||
|
palm1 = sketch.loadImage('palm-leaf-1.jpg'); // 405x600
|
||||||
|
palm2 = sketch.loadImage('palm-leaf-2.jpg'); // 405x600
|
||||||
|
}
|
||||||
|
|
||||||
|
sketch.setup = () => {
|
||||||
|
intensityNoiseResolution = 2;
|
||||||
|
colorNoiseResolution = 6;
|
||||||
|
blurQuality = 2;
|
||||||
|
goalInstances = 80;
|
||||||
|
filenamePrefix = 'seigler-p5-2-gradient_jungle';
|
||||||
|
|
||||||
|
window.onhashchange = () => {
|
||||||
|
seed = window.location.hash.substr(1);
|
||||||
|
generate();
|
||||||
|
};
|
||||||
|
|
||||||
|
seed = window.location.hash.substr(1);
|
||||||
|
sketch.noStroke();
|
||||||
|
sketch.colorMode(sketch.HSB, 100);
|
||||||
|
|
||||||
|
width = sketch.windowWidth;
|
||||||
|
height = sketch.windowHeight;
|
||||||
|
|
||||||
|
sketch.createCanvas(width, height);
|
||||||
|
|
||||||
|
maxD = (width + height) * 2 / Math.sqrt(goalInstances);
|
||||||
|
|
||||||
|
buffer = sketch.createGraphics(maxD, maxD);
|
||||||
|
pass1 = sketch.createGraphics(maxD, maxD, sketch.WEBGL);
|
||||||
|
pass2 = sketch.createGraphics(maxD, maxD, sketch.WEBGL);
|
||||||
|
noise = sketch.createGraphics(width, height, sketch.WEBGL);
|
||||||
|
|
||||||
|
buffer.noStroke();
|
||||||
|
pass1.noStroke();
|
||||||
|
pass2.noStroke();
|
||||||
|
noise.noStroke();
|
||||||
|
|
||||||
|
generate();
|
||||||
|
};
|
||||||
|
|
||||||
|
sketch.draw = () => {
|
||||||
|
};
|
||||||
|
|
||||||
|
sketch.keyPressed = () => {
|
||||||
|
if (sketch.key == ' ') {
|
||||||
|
seed = null;
|
||||||
|
generate();
|
||||||
|
} else if (sketch.key == 's') {
|
||||||
|
sketch.saveCanvas(filenamePrefix + seed + '.jpg', 'jpg');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sketch.doubleClicked = () => {
|
||||||
|
seed = null;
|
||||||
|
generate();
|
||||||
|
};
|
||||||
|
|
||||||
|
let resizeTimer;
|
||||||
|
sketch.windowResized = () => {
|
||||||
|
clearTimeout(resizeTimer);
|
||||||
|
resizeTimer = setTimeout(() => {
|
||||||
|
window.location.reload();
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
function generate() {
|
||||||
|
if (seed) {
|
||||||
|
sketch.randomSeed(seed);
|
||||||
|
} else {
|
||||||
|
let seed = Math.floor(sketch.random(1000000000000));
|
||||||
|
window.location.hash = seed;
|
||||||
|
sketch.randomSeed(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
sketch.noiseSeed(sketch.random());
|
||||||
|
sketch.blendMode(sketch.BLEND);
|
||||||
|
sketch.background('#000');
|
||||||
|
sketch.blendMode(sketch.ADD);
|
||||||
|
|
||||||
|
let sqpxEach = width * height / goalInstances; // square pixels per circle, helps with gridding
|
||||||
|
let unit = Math.sqrt(sqpxEach);
|
||||||
|
let rows = Math.max(1, Math.round(height / unit)) + 1;
|
||||||
|
let cols = Math.max(1, Math.round(width / unit)) + 1;
|
||||||
|
let noiseOffset = sketch.random(0, intensityNoiseResolution * 1000);
|
||||||
|
let indices = [];
|
||||||
|
for (let i = 0; i < rows * cols; i++) {
|
||||||
|
indices[i] = i;
|
||||||
|
}
|
||||||
|
shuffle(indices);
|
||||||
|
for (let i = 0; i < rows * cols; i++) {
|
||||||
|
// calculate row and col from i
|
||||||
|
let col = indices[i] % cols;
|
||||||
|
let row = Math.floor(indices[i] / cols);
|
||||||
|
|
||||||
|
buffer.noStroke();
|
||||||
|
buffer.blendMode(sketch.BLEND);
|
||||||
|
buffer.background('#000');
|
||||||
|
|
||||||
|
// perlin noise "intensity"
|
||||||
|
let intensity = sketch.noise(
|
||||||
|
noiseOffset + row / rows * intensityNoiseResolution,
|
||||||
|
noiseOffset + col / cols * intensityNoiseResolution
|
||||||
|
);
|
||||||
|
let d = maxD * (0.2 + 0.7 * intensity); // diameter
|
||||||
|
let c = sketch.color(
|
||||||
|
100 * (2 * sketch.noise(
|
||||||
|
2 * noiseOffset + row / rows * colorNoiseResolution,
|
||||||
|
2 * noiseOffset + col / cols * colorNoiseResolution
|
||||||
|
) - 0.5),
|
||||||
|
100, // saturation
|
||||||
|
intensity * 80 + 10, // brightness
|
||||||
|
intensity * 60 + 10 // alpha
|
||||||
|
); // color
|
||||||
|
buffer.fill(c);
|
||||||
|
buffer.circle(maxD / 2, maxD / 2, d); // always at the center of the buffer
|
||||||
|
|
||||||
|
if (sketch.random() > 0.5) {
|
||||||
|
buffer.fill('#000');
|
||||||
|
let cutoutAngle = sketch.random(2 * Math.PI);
|
||||||
|
let cutoutDiameter = sketch.random(0.1, 1.5) * d / 2;
|
||||||
|
let cutoutAdjustment = cutoutDiameter * sketch.random(-0.7, 0.3);
|
||||||
|
buffer.circle(
|
||||||
|
(maxD + (cutoutAdjustment + d) * Math.cos(cutoutAngle)) / 2,
|
||||||
|
(maxD + (cutoutAdjustment + d) * Math.sin(cutoutAngle)) / 2,
|
||||||
|
cutoutDiameter * 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let blurSize = maxD / 100;
|
||||||
|
// blurQuality is number of blur iterations
|
||||||
|
for (let pass = 0; pass < blurQuality; pass++) {
|
||||||
|
let radius = (blurQuality - pass) * blurSize / blurQuality;
|
||||||
|
pass1.shader(blurH);
|
||||||
|
blurH.setUniform('tex0', pass == 0 ? buffer : pass2);
|
||||||
|
blurH.setUniform('texelSize', [radius/maxD, radius/maxD]);
|
||||||
|
blurH.setUniform('direction', [1.0, 0.0]);
|
||||||
|
pass1.rect(0, 0, maxD, maxD);
|
||||||
|
pass2.shader(blurV);
|
||||||
|
blurV.setUniform('tex0', pass1);
|
||||||
|
blurV.setUniform('texelSize', [radius/maxD, radius/maxD]);
|
||||||
|
blurV.setUniform('direction', [0.0, 1.0]);
|
||||||
|
pass2.rect(0, 0, maxD, maxD);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.image(pass2, 0, 0, maxD, maxD);
|
||||||
|
|
||||||
|
do {
|
||||||
|
let cutoutAngle = sketch.random(2 * Math.PI);
|
||||||
|
let cutoutRotation = sketch.random(-Math.PI, Math.PI);
|
||||||
|
buffer.blendMode(sketch.MULTIPLY);
|
||||||
|
let cutoutHeight = sketch.random(1, 4) * d;
|
||||||
|
let cutoutWidth = cutoutHeight / 600 * 405;
|
||||||
|
let cutoutAdjustment = d * sketch.random(0.1, 0.8);
|
||||||
|
buffer.translate(maxD / 2, maxD / 2);
|
||||||
|
buffer.rotate(cutoutRotation);
|
||||||
|
buffer.translate(0, cutoutAdjustment);
|
||||||
|
buffer.rotate(cutoutAngle);
|
||||||
|
buffer.image(sketch.random() > 0.3 ? palm1 : palm2, 0, 0, cutoutWidth, cutoutHeight);
|
||||||
|
buffer.resetMatrix();
|
||||||
|
} while (sketch.random() < 0.8);
|
||||||
|
|
||||||
|
let displacementAngle = sketch.random(0, Math.PI * 2);
|
||||||
|
let displacementAmount = sketch.random(unit);
|
||||||
|
let w = width / (cols - 1) * col + displacementAmount * Math.cos(displacementAngle);
|
||||||
|
let h = height / (rows - 1) * row + displacementAmount * Math.sin(displacementAngle);
|
||||||
|
|
||||||
|
sketch.image(buffer, w - maxD / 2, h - maxD / 2);
|
||||||
|
}
|
||||||
|
noise.shader(whiteNoise);
|
||||||
|
whiteNoise.setUniform('u_resolution', [width, height]);
|
||||||
|
whiteNoise.setUniform('u_alpha', 0.05);
|
||||||
|
noise.rect(0, 0, width, height);
|
||||||
|
|
||||||
|
sketch.blendMode(sketch.OVERLAY);
|
||||||
|
sketch.image(noise, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shuffle(array) { // Fisher-Yates shuffle
|
||||||
|
var i = 0, j = 0, temp = null;
|
||||||
|
|
||||||
|
for (i = array.length - 1; i > 0; i -= 1) {
|
||||||
|
j = Math.floor(sketch.random() * (i + 1));
|
||||||
|
temp = array[i];
|
||||||
|
array[i] = array[j];
|
||||||
|
array[j] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue