I wanted a big swirling particle cloud following a Lorenz/Thomas attractor. CPU-updating 100k positions per frame in JS was a slideshow. I knew I needed the integration to happen on the GPU but kept getting scenes that computed positions on the CPU anyway.
What worked was explicitly asking for the attractor integration to live in the vertex shader driven by uTime, with only static seed positions uploaded once. Making the trajectory a pure function of (seed, time) means zero per-frame CPU work and it's deterministic.
Any recommended additive-blend settings so the dense core doesn't just clip to solid white?
Build a self-contained three.js scene: {COUNT} GPU particles (default 100000) tracing a strange attractor. Performance rules:
- Upload ONLY static per-particle seed attributes once (a seed float + initial offset). No position updates from JS after init.
- Integrate the attractor in the VERTEX shader as a function of `uTime` and the particle seed so the CPU does nothing per frame. Use the Thomas attractor (dx=sin(y)-b*x, etc.) with `uB` uniform; step it a fixed number of iterations in-shader from the seed.
- Render as `Points` with a custom ShaderMaterial; size attenuates with distance, clamped.
- Additive blending (`THREE.AdditiveBlending`, depthWrite:false) with a soft radial falloff in the fragment (discard past radius 0.5) so the cloud glows without hard squares.
- Color particles by their speed (finite-difference two shader steps) mapping slow->cool, fast->warm.
- OrbitControls, DPR capped at 2, and a small GUI for uB and uTime scale.
State your per-frame CPU cost (should be ~0) and how you avoid white-clipping the dense core.