An emitter, a pool, and a lot of dead particles
Every particle system starts from the same skeleton. An emitter spawns new particles at some rate from a source shape — a point, a cone, a disc. Each particle gets a position, a velocity, a lifetime and a random seed, and is pushed into a fixed-size pool. Every frame the whole pool is updated: age each particle, integrate its motion, and if its age exceeds its lifetime, mark it dead and let the emitter recycle the slot. Nothing here is unique to VFX — it is exactly the fixed-array update loop used by any particle simulation on this site — the difference between a boring grey dust cloud and a believable fire is entirely in the per-particle rules layered on top.
Lifetime curves: the secret of a convincing flame
A real flame is bright yellow-white at its base, thins to orange, and dissipates as translucent smoke. A particle fakes this with curves over normalised lifetime — functions of t = age / lifetime, from 0 (birth) to 1 (death) — driving colour, size and opacity independently:
t = age / lifetime // 0 at birth, 1 at death color = gradient(t) // white -> yellow -> orange -> dark red -> smoke grey size = lerp(startSize, endSize, t) * (1 + wobble(t)) alpha = fadeInOut(t) // ramps up fast, fades out slowly near t=1 Sparks use the same machinery with a much shorter lifetime and a colour curve that stays near white-hot until it snaps almost instantly to black, because incandescent metal cools and stops emitting visible light quickly. Fire uses a longer lifetime, more randomised initial upward velocity, and size that grows over its life to suggest expanding hot gas, whereas sparks shrink and disappear.
t = age / lifetime // 0 at birth, 1 at death color = gradient(t) // white -> yellow -> orange -> dark red -> smoke grey size = lerp(startSize, endSize, t) * (1 + wobble(t)) alpha = fadeInOut(t) // ramps up fast, fades out slowly near t=1
Additive blending: why fire looks like it is glowing
Normal transparency mixes a particle's colour with what is behind it. Additive blending instead sums the colour values directly onto the frame buffer: result = background + particleColor * alpha, with no subtraction. Where many bright particles overlap, their colours keep stacking until the pixel clips to pure white, which is exactly how overlapping incandescent light sources behave in reality. It is the reason a cluster of overlapping embers reads as one bright glow instead of a stack of visible translucent discs — and why using it for smoke looks wrong, since smoke absorbs light rather than emitting it and needs ordinary alpha blending instead.
Curl noise: turbulence without solving fluid dynamics
Real fire and smoke are governed by the Navier-Stokes equations, which are too expensive to solve per-particle at 60 frames per second for a game or a real-time preview. The standard shortcut is curl noise: take a 3D Perlin noise field and compute its curl (∇ × field) to get a new vector field that is divergence-free by construction — meaning it has no sources or sinks, so particles advected through it swirl and eddy without ever bunching into an unnatural clump or thinning into a hole. Each particle simply samples the curl field at its position each frame and adds a scaled version to its velocity, producing turbulent, swirling motion that looks convincingly fluid-like for a fraction of the cost of an actual fluid solver.
velocity += gravity * dt velocity += curlNoise(position, time) * turbulenceStrength * dt velocity *= (1 - drag * dt) position += velocity * dt
Sorting, depth and the GPU shortcut
Transparent particles must be drawn back-to-front to composite correctly, which means sorting the whole pool by camera distance every frame — an O(n log n) cost that becomes real for tens of thousands of particles.
Additively blended effects like fire and sparks get a free pass here: because addition is commutative, draw order does not change the final colour, so games skip sorting entirely for additive emitters and only pay the cost for alpha-blended smoke and dust.
Modern engines push the whole simulation loop onto the GPU as a compute shader, updating hundreds of thousands of particles in parallel — the CPU only issues the draw call and never touches individual particle data.
Frequently asked questions
Чи імітуються в грі та фільмах частинки з використанням реальної фізики?
Рідко повністю. Більшість VFX частинок використовують спрощену кінематику — гравітацію, опір, поле турбулентності на основі шумів, замість розв'язання рівнянь Нав’є-Стокса, які керують реальним вогнем і димом. Повне обчислювальне гідродинамічне моделювання використовується лише для епізодів у фільмах, де час рендерингу не є обмеженням; в іграх майже завжди використовується дешева апроксимація, оскільки потрібно працювати з частотою 60 кадрів на секунду разом із всім іншим на екрані.
Чому додавання кольорів робить вогонь і іскри яскравими та сяючими?
Додавання кольорів додає колір кожного зерен безпосередньо до пікселя на екрані, а не змішує їх між собою. Таким чином, перекриваючись, частинки накопичують яскравість, поки вони не досягають чистого білого кольору. Це імітує поведінку справжнього інцидентного світла — багато переплітаються джерел фотонів дійсно додають суму, тому це виглядає правдоподібно для вогню, іскор та енергетичних ефектів, але неправильно для диму або пилу, які поглинають світло і потребують стандартного альфа-змішування.
Що таке curl noise і чому його використовують для турбулентності замість звичайного шуму?
Curl noise бере обертальну частину поля Perlin, щоб створити векторне поле, яке за конструкцією є дивергенційно-звільненим, тобто не має джерел або стоків — частинки спіраються і ніколи не утворюють груди або не розповсюджуються незвично. Адвекція частинок вздовж прямого градієнта шуму Perlin може призвести до того, що вони накопичуються в кластерах або товстих ділянках, що очевидно неправильно для диму та вогню, які повинні зберігати об'єм, коли вони звиваються і пливуть.
Спробуйте наживо
Усе, що вище, працює прямо у вашому браузері — відкрийте Particle VFX і змінюйте параметри під час роботи. Нічого не встановлюється, нічого не завантажується на сервер, уся модель живе в одній вкладці.
▶ Відкрити симуляцію Particle VFX