Sasho Lazeski shared an enormous breakdown of the Zoloti Vorota project, talked about working in Substance, and shared a lot of useful tutorials for aspiring artists.
Hello, my name is Sasho Lazeski. I am a 3D Environment Artist living in Cologne, Germany. I have a degree in digital marketing and a career in sales and business development, but use most of my free time working with and learning about 3D environment art and art in general, trying to make it in the game industry. I have found my passion for 3D art around 5 years ago when I started doodling in ZBrush and was just moving vertices around in Blender. At the time I was sure 3D work was what I really wanted to do, but I was not sure which direction to choose. Among other disciplines, I experimented with some visualization and character projects, until I realized environment art is what I enjoy the most. You can still see some of my old character projects on my ArtStation.
My enthusiasm for 3D game art stems from my childhood, as I guess it does for many others. I remember playing games like Crash Bandicoot, Spyro, Medal of Honor as a child on PS1, and how I genuinely enjoyed the experience and imagined my real self in those worlds. I think having the chance to be part of a team that creates this type of experience of story and beautiful worlds for people around the world to explore and enjoy through video games is just amazing.
Project Motivation, Story, and Preparations
I wanted to make a scene with which I will improve my skills in modularity and procedural art, namely working with trim-sheets, tileable textures, modular asset sets, being mindful about maintaining texel density, etc. In brief, I wanted to go with a AAA game production pipeline but was not sure what kind of scene to choose. I also wanted the scene to be fairly big and to have the opportunity to play with different storytelling and mood elements depending on where you are situated within the scene. I am travelling often to Ukraine and since I use the metro anyway, I always make sure to stop and visit the “Zoloti Vorota'' metro station in Kyiv. I always do that since it is just so beautiful and inspiring, and each time I am there it feels like visiting it for the first time. From there I got the inspiration to make a post-apocalyptic version of that metro station since aside from really loving it, it had the potential to fulfill all the goals I wanted to achieve with the project and I could take some pictures for references myself. Side note: I recommend to anyone visiting Ukraine who is interested in mosaics and soviet history to visit the metro stations in Kyiv and Kharkiv. You pay once to enter the whole metro network, so it will not cost you extra if you go out of the train on a stop and then in again until you go out of the network in the city.
The main story I had imagined for the scene was, that there is war above ground and a clan takes shelter below in the metro, where they have managed to create a somewhat sustainable environment that covers their basic needs, but still needs to go out and raid for food and special supplies. Even in these darkest of times, people have not lost their faith in God and in each other, so they have adapted to the new normal and live a peaceful life in their heavily secured haven that they now call home.
Regarding references, I had three major types and sources I used:
- Original pictures I took myself in the station for the base scene (hall, pillars, mosaics, and trains), including some props and structures that workers there use or that sit there for emergencies and maintenance
- Soviet-influenced post-apocalyptic games like S.T.A.L.K.E.R and Metro Exodus. I just googled these and was especially looking for shots with varying composition, color, and lighting that I could use later as an inspiration for each area shot of my scene. These also helped with giving me ideas about storytelling and props enforcing that in each area
- Online references of other USSR metro stations, like ones in Russia, Kazakhstan, Georgia, Uzbekistan, etc. Here I found interesting elements that would help with consistency and add interest in the scene like the marble materials, escalators, booths, and additional props. Searching for these in the local language of each country with the help of google translate gave me a much greater selection of references to choose from.
I collected all of my reference images in pure ref, giving each group a separate section and a label to help with the organization since I ended up with an abundance of images in the end.
Throughout building the first iteration of the scene, which was the original Zoloti Vorota metro station, I attended Clinton Crumpler’s modular environments CGMA course which helped me a lot with making sure I was working efficiently and in a modular fashion as initially intended. Clinton was reviewing the scene progress weekly and was addressing all questions I had as well in a video review recorded with the scene files sent to him, which saved me a lot of time looking for answers myself and a thorough explanation of the whole topic at hand. That was a great learning experience and I would recommend the course to anyone that wants to build a modular environment in Unreal Engine. I did the second and final iteration later on when I decided to add the post-apocalyptic feel, storytelling, and mood to the scene. Here I had a lot of great input and help from Timothy Dries from the Beyond Extent community, who was too kind to give me his feedback and discuss ideas with me on how to dress up the scene to get it to the level wanted to reach.
Blockout and Plan
After collecting references for the scene, the next step was the blockout. It is important to set the scene scale and proportions properly to give you a proper base to work in later. Since the base scene in my case was an existing metro station that I would populate later, the blocking-out part did not take so much time. I took some rough measurements myself and managed to find some sketches online showing the dimensions of the station. During this stage, I was blocking out the hall, pillars, walls, and rails of the station.
To make your life easier when working with your blockout meshes in Unreal Engine, make sure the units in UE are consistent with the units in your 3D software, whereas 1 unit is equal to 1 centimeter, so your imported assets will have the appropriate scale. You can see how to do that here in this video by The 3D Tutor. Another life-saver is working on the grid, meaning importing assets with the pivot set to either a corner or a center point, with snapping enabled in UE, which will enable you to put modular assets like walls together flawlessly. The best tutorial on that is this one here by Jessica Helgesson. As an example, here are some modular assets I used in the scene that are snapped next to each other and shown in red where you could set pivot points for them so they can be duplicated and snapped together easily.
Lastly, it is recommended to use dimensions that will be easily transferred to a trim sheet or tile later on, like for example 2x2 meters, depending on your planned texel density for your scene. Having the blockout gives us a relative idea of scale, so we know how to transfer that information to the textures and trim sheets appropriately with the texel density we apply.
I was using 3ds Max for my blockouts and was testing the snapping on the grid beforehand in Max directly, so I was sure it would work properly later when I imported it in Unreal. From there I continued importing the individual assets and snapped them together until I had the main hall, pillars, walls, and rails ready. Here is how that looked as I tested it in 3ds Max and later in UE4.
To keep myself organized, I use Evernote, where I write notes, handle “to-do” tasks, keep track of time and save basically all information I find to be important and/or useful. Here is a video example of how you can create to-do lists in Evernote.
Modeling and Texturing with Texel Density, Procedurality and Modularity in Mind
After having the blockout ready, it was time to think about the texel density I will use for the scene, which is the amount of texture resolution on a given mesh. I decided to go with 5.12 texel density (2k textures for 4 meters of space) which is common for third-person games and enough for the level of detail I wanted to achieve. Here is an article from Leonardo Iezzi that I used as a reference for that, which covers pretty much everything you need to know about texel density. You can also check out Anthony O Donnell's free article covering that.
You can make sure you are consistent with texel density either:
- Manually - apply a checker texture on a reference plane with the dimensions of your chosen standard, for example, a 4x4 meter plane with a 2k checker texture for 5.12 texel density. Then scale the UVs of all other objects manually with the same checker texture applied until the density of the checker pattern matches the plane.
- With a script or tool - this method is recommended since it is faster. Some software packages even have tools like this integrated, especially on newer versions. I used 3ds Max 2018 which did not, so I used the Texel Density Tool plugin to help me with that. It is also worth mentioning that artists should not stress too much about this, since there is some wiggle room for mapping a trim, meaning we can scale UV islands up and down 20-25% to fit a trim texture as long as it is visually not too noticeable.
Given the size of the scene, I tried to apply tiling and trim textures as much as possible to save time and stay consistent across various sections of the scene. Because my meshes were set to real-world scale and I wanted to know how big to make the tileable and trim texture space, I used the UV islands for reference. Trims are most commonly square, and if you use the correct texel density the UV islands will fit perfectly. If however, you are dealing with an asset that is uneven, for example, 4x2 meters, make the trim 4x4 meters, and use the “butterflying” technique to deal with that asset - adding an extra edge on the mesh and flipping the UVs so it tiles flawlessly across the asset or to a given edge like in the example below (just observe the plane in the big red square and how the texture is flipped from the edge cut in the red rectangle).
Below I will go into further detail how I approached particular materials within the scene, however as a rule of thumb, I used Marmoset Toolbag for baking, Substance Painter for most of the unique assets, Substance Designer for most of the tiling and trim sheet textures, Photoshop for quick tweaks like alphas and input textures I grabbed online and combinations of all for the rest. For the mosaics, I used a combination of Photoshop, Materialize, and Substance Painter. Here are some of the most prominent tileable and trim materials I used across the scene, that I will go through in more detail in the following text.
I used plenty of trim sheets in the scene to both save time and enforce consistency across space. To create them, I do a little planning beforehand that gives me a good idea of how much room I need for each material to be represented in it. At this stage, I like to use Photoshop just to mark my trim plans with colors, or even Mindmaps if I want to keep myself more organized. In the example below I use Miro which is a nice mindmap tool that saves your images in the cloud and you can go crazy with connection lines laying your thoughts down. It is also collaborative and can be used intuitively in teams.
Below I demonstrate how my planning usually looks for trims, in particular here for my pillar and escalator hybrid trim sheets, meaning some part of the texture will be “static”, like signs or stickers, while others will be tiling on the left and right like rubber belts, pillar tiles, metal panels, etc (I recommend this tutorial by Hamish Ames for more info on that). During that process, I did some normal bakes first so I can test them out quickly on some meshes.
Here are some extra tests I did after that, one with the pillar trim and the platform edges with wall tiles once the texturing was done (to be covered more in the next section “Texturing: Mosaics, Substance Designer Vertex Painting Variations, Trims and Uniques”) and another with the escalator trim.
I used three trim creation variations in the project:
Baking – Creating a high poly model from which the Normals, AO, Curvature, and other input maps are derived with a bake with a low-poly plane on top. The general step-by-step process I apply here is:
- create the high poly and extended it over the sides of the low poly distance, so AO will not be baked on the sides resulting in a failed tiling effect later.
- apply materials with different colors on the high poly, so you can bake material IDs that will help later in the texturing process to swiftly isolate different sections for texturing.
- center the pre unwrapped 0-1 edge to edge UV low poly plane (using the grid in your 3D software helps with this), so it is right on top of and over the high poly version, to get the most accurate bake.
- baking and using those input maps for texturing in Substance Painter.
Substance Designer – Alternatively instead of baking you can just do that with the same approach you would have for tiling textures there. In this example, I just created a quick normal and AO map in Designer, which I then took into Substance Painter to finish off with some gold material and a marble material preset I created. You could of course finish everything in Designer, but I chose to combine both here since I had a ready material preset in Painter to help me with texturing with the help of those input maps from Designer.
Substance Painter – this is the fastest method, but usually at the cost of quality. It is easier to achieve better quality when you have input textures like in the previous two points, however when you do not need that type of detail so much or when those assets are not in focus so much, this method is viable. I used this method for the booth and locker kit - created several asset variations to use across the scene with moving the UVs across the trim texture to achieve that variation. I went ahead with texturing directly in SP and created and exported all necessary maps from there from scratch.
Here are a few other examples of trim sheets I used across the scene, which were all approached with one of the three methods mentioned above, or a combination of them.
Tileable Textures and Vertex Painting
For the tileables I used mostly Substance Designer. Here I would recommend the YouTube channel “Get Learnt w/ Chunck” since I used different tutorials Chunck has there to create my own textures. Once you get the logic behind any material created in Designer, it is then easy to tweak the nodes to achieve your desired result. For example, if you find a tutorial about kitchen tiles, you can easily transform that into floor tiles by mostly tweaking the existing nodes. 3DRedBox also has some nice ones and that is where I found a tutorial that helped me create the wire fencing.
It was now time to prepare some vertex paint materials. Vertex paint blends several material sets on the asset where it is applied which is controlled by painting with the R/G/B on the vertices of the asset. The channel inputs can be painted either independently or in combinations at the same time until you achieve what you aim for. Here are some shots of my setup, but for a closer look, I recommend this tutorial to help you get the logic behind that.
For the other materials, I had a pretty basic master material setup, but it did the trick for me since it enabled me to create material instances from it where I just replaced the texture input maps for the asset they were going to be applied for. Ryan Manning covers this topic in detail here.
Whenever working on tiling textures that do not come with vertex paint alternatives, I was trying to be careful to not make it obvious that they are tiling. That means no point on the texture like grunge or dirt should stand out too much, since that way it will be obvious when they are assigned to large tiling spaces across the scene later, like the floor or walls.
If therefore I needed to apply any variation, I used decals or I applied vertex painting. Here are some examples where I took the vertex painting approach and the variable materials that came with it:
- Floor (clean, dirty, and dirty/wet) – to create these materials I used Substance Designer, where this Grey Floor Material by Kalyson came in handy for the base and logic as mentioned earlier, and then transformed it into the types of floor tiles I needed for my project. Since I had all nodes in one project file, at the end of the node network I used “multiswitch” and “multiswitch grayscale” nodes where I plugged in all 3 variations of Albedo, Normal, Roughness Maps, etc. individually, so I could export each texture pack accordingly just with a quick switch of the input through the multiswitches.
- Wood structures (bright, dark, and painted) – for the wood I used as a base a ready Albedo wood texture, I edited it in Photoshop to make it tile, created other variations from that with added dirt and paint, and then extracted other base textures from it in Designer. This is elaborated in a bit more detail below under “Asset Kits – Wooden Structures”.
- Top walls (clean, dirty/moldy, and dirty/directional) – similarly as for the floor, to create these materials I used Substance Designer, with the help of this Concrete Material tutorial by Sharpstance.
To save myself time, in anticipation of objects I was planning to reuse across the scene, I decided to create various kits of assets. Here are some kits I used throughout the scene:
- Wooden Structures – I created a base wooden structure model, and two other variations of it with different UV layouts, to be stacked and reused from the side next to the base. Then I applied a vertex paint wood material with a clean and painted version to be used on the structures and ladders. For the wood material, I used a tiling texture I found on textures.com and then just added some color overlays in Substance Designer for the vertex paint variation. I created the ropes with splines in 3ds Max and then just applied a rope texture in Substance Painter with the help of some of the integrated patterns available there.
- Clothes – I did some basic clothes in Marvelous Designer (quick tutorial for that here by G Tutorial) and simulated them from the top of a pole downward since I was gonna hang them on wires or place them flat later. Then I textured them and put some holes and rips through as an Opacity Map, with the help of alphas or manual painting. It was fun using Marvelous, also for other assets like the trash bags, bedclothes, curtains, pillows, etc. and I recommend it to anyone who has not tried it to give it a go. There are plenty of youtube tutorials for all of these things. You need to think like a tailor when you stitch patches together and I found that to be very amusing and tranquilizing.
- Plaques – I collected some real soviet plaques from google search and saved them in pure ref. Then I distributed them around in an atlas fashion in Photoshop on a 2k canvas. Firstly I took out all colors and used levels to get only the wording from all of them. From there I created some plaque model variations in 3ds Max, using the dimensions of the base texture I had created in Photoshop. I imported everything in Substance Painter where I textured the plaques and used the Photoshop texture as both a mask for the Normal Map text indentations and a mask to color the text. I also created a Color ID Map before that I used to organize my folders easily in Substance Painter with a black mask and using “mask by color selection” to isolate each plaque swiftly.
- Palettes – I sculpted several planks and a corner cube, baked the normal detail down on low poly versions of them, and then assembled 3 palette versions from those planks and cube. For the textures, I used the ready “wood walnut” material as a base in Substance Painter, added some dirt, edge highlights, color variation with some of the grunges Painter offers as a black mask, some extra normal detail, and nail stamps on top.
I created similar kits for other assets as well across the scene, like the asbestos and metal roofing, posters, maps, other papers, and the locker kit mentioned above under the “trim sheets” section. My recommendation is to try to use them as much as possible when you are not preparing a hero prop to save yourself time, especially for bigger scenes, and in hindsight, I could have had more of them in this scene too.
For other assets where I wanted to apply unique textures, I either used a standard high to low poly bake process, or I used a mid-poly workflow to save time and avoid baking, where I used a Face Weighted Normals script to achieve a smooth look with few to none manual vertex normal tweaks. Warren Marshall covers this topic nicely here. As was also the case with the texel density plugin, this one also comes by default with newer versions of 3ds Max and is either a plugin or already integrated into other 3D software packages. FWN improves the shading of the models by changing the vertex normals to be perpendicular to the larger flat polygons, without the need to bake that information from a high-poly model. As an example, here is the accordion model I created with that workflow, even though in hindsight I could have optimized it a bit more:
As for the standard high to low poly workflow, sometimes I used a high poly directly from 3ds Max, while in other cases where I needed to create some more detail that is more challenging to create directly in Substance Painter, I was using ZBrush. That was the case with the mattress, where I created the high poly in ZBrush, and from the bake, I had created several versions just by bending and flattening the low poly model, either for a mattress resting on a pillar, or flatter versions I used for the beds in the medical quarters.
For the texturing in Substance Painter, what really helped was baking an ID map. With that, I could easily mask out specific areas for texturing, like the inner sponge, the outer cloth, and the rim rubber, without manually doing that by hand.
For the added normal details for the cloth of the mattress (not taking into consideration the dirt and other subtle effects), I used grunge spots, directional noise 4, hexagon triangle border, and the Substance Painter cloth material as a base. I then controlled the strength of each with a Levels node to get the mattress to a level of detail I was happy with.
Decals are an overlay effect we can add throughout the scene, where we want to add extra detail or element of storytelling. For a demonstration of what they are and how they can be used, here is a little video explaining how you could create normal detail decals with the help of ZBrush and how to use them in UE4. Decals can also have other information just like any other material – Normal, Color, Roughness, etc. Some typical decal candidates would be for example blood or paint stains, wall cracks, bullet holes, dirt, and dust. They can also be used as overlays for text on surfaces like graffiti. Here in unlit mode, you can see some spots I marked with a red checkmark, where I used decals – room names, entrance instructions, dirt and leakage, wall cracks and blood spatter.
For most of the decals, I used Substance Designer with the introduction this time of an Opacity Map which controls what part will be shown and what not from the input textures. For the text I just used Photoshop to create textures that were reused as both color and opacity – since it is white text on a black background, I also used it as an Opacity Map in those particular decals. Here is a video from Ryan Laley demonstrating how to create a decal in UE4 for reference. In the end, I also used some Quixel Bridge decals, most notably “asphalt cracks” and “damaged concrete” for the walls with reduced opacity, to complement the vertex paint materials I had already set up there.
I also used other external resources like Google Images and Textures.com that helped me either find input images from which I derived various maps to create materials or alphas for texturing, which all helped me finalize my project quicker.
Mosaics and Materialize
For the mosaics, firstly I used Photoshop to edit real photos I could find of the mosaics in the Zoloti Vorota station. Since I was using partial, side, and sometimes skewed images, I was firstly “gluing” them together, then was taking out the light information so I was left only with the color data to add other information later with other Maps. Lastly, I was doing the transformation so the mosaics fit in a rectangular shape in order to layout the UVs flawlessly later. For the stripe mosaics, I also made additional edits in Photoshop so they tile on the sides.
Once I was happy with the albedos I created, I used Materialize to extract additional maps from them. Materialize is free software that generates texture maps (i.e. Height, Normal, AO, Curvature, etc.) from input images. With a few tweaks with the sliders Materialize provides, I got the Normal and AO Maps I wanted. I did this same process for all mosaics.
From there I took all those input maps in Substance Painter, baked the rest of the input Maps if necessary, and finished off the texturing process there. I did not do anything too fancy in Substance Painter. Mainly I played around with the Roughness and did some minor color tweaks on the Albedo.
When I was making this same process for the big mosaic at the entrance – check-in area, I found out, given my texel density constraints, my initial UV setup could not fit the UV shells in the 0-1 space, even if I split the mosaic in half and turned the UVs. I could have made an exception and used a 4k texture just for that, but then instead still found a way to make it work. I made both halves of the mosaic fit in a 2k texture, by overlapping them and sharing the top-right part of each half, and also “glued” these parts together for the Albedo as seen below. That way the UVs could both fit by overlapping. I was happy my idea worked out and sometimes it is worth going through extra trouble if you believe you will get some extra knowledge and experience out of it.
Lighting and Final Composition
After the blockout and before lighting and final composition, the scene went through three phases:
- Committing to the blockout and testing some placeholder materials and low-quality light bakes
- Finalizing a clean version of the metro station and importing some props for testing
- Assembling props and kits together inspired by references and applying new composition and lighting ideas
Lighting the scene was one of the most challenging phases of this project since I was not comfortable with it as I am with other domains of 3D, especially since this was interior lighting to be done. My goal was achieving a mood of comfortability however at the same time indicating that times are tough outside and survival is the top priority of the people living inside.
I used a lot of gas lanterns with an orange tint and contrasted them with a few white to blue-tinted electrical and battery lights since they want to save on energy and use that sparsely. On top of that, I applied a subtle blue-tinted fog which I tweaked up and down a lot to get it to blend with the rest of the lighting scheme. I tried to push this color scheme and stay consistent across the scene with only a few exceptions. Consistency, in general, is appealing to the human eye and you want to avoid making your work look too messy in any way.
At first, I had way too many lanterns spread out in the scene, but then took out almost half of them since the scene looked too busy that way. I found it best to treat lighting similarly like you would do an initial blockout – start small and keep the post-processing and other effects for last, since otherwise, they will dictate not just the lighting but also how you texture your scene, which should be the other way around. Once I was happy with the point and spotlights I put across the scene, I then started to tune some post-processing settings like exposure, bloom, and tint, the indirect lighting intensity to have enough bounces in the room to avoid fully dark spots, and world setting – Lightmass. I was baking the lights with lower quality first to save on time, and only did higher-quality bakes when I did major changes to the light. A good way to control what you are doing is by checking the isolated light impact on the scene under the “detail lighting” view mode.
As a final step, I was adding some extra subtle point lights and sphere reflection captures. This was to highlight some areas of the scene that I would like the player to pay attention to, like the mosaics, entrances, and other focus areas where no light was already present. I kept these lights very subtle since you want as a best practice to only add lights when real sources of them are present. So if you decide to apply fake lights, better keep it subtle since the player can notice it and that breaks the immersion.
In regard to reflection captures, aside from one encompassing the whole scene, I put more of them next to puddles and shiny objects locally), because otherwise there is a danger the reflection will not match the world around it, especially on key objects. You can also increase the brightness of the reflection capture to make reflections brighter. This is not PBR compliant since you bump the brightness unnaturally, but it is okay if you do it mindfully and subtly just like with the fake lights mentioned above.
I really learned a lot from this project and it got me out of my comfort zone. With any new project, I try to apply at least 20% of new techniques or lessons I learn to the scene. It was really great to also get feedback from industry professionals like Clinton Crumpler and Timothy Dries as I was building the scene, with which I learned a lot of new things. This was my first personal project to focus on modularity and procedurality, specifically in terms of assets and tileable and trim textures. Having said that, the biggest lesson I took out of this project was getting comfortable with the modular workflow that is used in AAA games and real game productions, opposed to the unique asset building and texturing I was generally used to. I am happy that I feel a lot more comfortable applying this workflow in future projects. I also took some time in the end to explore the UE4 sequencer tools and cinematic cameras to compose the animation video and take cinematic film-like shots of the scene, and that was really fun.
There were a few challenges I faced in the project. Probably the biggest one I would point out was keeping persistent to finish it while at the same time balancing and resisting so many new ideas to add more and more things to the scene that was not initially planned since that always increases time to finish the project. As I currently have a full-time job in a different field, it was sometimes also challenging to prepare mentally and find a few hours each day to devote to the project. I also learned a lesson from that - reinforcing the importance of planning a project, prioritizing time to allocate to it, and being accountable for your work.
I feel I could have improved many things in the project, like optimization of the assets, lighting, and general composition, however, that is the nature of art – it is never really done, we just have to call it finished eventually and move on to another piece. There are still many more things to learn of course, which as mentioned I plan to address gradually in future projects and that is the beauty of this industry too. You are constantly learning as an artist – new workflows, software, techniques, etc.
To close off, I would again like to thank Clinton Crumpler and Timothy Dries for their precious feedback in helping me get the scene to where I wanted. Furthermore, I would like to thank the Beyond Extent community for the feedback they provided as well. Last but not least, a big thanks to 80 Level for giving me this opportunity to break down my project and for all of the help they provide to artists, as I have myself learned plenty from articles available there.
I hope this article helped you somehow with your 3D environment project. Please do not hesitate to contact me via ArtStation if you have any questions or believe I can somehow be of help to you. I am happy to connect and communicate with fellow like-minded artists that share the same passion for art and games!