Created
March 28, 2023 19:19
-
-
Save punund/139609ed5d752fecfcb95312e0844d0c to your computer and use it in GitHub Desktop.
Infection's main
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as ē from 'three' | |
import { evolve, multiply, pipe, times } from 'ramda' | |
// import { OrbitControls } from '../../mod/OrbitControls.js' | |
import { rnd, RN } from '../../mod/rnd.js' | |
import { createNoise2D } from 'simplex-noise' | |
import { mergeCurves, curves } from '../../data/curves.js' | |
import * as xyz from '../../fun/xyz.js' | |
import { | |
draw, | |
mend2, | |
populate2, | |
nurbs2, | |
revolution2, | |
surface2, | |
plainFunc, | |
} from '../../fun/common.js' | |
import * as material from '../../fun/material.js' | |
import { drawPalette } from '../../mod/palette.js' | |
import { init } from '../../mod/init.js' | |
import * as fx from './fxparams.js' | |
const toRgb = color => color.toArray().map(multiply(256)) | |
/*************************************************** */ | |
init({ | |
func: main, | |
square: true, | |
params: fx.params(), | |
}) | |
/*************************************************** */ | |
function main({ ww, wh, canvas, params }) { | |
const fxp = params | |
const { PI, floor } = Math | |
const SPORANGIA = 350 // floor(ww / 3) | |
const TUBE_RADIUS = floor(ww / 33) | |
const TUBE_DEPTH = floor(ww / 3) | |
const BUBBLES_PER_STRAND = floor(ww / 7.7) | |
const BUBBLE_STRANDS = fxp.dewAmount | |
const noiseRatio = [0.02, 3] | |
const noiseY = createNoise2D() | |
const noises = { | |
x: new createNoise2D(), | |
y: new createNoise2D(), | |
z: new createNoise2D(), | |
} | |
const color = new ē.Color() | |
const black = new ē.Color(0) | |
// functions applied to every vertex | |
const rfuns = [ | |
xyz.noiseXZcircular({ noiseRatio, radius: TUBE_RADIUS }), | |
xyz.bend({ radius: TUBE_RADIUS }), | |
] | |
const scene = new ē.Scene() | |
// Sporangia | |
times(() => { | |
const [x, z] = [ | |
RN(0, PI * TUBE_RADIUS), | |
RN(-0.05 * ww + 35, TUBE_DEPTH / 2 - 15), | |
] | |
const invasion = noiseY(x / 50, z / 50) > 1 - fxp.invasiveSpecies | |
const [colorTop, scale, fatten] = invasion | |
? [black, 0.4, 2.8] | |
: [ | |
rnd.chance( | |
color.lerpColors( | |
fxp.sprColorA, | |
fxp.sprColorB, | |
noiseY(x / 40, z / 40) / 2 + 0.5 | |
), | |
fxp.baseColor, | |
0.95 | |
), | |
1, | |
1.5, | |
] | |
pipe( | |
mergeCurves(rnd.between(0.8, 1)), | |
mend2, | |
populate2({ | |
colorBottom: fxp.baseColor, | |
colorTop, | |
scale: | |
fxp.scale * ((noiseY(x / 20, z / 20) * ww) / 2000 + ww / 1000), | |
fatten, | |
jitter: 0.14, | |
noiseY, | |
rfuns: [xyz.offset(x, 0, z), ...rfuns], | |
material: material.colorless, | |
bendRadius: TUBE_RADIUS, | |
scene, | |
}), | |
nurbs2, | |
revolution2, | |
draw | |
)([curves.Flat, curves.Pawn]) | |
}, SPORANGIA) | |
// The tube | |
draw( | |
surface2({ | |
func: plainFunc, | |
start: [-PI * TUBE_RADIUS, -TUBE_DEPTH / 2], | |
end: [PI * TUBE_RADIUS, TUBE_DEPTH / 2], | |
bendRadius: TUBE_RADIUS, | |
material: new ē.MeshPhysicalMaterial({ | |
color: fxp.baseColor, | |
clearcoat: 0.8, | |
side: ē.DoubleSide, | |
}), | |
noiseY, | |
rfuns, | |
scene, | |
}) | |
) | |
// Bubbles | |
const bubble = new ē.Mesh( | |
new ē.SphereGeometry(0.2 * fxp.dewSize, 64, 32), | |
material.lucid | |
) | |
times(j => { | |
let b | |
// distribute | |
let bv = new ē.Vector3( | |
rnd.float0(PI * TUBE_RADIUS), | |
6, | |
TUBE_DEPTH / 2 + 5 | |
) | |
times(i => { | |
let direction = new ē.Vector3( | |
noises.x((i + 1) / BUBBLES_PER_STRAND, (j + 1) / BUBBLE_STRANDS), | |
6 - | |
bv.y + | |
noises.y((i + 1) / BUBBLES_PER_STRAND, (j + 1) / BUBBLE_STRANDS), | |
// -1 | |
noises.z(i / 20, j / 4) - 1 | |
) | |
direction.normalize() | |
direction.multiplyScalar(2) | |
bv.add(direction) | |
// bend up | |
const bv_ = xyz.bend({ radius: TUBE_RADIUS })({ | |
xyz: bv.toArray(), | |
}).xyz | |
b = bubble.clone() | |
b.position.set(...bv_) | |
scene.add(b) | |
}, BUBBLES_PER_STRAND) | |
}, BUBBLE_STRANDS) | |
// Scene | |
const camera = new ē.PerspectiveCamera(49, 1, 0.1, 1000) | |
camera.position.set(5, 35, 150) | |
camera.lookAt(5, -30, -150) | |
// camera.updateProjectionMatrix() | |
const renderer = new ē.WebGLRenderer({ | |
canvas, | |
antialias: true, | |
preserveDrawingBuffer: params.drawingBuffer, | |
}) | |
const alight = new ē.AmbientLight(0xffffff, 0.25) | |
scene.add(alight) | |
const dlight1 = new ē.DirectionalLight(0xffffff, 0.9) | |
dlight1.position.set(10, 30, 30) | |
dlight1.target.position.set(0, 0, 0) | |
scene.add(dlight1) | |
// scene.add(dlight1.target) | |
const dlight2 = new ē.DirectionalLight(0xffffff, 0.9) | |
dlight2.position.set(0, -10, -10) | |
dlight2.target.position.set(0, 0, 0) | |
scene.add(dlight2) | |
renderer.render(scene, camera) | |
// function animate() { | |
// requestAnimationFrame(animate) | |
// controls.update() | |
// renderer.render(scene, camera) | |
// } | |
const paletteColors = [ | |
toRgb(fxp.baseColor), | |
toRgb(fxp.sprColorA), | |
toRgb(fxp.sprColorB), | |
'#FFF8', | |
] | |
drawPalette({ | |
canvas: document.getElementById('foreGround'), | |
ww, | |
wh, | |
bgColor: 'hsla(63, 39%, 50%, 0.48)', | |
colors: paletteColors, | |
}) | |
// animate() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment