In part one of Nikola Damjanov's making of he shares his workflow for creating game assets and environments
I would like to start with a small disclaimer, this was my first project in Unreal Engine (UE) and I admit that some of the workflow could be better and/or more optimized and if you have any comments please share them.
Step 01: Idea
This project started as a game prototype for Nordeus
; we wanted to make a PvP gladiator game. We had a week to put something together so I kit-based and slap-dashed a lot of stuff to make it in time. The game was scrapped for various reasons but I couldn't let it go. Then a year later I stumbled across the old files while thinking about my next personal project, so I decided to revisit the scene and redo everything from scratch.
The initial concept I had was to remake a part of the arena and use it as a backdrop for a gladiator's fight scene. I had a static scene and two characters in mind at that point, and had an idea to render everything in Marmoset
but I quickly ditched those plans. Shortly after I started rebuilding the scene I immediately searched for a more engaging camera angle then the one from the game prototype but that was hard since I was limited by the small part of the arena and however I tried to move the camera something was missing.
That's when I decided to build it whole. I thought it would be interesting to present it as a moment in time but with freedom to pan and rotate around, explore the scene and get more pieces of the story by experiencing the environment, atmosphere and the characters. So I switched the static shot idea with the one with a diorama. But the project was derailed again when I realized that Marmoset was not the best option to render scenes at this scale. I love Marmoset for presenting characters, props or small sections of scenes but I felt like this was out of its scope. I couldn't get the quality or flexibility I needed. That is when the second big change happened and I decided to switch to Unreal Engine
I have a lot of Unity
experience as I use it every day at work but I've never had the chance to play around with UE on a more serious scale. I've seen some mind-blowing and impressive real-time stuff from other artist and that gave me enough motivation to learn something new and try it out.
Screenshot from the initial mobile game prototype
Initial size of the arena
Scene assembled in Marmoset Toolbag 2
Scene assembled in Unreal Engine; immediately showing more depth and atmosphere
Step 02: Planning and modeling
The project was all over the place in its initial states these two stages eventually fused together. The models are very simple; as the scene is mostly rocks I started with basic shapes and simple PolyModeling, nothing fancy. Considering the initial plan to render everything in Marmoset I laid out almost the entire scene in 3ds Max
. I suggest that you be smarter than me - if you are planning to make something like this in a game engine assemble the scene there, use instances and save yourself time and performance. I was too lazy to rearrange everything again because I knew I had a lot of work to do and wanted to focus on other tasks.
Now that I look back I would definitely add more geometry to certain places; that is one of the drawbacks when you let the project go wild - you start with one thing in mind and end up with something completely different. Things get lost in the translation because when you are making real-time assets technical limitations are important so try to plan ahead and avoid making those limitations into defects.
Basic models used to build the scene
Step 03: Sculpting
Once I knew what the scene would look like, I separated every unique asset to a separate file, made UVs and imported them into ZBrush
. My ZBrush workflow was - import a low poly model, subdivide lots of times with smooth off to get more geometry but preserve the shape and couple of time more with smooth on to soften the edges. That gave me a good enough starting position.
Rock assets were made using Clay brushes to add volume then Trim brushes to remove it. Rinse and repeat to get the look of a stone. Towards the end of an asset's creation I used DamStandard, with a low radius, to define the major shapes, add more depth to crevices, and insert a crack here and there.
For the metal assets I used the same start as for rocks but didn't sculpt it too much. Instead I layered two or three Surface Noises (Erosion, Dent, or Corrugated) of various shapes and sizes, and then used the Trim brushes in between the steps to add large scale surface deformation. I was aiming for an old iron look and that did the trick.
Metal sculpts and example of a Surface Noise
For the cloth assets I used a slightly different process; I only subdivided with smoothing on as I wanted the edges soft and rounded, with a nice flow to them. I creased the edges I wanted to stay sharp. I used the Inflate brush heavily to make it feel like the fabric is sagging and details were added by using very nice cloth folds alphas from Ahmed Teka
. I didn't sculpt any surface detail or the torn parts because I knew I'd add them in the texturing phase.
Cloth sculpts and mainly used alphas
Step 04: Texturing
One of the few things I knew from the very beginning that I was going to texture everything in Quixel
. I have used it on standalone assets and I wanted to test it on an entire scene. The quality of the scanned textures that Quixel has is second to none but the software could be better on the usability side. Since Quixel doesn't have high to low poly baking I exported the normal maps from ZBrush but everything else was baked in Quixel (AO, Curvature, Object Space Normals and Position Gradients).
I started with a stone asset - that is what the majority of my scene is made of - and played around with textures. I experimented with a lot of things such as the color/darkness of the rock, the roughness, and amount of sand coverage. This was a very fun and enjoyable part and I suggest you take your time to try everything. Quixel is your friend here because you can easily layer materials using the powerful masking system.
With the look I was aiming for sorted all the rocks were practically finished. I created a smart material from the lookDev which gave me a preset for defining all the different mixed materials, their attributes and masks. After that, it was a matter of applying that smart material to all of the stone elements with some individual tweaking for base color and amount of sand.
Look development for the stone material
Stone smart material used on the stairs and final diffuse map
The metal material was much simpler since it had an iron base and some coating on the top. I was afraid how it would make the transition from metallic to nonmetallic surface look in a metalness PBR workflow but it turned out looking good.
Metal smart material used on the torch and final diffuse map
The cloth material was probably the most challenging part, not for the texture, that was straightforward - cloth material for the base, then some lighter color overlaid on the exposed parts, darker color multiplied in the occluded areas and washout color for edge wear. I also added some additional dirt in the end. What I had trouble with was the torn parts of the cloth. I had a couple of trial and errors before I found something that fitted the scene. I tried to use Quixel to make some grunge masks and then paint them wherever I needed them but that felt uncanny. In the end I opted for a photobashing approach. I gathered a lot of references of torn cloths such as denim, flags, curtains, and shirts; I then cut out interesting parts, desaturated them and played around with levels to get the best possible alpha map segments. From there I continued arranging them as puzzle pieces, trying to match the scale and give enough details to the cloth. But be careful, it is easy to go overboard.
Cloth material used on the shades and final diffuse map
References I gathered for making the cloth's alpha and the final result
I did the ground twice. At first it was a simple plane modeled in 3ds Max and modified to look like there is some slight height variation and some dirt buildup around the edges. It was textured as an 8K map, combining two types of sand (coarse and rough), dirt and pebbles. All of that was mixed with hand painted masks and it looked okay from far away but the plane was too large for one 8K map to look good close-up. I had an idea to split that plane into parts and have them use separate textures but that was a pain to do in Quixel. In the end I rebuilt the ground in Unreal Engine using its Terrain tools. I exported all the different maps from Quixel as unique tileable textures and then made a splat shader in UE that mixed those maps based on vertex colors. There is a tradeoff to this technique though - you get nice and crisp textures even in close-up but the complexity of mixing them is directly dependent on the amount of geometry that terrain has. So you will need to find a balance between geo resolution (performance) and complexity of mixing (looks), as always.
Comparison of ground texture details; top - unique 8K texture, bottom - splat shader with three 1K maps
Step 05: Assembly
Now I had everything I needed to start packing it in UE. After importing all the models and textures, I created three materials for the entire scene. All of the materials used the standard two sided metal/rough PBR base with default UE settings but with some slight differences. The cloth material, for example, used masked blend mode (for transparency) with a subsurface shading model and the terrain had a custom built mixing shader based on the layer blend node.
This was a huge milestone for me because at this point, for the first time, I saw the entire scene assembled, with textures. And it looked good even in its raw state, compared to Marmoset. I was really happy with my decision to rebuild everything from scratch; it also boosted my motivation for all of the work that was still in ahead of me.
configuration of the splat shader used for the ground
Next time I'll be showing you how I breathed some life into the static scene and brought it all together.
Have a look at more of Nikola's work here
Get your copy of The Unreal Game Engine comprehensive guide here
Do you have a tutorial or making of you'd like to share?