In this article, I wanted to describe my work process on one of my scenes and highlight some of the important aspects of its production. Despite the scene being published two years ago, I managed to find time to finish this article only now.
However, most of the workflows are still the same, except, maybe, Nanite+Lumen+RVT. The scene was made on UE4 though.
The original design of the trees and plants was made by David VDB for the first part of the challenge. Link to the design.
I had quite a lot of goals for this challenge, maybe too many actually. First of all, I wanted to show as many skills in one artwork as I could. Secondly, I wanted to go deeper into Unreal Engine because for the last several years I worked only with in-house engines.
Finally, I mostly worked with modeling whole levels with tiles and trims, so I thought that it’d be great to refresh my skills at props and texturing and show both: hard-surface modeling and organic.
That is why I decided to expand the original storytelling to something Subnautica-style, with a crash site, wreckages of old spaceships, crafting and research, and exploring the alien nature.
Regarding the mood, I wanted to achieve the feeling of a beautiful but dangerous, toxic environment. Something that you could say about: “I definitely want to explore it, but I’m not sure that I’ll survive”.
Obviously, it was not possible for me to finish everything during the Challenge so I decided to just finish nature, submit the intermediate result, and then proceed with the focus on the best quality possible for me at that moment.
Here I’m going to talk about the final version. A lot of stuff has been made but I’ll try to be as concise as I can. I’d break all my content down into three main parts: landscape generation, nature, and hard surface man-made objects.
To clarify the amount of content to make, I started to block everything out with basic shapes.
After several iterations, I came up with this:
It is important to have at least the first approach to the composition, determine the background, foreground, focus points, guiding lines, etc. The first pass for lighting must also be done in the early stages although later it might go quite far from the initial setup.
There are not all the props here because I was planning to work with them when the challenge is finished. Otherwise, I always try to understand the amount of content during the blocking stage. The ideal situation is to have all the props, modules, and other content in rough shapes before we start making them.
In this case, we are able to estimate the amount of time that we’re going to spend on them.
From the level design perspective, I just wanted to have the area comfortable to navigate, without places where the player can get stuck, and I would also avoid straight lines in paths. So the roots of the trees are grouped in three clusters, and all the props with collisions are also grouped in compositions.
Landscape generation in Houdini Houdini has amazing tools for terrain creation. Moreover, Houdini Engine, which is now free for UE, can convert the Houdini heightfield to an Unreal landscape with all the layers. I divided everything into two HDAs: terrain generation and placing the trees.
The terrain is based on simple polygonal meshes, and my HDA had 5 inputs: terrain, preserved area (that is almost not affected by noise generators), cliffs, rivers, and lakes. The first one is necessary, the others are optional.
Houdini terrain could be a topic of a separate article so I’ll just show an overview of my main blocks with some illustrations.
This terrain then goes to the trees generation HDA.
The final layers look like this:
Landscape Material in Unreal Engine
In UE4, I’ll be able to set different materials for them and even scatter meshes. I used this for my grass and roots. For the texture blending, the best option is probably the LandscapeLayerBlend node. It even supports a height blend.
To scatter objects over different layers in the same material, there is the node LandscapeGrassOutput. You will also need at least one Landscape Grass Type with grass settings. It’s convenient that there is an option to combine different meshes with different parameters in one Grass Type.
I used three of them: for moss, for glowing spores, and for three types of roots.
Here I decided to place all the glowing trees by hand in order to have better control of the composition.
For the mountains in the background, I used the same HDA but with a different source block geometry.
Some of the tileable textures were created fully in Adobe Designer, and some of them had a base from ZBrush.
Some of the textures from Megascans were used in my graphs as well.
Nature & Trees
Trees were one of the toughest parts. David VDB designed two types of them: “Glorbwood Tree” and “Elderspire Cypress”.
The root systems are quite the same for both types of trees. The only difference was that one was more concave, and the other more convex. So I made something in between. The main form was sculpted in ZBrush and decimated.
In terms of the level design, every tree has 3 “entrances” to make the exploration of the forest not so linear.
There is a great tip about texturing trees. Just bend the shells and align them vertically, and you will be able to texture all bark with tiles. It’s not as complicated as just long.
Obviously, you will need to make an extra UV channel for the lightmap, without overlaps (next-gen Lumen-guys, it’s not for you).
Texel density for the entire project is 682 px/m (2048px/3m), and almost all the textures are 2k/1k, but for the bark, it can be slightly different. It’s not so crucial on organic models.
I just sculpted the “branches”, two of them: a big and a small one. For scattering spores on the surface, I could use just placing in Maya or 3ds max, but I wanted to have full control of the shape and placing of every one of them.
That is why I made it in Houdini. The size, bend of every spore, and vertex color gradients that are used in my material further are controlled by ramp nodes.
Lianas are drawn over the roots with splines, the hang ones are just copied and placed by hand. To set vertex color gradients for them, I used a gradient texture and assigned vertex Color in 3ds Max. Blue channel I used for wind.
The moss on the tree is the same moss as on the terrain. I used the Unreal foliage tool to place it and then exported it as a single mesh. The final tree is assembled via a blueprint.
The pipeline for all the other plants were quite standard: sculpting, low poly, baking cloning leaves/flowers/spores and texturing. There are some variations, of course. To bring some cohesion to the look of the foliage, I used a pretty standard foliage artist technique.
I created a hemisphere and transferred the normal information from it to my moss. This operation can fix the messy look produced by a bunch of crossing polygons. In Maya, there is the tool Transfer Attributes, for 3ds Max there is a script Noors Normal Thief.
The roots are made in the same way as the trees: modeled and mapped on the tile map with straightened UV shells.
All materials for my foliage are based on one master material. It’s quite complicated so I’ll just go through some interesting points.
The overview looks like this:
For every block, I used a static switch parameter. In this case, I’m able to switch off all unnecessary features, and the compiler will optimize the final material. The block Emissive Tint adds a color gradient based on the blue vertex color channel and some color variations with the green channel.
Distance Fade dims the emissive channel of my distant objects. I need this to add some depth to the scene and support my fog VFXs. Fresnel Glow adds a slight glow in the center and a halo around spores. Spores Breath adds this effect of “breathing” on the trees’ spores.
Basically, it’s just cosinetimeabsolute world position (Z). The phase of the cosine also depends on the object’s position. Otherwise, all the trees would “breathe” simultaneously. These were the blocks that affected mostly the trees. XY Glow was created for the small green foliage and glowing sticks.
It adds some dynamic based on a simple noise texture, processed with the Motion_4wayChaos node, and absolute world position (XY).
The Wind block just controls the degree of influence on the standard SimpleGrassWind. It’s just a simple moving wave. To control the direction of the wind, I used a simple formula with sin and cos:
Blending just adds some blending with the surroundings of the object. I used a basic method with DitherTemporalAA plagued into PixelDepth Offset.
I also used SSS but there is nothing special. Just multiply by a parameter.
To show the impact on the soil of the planet during the landing, I decided to create a decal from scratch. I scattered some dots in Photoshop, applied directional blur, and used this image as a base for my ZBrush sculpt. In the end, I baked it and slightly tweaked it in Designer.
The alpha channel is also painted in Photoshop.
Landing Pod and Props
The design of my landing pod is a compilation of different real space crafts, especially SpaceX ones. I’m quite a space nerd, and hours spent in the Kerbal Space Program didn’t let me make just a “space-looking” something. I wanted it to be as functional as possible.
A heat shield to fight air plasma during atmospheric reentry. Reaction control system to orient the craft in space. Landing engines for the final slow down during descent. 6 fuel tanks: 1 with fuel and 1 with oxidizer for each of 3 pairs of landing engines.
All this stuff was unnecessary for games but I liked it. The main visual design idea for the props is that everything is based on triangles. Nothing special in high poly, just quad modeling, and simulation for fabrics. For seams between the panels, I used floating geometry. It’s way handier on such clean shapes.
Sometimes I used ZBrush to add details.
For props and the ship, I used the pipeline that is quite popular today: high/low poly, baking, unique texturing and then I used the second UV channel to add dirt with RGB masks. Everything that I can duplicate/mirror is not unique.
To hide this symmetrical look I just used a unique part in the middle and mesh decals with texts. Everything that can be reused must be reused and just a little bit tuned with some decals. In the picture, I showed this reusing with arrows. For all my pipes, I used a trim sheet texture. Texel density is the same – 682 px/m (2048px/3m).
For all these hard-surface objects, it is worth mentioning that if I had more of them and their sizes were bigger, I would go with another pipeline: tile textures, mapped on mid-res meshes with decals and trim sheets for seams, as well as dirt masks masked on the second UV channel to bring some natural look and visual cohesion.
The hose is a Spline Mesh with plugs as static meshes on the ends. As for animations, I used a pretty standard pipeline with bones and keyframe animation.
In Unreal, I built an Animation Graph to control different stages of animation, satellite dish rotation, and so forth.
For the shipwrecks in the background, the most important thing was the silhouette. In Maya, you can just push the key 7 (use all lights) and if you don’t have any lights in your scene you will see just a black silhouette. Might be handy for quick tests.
For the textures, I used tiles and masks.
The water shader was quite painful for me. I wanted to create water flow along the river and add some swirling near the shore. To achieve this I used 2 UV channels: one for vertical panning and the second for distortion with a flow map texture.
To make the flow map I used Flowmap Painter. This is a really great and absolutely free tool. How does a flow map work: It’s basically a vector map, but unlike a normal map, it contains the vectors of the flowing water in every pixel.
My normal map for the water bends over time with this flow map. This adds some nonuniformity to the water flow.
Lighting and VFX
Lighting passed through multiple iterations. The main problem was that my trees looked solid only if they were emissive. Obviously, it attracted too much attention to them. I dimmed them as much as I could and tried to balance them with my main object – the landing pod.
I also added lamps to guide the viewer. Actually, I have hundreds of light sources here: to add fake GI from the trees, to add rim light, to add flares. At the same time, almost all of them are static, so it didn’t affect the performance. Only the lightmap bake time. I ended up with this pipeline:
- I started by setting up the Skylight and Directional Light.
- Then I lit everything up with static lights. Here, I used static spotlights and sometimes rectangular and point lights to add accents and maintain a proper balance of values. It’s always better to check your lighting in grayscale mode so that color information won’t distract you.
- After light baking, I turned on my dynamic light sources to add flares and make my roughness maps work. In personal projects, I prefer movable spotlights. Otherwise, it is better to use stationary ones. They are cheaper. However, in the Lumen era, it might become history due to everything being dynamic now.
- The final touch was adding some rim lights and accents. Here, I also used movable spotlights. I can also add that I used static spotlights in my tree blueprint.
Another powerful tool to make the environment more readable is haze. I used planes with a cloud texture. A lot of them.
This is an image without lighting where they are more noticeable.
By the way, I use different levels for lighting, effects, post-processing, and cameras.
For lighting, I also turned my lighting level into a lighting scenario. This is a really powerful tool that allows you to try different sets of lights.
PostProcess volume is an incredibly powerful tool that can dramatically improve the artistic look of the artwork. I used two post-process volumes: one for the main setup and the second for a LUT.
It works like filters in Instagram for me. In the main post-process volume, I added bloom, lens flares, chromatic aberrations, film grain, and a dirt mask. I also tweaked my exposure settings a little bit. For film grain, I used a post-process material.
To sum up, this project turned out to be a junction between art aspects and technical issues. Even though it took 6 months to complete, and I had to divide it into two parts for the Challenge and my personal one for my portfolio, it was one of the best time investments.
I went way deeper into Unreal technical art than I had been before, brushed up my modeling and texturing skills, and achieved most of the goals that I had. Looking back, I can say that this particular scene has also affected my art career the most in the last two years.
So, I can only encourage everyone to devote some time to personal projects. It’s fun, it’s challenging, and it’s rewarding.