Andrea Sbabo talked about being a Houdini FX Artist, explained why the Houdini is his go-to tool, and shared a detailed breakdown of some of the projects.
Introduction
Hello from Italy! I'm Andrea Sbabo and I am currently an FX Artist for Cine Chromatix.
I am a self-taught artist, so mainly my school has been the Internet. Five years ago I started playing with Houdini in my spare time for fun and publishing my results online on Vimeo and YouTube. Two years later after starting, one of my projects gained some traction and I got offered a job at Cine Chromatix, my current company. Since then, I have been working on some projects with an amazing team of artists.
Choosing Houdini
When I started to take my first steps in the 3D world and decided I wanted to learn how to create various kinds of FX, one of the first questions I asked myself was where to learn them. My goal has always been to be able to create complex shots as I was seeing in my favorite movies. There are a lot of various software that let you create some fire, but what if you want to put this fire on a boat, while it gets destroyed by a dragon and it's floating on the ocean?
The possibility to do such a thing is to use different software and plugins or to use Houdini. Using different programs implies a lot more steps, importing/exporting heavy caches, finding a common file format, and so on. In addition, most of them can’t interact with each other easily. Houdini has the solution to all of them, plus it has a completely procedural workflow. So it was the obvious choice.
At first, especially if you are a beginner, Houdini can be scary because of the node-based interface, because you see here and there some lines of code or because it is different from what you might know in Maya, Blender, or others… and it's completely understandable! But trust me when I say that it's just a matter of learning how to "read" it. After that, it will become really easy to use.
There is a lot of great advice out there for wannabe magicians but my personal advice for the people who wants to learn Houdini is: while you are following a tutorial, keep an eye at the Geometry Spreadsheet and try to understand what's going on and how it works. This is where you can really see what a node does, which attributes, objects, or volumes you are creating/deleting/modifying. In the long run, this will help you a lot, especially if you still don’t understand VEX or Python.
Rain and Ripples Project
This was a project aimed to explore a night environment. How to render, shade, and composite rain and secondary elements.
The ripple generator is a tool that allows you to create easily animated ripples on surfaces, but not only this. It’s almost becoming more like a 2D fluid solver based on heightfields and because of that, it's also super fast. Being a heightfield it's also easy to convert it to geometry or export it as texture to be used directly in the shader or while compositing the shot.
Inside Houdini, there is already a Ripple Solver which works pretty well and is already integrated with DOPs, the simulation context of Houdini. The issue is that it requires a grid/geometry with a lot of subdivisions. It can become heavy very fast if it’s not a closeup shot but you need to cover a big surface, especially if you also want to capture smaller details. So that’s why I decided to go for the heightfields. I think about them as images with all the properties of volumes.
In the first input it needs a surface, in the second it’s possible to plug extra points which can be used as a source for the 2D fluid. Of course, it cannot create splashes or similar but it can be useful to easily create ripples of water running on the beach after a wave or droplets on a window.
The initial idea came a year ago but only recently I had a chance to do it properly. To do basic operations like projecting the heightfield on geometry I used nodes that are already shipping with Houdini, the solver itself is written in VEX.
The height and slope of the heightfield are what drives the fluid and make it move. Right now it works fine with flat surfaces or surfaces where the height field can be easily projected on. I am currently working on making it based on UVs, so it can work on any geometry which has them. More about this in the future!
First of all, I create the basic setup in Houdini, but once I’ve laid down the main elements I aim to do a quick render of one frame each. This ensures that everything works well together and also it gives me a better idea of what I can do in Nuke instead of 3D. An example could be to add very small details in compositing, or extra passes from the usual ones to make things look better. This saves me a lot of time later because I make sure that everything works from the start, before going into details that might be deleted shortly after or completely covered because I decide I want to add fog or similar.
Imperial Walker Attack Project
I completed this project using Houdini 17 and since then a lot of things have changed and improved, especially in the pyro workflow, so it doesn’t make much sense to go into the specific details of the setup.
Since the Imperial Walker is basically a huge mechanical beast, I decided in the early stages that I was going to place some constraints on the leg joints, to create a dynamic rig. And so I did. I placed cone constraints on each knee and where the legs are attached to the body. I oriented them using some attributes which you can find on the cone constraint node (for example “goal twist axis” or “goal up axis”) and gave them some freedom to move like a hinge.
I fractured the geometry using several planes distorted with noise and booleans. After that, an additional fracturing of the pieces above a certain size with a Voronoi fracture. As constraints, I decided to go for a mix of hard, glue, and soft constraints. I’ve set different force thresholds based on the part of the body and with which probability I wanted it to break.
As the breaking force, I used some metaballs. Since glue constraints don't break based on the force but instead based on the “impact” attribute, I had to delete the constraints inside the metaball inside an SOP solver.
The explosion itself is composed of several elements: the main fireball, the smoke generated by the pieces, and fire in the inner part.
One trick I used quite often in the past to add details to explosions was to render an additional pass with an advected noise. This is possible fairly easy in Houdini because it can generate a dual rest field, which keeps track of the movement of the volume. Using this dual rest field as the input position of noise inside the shader, you’ll get a noise that is moving naturally with the volume and it’s possible to add this as an extra image plane with the render.
You can also pack three different noises or three different frequencies of the same kind of noise plugging each one in the RGB channels. In Nuke you can then separate these channels, mix them with temperature/fire pass and use them as masks for adding extra details.
The River Project
This project started because I wanted to test a workflow seen in a tutorial called Applied Houdini – Liquids ll by Steven Knipping. The basic idea was from there, I’ve then implemented some tricks learned along the way.
The first thing I needed was to establish which kind of river I wanted to do, the shape, and the wideness. This is because, even if you find the best parameters for a kind of river, it doesn't mean they perfectly apply to another one. So I started to look for some references. A photo done early in the morning with a calm curved river in Alaska captured my attention, so I went for it.
So I jumped into Houdini and started to create the river bed. Keep in mind that the river bed is one of the most important things when you create a river. There are laminar flows and turbulent flows rivers. One of the main differences between the two is indeed the shape of the river bed, how many bumps it has, and of which kind.
To create my river bed I used heightfields which are really lightweight and fast compared to using a highly detailed geometry. On the standard heightfield, I painted the river shape as a mask by hand using the "heightfield paint" node and moved it down to create the basic riverbed shape. With a "heightfield noise" I have then displaced it using the previous mask, adding some details on the borders but without spending too much time on them, knowing that later I was going to scatter some rocks on top.
So I made a small tool for randomly generating rocks, saved some of them on disk, each one with 2 different LODs, and scattered them using a "heightfield scatter" node, which is great for this kind of thing. I was loading the high-resolution LODs of the rocks only at render time as packed disk primitives, meanwhile, for viewport visualization, I was using the low res version. I didn't scatter rocks at the bottom because I didn't want it to be too turbulent.
The next step was preparing the collision geometries to use in the simulation. The river geometry was quite straightforward, I just needed to convert it to geometry and extrude it to give some thickness. Then I converted it to a VDB Signed Distance Field (SDF). For the rocks, I loaded the low-resolution version and inside a for each loop I converted them to SDFs, finding myself with 1000 VDBs volumes which seems a lot, but VDBs are really lightweight. Then I merged them all, river bed and rocks, using "VDB combine". To do this you plug just one of them in the first input, all the others in the second one. Set Collation to “Flatten All B into First A” and Operation to “SDF Union”.
Finally, I renamed the volume to "collision". This is because during the simulation I wanted the calculation of the collisions to be as fast as possible and the fastest way is usually to feed them directly in the simulation as VDB volume. It needs to have that name otherwise it doesn’t work.
I have then set up the source for the flip simulation by creating an emitter at the top of the flowing river, this is going to continuously source water during the simulation. I also created an initial state of the river by filling the river bed with proxy geometry and then converting it for the simulation with a flip source. Since I decided to go for a curved river, I knew that it was very probable that at the start of the simulation the water would have tried to go outside of the bed. To avoid this and save some time on the preroll, I already gave it an initial velocity by using the tangent of a curve that follows the river shape. This velocity is constant in the middle of the river but I reduced it to zero near the borders, where the rocks are placed. Sourcing this initial state to the simulation, the first frame already had the correct movement, and then naturally it started to create swirls and turbulences on top of it.
For the flip simulation, I've used the initial state previously mentioned, so the bed is already filled from water at the first frame, and used a fluid source to import the source positioned at the top of the flow. One thing that it's worth mentioning is that I have enabled "Stick on Collision". This also helped a lot keeping the river inside its bed and avoiding overflows. What it does is blends the velocity of the flip simulation with the velocity of the collision geometry, which we know it's zero. So basically it slows it down. I have also set up some custom curl noises in some specific areas, for example near the rocks in the center of the river. This was to add some more interesting swirls to the water flow.
The whitewater is also spawning from some specific areas. I didn’t want to have too much of it, especially at the borders of the river. The lifespan of the particles is really short. In addition to that, I have enabled erosion and the repellants to give a more natural motion. Since when they updated the whitewater solver I always enable these two settings, which give impressive results easily.
The fog is a huge box, all around the river, converted to a VDB volume. Volumes are expensive to render, especially if it's covering everything in the shot as in this case. Being the camera static I decided to save some render time by rendering a single frame of it. I knew that in the compositing phase I could have added some noise and movement to it. I just wanted to get the nice scattering of the volume. The material I used for the fog is called Billowy Smoke. I have reduced the density to a very low value, but it really depends on the dimensions of the box you are using. I also changed the Scattering Phase to be slightly negative.
The snow is also generated in Houdini by scattering points on top of the surfaces, of course not where the water was going to be, and on top of the rocks using their normals. Added some noise to the radius of the particles, converted them to VDB (yes, I really love them) to merge them all together, smoothed it a little bit, and finally converted it to geometry.
Conclusion
There are several challenges I face during the creation of my personal projects. Some of them are highly specific based on the kind of shot, others are quite common.
For example, when I have to do some rigid bodies simulation, the most common problem is that the models have open geometries, intersections, non-manifold polygons (corrupted polygons), and so on. Of course, the 3D models which are available online aren't meant to be used for this and some time has to be spent fixing them.
Optimization of everything is also quite important, especially if the hardware you have is the mid-range PC that everyone has at home.
As for tutorials, I recommend Applied Houdini, Rebelway courses, and masterclasses made by SideFX itself. In Houdini, there are different kinds of FX that you can create and they are pretty much all covered. These tutorials are great in all aspects and they show you not only how to achieve a certain shot or FX but they also allow you to understand what's happening behind the scenes, so you can create whatever you want!
I want to say thanks a lot to 80 Level for reaching out and giving me the opportunity to share something with you. I really hope that you found something useful in this article!
Andrea Sbabo, Houdini FX Artist
Interview conducted by Theodore Nikitin
Keep reading
You may find these articles interesting