Houdini 22 pyro fireball with a speed-adaptive shredding microsolver, Karma XPU close-up of the mushroom cap

Custom GPU Pyro in Houdini 22: Build Your Own Solver

Technology Blog · Houdini 22 · Pyro

Custom GPU Pyro: Build Your Own Solver

How to architect a GPU-first pyro pipeline in Houdini 22 – from the anatomy of a single solver step to OpenCL microsolvers and a production workflow for explosions that look like yours, not like a preset.

GPU-first iterationOpenCL microsolversCOP Pyro · H22
AXIOM EXPLOSIONS ON STEROIDS — IDA VFX19:56 · GPU explosion setups
01 — Why build your own

The last 20 % is what makes an explosion yours

Every pyro shot starts in the same place: the stock solver gets you most of the way. What separates a studio look from a shelf-tool look is the rest – how a fireball rolls over itself, how quickly it sheds detail, how long the smoke hangs before it settles. That behaviour lives in the order and the content of the solver step, not in a single magic parameter.

GPU solvers such as Axiom showed how much faster look development becomes when a simulation answers in seconds instead of minutes. Building your own solver does not mean reinventing fluid dynamics. It means owning the pipeline around it:

  • Iteration speed – look dev on the GPU, so you can try ten ideas instead of two
  • Look ownership – custom forces that encode your studio’s taste for fire and smoke
  • Reuse – package what works as an HDA with a handful of artist controls
02 — The landscape

GPU pyro options in Houdini 22

Before writing a single kernel, pick the right base. Houdini 22 gives you several routes, and they differ in what runs on the GPU and how much you can customise:

RouteRuns onBest for
Pyro Solver – SparseCPUProduction default. Sparse domain, any microsolver, maximum flexibility.
Pyro Solver – Dense + OpenCLGPU (dense)Compact domains. OpenCL acceleration only works in dense mode.
Minimal OpenCL SolveGPUFastest look dev – keeps data on the device, fewer features.
COP Pyro (Copernicus)GPU, sparseIntroduced in H21, production-ready in H22 with implicit-surface sourcing and collisions. Extend with OpenCL COPs.
Axiom (Theory Accelerated)GPU, sparseThird-party plugin: OpenCL/Metal/CUDA with CPU fallback, built for fast iteration.
Heads-up for H22: the classic dense DOP nodes (Pyro Solver DOP, Smoke Object, Smoke Solver) are deprecated. Build new setups on Pyro Solver (Sparse) – which also handles dense and OpenCL modes – or on COP Pyro.
03 — Anatomy

What happens in one solver step

Every pyro solver – stock, Axiom or your own – repeats the same sequence per substep. Knowing it tells you exactly where a custom force has to go:

  1. Source – inject density, temperature, flame/fuel and velocity from your emitters.
  2. Forces – buoyancy, wind and your own custom fields push the velocity.
  3. Shaping – disturbance, turbulence and vorticity confinement add and preserve detail.
  4. Combustion – burn flame or fuel, release heat and add divergence (expansion).
  5. Advection – move all fields along the velocity field.
  6. Projection – the pressure solve removes divergence, so gas only expands where you asked it to.
  7. Dissipation & cooling – fade density, cool temperature, let the shot settle.
ONE SUBSTEP t → t + Δt 01SOURCE02FORCES03SHAPING04COMBUST05ADVECT06PROJECT07DISSIPATE NEXT SUBSTEP CUSTOM FORCES → STABLE
Mini-clip · the 7 phases of one pyro substep – projection (orange) turns your forces into clean motion
Rule of thumb: forces that run before projection are made divergence-free by the solver – that keeps them stable. Anything you change after projection can break incompressibility. Occasionally useful, usually a source of popping.
04 — The golden rule

Stay on the GPU

GPU solvers rarely lose time on maths. They lose it on copies between system memory and video memory. A single CPU microsolver between two OpenCL nodes forces a full round trip of every field it touches.

A · ALL OPENCL – DATA STAYS IN VRAM GPU kernel Akernel Bkernel C B · ONE CPU NODE IN THE MIDDLE – ROUND TRIP GPU kernel Akernel C CPU / RAM VEX node COPY ↓COPY ↑
Mini-clip · same work, very different travel time – every CPU node between kernels forces a copy out of and back into VRAM
  • Prototype in VEX, ship in OpenCL – VEX is quick to debug; port the logic once it works.
  • Bind only what you need – Houdini only copies data that is actually bound to a kernel.
  • Never read neighbours from the field you write – write into a temporary field first, or you get race conditions and noisy artefacts.
  • Budget VRAM – GPUs have no virtual memory. Too much data fails instead of slowing down.
  • Disable DOP caching for look dev – caching copies the fields every frame.
05 — Building blocks

Three custom microsolvers

These three forces cover a large part of what makes explosions feel art-directed. Each comes as a VEX prototype for a Gas Field Wrangle and as an OpenCL version.

COOL → SLOWHOT → FAST
A · temperature-driven lift
SLOW → SOFTFAST → SHRED
B · speed-adaptive shredding
BURN → DIVERGENCE → PUSH
C · burn-driven expansion
Tested in Houdini 22.0 (OpenCL SOP, Run Over: VDB): all three kernels compile and produce the expected values. Three gotchas we hit on the way:
1 · @TimeInc only exists when Include Timestep is enabled on the node.
2 · Houdini’s native volumes store vectors as three scalar volumes (vel.x/y/z) – for float3 bindings use vector VDBs (VDB Vector Merge).
3 · A kernel only iterates over the voxel topology of the grid it writes. A constant or empty grid (e.g. zero divergence) has no voxels – activate it from the burn grid first (VDB Activate, region from reference VDB).
Binding syntax differs slightly between the OpenCL SOP, OpenCL COP and Gas OpenCL DOP – use Generate Kernel to check the signature in your context.

A · Temperature-driven lift

Classic buoyancy, but only above an ambient threshold – hot cores rise hard, cooling smoke slows down and starts to roll instead of shooting upwards forever.

VEX · Gas Field Wrangle
// prototype: lift only where the gas is hotter than ambient
float lift    = chf("lift");
float ambient = chf("ambient");
float t = max(f@temperature - ambient, 0);
v@vel.y += lift * t * @TimeInc;
OpenCL
#bind parm lift float val=1.5
#bind parm ambient float val=0
#bind vdb temperature float
#bind vdb &vel float3

@KERNEL
{
    float  t = fmax(@temperature - @ambient, 0.0f);
    float3 v = @vel;
    v.y += @lift * t * @TimeInc;
    @vel.set(v);
}

B · Speed-adaptive shredding

Blobby explosions usually have uniform detail. Real fireballs tear apart where the gas moves fast and stay soft where it is slow. Mask your turbulence by speed:

VEX · Gas Field Wrangle
// add curl noise only where the gas is fast
float speed = length(v@vel);
float mask  = fit(speed, chf("speed_min"), chf("speed_max"), 0, 1);
vector n    = curlnoise(v@P * chf("freq") + @Time * 0.3);
v@vel += n * mask * chf("amp") * @TimeInc;

On the GPU, let Gas Turbulence generate the noise into a temporary field (it has an OpenCL option) and only apply the mask in your kernel:

OpenCL
#bind parm smin float val=2
#bind parm smax float val=12
#bind vdb turb float3
#bind vdb &vel float3

@KERNEL
{
    float3 v = @vel;
    float  m = clamp((length(v) - @smin) / (@smax - @smin), 0.0f, 1.0f);
    @vel.set(v + @turb * m * @TimeInc);
}
Houdini 22 pyro fireball with a speed-adaptive shredding microsolver, Karma XPU close-up of the mushroom cap
Tested in Houdini 22.0. The shredding wrangle above, plugged into the Forces input of a Pyro Solver (Sparse). 0.02 voxel size, speed_min 1.5, speed_max 6, freq 4, amp 30. Rendered with Karma XPU.
Houdini 22 pyro: baseline sparse solver (left) vs. speed-adaptive shredding (right) at frame 10 Houdini 22 pyro: baseline sparse solver (left) vs. speed-adaptive shredding (right) at frame 18 Houdini 22 pyro: baseline (left) vs. speed-adaptive shredding (right) at frame 26 with finer breakup

Frames 10, 18 and 26 – same source, same solver settings. Left: plain sparse pyro. Right: with speed-adaptive shredding. The cap tears into finer curls where the gas is fast, while the slow trailing smoke stays soft.

C · Burn-driven expansion

The blast should come from combustion, not from a velocity kick on the source. Feed divergence from the burn field – the projection step then turns it into a clean, physical push.

VEX · Gas Field Wrangle
// expansion where fuel is burning
f@divergence += f@burn * chf("expansion");
OpenCL
#bind parm expansion float val=2
#bind vdb burn float
#bind vdb &divergence float

@KERNEL
{
    @divergence.set(@divergence + @burn * @expansion);
}

Since Houdini 21 the Gas Burn DOP covers the basic version natively. The custom one is worth it when you want extra control – for example expansion that fades with the age of the burn.

06 — Wiring

Plugging it into a solver

Route A · DOPs with Pyro Solver (Sparse)

In Houdini 22 the Pyro Solver (Sparse) DOP has three extra inputs: Advection, Sourcing and Forces. Lift and shredding go into Forces, so they run before projection; divergence belongs into Sourcing. Running in sparse CPU mode? Use the VEX versions. Running dense with OpenCL? Keep the whole chain OpenCL so nothing falls back to the CPU in the middle.

Route B · COP Pyro in Copernicus

In Houdini 22 the COP Pyro block is the most direct path to a sparse GPU solver you can extend. Source with implicit surfaces (Pyro Source Shape → Pyro Source from Shape), use the new force nodes such as Pyro Vortex Confinement Force and Pyro Velocity Scale Force, and drop your own OpenCL COPs into the block. The H22 dry-ice example shows exactly this pattern of adding nodes to the solver.

Package it

Wrap the result in an HDA with six to ten exposed controls – lift, ambient, shred range, expansion, dissipation – plus presets for your typical shots. That HDA is your look.

07 — Production method

From reference to final explosion

The solver is only half the work. The other half is a disciplined method – the same reference-first, iterate-fast approach that the best Houdini training programmes teach:

  1. Break down the reference. Split the event into phases – flash, initial blast, fireball, rolling smoke, settling dust – and write a frame timing sheet.
  2. Proxy look dev on the GPU. Low resolution, Minimal OpenCL or COP Pyro. Decide shape and timing only. Wedge three or four parameters with TOPs.
  3. Lock the motion, then add resolution. Keep the approved low-res velocity as a guide. Run the final at production resolution, or try ML Volume Upres (Houdini 21+).
  4. Layer, don’t overload. Hero burst, secondary trails (Pyro Trail Source), ground dust and debris smoke as separate sims – easier to direct, cheaper to fix.
  5. Shade in context. Karma XPU, a linear/ACES colour pipeline, emission from temperature and flame – always judged against the reference.
  6. Package what worked. Presets, HDAs and a short note on why – that is how a studio look grows from shot to shot.
08 — Takeaways

In short

  • Pick the base first: Sparse for production flexibility, COP Pyro or Minimal OpenCL for GPU speed.
  • Hook custom forces in before projection – they stay stable.
  • Keep the whole chain on the GPU; one CPU node can cost more than all your kernels.
  • Drive the blast with divergence from burning fuel, not velocity kicks.
  • Your look is a method plus an HDA – not a single sim.
IDA VFX

Explosions for your production?

Start from production-tested Houdini explosion setups in our store – or bring us into your film, series or game project. We work remotely with studios worldwide.

Axiom is a product of Theory Accelerated. Houdini, Copernicus and Karma are products of SideFX. Training providers are mentioned for context only – this article is independent and written by IDA VFX.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top