Project & Goals
The project that I’m going to present helped me gain a foothold in the job market. Its initial goal was to hone my modular skills and to find new techniques in Unreal Engine to enhance the otherwise dull look of my modular environments. I’ll mainly go through 3Ds Max, ZBrush, and Substance Painter/Designer… And UE5 of course!
My former 3D professor Manuel Martin took A LOT of photos from a building in Montpellier, France. As my school years came to an end, I eventually found the time to use all those photos as references for my following personal project. The building is composed of two old terraced houses. I was only interested in recreating the building itself, not the garden and the street around. It was a great exercise to rely on the photos, thanks to their number (around 850 pictures, and it wasn’t too many). Unfortunately, the difficult part was to guess what was behind the fence and the edge. It was one of the reasons why I haven’t reproduced the garden. Google Street View may be a great addition to complete the references or even Google Maps for a sky view of the roofs.
Before the real work began, I planned my modules in Photoshop by analyzing a photo of the front of the building. Well, several photos in this case, because the trees and the lampposts hid part of the facade. It was also the occasion for me to already think about how many textures were necessary. You don’t have to stick to what you have planned in Photoshop. It is just intended to be a thought-starter.
Two years ago when I was still a complete beginner, I tried to reproduce in 3D the same building and failed. Why? I wasn’t methodic at all, and I worked hard directly on the high poly model of the door and classical consoles. Even before the modules. I was thus discouraged and I left the project unfinished. The lesson I learnt is that for the sake of a project, it might be best to start with the global shapes before working on the details.
Sorry to tell you that, but yes, size matters. It’s important to take some time at the beginning to be sure that the size of your building is realistic AND playable (conform with the character size and player’s camera). My first job was to calculate the size of the door by looking at the photos with people on it. Then, I was able to deduce the approximative dimensions for each element.
I continued by modeling a rough blockout of the ground floor modules with the door and the window included. Then, I imported them in UE5 and tested the size and the feeling in-game in relation to the player’s character. Most of the time, you have to make the openings larger in video games than in real life, to facilitate the player’s passage through a door. When the ground floor looked ok, I duplicated the variants and I made variants by floor. And off we go for a round in UE5, with all my floors modeled. This time, I looked at the visual impression of the height of the building in its entirety regarding the player’s camera. If your FOV is already set up by game designers but you don’t feel great with the building being too/not imposing enough, the best may be to modify the size of your modules. In my case, the result was satisfactory.
Playable: also checked.
Once the global size was adjusted, I refined the shape of some areas: for example, the arch opening needed more polygons. Then, I modeled the mid-sized architectural details: mostly the balconies, the stringcourse, and the cornices. They consisted of a few extruded faces without any details. The metal railing of the balconies had more complex shapes but was easily achieved thanks to the spline tool. They were later baked on a plane to create a trimsheet texture.
I moved to the UV step as soon as possible, to fix the last small issues in the models. Like the modelling, I started by laying out the UVs of the biggest parts, the walls, before working on the trimsheet. It’s easy to unwrap a module on a tiling 0 to 1 UV space when it has more or less a square shape. But what about a non-square module? In my screenshot example, I preserved the tiling on the edges by isolating the extruded part. You should take advantage of a corner to break and separate the UV islands.
Even if it is mostly plaster, I’d rather have good UV transitions on the mesh angles. Because even with a slight amount of brick texture, a sudden cut in the UVs becomes visible. Moreover, it is better to have UV tiling if we add chamfers on the edges, as we will see later.
Before doing the UVs of the cornices and balconies, I had to bake a quick trimsheet, at least for the normals and opacity mask to be tested in UE4. I divided a square plane in 10 equal parts, to greatly facilitate the UV layout. Most of the strips of my high poly trimsheet are larger than the strips of the plane, to be sure that it will bake seamlessly. It’s also for this reason that the models of my trimsheet are exploded: otherwise, the ambient occlusion may leak on the different bands.
The next step consisted of sculpting the small details in ZBrush, which are all the classical ornaments on the consoles. I sculpted them from scratch to stick as much as possible to the original references. I mainly sculpted using mask+inflate for the hard surface extrudes and separated SubTools for each kind of moulding. However, I’m sure I could have found some brush pack with all the necessary moulding for a better result in no time. I shamelessly used the Decimation Master tool to create the low-poly, with a few cleaning in 3Ds Max. If I had to create more optimized assets for a game, I would have to retopologize my high poly assets in Maya.
A good way to enhance the visual quality of some basic modular assets is to smooth the edges. Depending on the situation, I used two different techniques.
The first one is well known. It consists of transforming my low-poly modules into “mid poly” ones. I added a chamfer on 90° angle’s edges, playing with smoothing groups and weighted normals. I waited for the UVs to be finished before smoothing the edges. Actually, it was much more simple for me to unwrap and make the UVs tileable without any chamfer on the models. The “Preserve UVs” option worked pretty well, and I only had a few UVs to fix after that. Unfortunately, I was too shy about the chamfer’s thickness. As a result, the smooth edges aren’t visible enough.
The second method consisted of an edge wear trimsheet placed only on wall corners as a decal. I just sculpted some broken corners in ZBrush and baked them on a plane with a transparency mask. It’s more difficult to find tutorials on this technique, here is the only one I know, from Leonardo Iezzi: https://www.artstation.com/artwork/l3wwa
The plaster, the bricks, and the roof are basic textures from Megascan. Even if it would have been easy to make them in Substance Designer, I wanted to try photo-scanned textures in this project.
The trimsheet, the sculpted ornaments, and the wooden openings were baked using Marmoset in order to have better control over the cage. They were then textured very quickly in Substance Painter, using some dirt, edging, and grunge. I exported these textures on three 2k maps: base color, normal and packed ambient occlusion/roughness/metallic. The trimsheet required an additional opacity map because of the balcony’s metal railing.
At the beginning of my project, I found a very interesting article from Carlos Sánchez talking about creating buildings for PUBG: https://80.lv/articles/creating-diverse-buildings-for-pubg/
He talked about giving a unique mask per building to offer some dirt variation and damage without using Vertex Paint. To sum up, we often use the first UV channel to make our modules tileable and to keep our texel density. But we can also use a second UV channel to pack all the UVs from the walls together in the UV space (as we do for a prop). On this UV channel, we paint several masks to give a unique look to the building in Substance Painter.
It was a great way to bring variations without repetition over the modules. I definitely wanted to try this method. Substance Painter was of great help when working on the masks for the second UV channel. I created a smart material using separately the red, green, and blue channels to project ambient occlusion, some grunge, and moisture on the whole building. The good news is that a 2k texture looks sharp enough and not pixelated in the engine. Of course, if the opposite facade of the building is exactly similar, it’s better to save some UV space. That’s why I isolated two facades from the four ones. Curiously, Substance Painter only recognized the first UV channel. So I had to create a duplicate version of my building with the second UV channel as the first one, and import this one in Substance Painter.
The R and B channels gave some tint and luminosity variations to the textures. The grunge mask from the G channel was used as a way to mix my plaster and brick textures. I derived the master material into instanced materials with different applications. For example, one was used specifically for the roof and added moss in the interstices. In the screenshot example, the AO/Roughness/Height textures were separated for better readability, but you must pack these textures together. I still have a lot to learn with shaders. Indeed, there is a lot more that we can accomplish with just a few masks. I fell in love with the procedural approach because this method allows me to add details without any vertex painting or decals.
Moreover, I had some fun experimenting with a glass shader for the windows. It all started with an hdr image with the “InteriorCubeMap” node linked to the UVs, to give the illusion that there is a room behind the window. I then projected several masks to simulate dirt, drops, and so on. To finish, I added a “CameraDepthFade” node to make the cubemap interior more visible if the player comes near. It’s subtle but it’s better to see the interior clearly only at a certain distance, to avoid the repetition between the windows.
Scene set up
The lumen system from UE5 was a game-changer. It gave such a great lighting atmosphere in no time, only using the directional light.
I filled the scene with megascan assets, to create a street surrounding. I went through Speedtree to create an urban tree using their atlas. In the shader, there is a slight emissive to simulate the light going through the foliage, in addition to the subsurface.
The road and the pavement were based on a simple shader using some masks again, to mix two textures and to add precious details, as new asphalt squares. This way, I only added a few decals for the white lines and the manhole cover. By default, UE5 materials only support 16 texture samples. This restriction may be problematic when dealing with a landscape material. A way to get around that is to select “Shared: Wrap” as the Sampler Source in the parameters of each Texture Sample node.
This project took around one month to complete. I spent some time learning new techniques, and I realize now that it’s only the beginning of my journey. The RGB mask method in a second UV channel can be very promising. I would like to learn the maths behind the shader’s nodes in Unreal Engine, in order to achieve better results next time. I would like to thank Games Artist for this opportunity to explain my workflow and Arthur James and Lucas Dziura for reviewing my article. And thank you for reading! I hope this article has been at least a little useful to you. If you have any tips to improve the workflow or the shaders, I would be glad to hear about it! Here’s my social medias if you want to connect with me and see more of my work: