Tony Vo walked us through the process of creating an abandoned tram for the Last Yard project, showed the work with vegetation, and demonstrated how the fabrics were made with Marvelous Designer.
Introduction
Hello, my name is Tony Vo, and I’m an environment artist from the United States. Art and video games have always been a big part of my life, and I always dreamed of working in a career related to them. Though I initially became an engineer due to the stability it provided, I soon realized I had no passion for it and found myself stagnating.
During this time, I discovered 3D art and began learning to create props through Blender using various online courses and tutorials during my spare time. I've always been amazed by game environments and how they are able to immerse you within their world through intricate details and the mood they present to the player. After thorough research, I discovered Think Tank Training Centre and took the plunge to enroll in its online program focusing on game environments.
Through my time at Think Tank Training Centre, I was able to devote the majority of my time to learning and developing my skills, where I learned about industry standard workflows and became familiar with the various tools and techniques used to create game environments. As a recent graduate, my only projects so far have been the ones I’ve developed at Think Tank, and I’m looking forward to joining the industry where I can contribute my skills and continue to grow.
Last Yard
For my final project at Think Tank, I had the pleasure of working with Kacper Niepokólczycki, who helped to keep me on track and provided invaluable feedback. I started the project by going through concepts on ArtStation with the goal of finding a concept with a somewhat complex environment that would allow me to put to use various skills and workflows.
I eventually found a concept by Huihui Chen that caught my eye due to its vibrant colors and mood. It depicted an abandoned tram station turned into someone’s personal gardening yard. I was fascinated by how detailed the concept was and the emotions it evoked through its composition and lighting. Additionally, the concept had a wide variety of assets that I could create using different workflows. Once the concept was set, I began gathering references, creating an asset list, and developing a schedule.
I organized references using pureRef. I mainly stuck to using real-world references, which were mostly pulled from Unsplash, Flickr, and Google Images. Since it can be difficult to get high-quality pictures from Google Images, I would adjust the advanced settings to filter for only images larger than 40 megapixels.
I also used Google Lens to identify some of the props I was unfamiliar with or to find references that better matched a prop in the concept. When selecting which references to use, I look to see if there are any details in the reference that would be useful, such as its texture, any important details, or if it provides a new angle of the prop. It was also important to me that the references had a sufficiently high resolution, which helped a lot later when creating materials.
From the text within the concept, I was able to ascertain that the concept itself used Dobashi Station, a tram station located in Japan, as its base. I located the station using Google Earth, which provided me with several invaluable references, helped me to understand the layout of the station, and provided a good view of the background buildings.
I start off by matching the camera to the concept within Maya. I used fSpy to create the initial camera, which provides a solid starting point, and imported it into Maya along with the concept. I referenced this tutorial to create a camera using fSpy:
Once the camera is set up, I begin blocking out the larger elements in the concept, such as the tram, walls, and buildings with basic shapes, and moving them into place to match the concept. Throughout the blockout phase, I’m constantly readjusting the camera as each of the assets is blocked out.
During this time, I also import a mannequin and place it throughout the scene to make sure the scale of the assets is correct. Once I have everything blocked out and am happy with the camera perspective, I will import the camera and the entire blockout as a single mesh into Unreal Engine to make sure there are no issues in-engine.
The blockout is used as a guideline for where to place the props once they are created. I also create the initial lighting using a directional light and angle it to match the concept. For the tree blockout, I reused a tree created from my last project as a placeholder to help visualize the overall composition of the scene.
Assets
My assets were separated into 4 main categories: props, modular assets, cloths, and foliage.
Props
Since most of the props were simple in shape, my mentor suggested using a midpoly workflow to create them, which he stated was now a common approach in many games today. This workflow greatly speeds up the modeling phase as you don’t need to model both a high- and low-poly model, allowing you to skip baking and retopology, but comes at the cost of an increased polycount. It also helped later in the project when I needed to make some quick fixes or alterations to a prop which simply involved an adjustment to the midpoly model and its UV.
The workflow mainly involved modeling out the prop in Maya, then adding a bevel to the hard edges and applying face-weighted normals. By default, Maya will apply face-weighted normals when softening edges, but it’s not perfect and sometimes results in some noticeable shading issues on faces. In these cases, I used a script to correct the vertex normals, which would fix the shading issues. I recommend the tutorials below, they helped me understand face-weighted normals and how to apply them in Blender and Maya. The script to correct vertex normals in Maya is found in the second video.
While working on the mid-poly models, I tried to keep the polycount as optimized as possible. For models such as the drum barrels, where you would expect some dents or bending, I used the soft select to slightly move vertices to add the appearance of dents and break up the straightness of the prop to create a more realistic look.
Modular Assets
For this project, I created modular assets for the tram station walls and background buildings. The buildings referenced were ones I found around Dobashi Station, which I pulled from Google Earth. These buildings worked well with modularity since each story of the buildings was essentially identical.
The walls were created using 4 x 3 m modular pieces, while the roofs and balconies used a 4 x 1 m mesh. Using 4-meter pieces allowed me to easily UV each of them while maintaining perfect tiling. I kept the modular pieces fairly simple to save time and because they were so far in the background. Once the modular kit was created, I put together the various buildings as blueprints which I then placed into the scene.
Foliage
The foliage was based on common gardening plants that matched the concept. I started by modeling all the leaves and grass in Maya, focusing on creating the silhouette of the leaf and its stem. Then I imported the models to ZBrush and sculpted them in the smaller details. I added variation to the silhouette with the Move brush and surface variation with the Clay brush, and I created the veins mainly with the DamStandard brush. Finally, I imported the sculpted leaves back into Maya and laid them out onto a plane for baking and texturing in Substance 3D Painter.
Once the leaves were baked and textured, I imported the textures into SpeedTree, where I assembled the plants and created the tree. This mainly involved experimenting and testing different settings within SpeedTree to match the references.
For the tree, I started by creating a branch in SpeedTree. I locked the camera in a top view, created the branch, and spread the leaves throughout. I made sure the leaves didn’t overlap too much. I also created other small branches for some of the smaller foliage.
Once everything was in place, I baked the branch textures in SpeedTree. Next, I created the trunk of the tree and its main branches. I kept the trunk fairly simple since the bottom parts of the trees would not be seen much and to keep the polycount down. Finally, I added the baked branches throughout the tree, trying to give the tree a puffy appearance.
Cloth
The cloth props for this project included any of the props with some sort of fabric or wrinkling, such as the tarps and wrapped boxes. These were all created using Marvelous Designer. I began by importing any assets that the fabrics interacted with into Marvelous Designer. For the banner and tarps, I created a rectangular fabric and pinned the corners to hold them in place, referencing the concept, then allowed the cloth simulation to run. I then manually adjusted the tarps during the cloth simulation and adjusted the material settings, focusing on creating visible and varied wrinkles in the cloths.
For the wrapped boxes and police tape, before running the simulation, I set the pressure to a negative value which causes the fabric to wrap around the mesh during the simulation.
Once I was happy with the results in Marvelous Designer, I imported the cloths into ZBrush, where I polished them. I mainly made subtle adjustments, using the Smooth brush to fix any issues and the Pinch brush to strengthen wrinkles. The cloths were then exported as the high poly model. The low poly model was created by decimating the mesh to a reasonable polycount without affecting the overall form significantly. From there, the low poly models were imported into Maya for UVing, and baked in Substance 3D Painter.
Retopology
For this project, I used a texel density of 10.24px and 2K textures across all assets since I was aiming for a higher quality for this portfolio piece. I stuck to using Maya to UV all the assets. When unwrapping, I start by creating a camera-based UV to reset the UVs, removing all the seams.
UVing mid-poly assets differs from UVing low-poly models. It’s not necessary to add a UV cut on every single 90-degree angle. This means much more connected UV shells, resulting in fewer UV islands and less padding, thus allowing for better use of the UV square.
However, an issue I ran into was that it was difficult to straighten out the UVs perfectly using Maya’s automatic tools due to the bevels, so I manually straightened out areas of the UV where the texture required it. For the smaller props, I packed them all into the same UV space to texture them all at once. Most of the various signs and posters were also packed into a single texture.
For larger props, such as the modular assets, pavement, and ground, I used tileables with the UVs placed in a way so as not to break the tiling once the textures were applied.
Texturing
Assets were either textured through a unique texture created in Substance 3D Painter or using tileables mainly created in Substance 3D Designer. For unique textures, I start with a base layer, making sure to add enough variation to the color and roughness. I then repeat adding additional layers as needed. I also like to add some subtle variation in the height using various noises to add some imperfections in the prop through the material. I finish by adding a dirt and grunge layer on top, using generators and masks to create them.
For the drum barrels and flowerpots, I also created a mask to allow me to easily adjust their base color in-engine without affecting the color of the dirt and rust layers. The mask was packed in the alpha channel of the base color.
I created several different tileables through Substance 3D Designer to texture all the larger props. I started by finding reference images for the material I was building, making sure they were in a high enough resolution to see the smaller details as well. I always start by creating the height map and trying to match the micro and macro patterns found in the reference. This usually takes me a lot of experimenting until I get a good height texture.
Once I have the height texture, I create the color and roughness textures from there. The bark material was particularly challenging, and this breakdown by Peter Sekula helped me out a lot. I used decals and a material function to add dirt variation to all the tileables to break up the repetition.
I made master materials in Unreal Engine for each type of material. For example, I had a main master material for PBR materials, another for the glass material, one for the foliage material, and so on. From the master materials, I created several material instances, each with easily adjustable parameters. I like to use Named Reroute nodes to keep the nodes organized in my master materials. I also created some material functions for node setups I repeatedly used throughout all my master materials to keep the shader more organized.
The glass material was created mainly following the tutorial below, and a world position mask was used to add dirt and roughness variation to the glass material.
Tram Texture
The tram was textured entirely using tileables, RGB masking, decals, and Parallax Occlusion Mapping (POM) decals.
The tram was modeled using the mid-poly workflow. I used two different UV sets, one with the UVs all packed into a single UV square and a second UV with the correct texel density. Since Substance 3D Painter only reads the first UV set, I made sure to set the packed UVs into the first UV set. The first UV set was used to create the RGB masks.
Upon importing the tram into Substance 3D Painter, I baked it using itself as a high poly to create the required mesh maps. For the RGB mask, I used the red channel to store the dirt mask, the green channel for the color variation mask, and the blue channel for the paint mask. I used generators and manually painted some details to create the masks and set their base color to match their corresponding channel. Once completed, I exported the RGB texture and imported it to Unreal Engine. This article by Aleksandr Silantev helped me set up and use RGB masks.
I used decals to add text, signs, and additional paint splatter of various colors to the tram. Then I created POM decals to add additional normal details to the tram without increasing the topology count. The POM decals were all modeled within Maya and baked onto a single plane, which I then manually cut to get the individual decals. I mainly followed this tutorial when creating and setting up the POM decal shader within Unreal Engine.
Composition
For the overall composition, I tried to match the concept as much as possible. In the concept, the pavement and ground were too clean, so I made some adjustments there by scattering leaves and creating leaf piles throughout the scene as well as adding decals to the pavement to make it dirtier. To create the leaf piles, I used the Physical Layout Tool, which is available for free on FAB. This plugin allows you to use physics and collision to drop in meshes as instances to quickly create piles or scatter meshes around.
The ground material in the concept was difficult to get a read on, so I based it on the reference images of the actual ground at Dobashi Station. I used vertex painting with a height map to blend the bricks with a dirt material and to add cracks and small rocks throughout. There was a total of 4 materials used for the ground material, and all were created within Substance 3D Designer.
Since the key shot caused the ground to be viewed at an angle, the ground appeared very flat with only a normal map. So, I created a couple of small basic rocks in Maya, reused the brick texture for them, and manually placed them throughout the ground material to add depth to the ground.
Decals were used a lot throughout the entire project, either to add text, create variation in the texture, or add some dirt or wear onto a prop. Since this project required a significant number of different decals and text, I created decal atlases that could store various decals on one texture. This helped to organize the textures a bit better and lower the number of textures I needed to import. I created a decal master material that could switch between using a single decal texture or a decal atlas texture. From the material instance, I could select which decal to use based on its position on the atlas. The shader also allowed me to add a breakup to the decal using a mask, which allowed for further customization.
The paint splatter decals were all created in Photoshop. There were also several images I used for the various posters and signs in the scene. I don’t want to take credit for them as they were downloaded from Unsplash or from websites I found on Dobashi Station.
For the final touches, I added falling leaves using Niagara, subtle wind movement to some of the foliage and tarps, and a flickering sign to the tram. These small movements helped to bring the scene to life.
Lighting & Rendering
I used Unreal Engine’s Lumen for my lighting setup to achieve realistic lighting. While the directional light provided the main light source, I added several lights throughout the scene to highlight specific areas, such as the tree up front, the front of the tram, and several of the trees in the background. I also used spotlights to create a gradient in the lighting on some props, like the sign in the front. This helped to add more variation to the texture.
All my post-processing was done within Unreal Engine. The main fog was created using the exponential height fog with the volumetric fog, which enabled a subtle fog, which was important in creating a realistic atmosphere. For the stronger fog in the background, I created a simple fog shader that allowed me to manually control the strength and color of the fog.
I also created subtle god rays in front of the tram through a rectangular light with its volumetric scattering intensity set to a high value. Other than that, the only other post-processing used was the vignette to darken the corners of the key shot. The overall result created a vibrant, colorful scene through lighting.
Conclusion
Overall, this project was completed over an 18-week period. The biggest challenge was being able to stay motivated enough to keep making progress every day. There was a lot of experimenting and redoing things until I got a good result. I struggled a lot with figuring out how to texture the tram specifically, and it took a couple of iterations.
My advice is not to be afraid to fail, as that’s usually when you end up learning the most. Going through the creation of this project has given me confidence in my skills and helped me to grow a lot as an artist.
I’d like to thank Amber at 80 Level for taking the time to conduct this interview with me and giving me the opportunity to share my work. I’d also like to thank my mentor, Kacper Niepokólczycki, for all his help along the way. Finally, thank you for taking the time to read this breakdown of my project!