Dávid Kerekes talked about some of the technical advantages Houdini gave to him while working on the virtual tracks for the mobile game Offroad Heat.
My name is Dávid Kerekes (25), a self-taught Technical Artist from Hungary. I got into 3D when I was 17 and couldn’t be stopped since then. I used to be more of an environment artist with a keen interest in VFX until Houdini came around and slowly transformed my worldview. It’s all started at version 15 and now it feels like I’m more into Technical Art than anything else. Right now I’m working at Luminet, a humble Hungarian studio with 4 people on the core team and some roles outsourced. Not so long ago we used to make our own games but we decided to make the switch and got more focused on contract works for other game companies. Right now we are dealing with various projects many of which happen to be VR-Mobile related and makes use of procedural techniques for quite some extent.
The project I’m about to show you was fairly critical in our journey as a team. We got a request to create off-road racing environments for an upcoming mobile title. The tracks and elevations were already set in stone and our job was to make it look cool somehow and running smoothly. So this basically meant, we had to deal with the terrains, textures, foliage, assets, lighting, shaders, collisions and while being careful to leave the tracks as intended by the developer.
The deadline was 6 weeks ahead and we had to come up with 3 biome types for 19 levels on a set quality bar while also making sure it could run at an optimal performance.
And this is where Houdini came into the picture.
Around 80% of the work was done procedurally.
For starters, we got premade Unity terrains from our contractor with some minor sculpted details and road directions. After exporting this data into a simple mesh we were able to convert it into a Houdini Heightfield. This height field data was pulled through one of our 3 biome specific erosion networks. Each biome network had unified controls for elevation, erosion, and sub-biomes like multiple types of grass or soil.
This way we had a generalized terrain system and we could convert any level to any biome in minutes. Also, one of the biggest advantages was that we could iterate freely on our biome looks without breaking the whole system. For example, in the splat map phase, we had to go back several times and add some necessary data to the height fields.
With the road mesh, we had a pretty straightforward job. It’s generated from a single hand-drawn curve by a sweep node with the easiest trick in the book, arc-length UVs.
It also had some ramp and slider controls for width and segment count that were collected on a single node for usability’s sake. The road mesh was then projected down against the raw input terrain giving it the intended elevations and passed further for the biome, UV, collision and export phases.
Extracting the road’s edges gave us the opportunity to automatically place the barriers. It’s a simple clone system with some precalculated random curve frame and rotation values relying on VEX and VOPs. The result was also UVd and prepared for export.
Paint controls helped a lot to break up the procedural and random feel. Later down the pipeline we also had to optimize and slice said meshes into chunks for culling.
Few lines above I mentioned that our biome networks had some connections to our splat maps. By using simple height filed masks all the crucial splat data could be extracted. Where is the road, how steep the terrain is, where the rocks are? By fetching them all into a COP network it was easy to mix up some interesting details. For example, we had to blend the road mesh texture with the terrain. By using the COPs and the given data the road edges could be expanded and blurred in a way that is perfect for covering up the road-terrain connections. And it’s also completely procedural so any changeup in the system would still propagate down to this and we would get our result immediately. Every other channel was used as a mask for different terrain textures.
As far as procedural asset placement goes we skipped it. Solely because the tracks were relatively small and we wanted at least this much artistic control over them. Also, it gave us much more confidence to build a more refined pipeline around these hand placed objects. So we simply placed everything in Unity than we export the result to Houdini for later use in the lightmapping phase. This way the engine could do all the batching tricks that it has to in order to keep our framerates nice and steady.
UVs, Light Baking, and Shadow Maps
When it comes to light baking each biome differed based on artistic preferences. Maybe, the most interesting one is the forest biome. Right after importing back the hand placed dressing the foliage and everything else got separated and converted to fog volumes with different resolutions and sharpness. Using this method we got soft AO-like shadows on our road and terrain from game res tree cards and low poly assets.
At first, I thought “ok we have to bake lightmaps for everything”. As it turned out it wasn’t necessary. Lightmapping the terrain, the road, and the barriers were more than enough to achieve what we were looking for. Given the soft shadows, there wasn’t so much detail to deal with and we could go lower for our lightmap bakes without any noticeable visual errors during gameplay. For the lightmap UVs we used a simple UV unwrap node with a larger padding to decrease light leaks on small polygon faces. The height field conversion helped us by generating its own UVs for the terrain that we later copied to the road mesh for making it simple. Of course, this meant we wouldn’t be able to handle overlapping road pieces during the baking process but we didn’t have to. The result was a singular Lightmap Texture for the road and terrain, and a different one for the barriers.
When it comes to collisions we had our fair share of back and forth until we came up with something usable. Minimizing the artifacts and errors is the key here. First, we took all the objects that the cars could collide with and converted them into a blob mesh. The road edges were perfect starting points. I just had to carve a slim strip of geometry from the sides and push it back enough to leave space for every potential collision point. Then it ran a quick Ray SOP to figure out the initial positions and extruded itself vertically to run a second Ray pushing the precision even further. It Wasn’t always perfect of course. But it reduced the manual work greatly.
Advantages of Houdini
What’s great about Houdini is that it allows for an artist like me to achieve things that I would never even dream of. Writing and designing my own tools and systems really is the next level for me and gives me the chance to create specialized mechanisms. In my workflows, I rely heavily on VEX and VOPs because it’s fast and can be easily built upon. With the help of some math, it could really open up the possibilities. Houdini saves you time and that way you have more time to iterate.