News

No sprite sheets. No VFX textures. No pre-baked effect meshes. Creative developer @chirovisuals has open-sourced an entire Elemental Sandbox built in Three.js, where every spell effect you see is generated on the fly by hand-written GLSL and GPU-simulated instanced particles — and the whole thing is MIT licensed on GitHub.

Five abilities, two ways to aim
The sandbox is built around skillshot casting. Four abilities are line casts: press the key to arm, a League-of-Legends style arrow appears on the ground and swings with your mouse, then click to fire. The fifth is a far cast, where the arrow is replaced by a ground-targeted circle that follows your cursor.
- Q — Frost Lance: a fracture front races out along the line while ice crystals tear up out of the floor behind it, opening into a wall of blades at the far end.
- E — Storm Lance: a bolt leaves the caster hand trailing a bundle of lightning filaments that gutters, re-strikes, and blows out, burning a branching scorch into the floor.
- R — Cinder Fall: a burning rock is lobbed downrange trailing a raymarched wake of gas, detonating on arrival and tearing the ground into glowing molten cracks.
- F — Nova Beam: a column of light with a white-hot core, cyan sheath, and gold ribbons spiralling around it — the only cast still happening a second after it lands.
- V — Voltaic Snare: the far cast. A leash of current whips across the floor, a violet column tears up out of the middle, and tendrils crawl outward to the boundary.
Why it matters technically
Almost everything on screen is procedural. The crystals are generated geometry, the lightning bolt is a strip of ribbon placed entirely by a vertex shader, the meteor is an icosphere cratered by fracture planes, the beam is a parametric tube drawn three times at three radii, and the ground burns, rime, and targeting arrow are signed-distance and noise shaders. The mist, sparks, chips, and glitter are all GPU particles with procedural silhouettes — there are no sprite textures anywhere in the project. The only binary assets loaded are the rigged character (a Mixamo FBX with its animation clips) and an HDR probe used for image-based lighting.
The real headline: 938 live sliders
The standout feature is that every parameter is a live slider — 938 of them — and they stay live while the simulation is paused. Hit P to freeze a frame mid-eruption, mid-strike, or mid-burn, then reshape the silhouette, palette, and timing against a still image. Dragging a height value re-grows an ice field that is already standing; changing the jitter re-kinks a bolt that is already in the air.
That is possible because of one disciplined rule in the codebase: abilities store only what the dice decided (unitless fractions and seeds), never resolved metres, radians, or seconds. Every dimension is resolved against the settings object inside the update loop — which runs on a zero-length frame too.
Performance notes worth stealing
The project is also a lesson in cheap rendering. A whole ice field is three draw calls regardless of crystal count. An entire lightning bolt is two draw calls no matter how many filaments. A full snare — leash, pillar, tendrils, and rim arcs — is two draw calls plus one for the field. Abilities, decals, bursts, and particles are all pooled, so spamming casts recycles slots instead of allocating.
Try it yourself
The full source and playground are on GitHub under an MIT licence. Clone it, run npm install and npm run dev, then press G to open the VFX editor and start pulling it apart.
- Source code: LinearAbiltyCastingThreeJS on GitHub
- Follow the creator: @chirovisuals on X
- Original post: see it in action
- Learn more about Three.js
If you build games or web experiences, this is a rare chance to read a production-grade real-time VFX system top to bottom. Which element would you test first?


