Download hip: File:smoke_detailed.hip
Most of the smoke and pyro notes on the dops page were written several years ago, and was more about getting the general ideas covered. While they do that fine, they're all pretty low res and wispy and 'magical'. This has been gnawing away at me for ages; how was everyone else getting those cool big scale realistic highly detailed smoke sims?
Well, the latest work my students were doing at the university meant it was time to learn this properly. I'd spoken to a few Proper Fx Artists at Animal Logic and other places, they all insisted it's pretty straightforward:
Particles -> convert to vdb -> smoke solver -> add disturbance
Took a bit of experimenting, but they were right. Here's the run through.
First, the particle sim. Usual deal, noisy sphere, noisy velocities, but it's important to get this right. If the particle emission is too sparse, the smoke sim will be dotty and bitty. Too dense, the velocities will tend to smooth together creating mushrooms. If the particle all emit at the same velocity the result is boring. Too much chaos and the smoke looks too incoherent. It's an interesting balancing act!
Here's the particles that drive this setup, I found using an attrib noise for @v on top of the @v based on the emission geo normals gives interesting clumps and whatnot. I also emit it only for 5 frames, the particles on the first frame emitting slowish, next frame a little faster, next faster still. The overlapping particles at different speeds generate interesting motion when fed to the smoke solver.
Particles to volume source
Next is to translate those particles into volume sources. I've used the new volume sourcing workflow where attributes are setup on particles, then rasterized to volumes at the last minute. The volume rasterize attributes sop does a great job of making volumes from points, is quick to calculate, and handles 'smearing' the volumes with the particle motion blur really well. It also takes into account pscale, so adding some random scales helps break up the sim.
To set pscale I use an attribute randomize, but use the 'custom ramp' distribution so that I get a few big pscale values, the rest are smaller. This, plus the velocity blur option on the rasterize, gives an interesting natural look to the source volumes:
You can see I've got a pyro source in there too, it's designed to setup the correct attributes on points to then feed to a volume rasterize attributes, then into a sim. As it turns out I'm not really using any of them here (I set my own density attribute later on, and don't use temperature), so it can be ignored/deleted.
The smoke sim itself is quite minimal. It's using a smoke solver instead of a pyro solver, openCL is enabled on all the nodes I could find. The resizing is driven by tracking the sop volumes, buoyancy is turned off (meaning I don't need temperature), only density and vel are sourced into the sim.
Run like this the base result is interesting; its fast to simulate (about 3 frames a second on my laptop), follows the particle motion well, and there's enough gaps and variation in the incoming velocities to allow the solver project-non-divergent step to generate interesting curls and vorticies.
There's smooth mushroom shapes everywhere though, ew. The nice local velocities per 'plume' allow the project-non-divergent step to really comb and smooth things over, perfect environment for growing mushrooms.
Time to add disturbance.
Adding a gas disturbance should help add the fine detail and calm down the mushroom effect. As explained in a Jeff Wagner video I saw at some point, disturbance is basically white noise, pure randomness added to your fields, added explicitly to give the project-non-divergent step a hard time! When it gets these chaotic values it tries its best to balance it out, creating mini eddies and ripples that look cool.
By default disturbance is set to work on temperature, which I mentioned earlier I've disabled, so I've set disturbance to work on vel instead.
The trick is to find the right values. Push the disturbance intensity too high, it starts to draw attention to itself and look a bit wiggly and 'magical'.
Push it further still and the project-non-divergent won't be able to balance it, which looks like a hashy, nasty, overly disturbance'd sim that you see a lot in beginner sims.
You also have to balance the block size. This is the scale of the white noise, you want to get it to the right scale to make the sim feel right; too big and it's just weird random forces pushing your sim around, too small and it has no effect. Get it juuuust right.
Overcranking and undercranking vel in the volume source dop can heavily influence behaviour; if vel is too strong, the project-non-divergence step will get overwhelmed and lean the overall sim in the direction of the most velocity. Sometimes this can be a good thing if you kick the disturbance high enough to be able to affect the smoke edge, and give you interesting asymmetrical sims.
Here's an example; same sim, but with vel scaled to 2, disturbance block size halved, and including a gas dissipation to fade the smoke over time. It gets more of a rolling, high detail mushroom cloud vibe:
While here I've scaled v down to 0.5, and lowered disturbance as well to compensate. This lets the density lead the velocity a little more, making for a cleaner shape that follows the particle motion better, not as chaotic as the previous one (but maybe a bit less fun too)
I also used a wrangle to set @density on the particles before going to the rasterize node, this way I can fade the density via @nage, so there's not such an obvious density pop-off when the particles die. It's at this point the pyro source node isn't really doing anything, should probably delete it.
You can see that a lot of this work is about gaming the project-non-divergent step, getting an understanding of how it tries to balance unstable forces to get you that iconic swirly smokey look. You can override this by playing with a @divergence field. Setting values above 0 will allow for forces to expand outward in an unbalanced way. You know, like an explosion. The thing we're trying to do.
Using the same ramp trick, I made a wrangle to set some divergence per particle at the start of their life, then quickly go down to 0 so that it doesn't break the rest of the sim. Making sure divergence is added to the list of attributes on the rasterize node, and adding it to the volume source dop, things get interesting:
The first few frames fill out much more quickly, as the positive divergence pushes the sim out as if there's a lot of gas being released, which in turn makes the end of the sim look a lot bigger, chaotic, dangerous.
Turns out getting that high-res smoke look isn't too hard, and this feels like a solid base to build on. All seems obvious in hindsight, and everyone else seemed to understand it, I'm just an idiot. Good to plug this hole in my knowledge though!
I got some interesting feedback already from fx folk who really know what they're doing, next steps all seem to involve masking the effects of disturbance and other gas nodes through things like measuring the speed of the velocity, makes sense. That's your homework, let me know how you go. :)
Oh, make sure you've set your display texture mode to HDR , and either in the same dialog or in a volume visualisation sop set the texture res to at least 512x512x512, otherwise the viewport will look blobby and lame, while in fact the underlying sim data might be fine.
Hey, if you found this useful, don't forget to click those patreon/paypal links below.
If you like the idea of learning this kinda stuff in a fun intense year with a bunch of like-minded folk, come and do a Masters with us at the University of Technology Sydney!