Project Titan

In this very special article we’re joined by the team behind Project Titan, a tech demo designed to test and showcase Houdini’s procedural environment workflows in Unreal Engine 5. We go behind the scenes and discover how Houdini was used in harmony with other popular environment art tools.

Intro

Simon: I’m Simon Verstraete and I’m a Technical Artist that focuses on procedural content. Years ago it all started by studying Digital Arts and Entertainment, where I learned the basics for 3D art.

Lea: My name is Lea Kronenberger and I’m a 3D Artist from Germany. I started out as an architectural draftswoman, where I discovered my passion for 3D environments and then switched into 3D art for games about 5 years ago.

For Project Titan we worked with amazing people. Other team members are: Robert Schröer, Frederik Plucinski, Maximilian Lessle, Anna Molamphy, EXE Collective, Thomas Tobin, Carl Drifter, Lino Drieghe, Mike Golden, Chase Hardy

Materials / Shaders

Lea: We used a few master materials for the majority of the environment in combination with tiling textures from the Megascans library. The master materials have shared material functions, such as global dirt to break up the repetitive look. Then we used material instances for different kinds of bricks, metals and so on.

There were also unique materials needed to work with specific Houdini tools, which we will break down in this article. Some of those were straightforward to create, while others required more work to compress and decompress data correctly on both the tool and shader side.

Simon: Usually when Houdini is involved there are 3 common ways to share/send data with materials, these are vertex colours, textures and UV data (which we will talk more about). Based on what you want to do and how much data you will need, one will be preferred above the other one.

Vertex Colour

Simon: The cable tool is a great example of Houdini calculating vertex colours to be used in a Shader. The idea here is that we have a big cable surrounded by smaller cables, these smaller cables have then a gentle sway of the wind.

In Houdini I have my setup where the cables are generated, you could watch the tutorial about it or use the Labs Cable tool.

From the generated cable, we split the cable in two parts. The small cables and the big cables. Each of them will then be coloured, big cable black (value = 0 ) and small cable white (value = 1). This will then be vertex colours once exported.

Small Cables and Big Cables

Now the trick to blend them together is using an attribute transfer. This will be based on the colours of the big cable transferring into the small cable. Next step would also be smoothing this to get a better transition. This is then the final output and the values on the vertex colour can be used to control the wind sway on the smaller cables.

Cable Vertex Colours

Lea: In the shader we used a simple sine function wind animation to make the cables sway. The trick is that the strength of the effect is controlled by the green vertex colour, where a colour closer to 1 means that the wind effect is stronger. The red and blue channels were also used here. Red sets a random value between 0-1, which we use for random colour as well as wind variation per cable. This allows for variation even when we use the tool to generate many bundled cables. The blue channel is used for ambient occlusion. The shader and tool were developed simultaneously and we tested the shader on simple primitives beforehand.

Cables Shader

Textures

Simon: An example of textures used to control shader data is the adboards. The adboards itself are based on what was created in the game “The Ascent”. Check out more here and check out their awesome game.

The overall idea is that a texture or image in the shader gets UV offsets over time and that will create an animation effect. In Houdini the animation is made, this is done by taking a plane and animating it with keyframes. In the GIF below you can see how to set simple key frames on parameters. You could also make a HDA that has animation presets and parameters to speed things up.

Adboard Keyframes

Then with this plane moving up or down we want to save out this movement over time. From the plane the pivot or the centroid was used to store this data. So this is a single point with the attributes of moving or scaling that has happened. In the GIF below you can see the posx, posy and pscale attributes that are saved.

Adboard Attributes

With these attributes we can lay them out to visualize and see our data that we will need in the shader. Here is an example of the solver being used to stack the points overtime. This also represents what our texture will look like when copying a grid on the points.

Adboard Data

To finishing this off the COP (composition network) is used to then render this into a texture.

Adboard Texture

Here is an example of that output. It is a 1x64 pixels and the 64 stands for the amount of frames. So in a shader we zoom in on the first pixel and that is then the UV offset for the first frame. Then you move 1 pixel over time and you will get the animation offsets. Only thing left is also getting the values out of the textures. The colours you see represent the values, so R and G is for the position of the texture and B can be scaling. You can mix things here based on what you need.

Lea: Following up from this, we used 4 elements to make up our adboards. These are stored as a row each in the texture described above, resulting in 4x64 pixels textures. In the shader this texture first needs to be read and decompressed so that we can access the data and add parameter controls to it.

Adboard Material Function

The ‘Read Data’ part in the shader maps the UVS to the first pixel, then progresses through the rest of the data over time. Each channel is broken out via component masks (R,G,B) so their data can be used individually for the animation. Each channel of data (RGB) is passed through a material function that reads their controls and adjusts the effect accordingly. Everything else in the shader is just additional effects to make the screens more believable

Adboard Shader

Crowds / Characters

Simon: The Characters itself are done using Vertex Animation Textures (VAT). This means that the Character has no bones and is animated with textures in a shader by using WPO.

To do this VAT a lot of data is stored as textures but also in UV channels. The image below show the second UV channel of a mesh. The UV is fit into the top part of the UV. This is because this aligns with the textures. In the texture the frames are stored vertically and to get the first frame or loop over frames the second UV is used with that.

Character UV Data and Position Texture

Another cool trick or more experiment with UV here was masking for variations. We wanted to have variation quickly on the characters by each copy.

Character Variation

The way this is built is by storing multiple cloths on the base VAT mesh. Then the UV is sliced in a grid, on each part of the grid a clothing piece is laid there. The reason for this is that we can use this for masking the cloth pieces.

Clothing UV Grid

The masking is controlled by a simple texture of a few pixels. Moving or swapping the texture will result in different masks, so that will give a different clothing type.

Clothing Type Masking

Overall I would say that this was more leaning to a prototype side of things, where it was just good enough for Project Titan. More research on this could maybe lead to something interesting.

For a detail view on the characters you can find a tutorial here.

Windows

Lea: There are also other interesting ways to integrate shaders with Houdini content. One example would be the windows shader, that we developed to add some more art directed user input to the Houdini building tool. This shader is based on Trey McNair’s amazing shader work. We loved the idea of random curtain positions and wanted to have something like it for our project as well. Since all building parts, including windows, are placed as instances with the Houdini building tool, we can access the PerInstanceRandom in the shader and use it i.e. with a Lerp node for interesting variation. This is not restricted to use with Houdini tools though.

Windows Shader

Another thing that we added here specifically to improve art direction is the ability to control window tint and brightness based on their world location, so that you could keep the lower building parts darker while still using only one tool and material instance.

Windows Parameters

Planning

Simon: We sort of had 2 different teams: the art team and the Houdini team, both worked very differently. With the Art team Robert Schröer started immediately, we gave him all the info and concepts we had and started creating a planning board with Miro. Here were all the assets listed and other topics to do. From there in the meeting we discuss what are the first things to tackle.

With the Art team we had weekly meetings, this was also easier since all of the artists were from around Germany which makes it better to plan in meetings. So every week we had a discussion about the scene and everyone would show what they have been up to and plans for the next steps. When it came to feedback to Houdini tools it all came through me. The Houdini team worked a bit differently, the people here were from all over the world. I personally often had one on one meetings with the Houdini artist talking about the tools. A lot of the tools were also created before the Art team came, so tools were in that sense more planned out. Once the scene actually got built, tools were then tweaked accordingly.

Learning Houdini

Simon: For Houdini, start with the basics, get familiar with using nodes and navigation in the program. After that focus on subjects that you want to learn, this can go from worldbuilding to simulations. On the SideFX website you will find a great collection of many tutorials. On the site you can also filter on level or subject. The main thing I would say is follow what you find interesting and research that subject.

Lea: Start small and pick a subject that you are passionate about. It’s so much easier to get into shaders if you have an actual use case on a project. I have good experience with doing so in art challenges, since they have guidelines and a deadline, which can help you stay focused. I would suggest starting with the basic terms to understand what shaders, materials, instances, functions and so on mean. For shaders in Unreal specifically, the Unreal Engine Documentation is a great place to start and go back to (I still check it regularly). As a general great resource, I can recommend Freya Holmér’s YouTube channel, which is about coding but in my opinion also very valuable to understand the basics of shader work.

Outro

Overall Project Titan shows a great combination of procedural and art directed Houdini Tools, with these tools artists were able to build what they had in mind faster and without too much compromise.

If you are interested in Project Titan and the tutorials related to it check them out here.

Thank you for reading, special thanks to all team members and of course thanks to EXP.