Sunday, May 15, 2011

Houdini: Foam Pass for level set fluids

I've been using Exotic Matter's Naiad for water simulations, and apart from the main simulations, other layers are included, such as foam particles floating on the surface, as well as particles ejected away from the surface to simulate spray.

This experiment is an attempt at creating foam off a Houdini Level Set Fluid simulation (Note: Naiad uses FLIP fluids.)

Emission is basically scattered points on a  mesh that was converted from the fluid's main level set ("surface" volume: with a convert sop you can get a mesh). Two parameters are used to control emission regions; curvature (measure SOP) and velocity (lookup into velocity volumes).

These points are then used as for emission in POPs; this particle layer is relatively fast to simulate because it's all pops! Inside pops, there is a fake "advection" stage where the particles sample the velocity volumes from the base simulation, and uses that to move each particle to its new position.

This however will result in particles moving into positions below the surface, or a bit too high above the surface. Tests indicate this can be improved by a high resolution level set, but we all know how expensive those are ;-)

Instead, a VOP POP was created to move the points based on the gradient of the base simulation's distance field, and points are moved accordingly to whether they are negative or positive (i.e. negative distances moved towards the surface following the gradient vector; positive distance are again moved, but against a negative distance vector).

I have no idea about those spots that hang on the ceiling - there is a cull pass that removes particles if they are a set distance away from the distance field. Since those particles are hanging there, I'm assuming there are remnants of the level set that do not have velocities affecting them and not dissipated.

That's it for this experiment, maybe I'll look into it another day.


Saturday, May 14, 2011

Houdini: Arrow system using Quaternions

Got inspired the last few days to design an "Arrow" system and finally took Friday evening and Saturday morning to figure out a good way to create a system that allows stuck particles (arrows) to change their orientation based on the underlying deforming geometry.

The main concept is getting an origin frame of reference (in this case, it's the primitive normal of the collided polygon that the particle hit, as well as the vector of the first two vertices. These will give a reference frame.), as well as a constantly updating frame of reference (the prim normal and vector again, from the deforming primitive).

Originally, I had used the Align VOP to perform this calculation, however, the align vop simply returns a transform from one vector to another vector via the shortest path. In this case, it is basically a rotation with an axis that is the cross product of the two vectors. What we want is a proper rotation, so I used the look at vop to generate rotation matrices from the two frames of references.

Next, these were converted to Quaternions, and then I used the SLERP function (Spherical Linear Interp VOP) to obtain yet another quaternion that blends the original frame orientation to the final deformed frame.

The issue I encountered was that the SLERP function returns the initial orientation quaternion when both the initial and target orientations are the same - this is obviously the case during the collision frame; both reference and initial orientation are exactly the same.

This, we do not want; as during the collision frame, I want my arrow's normal vector to be operated on by a Quaternion of xyzw = {0,0,0,1}, not the quaternion for the initial frame. Hence, by subtracting the initial frame's quaternion from both the initial frame as well as the target frame (this is done by doing a quaternion multiplication of the conjugate of the initial frame's quaternion against both initial and target quaternions before putting them into the SLERP).

This seemed to work, from the examples above. :)

Woo! Slowly attacking quaternions. And Houdini just makes it so simple.

Other issues I encountered is during rendering: proper motion blur for the arrows. With a stuck particle, the "v" velocity vector is actually locked in place whilst the particle is with the pstate of 16, hence during renders, this is uber incorrect.

Initial tests using to Attribute Transfer velocity vector (calculated using a Trail SOP) did not work out as it was very inconsistent. What I did then, was to do a look up into the geometry (the collision POP stores the posprim attribute, allowing us to find out which primitive to query), and allow the hit arrow to take the velocity of the underlying geometry.


Sunday, May 08, 2011

Saxophone Log: May 2011

Here's another saxophone log from this month. I'm playing from a play along book called "Dig It!" for Saxophone.
What's nice about this is that just one book caters for Alto, Tenor and Soprano as well! The Tenor and Soprano scores are similar, just that the soprano will need to be played one octave below the score. In addition, there are multiple parts for the different saxes, to be played together e.g. alto + 2 tenors. Good stuff!