Home Creators Posts Import Register Favorites Logout

Content

We’ve covered a lot of ground so far in The Complete Houdini: interface basics, file I/O, modeling, UV creation, and more. It’s now time to dig into one of Houdini’s greatest strengths and its main claim to fame, simulations!

Houdini boasts a comprehensive toolkit for creating all kinds of simulations, including Vellum (cloth, hair, grains and fluids), Pyro (fire, explosions and smoke), FLIP (fluids including water, mud and lava), FEM (finite element method, often used for muscle and skin), Oceans, and, last but not least, our topic here, RBD or Rigid Body Dynamics.

RBD covers a range of simulations involving the interaction of hard surface objects, from toppling blocks to shattering glass to crashing cars. We’ll start small with a basic practical use case for RBD: a simulation of a billiard table with ricocheting balls.

Setup

To get started we’ll need to set up a few geometry objects:

A table with a raised edge and six pockets.

Fifteen colored balls and one cue ball.

A cue stick.

A proxy collider object to set the cue ball in motion.

We can draw on the modelling knowledge we gained earlier in this series to create the table geometry. Add a box, blast (delete) the top, and extrude the edges to form a lip all the way around. We can place one tube with multiple transforms to create the pockets and use a Boolean operation to intersect with the table. Here’s the finished result and the node tree. No need to get fancy here, just the minimum to create realistic boundaries for our simulation.

Before we continue, note that scale is very important when working with simulations in Houdini. Houdini doesn’t measure things in meters or feet or similar. Rather, Houdini simply uses a generic unit. A 1 x 1 x 1 box could be 1 millimeter, 1 mile, 1 anything.  

However, many default settings in Houdini simulation tools are based on meters. For example, the default gravity force acceleration is 9.8 meters per second per second. Therefore, if you want gravity to behave realistically relative to objects in your scene you should define one Houdini unit as one meter. If you prefer, you could set gravity to 32 units (feet) per second per second and modify the dimensions of your objects accordingly.

With all this in mind, I left gravity at the default “meters” and set the billiard table model to 2.75 x 5.5 (meters) and the balls to a diameter of 0.05715 (57.15 mm). Note that I linked the width of the table to its length by setting the Z parameter to ch(“sizex”)/2. This means that the width is always half of whatever length value I choose.

Our scene needs 15 balls and one cue ball, all the same size. There are many ways to create a large number of (mostly) duplicate objects. I just brute forced it in this case and made 16 mini node trees, each with a color node or two attached to assign colors. I used selections to color just the middle stripe on some balls. To make some sense of all these nodes I arranged them in a representation of how they’re set up on the table. An eccentric approach maybe, but it makes it easy to identify them!

This could be streamlined a lot. You could instance one sphere on 15 points and set the color based on the Cd (color) attribute of each point. With a simple setup like this it doesn’t really matter, but there are many opportunities for optimization.

I arranged the balls using the viewport transform controls and set them so they just barely touched the table top.

I created a cue stick which won’t be used in the simulation, only in the render. It’s a tube with a taper and beveled ends.

Finally, I made a small box to act as a collider to get the cue ball in motion. I’ll explain why we’re doing this instead of using the cue stick in a bit.

The Simulation

The core of our simulation will be the RBD Bullet Solver node. This is Houdini’s modern, artist-friendly tool for rigid body simulations. (True Houdini scholars will be interested in the older DOP Network approach to simulation. This is a hardcore, very complex way of creating simulations that indeed can still be quite useful. If you need infinite power and flexibility then creating a DOP Network will be the way to go, but it comes at a steep cost in terms of usability.)

In most use cases the RBD Bullet Solver is sufficient and it’s much easier to learn and customize.

For our simulation we’ll connect the merged collider objects (the table and the box) to the Collision Geometry input, and our merged, soon-to-be simulated balls to the Geometry input on the left.

To get things moving, let’s animate our collider box. Simply keyframe its position so that it accelerates to a point where it hits the side of the cue ball.

Note that his behaves just as you’d expect in real life: if we pull the collider only back a short distance and give it a long time to reach to the ball, then the ball won’t move much. But, pull the collider back a long way and accelerate it quickly: the ball will be hit hard.

If we leave all settings at default and press play we’re going to get some unexpected results. First of all, the balls may start moving and settling on their own, depending on how microscopically close you got them to surface of the table. And the box collider isn’t colliding at all!

Let’s start customizing our RBD settings to get this all working as desired.

To address the settling issue I often do two things: set the Sleeping Time parameter to an aggressive value so that objects stop all motion relatively quickly. I also set a “pre-roll” on the simulation so that the settling process happens before the first frame. In this case I set the sleep threshold to 0.2 and added 5 pre-roll frames (Start Frame set to -5). This allows the balls to begin in a completely motionless state.

We’ll also want to increase the number of Substeps. Substeps are divisions within each frame that allow collisions and movement to be more precise. For example, if the box hits the cue ball between frames 11 and 12 in the timeline then the collisions will be detected incorrectly. We use substeps to divide each frame to look for more events to incorporate into the simulation. I found that 3 Global Substeps worked well for this scene.

To address the collision issue, set the Collision Type to Deforming.

This accounts for any animated colliders that our simulation will have to interact with. Note that a collider never responds to the simulation. They can only follow their own predetermined motion and act as immovable objects that the simulated objects react to.

I also reduced the Collision Padding to 0.001 to make sure the collisions are precise. With larger padding values the balls might react to each other even if they aren’t even close to touching.

After making these changes, press play again and our simulation is now in motion!

We’re getting some strange collision behavior with the balls jumping over the edge of the table. The reason for this is that the table has a rather complex volumetric representation. We’ll want to set the Collision Shape to Concave to account for this.

This is behaving much better now, but there is one glaring problem: it never stops. This is a very common issue with RBD simulations in Houdini or any other app that implements the same type of “bullet” solver.

We can partially address this by dialing in the Density, Bounce, Rotational Stiffness and Friction parameters. Here are the values I settled on that looked mostly like you’d expect billiard balls to behave. And yes, you could probably mess with these settings a lot (and I mean a lot) more and finally get a result without too much excess motion.

However, down this path lies pain and frustration. As artists we want to make something that looks good and that we can control. We’re not trying to create a perfect scientific simulation. (At least not in this case, but many people do use Houdini for that purpose! You could implement an entire physics paper in Houdini if you wanted.)

Let’s dive into how to use Houdini’s VEX scripting language to let us micromanage the inertia of our simulation and get a controlled, realistic result. Many tutorials will tell you that you don’t really need to use VEX in Houdini… but, real talk… you do. It’s just a fact of life that Houdini needs low-level intervention to get the best results. It’s designed from an extremely technical standpoint and you’re not going to be very happy with the workflow unless you start using VEX, at least in small doses, for almost everything.

In order to address our out of control, never ending motion, we need to find a way to control the velocity and rotation in our simulation. Select the RBD Bullet Solver node and open the Geometry Spreadsheet. We can see that every point in every ball has constantly changing v (velocity) and w (rotation) values. These are all controlled internally by the simulation, but what we want to do is “put on the brakes” manually.

Here’s how I addressed this problem using VEX. We can add customizations to our RBD Bullet Solver by double clicking on the node and attaching new nodes to either the PRESOLVE or POSTSOLVE outputs. I connected a Geometry Wrangle to the POSTSOLVE output. This means that the simulation does all its math on one frame, then we append our custom operations to those values.

Note that in Houdini a VEX “wrangle” (usually) runs over all input elements. We’ll select Run Over: Points here. What that means is that every single point in the scene will have our code applied to it, all at once. VEX automatically supports parallel execution and using processor threads for optimal performance. For example, if we write @P += 1 in VEX we’re not saying add 1 to ONE point’s position, we’re saying add it to ALL points’ positions, all at the same time. This operation is then repeated on every frame of an animation or simulation.

To identify balls that are already slowing down, we look for v and w values below a custom threshold. When that threshold is met or exceeded, we then apply a multiplier to the value to gradually reduce it. Say our velocity threshold is 1 and the multiplier is 0.99. This means that for each subsequent frame the velocity is reduced by the multiplier: 1 x 0.99, 0.99 x 0.99, 0.9801 x 0.99, etc. As we do this, the values will eventually get low enough that our “sleep” threshold will be hit and the ball will stop moving completely, which is what we want.

I used the Create spare parameters feature in the wrangle node to create sliders for each of our script input values. Anything defined with a chf (“channel float”) can be turned into a UI element for easy interaction. This makes customization and testing a breeze since all we have to do is change one or more values in the UI and rerun the simulation to see how things are looking.

We check if we’re at frame 40 or beyond (just to give the simulation a chance to do some crazy, uncontrolled stuff for a bit). If we are, we then check for any v absolute values below 0.1 and w values below 5. If we find some, we multiply those values by 0.985. These values are then fed into the next frame of the simulation. The simulation does its math with the new values, then we check again and apply the brakes further. In fairly short order we’ve gently slowed all existing motion down to a near stop, the “sleep” threshold is met and all our balls go inactive. Here’s the complete script:

@v_threshold = chf("Velocity");@w_threshold = chf("Rotation");@decrement = chf("Decrement");

if(@Frame > 40) {    if(abs(@v.x) < @v_threshold) @v.x *= @decrement;    if(abs(@v.y) < @v_threshold) @v.y *= @decrement;    if(abs(@v.z) < @v_threshold) @v.z *= @decrement;

    if(abs(@w.x) < @w_threshold) @w.x *= @decrement;    if(abs(@w.y) < @w_threshold) @w.y *= @decrement;    if(abs(@w.z) < @w_threshold) @w.z *= @decrement;}

Seeing how complex this is getting, you might have a hint now as to why we used a simple box collider to set the cue ball in motion. If we used the cue stick model we open up a whole can of worms: what part of the cue stick is the hitting the cue ball? Where is it hitting? Is there angular velocity because the cue stick is tilted down? What is the mass of the cue stick?

All we want here is “cue ball move” and slamming a simple box into it is a quick and easy way to make that happen. We can animate the cue stick to match the impact position and frame of the box so that looks like the cue stick is creating the initial collision. That’s movie magic!

The takeaway here is that the math behind these type of simulations is incredibly complex and all we really want is something that looks good and looks real. Any shortcuts to get to that result are fair game. We took a lot of shortcuts here: collider proxy, only “generally correct” simulation parameters, no air resistance, and custom damping with VEX. It looks really nice and we got to that result in a fraction of the time it would have taken to do everything in a totally mathematically accurate fashion. To paraphrase an old saying, if it looks good, it is good!

Conclusion

In this article we learned how to set up an RBD simulation in Houdini, which parameters to dial in, and how to exercise further control using VEX scripting. This kind of work in Houdini can be very satisfying. Seeing a scene “come to life” is a uniquely enjoyable feeling. We’re just getting started with Houdini’s simulation capabilities and there will be a lot more to come in The Complete Houdini. Stay tuned!

Files

Comments

No comments found for this post.