Ekaterina Surikova talked about the working process behind the Houdini Wall Breaker project and shared some useful tutorials for aspiring Houdini Artists.
Hello everyone! My name is Ekaterina Surikova, I am a Texture and Material Artist at Saber Interactive. Although my education had nothing to do with computer graphics or game art (I have a degree in journalism and design of printed media), I fell in love with 3D the moment I modeled my first object in 3ds Max. By the end of my university education, I already had a small portfolio and could find my first job at a small game studio. While working there I continued to develop my skills as a 3D Artist and after a year and a half got my current job at Saber.
My journey in procedural art creation started with Substance Designer. I really loved the non-destructive workflow, the opportunity to change any parameter at any time. So, when I started feeling comfortable working in Substance Designer, I decided that it was time to try something new, and began learning Houdini.
The first Houdini tutorials I watched were made by Rohan Dalvi. I can definitely recommend his videos on Vimeo and YouTube. He has also made a free course for SideFX. As for scripting in VEX, Tokeru was a real lifesaver. There are many other useful free resources like Junichiro Horikava’s YouTube channel and Simor Verstraete’s ArtStation blog.
Wall Breaker HDA
I got the idea for my latest project – Houdini Wall Breaker – when I saw wall objects made by modelers for the upcoming Saber game. I imagined how much time it took to cut the wall according to the texture pattern and place all the bricks at the edge of the break by hand. Then I decided that it would be really nice to have an asset that can make the process automatic. Surprisingly, it took me only two days to find out the solution and create the asset.
First of all, I needed a way to turn a texture into a bricks geometry. Fortunately, Houdini has an instrument that does exactly that: Trace node. It takes a black and white mask (made in Substance Designer in my case) and outputs actual geometry. All I had to do after that was extruding the bricks.
The next step was also quite simple. I just assembled the bricks. It gave me a point cloud, where each point represented the center of each brick. I grouped the points inside of the bounding object representing the shape of the hole and split them from the rest of the bricks. After unpacking points, I got the actual geometry of the bricks back.
Creating the cutter object for boolean required just a little bit of inflation (so that bricks started to intersect) and converting into VDB and back into geometry. This way I got rid of any intersections inside cutter geometry. Then I simply subtracted the cutter from the wall with Boolean node.
I also used Cutter Object to define edge bricks. I just used the Peak node to inflate the geometry once again, then used it as a bounding object for grouping some points of edge bricks. This group was expanded to connected geometry. Finally, everything but the edge group was deleted by the Blast node.
The process for isolating bricks perpendicular to “edge” bricks was pretty much the same. The tricky part was placing pivot points for their rotation. Each brick also had to be rotated clockwise or counterclockwise depending on whether it was located to the left or to the right of its neighbor “edge” brick. To find the right direction I used For-each connected piece loop, which allowed me to isolate every single brick. I started by extracting its centroid (point in the center of the bounding box), then transferred on it normal from the cut wall. Z-direction of that normal was then used to define the location of the pivot point and the rotation direction itself. The same normal direction information was used for moving half of the corner bricks behind their neighbors to create a zip pattern.
The last thing I had to do was adding some details to the bricks. The method was rather simple: I firstly beveled them with a bit of bevel width variation, you can see this method in this video by Simon Verstraete.
Secondly, I added a bit of edge damage. The way I did it is very common and requires only several nodes. It starts with Remeshing an object to get more polygons. Then the remeshed version is a bit smoothed and distorted with Mountain SOP (Center Noise parameter turned off). The resulting geometry gets booleaned with the original in Intersect mode. This gives nice damaged corners and edges and allows to output separate groups for damaged and undamaged surfaces for further material assignment. I finished the detailing process by using Labs Dissolve Flat Edges SOP and PolyReducing. Finally, I unwrapped the bricks using the Labs Auto UV node.
At that point, I thought that my job was done. However, after some tests, I understood that having every brick uniquely unwrapped led to the huge size of textures needed. So I had to find a way to use only several uniquely unwrapped bricks and copy them in the right places. For uniform bricks, it was not a very hard task: I just deleted all the bricks but the first five ones (and later exposed the amount for the end-user), detailed and unwrapped them, and moved them to the center of the world. Then I extracted centroids of all the original bricks and copied my detailed versions on these points. Copy node's “Piece Attribute” parameter allowed me to use random brick from my five variants on each point. I also randomly rotated every brick 180 degrees on each axis to achieve even more variations.
Working with non-uniform bricks was a bit harder. My best guess was to use bounding box information to match detailed bricks with their original versions. For that, I used two intersecting For-Each loops (by connectivity). The first one allowed me to isolate every single original brick. In the second loop, I compared this isolated brick with every detailed brick from my five variants. Then I deleted all the detailed bricks that did not match the original’s dimensions. The rest of the process was the same as for the uniform bricks.
And that’s pretty much it. All I had to do to finish the asset was to expose parameters in the HDA interface to allow the end-user to change the look of the output wall. Finally, I tested HDA using different input shapes and randomly changing the parameters to make sure it worked stable.
The hardest part of learning Houdini is to start. The number of possible workflows can be overwhelming at first. And the best advice I can give to beginners is to set a goal and start working on a particular project. It can be an HDA, or an effect, or anything. Focusing on solving particular problems helps not to get lost in a world of possibilities that Houdini provides. It took me half a year to finish my first asset, but I learned a ton of useful information during this period.
The second piece of advice is to dive into Labs Tools. They are free, and they are usually simple HDAs. So after allowing editing of content it is possible to enter a particular node and look at what’s inside. There are many tips and tricks one can learn from simply examining how things are made by the Labs Team.
I would like to thank 80 Level for the opportunity to share my working process. I hope this article will be helpful for those who learn Houdini.
You may find these articles interesting