Skip to content

Instantly share code, notes, and snippets.

@punund
Created March 28, 2023 19:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save punund/139609ed5d752fecfcb95312e0844d0c to your computer and use it in GitHub Desktop.
Save punund/139609ed5d752fecfcb95312e0844d0c to your computer and use it in GitHub Desktop.
Infection's main
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