Create procedural GROWTH systems
Simon Holmedal details his process for the creation of the Us By Night event opening titles
Simon Holmedal describes his process for producing the opening titles for the Us By Night event
Back in November 2017 I directed and produced my first title sequence for a design event in Antwerp called Us By Night. The film is one continuous shot of a growing superstructure that acts as a backdrop for the title cards.
I have always been fascinated with procedural workflows so the goal was to take this to the next level. I wanted to build something with dependencies that followed a ruleset, so that it could grow itself without me having to direct it. I had over 65 title cards that needed to be shown throughout the piece. My intent was to create a scrolling background that continues to build from the bottom up to form a bigger structure that would represent a trophy of sorts for the event itself. This shape would represent the creation and evolution of ideas and the visual style would hopefully communicate personal growth. This ‘trophy’ would be revealed at the very end of the sequence and would also act as a sign-off for the event.
I have done many growthrelated systems in the past that aimed to achieve similar goals – generating highly detailed geometry on the fly in a simulated structure over an extended period of time without any cuts to the edit. One of the key hurdles that needed to be overcome was (unsurprisingly) the inevitable memory limit, not to mention the struggle of trying to maintain surface detail up close while still presenting an interesting-looking surface from a distance.
My strategy was to create a number of pre-made elements that would have their own UVS and materials already in place, then to build up the larger surface out of these as instanced geometry. This way I could maintain a high level of detail at any scale since I wouldn’t have to worry too much about the memory limit.
01 Building the elements
Since the launch of Houdini 16 we have been blessed with an insanely capable Boolean tool, so I decided to put this to the test. I started with a cube as an input geometry and quickly generated some UV coordinates on this, then scattered some smaller copies of the same cube onto the surface of itself. I used these smaller copies to cut away chunks from the original cube, and I did this multiple times with a feedback loop.
So now we have a less regular shape. The next step was to use this shape in another feedback loop that copies a smaller version of this shape onto itself and unions everything together into a larger shape, over and over again. The end result is a somewhat complex surface that has more of an irregular form, but still has the same visual style as the original chunk we created in the first step.
The next step is to go through each primitive on this shape and shuffle the UV coordinates of each polygon to capture a different part of the UV tile. This is so that when we apply textures to this object later we won’t get any repetitions on how we sample the texture. I used a VOP for this.
02 the main Structure
I decided that I wanted the system to grow in a very organic fashion, to create a hypnotic vibe where it would just seamlessly expand and evolve, similar to how plants grow in nature. My intent was to visually contrast this behaviour with a hard metallic/ mineral look to create familiarity but with a dark twist, mainly because I’m a sucker for darker, more cinematic designs.
First I needed to form a base shape. I started with a disc and scattered a few hundred points on it. I then advected these points with a vector volume and traced their paths to form lines moving up and away from the original position on the disc. I decided I needed to break up the shape a bit so I scattered some primitives on random locations of these paths and some additional points on the primitives. Then I scattered points on the original curves and merged the two point clouds together.
Next I stepped through the points with a VOP network using a point cloud lookup, effectively finding the positions of the ten nearest points from any given point and connecting them with lines. I later resampled these lines to
create additional curve points. I displaced these points from the original curve to create more of a spring or coil shape. All of this was done to break up the original shape formed by the advected points while more or less staying within the same silhouette. Once I had this structure in place I remeshed it by creating a VDB volume from the points and converting it back to polygons. Now we finally have a base shape that we can work with.
03 create communication network
The next step was to displace the shape with a Mountain SOP and triangulate the surface by Polyreducing it. This does two things for us: first, we are getting fewer points, making it less intense to work with and will require less memory, but the polygons are also a more varied size and aspect ratio.
Now we need to build a communication network. This will be the underlying network that will inform how each piece of the system will transform and scale in the end. I started by defining a few source polygons on my shape to act as the seed for our network. From these points I then traced a path through the entire shape, connecting and branching each polygon until the entire object was captured. This was done in a vex-based subnetwork that I later compiled with a compile block. The result of this is that we now have a network that describes the path for any given part back to the source of the structure. It also allows us to find the direction along this path by subtracting the first and second point of each line segment, effectively creating a vector pointing along this path.
04 Dart-throwing Approach
We are now almost ready to grow the entire system. But first we need to scatter a point cloud on our original shape. This is the actual placement of the elements making up the surface. For this I used a dart-thrower technique.
A dart-throwing approach is basically a way to produce a natural-looking distribution of points over a surface. The way
a dart-thrower works is that you start with a surface and you ‘throw’ a bunch of points on it, and each point gets a size (or radius) assigned to it. Then we check if any of these points were intersecting with nearby points. This can easily be achieved with point cloud lookup in a wrangle or a VOP. My preferred method is VOPS.
We remove intersecting points. Then we ‘throw’ more points onto the surface, this time slightly smaller points but more of them, then we check for intersecting points and remove them.
A few iterations later and we now have the surface filled with points, and I also did this to the volume of the shape. I decided I wanted to add a unique matrix rotation to each point as well so that it would look even more varied, to hide the fact that I only had a handful of instanced minerals to make up the entire system in addition to the size difference. I also randomly split the point cloud into four different groups that would get different objects assigned to them. Each object had its own shader attributes too.
I then created a small system to handle the weighting of the transformation by walking through the network and normalising the amount of steps needed to walk from the first to the very last position on the communication network. By normalising the range I got it down to a range between 0-1 so that I could easily animate later. The animation is controlled through the network, giving it the impression that the entire shape grew from just a small seed.
05 Final touches
All that is left to do now is to do some serious matrix math to figure out the orientation, transformation and scale of every point of the point cloud.
We need to find the nearest segment in the communication network to any given point. Once we have this we just need to add up all the points in the network down to the seed point and apply the matrices of all the points, not forgetting to mask this with the weight attribute or there will be no animation at all. The last step is to instance the geometry onto the points and we are more or less done with the fold structure.
This step-by-step focuses on just one part of this project, but it was the hero part. I essentially created a joint system from scratch, rather than taking a more traditional rigging approach.
This is mainly intended as a window into how I problem-solved and came up with these solutions when creating this piece. The one advice I give you is this: stay curious and when faced with a complicated task, regardless if it’s Houdini related or anything else in life, break it down into bite-size tasks and solve them one by one. Before you know it, you will have solved the entire problem.
The rest of the film was built up using various modelling techniques such as Booleans and VDB volumes with volume advection. Then at the very end some kit-bashing of baked-down systems and versions of this fold structure to create more complexity at a different scale. •
evolution The theme for this project was the concept of evolving ideas and personal growth, depicted by the sequence’s ever-growing infrastructure
Base mesh – advected points
Base mesh – triangulated
This project was rendered in Octane, and all the post was done in Fusion compositing in Fusion