Learning Houdini: Post-Course, Thoughts and Creating Tools

Making Of / 08 October 2019

This post was originally written on September 20, 2018

Background, in 2018, I did a Houdini certification at NYP in Singapore.


Houdini Course

Last Assignment

A year ago, I completed my Houdini class. My last assignment was part of the VEX module and it’s probably the chapter that scared me the most and ended up enjoying a lot. There was a lot of “Ah ha” moments and it was really satisfying to finally be able to accomplish anything trough code and understanding it. 

The final assignment brief tasked us with the following tasks:

1.    Starting from the given MeteorCrash_start.hipnc file.

2.    Using Houdini, fracture the meteor so that even the inside of the meteor contains small pieces.

3.    Writing VEX code (through Attribute Wrangle node) to drive the meteor planet crashing effects, so that the core crashing effects are deterministic (not through any form of simulations).

4.    In the VEX code, vector dot product function must be used to detect the penetration between the meteor and the planet. And vector cross product function must also be used to determine the spreading directions of the shattering pieces of the meteor.

5.    Transfer attributes from the force field to the meteor to drive features of the meteor pieces (like color for example)

6.    Flipbook at least 100 frames to show the whole process of the meteor crashing into the planet (starting from a whole meteor).

7.    BONUS: adding extra particle effects to the crashing effects to make it more impactful. Simulations (through SOP Solvers or DOP Networks) can be used to create the particle effects.


Above is the whole network I did for creating the system above. The code is stored in the attribute wrangle nodes in purple.

  • The meteor breakage was done using the same techniques used for the house explosion simulation.

  • Using vex, I was able to drive the disintegration of the meteor proportional to its distance from the planet. 

//Fetch data 
int nearPoint = nearpoint (1, [email protected]);
vector nearPos = point (1, "P", nearPoint);
vector nearNormal = point (1, "N", nearPoint);
float distance = length (nearPos - [email protected]);
vector diff = nearPos - [email protected]; 

//dot product 
float dot = dot (normalize(nearNormal), normalize(diff)); 
//set group 
if (dot > 0) {
        setpointgroup(0, "insideForceField", [email protected], 1, "set");
 }
 
if (distance < 0.1) {
    setpointgroup(0, "impacted", [email protected], 1, "set");
 }

//cross product
vector cross = normalize(cross(nearNormal, diff)); 

//strenght of spreading of meteor pieces 
float spread = fit(distance, 0, 0.2, 1, 0) * chf("impactForce"); 
vector impact = cross * spread;
 
//applying impact force 
[email protected] += impac
  • I set up groups to delete some parts once they were passed a certain distance and to transfer the color attribute of the planet atmosphere on the selected impacted pieces.

So far, all of it was deterministic. The debris are, however, a simulation because we need information from previous frame to calculate what is coming, which requires a solver sop. 

  • The simulation was setup with an initial velocity.

  • Inside the solver, we used the velocity to move the particles.

[email protected] += [email protected];
  • Then, I had to create the force to drive the attraction of the particles to the planet’s force field and also the force to repel them from it.

Attract

I set the particles to be attracted to the centroid of the force field. Using a cross product, I am able to make them rotate toward that center point.

//Fetch Data 
vector normalizedVelocity = normalize([email protected]);
vector normalizedDifference = normalize(chv ("forceFieldCentroid") - [email protected]); 

//Cross product 
vector cross = normalize(cross(normalizedVelocity, normalizedDifference)); 
//apply rotation 
vector4 myRotation = quaternion(0.5, cross); 
[email protected] = qrotate(myRotation, [email protected]);

Repel

The particles are rotated away from the nearest point on the force field proportionaly to the distance between them and the force field. Similarly to the attract portion, the repel portion uses a cross product to rotate the particle away. To drive the intensity of the rotation base on the distance between the particles and the nearest point on the force field, I am using a fit function like the dissolving meteor.

//fetch data 
int nearPoint = nearpoint (1, [email protected]); 
vector nearPos = point (1, "P", nearPoint); 
vector nearNormal = point (1, "N", nearPoint); 
vector diff = nearPos - [email protected]; 
float distance = length(diff); 

//cross product to get the axis of rotation 
vector cross = normalize(cross([email protected], nearNormal)); 

//strenght of rotation we want to apply 
float angle = fit(distance, 0, 0.5, 1, 0) * chf("rotationIntensity"); 

//apply rotation 
vector4 myQuat = quaternion(angle,cross); [email protected] = qrotate(myQuat, [email protected]);

In the future, I would like to improved the motion of those particles as their spreading motion is happening quite slowly and is a little bit awkward.

Post-Class

The class gave me a good foundations where I explored all the big features of Houdini and I build upon those to continually improve. It allowed me to be fluent enough so I can watch webinars, tutorials and talks with more ease. But I am also aware that I barely scratched the surface of what Houdini can do, and more broadly, the possibilities and potential of having a procedural art pipeline.

The full course is composed of two parts: the classes and a project module. I won’t be doing the project module but I still would like to do some projects and tools of my own. So I am currently brainstorming and researching what kind of tool I would like to develop. It is also a way to stay updated and keep all of what I’ve learned fresh as it’s so easy to forget things when you don’t practice.

Small Tools

I created a tool for generating a golden spiral and another one to visualize the superformula. They are not converted into a digital asset yet as I am not done with the UI, but this will be the next step.


Learning Houdini: Flipper Game

Making Of / 08 October 2019

This post was originally writtenon July 2018

Background, in 2018, I did a Houdini certification at NYP in Singapore.

The assignment brief:

Flipper is a game character that has been animated to move in a circular path, along the ground which is colored in patches of red and blue

Part1 
 Much like in a computer game, as Flipper moves along the ground and touches the RED areas, he will score points in the form of coins or balls that will emit from the contact areas. These coins will bounce a few times and settle on the ground.

Part 2
 As Flipper returns the second time, he will ‘collect’ these coins.  The coins will be ‘sucked’ into him when he comes near them.

Bonus :  Much like a game, display the number of coins collected at the top right of your camera. Use the font SOP to create this.    

The simulation is divided in two parts. The challenge in part 1 was how to detect the red zone and only emit from those points when Flipper passes over them. They are multiple ways to approach the problem, but one of the simplest solution was:

  • Get the intersection between the rubber toy and the ground.

  • Add some thickness and scatter points along the intersection.

  • Transfer the color attributes from the ground to the points. 

  • Delete any points that are not red.

  • The remaining points would then be the emitters.

Transitioning between part 1 and part 2 was another challenge. You want to stop Flipper emitting particles before he starts attracting them and you don’t want it to suck back the particles as soon as they were emitted. I ended up going with a “hard coded” solution instead of having a fully procedural one so there is room for improvement.

  • I ended up deleting the emitter points at frame 71 when Flipper is done doing its first lap.

  • Because the particles network (Popnet) still exist, the already emitted particles stay there.


The second part involve creating a force that would push the particles to Flipper when it is close to them. This part was probably the easiest one to do but keeping good controls over the simulation was a little bit tricky. We first need to create the suction force.

  • To get the suction force, we need to calculate the distance between a particle and Flipper. 

Then, we need to establish the conditions for when the suction is applied.

  • The distance between Flipper and the particles needs to be under a certain number.

  • The frame should be past 71 (when Flipper is done emitting).

Finally, we need to set what happens to the particles when they are sucked back to Flipper. My first reflex was to kill the particles when the distance between Flipper and the particle is below a certain number, but because we want to keep track of the score, we cannot kill them inside the simulation. Instead, I am using a collision detection node. 

  • With the particle collision detect node, I can keep track of the particles that were absorbed by Flipper, but I can also group them. 

  • Outside the simulation, you can then delete the group so they don’t stay visible. 

  • With a Font node, you can then read the collision number to show the score.

I replaced the particles by coins to add context to the simulation. The coins were also falling without rotating because their orientation follows their normals. I used their velocity as their normals instead so they can fall in a more natural way.