We’ve long admired the stylized assets of Jonathan van Immerzeel. When we learned that he used SpeedTree on the game Lake, we had to take the opportunity to learn more about his process.
Lake is a narrative adventure game that offers a slice-of-life experience as you take on the role of a postal worker in a sleepy lakeside town. It is set in the fictional Providence Oaks in Oregon during the 1980s. Developed by Gamious and published by Whitethorn Games, it’s now available on PC, Xbox, and Playstation.
Around the age of 12, I started dabbling with making levels and mods for the original Unreal Tournament, which kickstarted an interest in game development. After high school, I studied computer science, programming, and game art/technology, all with the intent to pursue the interest as a career. While earning my bachelor’s degree in 2015, we were granted two specialization terms, which meant picking a subject to improve in and detailing the learning process. The production of vegetation assets was mostly shrouded in mystery for me, so I was quick to pick it as my subject.
When I was really getting my feet wet with 3D modeling, games like Rime and The Legend of Zelda: Breath of the Wild™ always managed to captivate my interest. Their abstracted art styles and use of color inspired a sense of adventure and exploration which really resonated with me. Non-photorealistic game art still sits at the core of what I strive for.
More recently, Ubisoft’s open world games have set the bar for me in terms of scale and worldbuilding workflows. I can only imagine the amount of research and development that must go into vegetation alone.
Over time, I started learning more about the natural world through reference materials, which drove me to see those places in person. This provided me ample opportunities to capture source materials and generally soak up inspiration. In a sense, observing and simplifying the intricacies of nature and translating them to a video game context sits at the heart of my job!
When I was approached to help flesh out Lake’s proof of concept, the prospect of building a world set in a conifer-riddled environment really sparked my interest. I was given pretty much free reign on the matter, and that’s a degree of freedom and trust I did not take for granted. The Pacific Northwest is a treasure trove of diverse vegetation, so I was excited to start working on a collection of assets in a professional context. It was immediately obvious I would be using SpeedTree to realize this.
In hindsight, the days spent working on vegetation for Lake were probably the fewest, yet most enjoyable days. There’s just something special about getting into a creative flow and watching something slowly grow into its own character. I have an inexplicable admiration for vegetation; it’s a testament to the determination and perseverance of natural life. I could only hope to do it justice.
Vegetation is plentiful in Oregon, where Lake is set. The state itself can be divided into many different ecoregions, though it largely boils down to temperate forests, grasslands, and high deserts. Forests provide a more closely knit, intimate setting, which lent itself well to the type of game Lake is, so it served as a primary reference point.
After frequenting some federal forestry websites, I came across this rather vintage forestry guide. It proved to be extremely useful for figuring out which trees are commonly occurring. Every species is covered in detail, including scale measurements, which is particularly useful for game assets.
This made it very straightforward to find the actual names of trees I was seeing in photographs and build out an asset list. In turn, I could look for specific reference photos.
Because the variety of species was already too plentiful, I took some creative liberties by omitting any trees that may have looked too much alike when in Lake’s art style. Evidently the Douglas fir was the dominant species (it covers about half of the state!), which is also reflected in the game world. I was eager to create more variety, like a forest of Oregon’s famous giant Sequoia trees, but the world wasn’t very big and there was the looming danger of turning it into an arboretum.
The actual production workflow is likely similar to what’s considered standard: The smallest element is created as a texture first, usually a leaf, followed by a branch texture which, in turn, is used to create branch geometry. Finally, the construction of the tree can begin in the modeler.
I tend to use primary colors for branches and leaves so that I can adjust the colors of the final texture atlas in Substance Designer. This way I can quickly tweak them and observe the result in the game world.
For branches, I almost exclusively created them with frond generators, since these can be affected by forces and allow for non-uniform sizes. In contrast, leaf generators offer superior control over normals, which is essential for correct lighting. This is a little more difficult to achieve with fronds alone, but ultimately doable.
The density of the leaves was a particular aspect requiring a lot of iteration since it influences the perceived volume, visual noise, and appearance of shadows.
I’ve only recently had the opportunity to try out SpeedTree 8, which basically makes step five (cutting out cluster geometry from the atlas) obsolete since branch geometry can now be created right in the modeler. With that and leaves being affected by forces, those are at least two definite reasons to upgrade from 7 for whatever project comes next.
Traditionally, a tree model uses separate materials for its trunk and branches/leaves. This has the benefit of alpha testing not being required for the trunk geometry, though it technically means a tree has to be rendered in two separate steps. Welding for branches was always disabled since this added an additional material.
When SpeedTree assets are imported into Unity, a post-processing script runs that removes all automatically generated materials and textures. It also bakes a mask into the second UV channel, which is used in Lake’s tree shader to differentiate between branches and the trunk. This made it possible to use a single material for trees, drastically improving CPU performance.
Trees typically consist of anywhere between 800–3500 triangles and always have at least two LODs. This was a pretty healthy triangle budget considering that there’s a total of 170k individual trees.
One of the most valuable things I have learned regarding the production of vegetation assets is the concept of maturity: Trees in a forest are never all the same age, nor do they have access to the exact same resources (water, nutrients, and sunlight). As such, for any given species, a variant representing each of its life stages should be created. This produces a natural-looking variation in height and foliage density. As long as vegetation is randomly rotated and scaled, repetition is very hard to notice.
Perhaps one of the most difficult aspects of creating branch clusters is striking a fine balance between how large it is in the texture compared to its physical size on the mesh. This dictates both triangle count and perceived density. I can’t pinpoint an exact science to this, but iteration is key. Given SpeedTree’s non-destructive workflow, experimenting with scale, foliage density, and branch/leaf distribution is fortunately an easy, iterative process that simply takes patience to complete.
There’s definitely an ambition taking shape to work on an environment pack inspired by the Pacific Northwest. I’m eager to explore a more elaborate approach by actually traveling there, in order to capture reference materials. Next to identifying species to build out an asset list.
I don’t think I could shape my job into anything cooler than that!