xxxxxxxxxx
/**
* This is an entry to @sableRaph's weekly creative code challenge
* for the theme "fungi."
*
* The code is mostly two parts:
* - the Mushroom class, which makes a random stem and cap as
* p5.Geometry
* - the smoke shader, which is a video feedback effect. Each frame,
* the previous frame is stretched according to a Perlin noise
* flow field and is made less opaque. If the flow field stretches
* pixels apart, they're made less opaque. If it compresses pixels
* together, they become more opaque.
*
*/
let prev, next
let smokeShader
let timeSeed
let mushrooms = []
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL)
setAttributes({ antialias: true })
pixelDensity(1)
smokeShader = createShader(makeSmokeShader())
prev = createFramebuffer({ format: FLOAT })
next = createFramebuffer({ format: FLOAT })
timeSeed = random(100000)
}
function mousePressed() {
makeMushrooms()
}
function makeMushrooms() {
while (mushrooms.length > 0) {
mushrooms.pop().unmount()
}
const numMushrooms = random([4, 5, 6, 7])
for (let i = 0; i < numMushrooms; i++) {
mushrooms.push(new Mushroom(createVector(
map(i, 0, numMushrooms-1, -width*0.3, width*0.3) + random(-0.05, 0.05) * width,
height*0.3,
0,
)))
}
prev.draw(() => clear())
next.draw(() => clear())
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight, WEBGL)
}
let scene = -1
function draw() {
[prev, next] = [next, prev]
const t = millis()
const timePerScene = 20000
const nextScene = floor(t / timePerScene)
if (scene !== nextScene) {
makeMushrooms()
scene = nextScene
}
next.draw(() => {
clear()
noStroke()
push()
// Do video feedback to make a smoke effect
shader(smokeShader)
smokeShader.setUniform('uTime', timeSeed + t)
smokeShader.setUniform('uScale', min(width, height))
smokeShader.setUniform('uTexture', prev)
smokeShader.setUniform('uFadeColor', [1, 1, 1, 0.995])
// Try messing around with some of these parameters to
// change the feel of the smoke!
smokeShader.setUniform('uNoiseDomainScale', 0.016) // the smoothness of the smoke
smokeShader.setUniform('uNoiseRangeScale', 0.5) // how much influence the flow field has
smokeShader.setUniform('uNoiseTimeScale', 0.0005) // the speed at which the flow field changes
smokeShader.setUniform('uWind', [-0.1, 0.1]) // constant offset, in pixels per frame
smokeShader.setUniform('uCoordScale', 1.001)
plane(width, height)
pop()
// Each mushroom adds some more white to the frame
// to spawn more spores. This is just a small version
// of its cap model.
fill(255)
for (const mushroom of mushrooms) {
mushroom.drawSpawn()
}
})
background(0)
noStroke()
const mushroomLights = () => {
directionalLight(100, 100, 100, 0, 1, -0.3)
directionalLight(150, 150, 150, 0.5, 0, 1)
directionalLight(150, 150, 150, -0.5, 0, 1)
directionalLight(255, 255, 255, 0, 0, 1)
}
push()
mushroomLights()
for (const mushroom of mushrooms) {
mushroom.drawStems()
}
pop()
drawingContext.disable(drawingContext.DEPTH_TEST)
imageMode(CENTER)
image(next, 0, 0)
drawingContext.enable(drawingContext.DEPTH_TEST)
push()
mushroomLights()
for (const mushroom of mushrooms) {
mushroom.drawCaps()
}
pop()
imageMode(CENTER)
image(next, 0, 0)
}