From 854b6b7e0b5da80405cd4c09c7dfa6af1f63644f Mon Sep 17 00:00:00 2001 From: alex-mcneilly Date: Tue, 27 May 2025 18:25:52 -0700 Subject: [PATCH] refactor particle simulation into one file --- examples/vfx-particle-simulation/index.html | 237 ++++++++++++++++++-- examples/vfx-particle-simulation/main.js | 203 ----------------- 2 files changed, 223 insertions(+), 217 deletions(-) delete mode 100644 examples/vfx-particle-simulation/main.js diff --git a/examples/vfx-particle-simulation/index.html b/examples/vfx-particle-simulation/index.html index eaaa339..bc5b8a0 100644 --- a/examples/vfx-particle-simulation/index.html +++ b/examples/vfx-particle-simulation/index.html @@ -1,26 +1,18 @@ - Forge • VFX Particle Simulation - - + diff --git a/examples/vfx-particle-simulation/main.js b/examples/vfx-particle-simulation/main.js deleted file mode 100644 index e643532..0000000 --- a/examples/vfx-particle-simulation/main.js +++ /dev/null @@ -1,203 +0,0 @@ -import { - ForgeRenderer, - PointerControls, - SplatMesh, - VRButton, - generators, -} from "@forge-gfx/forge"; -import GUI from "lil-gui"; -import * as THREE from "three"; - -export const SNOW_HEIGHT = 8; - -async function main() { - const canvas = document.getElementById("canvas"); - const renderer = new THREE.WebGLRenderer({ canvas }); - const scene = new THREE.Scene(); - - const forge = new ForgeRenderer({ renderer }); - scene.add(forge); - - const camera = new THREE.PerspectiveCamera( - 75, - canvas.width / canvas.height, - 0.1, - 1000, - ); - camera.position.set(-1, 12, 100); - camera.rotateY((3 * Math.PI) / 2); - scene.add(camera); - - const pointerControls = new PointerControls({ canvas }); - - function handleResize() { - const width = canvas.clientWidth; - const height = canvas.clientHeight; - renderer.setSize(width, height, false); - camera.aspect = width / height; - camera.updateProjectionMatrix(); - } - - handleResize(); - window.addEventListener("resize", handleResize); - - const splatURL = - "https://asundqui-public.s3.us-west-2.amazonaws.com/gsplats/snow_street.spz"; - // "./snow_street_crop8.ply"; - const background = new SplatMesh({ url: splatURL }); - background.quaternion.set(1, 0, 0, 0); - scene.add(background); - - const halfWidth = 25; - const halfDepth = 50; - const snowMinYClamp = -0.7; - const cam = camera.position; - - const snowVolumeBox = new THREE.Box3( - new THREE.Vector3( - cam.x - halfWidth, - cam.y - SNOW_HEIGHT / 1.5, - cam.z - halfDepth, - ), - new THREE.Vector3( - cam.x + halfWidth, - cam.y + SNOW_HEIGHT * 2, - cam.z + halfDepth, - ), - ); - - const snow = generators.snowBox({ - ...generators.DEFAULT_SNOW, - box: snowVolumeBox.clone(), - minY: snowMinYClamp, - color1: new THREE.Color(1.0, 1.0, 1.0), - color2: new THREE.Color(0.91, 0.9, 0.97), - density: 1000, - maxScale: 0.01, - }); - scene.add(snow.snow); - - const gui = new GUI({ title: "Clouds" }); - const controls = { - fallVelocity: generators.DEFAULT_SNOW.fallVelocity, - wanderScale: generators.DEFAULT_SNOW.wanderScale, - wanderVariance: generators.DEFAULT_SNOW.wanderVariance, - maxScale: 0.01, - color1: new THREE.Color(1.0, 1.0, 1.0), - color2: new THREE.Color(0.91, 0.9, 0.97), - isPaused: false, - fallDirection: new THREE.Vector3(0, -1, 0), - windDirection: "No Direction", - _previousFallVelocity: generators.DEFAULT_SNOW.fallVelocity, - _previousWanderScale: generators.DEFAULT_SNOW.wanderScale, - _previousWanderVariance: generators.DEFAULT_SNOW.wanderVariance, - }; - - // snow parameters - gui.add(controls, "fallVelocity", 0.01, 0.5, 0.01).name("Fall Velocity"); - gui.add(controls, "wanderScale", 0.01, 1, 0.01).name("Wander Scale"); - gui.add(controls, "wanderVariance", 1, 5, 0.1).name("Wander Variance"); - gui.add(controls, "maxScale", 0.001, 0.05, 0.001).name("Snow Size"); - gui - .add(controls, "isPaused") - .name("Pause Snowfall") - .onChange((value) => { - if (value) { - controls._previousFallVelocity = controls.fallVelocity; - controls._previousWanderScale = controls.wanderScale; - controls._previousWanderVariance = controls.wanderVariance; - - snow.fallVelocity.value = 0; - snow.wanderScale.value = 0; - snow.wanderVariance.value = 0; - } else { - snow.fallVelocity.value = controls._previousFallVelocity; - snow.wanderScale.value = controls._previousWanderScale; - snow.wanderVariance.value = controls._previousWanderVariance; - } - }); - - // color - const colorFolder = gui.addFolder("Snow Colors"); - colorFolder - .addColor(controls, "color1") - .onChange((value) => { - snow.color1.value.set(value.r, value.g, value.b); - }) - .name("Color 1"); - colorFolder - .addColor(controls, "color2") - .onChange((value) => { - snow.color2.value.set(value.r, value.g, value.b); - }) - .name("Color 2"); - - const directionFolder = gui.addFolder("Wind Orientation"); - directionFolder - .add(controls.fallDirection, "x", -1, 1, 0.1) - .onChange(() => { - controls.fallDirection.normalize(); - snow.fallDirection.value.copy(controls.fallDirection); - }) - .name("East-West"); - directionFolder - .add(controls.fallDirection, "z", -1, 1, 0.1) - .onChange(() => { - controls.fallDirection.normalize(); - snow.fallDirection.value.copy(controls.fallDirection); - }) - .name("North-South"); - - const windFolder = gui.addFolder("Wind Direction Presets"); - windFolder - .add(controls, "windDirection", [ - "N", - "NE", - "E", - "SE", - "No Direction", - "S", - "SW", - "W", - "NW", - ]) - .onChange((value) => { - const directions = { - N: new THREE.Vector3(0, -1, -1), - NE: new THREE.Vector3(1, -1, -1), - E: new THREE.Vector3(1, -1, 0), - SE: new THREE.Vector3(1, -1, 1), - "No Direction": new THREE.Vector3(0, -1, 0), - S: new THREE.Vector3(0, -1, 1), - SW: new THREE.Vector3(-1, -1, 1), - W: new THREE.Vector3(-1, -1, 0), - NW: new THREE.Vector3(-1, -1, -1), - }; - controls.fallDirection.copy(directions[value]).normalize(); - snow.fallDirection.value.copy(controls.fallDirection); - }) - .name("Wind Direction"); - - const vrButton = VRButton.createButton(renderer); - if (vrButton) document.body.appendChild(vrButton); - - let lastTime; - renderer.setAnimationLoop((time) => { - const t = time * 0.001; - const dt = t - (lastTime ?? t); - lastTime = t; - - pointerControls.update(dt, camera); - - if (!controls.isPaused) { - snow.fallVelocity.value = controls.fallVelocity; - snow.wanderScale.value = controls.wanderScale; - snow.wanderVariance.value = controls.wanderVariance; - snow.maxScale.value = controls.maxScale; - } - - renderer.render(scene, camera); - }); -} - -main().catch(console.error);