Peter Sanitra shared how he created his awesome Tree & Soil animation in SideFX Houdini: realistic rigid bodies, pyro dust effect and more!
My name is Peter Sanitra. I am from the generation of CG artists who started working in this field in the 90s. The industry was not so big back then and it was common that one guy did everything from modeling to final render. I would say I’m a CG Generalist with a passion for FX work.
For about 10 years now we work together with Marek Denko as NoEmotion. Most of the time we work on rendered game cinematics, movies, and commercials. I spent most of my time using 3ds Max, but during the past few years, Side FX Houdini became my preferable tool.
Goals of the Project
Whenever I have some free time, I like to play with new setups in Houdini. I was doing two completely separate RNDs. One was soil-based on RBDs with grains. The other one setup was simulation rig for meshes coming from SpeedTree. Both went well, and to challenge myself, I decided to join them together.
Making Realistic Rigid Bodies
How to achieve realism? The answer is the following: constraints. A lot of them, different types, variations and local control. One cannot just drop Connect Adjacent Pieces, set the glue and hope it will look like soil. I was using multiple types of constraints, some large-scale connections, smaller, local ones. Some pieces were not connected at all. Pieces near tree are constrained to the roots, and their strength increases the closer they are to the trunk.
Top layer under the grass uses both glue and hard constraints. Hard constraints were actually set up to be spongy, not hard. They were allowed a bit of rest length change and force mixing, so they don’t look too rigid and can flex a bit.
After packed RBD sim was done and cached I also stored hires VDB representation of it. It was later used many times on other solvers for collision with tree, grains, leaves, and Pyro.
Individual RBD pieces were displaced on render time based on stored REST positions to give them additional detail.
Visualisation of various constraints used for the RBD simulation:
Soil Simulation: POP Grains
Pop grains are very versatile and relativity fast. They can run on GPU too, even in high numbers. In my case 5-7 millions of grain particles colliding with the RBD pieces, tree, and themselves. It is very important to prepare your collision meshes well. They should be watertight. Also, they should be able to provide sub-step data for the collision to avoid any penetration of fast-moving objects. I almost always use VDBs, as they are multi-threaded, and you can cache them on farm and sample volume collision from HDD directly in dops using Static Object dop.
Grain particles were sourced from areas of broken rigid bodies chunks. I also transferred some useful attributes from RBDs to particles, like the original chunk ID it belongs to, color, UV, or depth that I utilized later for shading. You can for example shade the soil base, making it dry or wet, darker or brighter.
It was quite a hard decision on what approach to use for the tree. All have pros and cons. Some are fast like grains. Some work better with large geometries like packed RBDs. FEMs are good at giving softer look. I went for wires because at the camera distance, it gave me the best ratio of control vs speed. Also, fractal nature or hierarchy of tree is very close to splines with variable thickness.
In the first stage, I generated a spline representation of the tree, with proper links/pins of children to parents. On these splines (per point) I stored attributes important for the sim. Like stiffness, mass, collision radius etc.
There were 6 levels in the spline structure – roots, trunk, branches 1/2/3, twigs. Altogether around 70k points in 13k primitives, for the whole tree. I was still able to run it under 1h for 100 frame sim. Very reasonable.
To get the actual tree mesh deformed with the splines I used a mixture of point and spline deformers. Big deformations tend to lose volume a bit, but delta mush will help with that.
The grass was also simulated with splines, actual meshes deformed in for each loop and cached.
Leaves are done in a separate sim. First, I isolated locations of leaf stems, populate the structure with flat boxes, correctly oriented, based on xform matrix of original leafs geometry. Boxes are then simulated as packed RBDs with limited position and rotation constraints, so they don’t move too violently. Some of them could break and fall and are passed into a separate POP sim. After everything was done, I replaced the proxy geo back with the proper leaf meshes.
For Pyro dust emission I used multiple sources. Primary these were zones where bigger chunks break apart. If you are using packed RBD sim, you can use Debris Source node as a start, and filter the results more with age, speed or acceleration. Secondary, I emitted from the pop-grains too, again with some appropriate filtering or at least age ramp.
You can further improve the dust emission location with some variation of density by UV noise, REST noise or similar to make it look more natural. Before doing actual Pyro sim, I advise you to cache out any sources to disk. You are probably going to run pyro sim dozens of times before you set it right. No reason to calculate sources each time you do so, just do it once and read from the disk.
For the actual sim, it needed a proper balance of forces and density. There is no temperature here, no buoyancy. It’s just gravity, speed, and weight of the dust versus the resistance of air. It was very important to create a variable velocity field of the air to oppose the dust motion. Velocities were sourced from soil chunks, from grains particles, from tree branches even leaves. I took velocities from all the elements and sourced them into pyro vel field.
Final pyro sim was done with 2 DOP substeps and 4 solver substeps because some motions were quite fast. Resolution of the grid was 500-1000 voxels cube grid, which I was still able to run with GPU openCL on GeForce 1080 TI
Everything was pretty much cached to disk, so pre-render scene conversion/preparation time was minimal. These days with fast SSD/NVME drives you can load 2-3GB of data in an instance. For rendering, I used Redshift for multiple reasons. The integration of RS in Houdini is very well done. You can pretty much take any type of data from Houdini attributes and render it. Volumes are very fast to render, too. And of course, it runs on GPU. I could easily run rendering tests in the background while still doing my daily jobs. For pure renders speed/performance. I had a setup with single dome light, it’s very fast to do for most of the raytracer engines. There is a minimal amount of GI or glossy bounces in the scene, so it reached given noise threshold quite fast. 2-3 minutes for Full HD frame on single 1080Ti.
I really enjoyed doing this RND, it was both challenging and rewarding. Looking forward to the next one.
Here are some of my other works:
Peter Sanitra, CG Artist
Interview conducted by Kirill Tokarev