GLSL / WebGL Minimal

Simple Particles: WebGL / GLSL Minimal walkthrough

Vertex-shader formula; flow nudges positions at render time. This walkthrough explains what the demo is doing, which library outputs it uses, and which parameters matter.
Demo walkthrough

This version keeps the integration small so the moving parts are visible. It uses the WebGL / GLSL path from `three-fluid-fx`, where the effect is built with EffectComposer passes, ShaderMaterial uniforms, and WebGL render targets.

Live demo

Minimal WebGL Examples: Simple Particles Open example

What this demo teaches

Instead of running an expensive physics simulation, we sample the fluid flow directly in the vertex shader. The fluid acts like a real-time magnetic wind that stretches, twists, and displaces the rigid shape only where the cursor touches it, instantly snapping back when the wind dies. In this variant, the relevant fluid output is Texture objects: velocityTexture, densityTexture, and dyeTexture when dye is enabled.

  • Understand the difference between procedural particles and GPGPU particles.
  • Use fluid flow as render-time displacement instead of integrated motion.
  • Keep the base shape readable while still reacting to the cursor.

Implementation path

  1. Generate the base shape from instance id

    The knot formula gives every particle a deterministic home position. There is no position texture to update.

  2. Sample the fluid at the projected point

    The shader uses the particle position to find the matching screen-space fluid sample.

  3. Blend flow into displacement

    Threshold and range controls decide when the brush is strong enough to bend the shape.

  4. Minimal scope

    It avoids GUI state and preset switching. Read it first when you need the smallest reliable version of the technique.

const particles = createTrefoilParticles({
  velocityField: fluid.velocityTexture,
  count: 4000,
  displacement: 0.34,
})

renderer.setAnimationLoop(() => {
  fluid.step(dt)
  particles.update({ elapsed, dragStrength, maxFlowSpeed })
  renderer.render(scene, camera)
})

Parameters to tune

Parameter What it controls How to tune it
displacement Maximum offset added to the procedural position. Raise until the cursor is visible. Lower it if the knot stops reading as a knot.
dispThreshold Minimum fluid activity before particles move. Increase it to ignore background noise and keep the shape stable.
dispRange Softness of the transition above the threshold. Wider ranges feel organic. Narrow ranges feel graphic and sharp.
dragStrength Extra pull along screen-space flow. Use small values. Too much drag turns the procedural object into a smear.

Source landmarks

Start from examples/glsl/minimal/particles-trefoil/main.ts. These are the parts worth reading first:

  • The trefoil position formula.
  • Fluid sampling in the vertex or TSL node path.
  • Threshold and displacement controls.
  • Point size and rotation updates.

Production notes

  • Use procedural particles when the object has a strong identity: a knot, logo, text, shell, or mask.
  • Do not add GPGPU state unless the particles need memory.
  • Clamp fast flow so quick pointer movements do not explode the shape.