This tutorial was written by the amazing Anastasia Opara and appeared in issue 105 of 3D Artist
To appreciate what ‘realism’ means in the context of procedural art creation, let’s first discuss certain aspects of our perception. Humans are great pattern-recognition machines. We deal with a huge amount of data on daily basis and at a certain point our brain starts to classify those into ‘stereotypes’ or ‘patterns’. We’ve seen it once, we do not have to see it again to appreciate its meaning. However, our brain is so good at ‘archiving’ that extracting the original information can be troublesome. In my opinion, that is the foundation of one of the most intriguing parts of proceduralism. With proceduralism, you have a blank slate; a machine with no knowledge of ‘art’, with no sense of ‘artistic’. Therefore, the question becomes: “Can you decipher and break down into understandable chunks what ‘appealing’, ‘good-looking’, ‘real’ ultimately is?” Art is an abstraction, just like programming, and we are going to make these two dimensions work together to produce the result you see here. Think of it as a painting process – we will start with wide, general brush strokes and go deeper and deeper to the finest details. Instead of brushes, our tools will be VEX (a C++ based Houdini language) and native Houdini nodes.
The generated houses are done fully inside of Houdini, all the way from the initial silhouette to the final shading. This tutorial will provide you with a general overview of some of the procedural techniques I’m using for the Procedural Lake Houses project. For the full step-by-step tutorial, feel free to visit my website or my Gumroad page.
Step 01 – Make a body silhouette
The idea behind a procedural body silhouette is quite simple. First of all, we need to ask ourselves, ‘How do we build something when we do it manually?’, and the answer is that we always build something in relation to what we already have. Therefore, our starting point will be a box, which we will convert into a grid-constrained Point Cloud with a Scatter node and VEX (you can also use Points From Volume), and that Point Cloud will be a driver for the placement of all the future boxes. And those future boxes will get absolutely the same treatment, therefore driving the next loop of placement.
Step 02 – Roof base
Once we have the body set up, we can continue building our relations, and the next step will be creating the roofs. We already have a great foundation, which is the top surface polygons of our body, which we can isolate with a Blast node by asking it to delete the faces, whose normal doesn’t face upwards. However, the remaining polygons represent the grid, and we would like to have one square polygon per roof. By merging the grid tiles together with their neighbours starting from a random one, we will achieve a great variety of patterns.
Step 03 – Roof heights
The next step would be to calculate the elevation of each roof. We will start with an abstract elevation X, which we will assign to any roof, therefore making it our starting point. By looking at the roof’s neighbours and their relative position, we can label each neighbour with an elevation of X+1 or X-1. We can repeat this loop until every roof gets a certain value relative to our starting X, which, upon completion, will be converted into a numeric attribute. That attribute will drive the strength of the extrusion.
Step 04 – Body modules placement
Now it’s time to populate our procedural building base with pre-made modules. The idea is quite similar for every asset, therefore I will make an example of Stairs module. By isolating the polygons that have a Y position above the first floor of our grid we can find the possible locations. However, some of them can be situated in places that would make our stairs intersect with the body. Therefore, we have to cast rays from that position to check whether the space for our possible placement is not occupied. This can be achieved with VEX or Ray SOP.
Step 05 – Place the roof modules
Roof modules are a bit trickier because they require a custom scale attribute as, unlike the grid-constrained body, each of our roofs has its own dimensions and scale. By resampling the edges of our roof with our custom rates with VEX, we can extract the positions for the roof rims modules. As for the orientation, we can calculate a vector based on the direction of the roof base that would serve as a guide.
Step 06 – Place the doors and windows
The last step for the procedural module placement is to place doors and windows. We will need to create a Random Seed that will control which faces of our body will become doors or windows. We will also need to take into account that we do not want doors where there’s no access to a floor, or windows that would look onto walls or roofs. That can be achieved with, again, ray casting and by labelling each face with an attribute of its type, such as ‘door’, ‘window’ or ‘wall’. By introducing a probability control, we can manipulate how many windows we want in the final result.
Step 07 – Patterns Seed pool
Now it is time to move on to creating procedural patterns for our walls. First of all, we don’t want every wall to have a unique pattern because that would become too noisy. Therefore, we will create a pool of possible Seeds for every wall to choose from. That Seed will drive the pattern creation. This way we can control how many patterns we want per building and what unique proportion between wooden beams and wooden scales they would have.
Step 08 – Generate wood patterns
To achieve a believable wooden beam structure, we will start with a Divide node to give us equal splits of an average beam size we would like to have. However, in real life those will never be entirely identical, especially if the house is old. For that reason, we will randomly offset the edges to give the divisions a more ‘organic’ look. We will do so in both depth and width dimensions.
Step 09 – Create the scale pattern
The foundation for our scales will be our wall divided into a square grid, where every tile is cut to form a shape of a scale. You can think of it as a factory assembly line, where every tile from the wall is placed onto the origin to ensure that the ‘blades’ of our cut operation (Clip SOP) always have the correct relative location.
Step 10 – Roof and body deformation
One of the vital steps to giving our building character is making it crooked. We will do this in layers, starting with the roof. It’s crucial not to create holes in our geometry during this stage, which is why we will mark key points and exclude them from the deformation. We will use a Lattice node, where we will translate, scale and rotate parts of our Lattice box, which is responsible for the deformation. The same step will be repeated for the whole body and top floors, giving a more complex-looking result as opposed to the one with only a single deformation.
Step 11 – Procedural pier
Another fully procedural asset is the pier. By isolating the building’s footprint and expanding it, we can easily derive the necessary area for the pier. As for the wooden beams, the technique is similar to the wood pattern generation. In this case, however, we would have long streaks of geometry, which wouldn’t look very realistic. Therefore, to break them, we will run a loop where we find the biggest wooden beam and, if it’s too large, we’ll divide it. Keep going until all of the wooden beams satisfy to our length condition.
Step 12 – Shade and render in Mantra
Up until this point we’ve accumulated a lot of attributes, which we will use to drive our procedural materials and randomise the colouring of our wooden beams and their tonal offset. We will assume that the house wasn’t built from the same tree – in fact, it could have been built from multiple species. All of these extra touches and attention to detail will create a hand-crafted feeling to the final generated model. A lot of dependencies for distribution of things like moss are controlled by the Y position, which will help to regulate the multiple layers of noises that serve as a mask.
Step 13 – Composite the promo image
After the system is finished, we can ask it to generate as many houses as we like. I baked around a hundred and then selected the ones that would work the best with the composition sketch I made for the promo shot. The background for the final render is a photo from my personal archive from a trip to the south of France. A biting frost, and at the same time a warm and gentle early morning look imprinted itself in my mind and I tried to re-create the feeling in the final compositing. The water surface and reflection is a separate render pass, which was composited into the main image later. Smaller details like frost on the roofs, nets and tiny silhouettes of people in the boats are painted in Photoshop. Once the main render passes were assembled together, colour editing and the mood were achieved in Photoshop as well.