Babylon.js Particle Fountain — Gravity-Fed ParticleSystem Snippet

Babylon.js Particle Fountain · Animations · Plain HTML, CSS & JS · Live preview

CategoryAnimations

What's included

Features

Procedural particle texture
A radial-gradient sprite is drawn to a DynamicTexture at runtime, no image asset needed.
Cone-shaped point emitter
createPointEmitter with direction1/direction2 vectors defines a natural upward spray.
Real gravity simulation
A constant downward gravity vector produces an arcing fountain shape organically.
Lifetime-based fade
colorDead with zero alpha fades each particle out smoothly as its lifetime ends.
Additive glow blending
BLENDMODE_ONEONE makes overlapping particles brighten instead of layering flatly.
Live emit-rate control
A slider adjusts ps.emitRate in real time with no restart needed.
Palette cycling
One button swaps the full color1/color2/colorDead set to a different preset scheme.
Orbit camera included
ArcRotateCamera lets the fountain be viewed from any angle while running.

About this UI Snippet

Babylon.js Particle Fountain — Emission, Gravity, and Fade Explained

Screenshot of the Babylon.js Particle Fountain snippet rendered live

A particle fountain looks complex but is really four independent, composable systems working together: how particles are shaped (texture), where they start and in what spread (emitter), what forces act on them after emission (gravity), and how they visually disappear (lifetime-based color/alpha). Babylon.js's ParticleSystem exposes all four as plain properties, no custom shader code required.

A procedural sprite, no image asset

Instead of loading a PNG dot, the sprite is drawn at runtime onto a BABYLON.DynamicTexture, which wraps an offscreen <canvas> you can draw into with the normal 2D Canvas API:

var grad = ctx.createRadialGradient(...); grad.addColorStop(0, 'rgba(255,255,255,1)'); ... ctx.fillRect(0, 0, texSize, texSize); dynTex.update();

A radial gradient from opaque white at the center to transparent at the edge produces a soft glowing dot — exactly the shape you want for a particle, generated in a few lines instead of shipping an asset.

createPointEmitter defines the spray shape

ps.createPointEmitter(new BABYLON.Vector3(-0.5, 4, -0.5), new BABYLON.Vector3(0.5, 5.5, 0.5)) is what gives the fountain its cone shape rather than a single perfectly straight jet. Every new particle starts at ps.emitter's position, and its initial direction is chosen by picking a random value between the emitter's direction1 and direction2 vectors on each axis — so direction1 = (-0.4, 1, -0.4) and direction2 = (0.4, 1, 0.4) together define a narrow upward cone that varies slightly in x and z while staying strongly biased toward +y. Widen those vectors and the fountain sprays wider; narrow them and it becomes a tight jet.

Gravity, not a scripted arc

ps.gravity = new BABYLON.Vector3(0, -9.1, 0) is applied by the particle system to every live particle's velocity every update tick, exactly like real gravity accelerates a thrown object downward. This is why the fountain arcs and falls back down convincingly — nobody scripted a parabola; it emerges from constant downward acceleration acting on the particles' initial upward velocity, the same physics as a ball thrown into the air.

Lifetime-driven fade, via colorDead

Each particle is assigned a random lifetime between minLifeTime and maxLifeTime. Over that lifetime, Babylon interpolates the particle's color from color1/color2 (chosen randomly per particle at spawn) toward colorDead — and colorDead here is set with alpha 0:

ps.colorDead = new BABYLON.Color4(PALETTES[i][0].r, PALETTES[i][0].g, PALETTES[i][0].b, 0);

Fading alpha to zero rather than just changing hue is what makes particles disappear smoothly at the end of their life instead of blinking out of existence on their last rendered frame.

Additive blending for a glow

ps.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE switches from normal alpha blending to additive blending — overlapping particles' colors sum instead of layering opaquely, so the water source of a fountain looks bright and glowing where particle density is highest, rather than looking like a flat sprite stack.

Reusing it

The same four-part model — texture, emitter shape, forces, lifetime fade — applies to smoke, sparks, snow, or magic effects; only the vectors and colors change. Pair it with a Babylon.js Spinning Product Viewer to see the same ArcRotateCamera/render-loop setup used for a mesh instead of a particle system.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Particle systems reward hands-on experimentation more than most animation techniques, so use an AI assistant to explore the parameter space quickly. Paste this snippet into Claude and ask it to explain exactly how minEmitPower/maxEmitPower interact with gravity to determine the maximum height and total flight time of a particle, and to derive the relationship (roughly: peak height scales with the square of initial vertical velocity, divided by twice the gravity magnitude, basic kinematics). Then ask what visual difference results from narrowing direction1/direction2 toward a single vector (a tight jet, more of a fire hose) versus widening them significantly (a broad spray, more of a sprinkler). To extend it: ask it to add a second particle system for splash/mist particles that spawns when fountain particles reach y=0, add mouse-attraction so particles bend toward the cursor, tie emitRate to an audio input for a music-reactive fountain, or replace the radial-gradient texture with a star or spark shape drawn on the same DynamicTexture canvas.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a particle fountain effect using Babylon.js (from a CDN, global namespace BABYLON) in plain HTML, CSS, and JavaScript with a single <canvas> element.

Requirements:
- Initialize a BABYLON.Engine and Scene with a very dark clear color, and an ArcRotateCamera with attachControl enabled so the user can orbit the scene, clamped with lowerRadiusLimit/upperRadiusLimit.
- Add a small cylinder mesh near the origin as a visual "base" the fountain appears to emit from.
- Generate the particle sprite procedurally at runtime using a BABYLON.DynamicTexture: draw a soft white radial gradient (opaque center fading to transparent edge) onto its 2D canvas context and call update() -- do not load any external image.
- Create a BABYLON.ParticleSystem with a capacity of a few thousand particles, set its particleTexture to the DynamicTexture, and use createPointEmitter(direction1, direction2) with two vectors that bias strongly upward (+y) but vary slightly on x/z, so particles spray in a narrow upward cone rather than a single straight line.
- Set minEmitPower/maxEmitPower for initial launch speed, minLifeTime/maxLifeTime for how long each particle lives, minSize/maxSize for particle scale, and an emitRate.
- Set ps.gravity to a downward vector (e.g. (0, -9.1, 0)) so gravity pulls emitted particles back down and produces a natural arcing fountain shape rather than particles flying straight up forever.
- Set color1, color2 for spawn color variation and colorDead with alpha 0 so particles fade out smoothly as their lifetime ends rather than disappearing abruptly.
- Set blendMode to BABYLON.ParticleSystem.BLENDMODE_ONEONE (additive blending) for a glowing look where dense particle clusters appear brighter.
- Call ps.start(), and run the render loop with engine.runRenderLoop(() => scene.render()), plus a resize handler.
- Add a slider that live-updates ps.emitRate and a button that cycles through at least 3 color palettes by reassigning color1/color2/colorDead.
- Style the page as a very dark panel with the canvas as the focal element, rounded corners, and a subtle border.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

Requires
<div class="bpf-stage">
  <div class="bpf-head">
    <span class="bpf-tag">Babylon.js · ParticleSystem</span>
    <h2>Particle Fountain</h2>
    <p>Thousands of particles emitted upward, pulled down by gravity, fading out over their lifetime.</p>
  </div>
  <canvas id="bpfCanvas"></canvas>
  <div class="bpf-controls">
    <label class="bpf-label">Emit rate
      <input type="range" id="bpfRate" min="50" max="1000" value="350" />
    </label>
    <button class="bpf-btn" id="bpfColor">Cycle color</button>
  </div>
</div>

Step by step

How to Use

  1. 1
    Add the Babylon.js CDNInclude the babylon.js UMD build for the global BABYLON namespace.
  2. 2
    Paste HTML, CSS, and JSA canvas renders a glowing particle fountain emitting from a small base disc.
  3. 3
    Watch the arc formGravity pulls emitted particles back down, producing a natural fountain arc.
  4. 4
    Drag the emit rate sliderps.emitRate changes live, thickening or thinning the stream.
  5. 5
    Click Cycle colorSwaps color1/color2/colorDead to a different palette from a preset list.
  6. 6
    Orbit the cameraDrag on the canvas to view the fountain from different angles via ArcRotateCamera.

Real-world uses

Common Use Cases

Celebratory effects
Success states, achievement unlocks, or checkout confirmations with a burst of particles.
3D landing page hero elements
An ambient animated centerpiece for a product or agency site.
Teaching particle systems
A clear, commented reference for emitter shape, gravity, and lifetime fade.
Game UI and effects prototyping
A starting point for spark, magic, or liquid effects in a Babylon.js game.
Data-driven visual flourishes
Emit rate or color tied to a live metric for an ambient dashboard visualization.
Learning DynamicTexture
A minimal example of drawing a procedural sprite without external image assets.

Got questions?

Frequently Asked Questions

It is drawn at runtime into a BABYLON.DynamicTexture, which exposes a standard CanvasRenderingContext2D via getContext(). A radial gradient from opaque white at the center to transparent at the edges is filled into it and dynTex.update() uploads it as the particle texture, avoiding any external asset request.

It sets the emission shape by defining two direction vectors, direction1 and direction2. Every particle spawns at the emitter position and picks a random initial direction with each axis independently interpolated between those two vectors, producing a cone spray rather than a single straight-line jet.

ps.gravity applies a constant downward acceleration to every particle's velocity on each update tick, exactly like real gravity. Particles start with strong upward velocity from minEmitPower/maxEmitPower, and gravity continuously reduces that vertical velocity until it reverses, producing the natural parabolic fountain arc with no scripted curve.

Each particle is assigned a random lifetime between minLifeTime and maxLifeTime, and Babylon interpolates its color from its spawn color (color1/color2) toward colorDead over that lifetime. Setting colorDead's alpha channel to 0 means the interpolation ends in full transparency, so the particle visually fades rather than vanishing on its last rendered frame.

It switches the particle system from standard alpha blending to additive blending, where overlapping particle colors are summed rather than composited normally. This makes dense clusters of particles -- like near the emitter -- appear brighter and glowing, which reads as more energetic/fluid than flat alpha-blended sprites.

Initialize the Engine, Scene, ParticleSystem, and DynamicTexture once inside a useEffect (React) or onMounted (Vue) against a canvas ref, keep a reference to the ParticleSystem instance to update emitRate or call dispose() on unmount, and drive UI controls (sliders, buttons) through normal component state that writes to that instance's properties directly rather than re-creating the particle system on every render.