[rendering] Fog-like particle systems feed the volumetric fog (heuristic: density from the particles' contents) #1003

Open
opened 2026-10-24 00:05:50 +00:00 by sky_line · 1 comment
Owner

Creators build fog, mist, smoke, steam and dust out of particle systems: many large, soft, low-alpha billboards. Rendered as billboards they show the usual problems -- hard intersections with geometry and terrain, sorting pops, flat camera-facing sheets, no shadowing or light scattering, and heavy overdraw. With the volumetric fog on (RenderVKVolumetricFog) we already have a lit, shadowed participating medium; these systems should be able to become part of it.

Idea
Classify particle systems as fog-like by a heuristic, and inject them into the volumetric fog's density volume, with density and colour taken from what the particles actually contain. Then fade or drop their billboards.

Heuristic inputs (per system, not per particle; hysteresis so a system doesn't flip)

  • Particle size large relative to spacing, so billboards overlap heavily.
  • Low per-particle alpha, alpha blended (not additive / emissive: sparks, fire cores and glitter stay billboards).
  • Texture is soft and low-frequency: a radial or cloud-like alpha with no hard edges or recognisable shapes (e.g. a precomputed per-texture stat: mean alpha, alpha gradient energy, colour variance), or the default particle texture with a large size.
  • Slow speed and long life relative to size, so it drifts rather than streaks.
  • Enough particles alive, or a high enough emission rate, to read as a volume.
  • Opt-out: anything the heuristic misjudges stays a billboard (setting to disable it; possibly a per-object override later).

Density and colour from contents

  • Per particle, splat into the froxel/fog volume: density = alpha x texture mean alpha x size-normalised coverage; scattering albedo / tint = particle colour x texture mean colour.
  • Emissive or bright particles add a small in-scattered emission term rather than density.
  • Respect particle fade in/out, so density follows the system's lifetime curve.

Render

  • Injected density gets the fog's existing lighting: sun/moon shadows, local lights, projector shadows, GI where available.
  • Billboards of converted systems cross-fade out over a short range (not a pop), so they keep their look until the volume carries it; keep billboards beyond the fog volume's range.
  • GPU-driven: classification on the CPU once per system (cheap), splat done in a compute pass from the particle buffer; no per-particle CPU work per frame.

Settings
A master toggle (off by default until tuned), plus a strength multiplier and the classification threshold, exposed for testing.

Test scenes: fog / steam / smoke particle builds, campfires (smoke converts, flame cores stay), waterfalls' mist, dust in sunbeams (should gain shadowed light shafts).

Creators build fog, mist, smoke, steam and dust out of particle systems: many large, soft, low-alpha billboards. Rendered as billboards they show the usual problems -- hard intersections with geometry and terrain, sorting pops, flat camera-facing sheets, no shadowing or light scattering, and heavy overdraw. With the volumetric fog on (`RenderVKVolumetricFog`) we already have a lit, shadowed participating medium; these systems should be able to become part of it. **Idea** Classify particle systems as fog-like by a heuristic, and inject them into the volumetric fog's density volume, with density and colour taken from what the particles actually contain. Then fade or drop their billboards. **Heuristic inputs (per system, not per particle; hysteresis so a system doesn't flip)** - Particle size large relative to spacing, so billboards overlap heavily. - Low per-particle alpha, alpha blended (not additive / emissive: sparks, fire cores and glitter stay billboards). - Texture is soft and low-frequency: a radial or cloud-like alpha with no hard edges or recognisable shapes (e.g. a precomputed per-texture stat: mean alpha, alpha gradient energy, colour variance), or the default particle texture with a large size. - Slow speed and long life relative to size, so it drifts rather than streaks. - Enough particles alive, or a high enough emission rate, to read as a volume. - Opt-out: anything the heuristic misjudges stays a billboard (setting to disable it; possibly a per-object override later). **Density and colour from contents** - Per particle, splat into the froxel/fog volume: density = alpha x texture mean alpha x size-normalised coverage; scattering albedo / tint = particle colour x texture mean colour. - Emissive or bright particles add a small in-scattered emission term rather than density. - Respect particle fade in/out, so density follows the system's lifetime curve. **Render** - Injected density gets the fog's existing lighting: sun/moon shadows, local lights, projector shadows, GI where available. - Billboards of converted systems cross-fade out over a short range (not a pop), so they keep their look until the volume carries it; keep billboards beyond the fog volume's range. - GPU-driven: classification on the CPU once per system (cheap), splat done in a compute pass from the particle buffer; no per-particle CPU work per frame. **Settings** A master toggle (off by default until tuned), plus a strength multiplier and the classification threshold, exposed for testing. **Test scenes:** fog / steam / smoke particle builds, campfires (smoke converts, flame cores stay), waterfalls' mist, dust in sunbeams (should gain shadowed light shafts).
sky_line added this to the Slipstream project 2026-10-24 00:05:50 +00:00
Author
Owner

Design agreed with the owner (2026-10-24):

Classification: per particle system on the CPU from LLPartSysData (deterministic, reclassified when the system changes).

  • Hard exclusions: additive / emissive / glow; ribbon / targeted / follow-velocity; small (<0.5 m), fast (>1 m/s) or short-lived (<1.5 s) particles; shaped textures; worn attachments (initially); HUD; volumetric fog off.
  • Soft score: big x faint x slow & long-lived x normal alpha blend x soft texture (per-texture stats: mean alpha, edge energy, mean colour; unknown stats = stay particles) x enough alive.
  • Convert above 0.7, revert below 0.5, blend in between.

Owner requirement: REAL density. Fog-machine billowing clouds that follow the emitter speed and direction and spread out and fade the way the particles do. Froxel injection alone is too thin. So:

  • Keep simulating the particles as invisible density carriers.
  • Splat them into local world-space density bricks (pooled atlas, budget / LRU / stats; ~5-10 cm voxels near the camera).
  • Mass is conserved: the kernel grows with age and the peak drops, which gives the spreading. The particle alpha fade sets the dissipation.
  • Curl-noise domain-warp detail, advected, for billows.
  • Ray-march the bricks in their own pass, composited with the froxel fog by depth, lit by sun shadows, local lights and projectors, with in-brick self-occlusion.
  • Master toggle off by default, debug view (tint + brick bounds), density and billow settings.
Design agreed with the owner (2026-10-24): **Classification:** per particle system on the CPU from LLPartSysData (deterministic, reclassified when the system changes). - Hard exclusions: additive / emissive / glow; ribbon / targeted / follow-velocity; small (<0.5 m), fast (>1 m/s) or short-lived (<1.5 s) particles; shaped textures; worn attachments (initially); HUD; volumetric fog off. - Soft score: big x faint x slow & long-lived x normal alpha blend x soft texture (per-texture stats: mean alpha, edge energy, mean colour; unknown stats = stay particles) x enough alive. - Convert above 0.7, revert below 0.5, blend in between. **Owner requirement: REAL density.** Fog-machine billowing clouds that follow the emitter speed and direction and spread out and fade the way the particles do. Froxel injection alone is too thin. So: - Keep simulating the particles as invisible density carriers. - Splat them into local world-space density bricks (pooled atlas, budget / LRU / stats; ~5-10 cm voxels near the camera). - Mass is conserved: the kernel grows with age and the peak drops, which gives the spreading. The particle alpha fade sets the dissipation. - Curl-noise domain-warp detail, advected, for billows. - Ray-march the bricks in their own pass, composited with the froxel fog by depth, lit by sun shadows, local lights and projectors, with in-brick self-occlusion. - Master toggle off by default, debug view (tint + brick bounds), density and billow settings.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sky_line/Slipstream#1003
No description provided.