Realistic Weapon Art Workflow – 10mm AUTO SMG – Alberto Catalán
Hello everyone! My name is Alberto Catalan Gallach, I’m 23 and I’m currently working as a Freelance 3D artist. My aim is to create solid Environments, PropArt and weapons for the video game industry, that’s why I really enjoy trying new workflows and tools that improve my skills as an artist and accelerate my work process.
This is the workflow that I have followed for creating the 10mm AUTO SMG:
1.Creation of a model with all the desired detail (3ds Max)
2.High-Poly creation (ZBrush)
3.Low-Poly creation (3ds Max)
4.Unwrap (this time I decided to use the native 3ds Max UVW Unwrapmodifier)
5.Baking (Marmoset Toolbag 4)
6.Texturing (Substance Painter and Photoshop)
7.Rendering (Marmoset Toolbag 4)
Idea and References
My main objective in this project was to create a weapon that had not already been created on many occasions, so I decided to look for original concepts, and the concept of Kris Thaler from his 10mm AUTO SMG was the one I ended up choosing. You can go through his ArtStation profile since all his weapons concepts are impressive. Being a weapon created from a concept, my intention was to reproduce the design as exactly as possible, so for the modeling phase I used this concept as a reference, and for the texturing phase, look for references of the materials that make up the weapon to adjust it as much as possible to how these materials behave in reality.
Creation of a model with all the desired detail
For this phase, I used 3ds Max. I started by creating a very simple block to define the dimensions of the weapon using the orthographic views of the concept as a kind of blueprint, to be as faithful as possible to the design of the weapon.
Once all the dimensions of the weapon were defined, I began to create the model with all the details. At this stage, I did not particularly worry about having an extremely clean topology since I intended to create the High-Poly model using Zbrush. It turns out this path was a much faster workflow for creating high-Poly models of this type than the classical step by step subdivision. I could allow myself to follow this path because it was a personal project and had total freedom.
As I was going to get my High-Poly model in ZBrush, it saved me a lot of time creating a simple shape of all the details that were only going to be drawn on the normal map. In this way, I only used the LiveBoolean tool inside ZBrush to subtract these parts to the main mesh.
To create the High-Poly model in ZBrush, I made a couple of adjustments before importing my Max model. First of all, create the Smoothing Groups for each of the parts of my model in the desired way. Next, I added a UVW Unwrap modifier and in the UV editor, I used the Flatten by Smoothing Groups option. You don’t need to worry about there being any overlap in the UV islands as this process is just so that when importing the model to ZBrush, and using the Auto Groups With UVs tool, ZBrush interprets each island of UVs as a different Polygroup.
It is also recommended, but not essential, to add the TurboSmooth modifier with the setting “by Smoothing Groups” with the desired iterations. This way, the curved surfaces of the model will be much smoother initially when imported into ZBrush.
After importing the model to ZBrush, I used the Auto Groups With UVs option to create the polygroups of each subtool as I said before. Once the polygroups are created it’s time to make a Dynamesh.
With the desired geometry in my model, I proceed to smooth the curved areas. For this, I use the Polish By Features option until no facets are noticed.
The last step to create the smoothed edges is to press MaskByFeature with ‘Groups’ activated in the Masking section. This way a mask is created when the polygroup changes. I grow this mask with GrowMask until it reaches the desired size. I also use SharpenMask and BlurMask to give it the desired hardness.
When the mask covers the desired area, I press Ctrl+Alt+Left Click in an empty area of the viewport to invert the mask and, after that, I use the Polishslider in the deformation section until I achieve the desired softness on the edges.
We can also use the Decimation Master tool before exporting our ZBrushHigh-Poly in case we have performance problems with the PC. This tool will reduce the amount of tris to the desired percentage, above all eliminating unnecessary geometry from flat surfaces. In my case, it was not really necessary.
Being a personal project without a tris budget, I indulged myself in the luxury of using all the geometry that I considered necessary. To create the Low-Poly model in 3ds Max, I used the model that I have brought to ZBrush as a starting point to clean up the unnecessary geometry. I removed all the geometry of the model that did not generate a silhouette; all the details that do not contribute to the silhouette will be drawn in the normal map and will work correctly.
To unwrap the UVs with the 3ds Max editor I work as follows: I set the smoothing Groups of the model correctly, always keeping in mind that if there is an angle change greater than 45 degrees there must be a change smoothing Groups.
Each change of Smoothing Groups implies a cut in the UVs, that is, a different UV island, although additional cuts can be made to relax the UV islands that don’t imply a change of Smoothing Group.
To correctly unwrap the UV islands, initially, I used the option “Flatten by smoothing Groups” selecting all the islands, followed by the option “QuickPeel”. If we have set the Smoothing Groups correctly, this will give us a very good basis to start with our unwrapping since the islands will be separated correctly. If any island has too much tension that can generate deformations in our UVs we will introduce additional cuts. If any islands are not unwrapped correctly with Quick Peel I usually use the Pelt Map option to get somewhat more precise control over the unwrap.
When all my islands were correctly unwrapped, it was time to put all the islands as straight as possible. For this, I started by selecting an edge that I want to position completely horizontally and pressing the “Align To Edge” option. Then I select the rest of the edges that are almost horizontal and press”Align Horizontally in Place”, and “Align Vertically in Place” for the rest of the edges that are practically vertical to align them perfectly.
Putting all possible edges completely straight will prevent from obtaining the jagged effect that is generated in the textures when there are inclined edges, and which is usually especially annoying in the Normal Map.
With all the islands unwrapped and as straight as possible it is time to pack them. For this my method in 3ds Max’s UV editor is to select all the UV islands and to select the option “Rescale Elements”, this will convert all our UV islands to the correct size with respect to the others, that is, the pixel density in the texture will be the same for all the islands. Later I use the “Pack Normalize” option, varying the Padding option until I get the correct Padding.
This way, I get automatically packed UVs that serves as a base to manually relocate the islands I consider so as not to leave empty spaces in the UVs. If there is an empty space that is not possible to fill with any other element of the scene I usually choose to increase a little bit the size of those UV islands that will be more visible in the scene, just as I usually decrease the size of UVislands that are practically not going to be seen if I need more space on the UV map.
This time I decided to use a 4k texture set for the main weapon, and a 2ktexture set for the suppressor and the sight.
For the symmetrical parts, I moved the islands of duplicated UVs (overlapping)to the adjoining UV space, making sure they were in the same position as the original UVs. This avoids problems in the symmetrical pieces when baking.
To save time when importing into Marmoset, it is very important to use good nomenclature. I usually use the Marmoset Quick Loader, with this tool I simply have to choose a name for each part of the low poly model, followed by the suffix “_low”, and call all the parts that are part of the high poly of that model with the same name, followed by the suffix “_high”, and after that an optional suffix “ _part1” that indicates what part of the high model it is.
E.g.: object_low, object_high, object_high_variation1, object_high_variation2
This way we can export from 3ds Max all the models that we are going to bake in the same texture map and, provided we use this nomenclature when importing it, Marmoset Quick Loader will automatically group all the bake groups in the scene correctly.
Another advantage of Marmoset is the possibility of being able to change the bake cage easily with the “max offset” slider. We can also decide in which direction the object’s normals will bake with the paint skew function, something very useful since all the details of the normal map on flat surfaces should be painted in a completely black value in order to force the bake direction of the normals to a completely perpendicular to the surface position, otherwise, unwanted deformations in our bake may appear.
Trying to save as much time as possible, my procedure is to initially bake only the normal map with low-quality parameters and a very low resolution. Then I adjust the cage and the skew perfectly, and I fine-tune the parameters using a resolution usually of double the target resolution that I’m going to use in the engine:
Let’s dive a bit into the maps I bake in Marmoset:
Normal map: In my case, I flip the “Y” channel because my map’s destination is Unreal Engine that by default works with DirectX. Conversely, for Unity, we should not flip this channel because by default it works with OpenGL.
Ambient Occlusion: When baking the Ambient Occlusion, I wanted to generate only the occlusion of each object on itself (the general occlusion will be added to the motor), so it is important to deactivate the parameters of “Floorocclusion” and “ignore groups” in the configuration of this map.
Thickness: This map is necessary when texturing in Substance Painter, it is used by many of the generators that I will use later.
Material ID: This map is very useful when creating masks and texturing different materials in parts that only exist in our high poly but in low poly are to be flat and will be drawn on the normal map.
In 3ds Max, a different material is added to each material that we want to create later in Substance Painter (one material for steel, one for orange paint, one for white paint…) before exporting our models for bake with the option“embed media” activated in our export settings.
If we don’t want to lose the color that we have assigned in 3ds Max, we can obtain this map by baking it like the Albedo map in the Marmoset Toolbag. If we simply bake Material ID, Marmoset will assign random colors.
Curvature: This map is very useful when we are going to make the textures to mask the edges of our objects. The result of the Marmoset map is usually a fairly thin border, so if we want a mask with thicker edges we can also bake the map that will give us this result in Substance Painter. I usually bake this map in both software packages to choose which one of the two curvature maps gives me a better result depending on what type of mask I want when texturing in Substance Painter.
Height: This map is only used in case we want to use tessellation or parallax occlusion inside our engine. I used parallax occlusion on a couple of elements.
World Space Normal & Position: These two maps are used internally Substance Painter when using generators or smart masks and I bake them in Substance Painter without the need to add a high poly
Before importing our low poly model to Substance Painter it is important to return the UV islands of the symmetrical parts to their original position in our UV space. Otherwise, we will not be able to work directly on these parts in Substance Painter. Next, I explain, step by step, how I worked on my textures:
Base material definition: This part, although it may not seem so, is one of the most important of the process. A good definition of the base material will give us the desired credibility. In this base material, I usually adjust color, roughness, and metallic behavior. Then I work on it.
It is highly recommended to create layers of color variation with a very low opacity on top of our base color layer and use some blending mode that suits you well. This, although practically unnoticeable, will give us a much more interesting base color.
Scratches and peeling on painted surfaces: To achieve this level of deterioration, this time I created the metallic material that would be under the paint and masked it with the Curvature generator and a warp effect so that the mask was not completely perfect. To have more manual control, I finally added a paint layer in subtract mode to paint with white values with an appropriate brush, like dirt brushes, to erase by hand those metal areas that do not convince me.
Dust: used the dust mainly to create variation and contrast on the roughness map. I decided to make two layers, one softer general dust and one with more dust accumulation in specific areas such as joints and recesses where it would mostly accumulate.
In the softer dust layer, I used a fairly dark color on the color base so that it was not very visible, and a medium-high value roughness, plus I moved the metallic value to 0. To generate the mask, I used a dirt map from the grunge section, I adjusted it by adding some levels to contrast it a little bit more & finally one of the BNW spots maps in multiply mode to break the homogeneity of the mask a bit.
In the specific dust layer, I used a lighter colored base than the previous one to make it more visible, a very high roughness value and also brought the metallic to 0.
Glossy splatters: I thought it was a good idea to create a layer with some quite glossy variations, such as oil splashes or also grease from the hands, in order to make the most of the roughness map and create as much variation as possible.
A little trick to give a more realistic touch to our Base Color map is to add a very subtle sharpen filter to our final map, either in Substance Painter or in Photoshop.
It is a good habit to texturize our models with an HDRI that does not add color to the lighting so as not to get confused when creating the Base Color. The HDRI I that I used, in this case, is called “Tomocco Studio”, included in Substance Painter. It is also the one I used later when rendering in Marmoset
The first thing I did when rendering each shot was to find a camera shot that I found interesting. I decided to base most of the renderings on the Kris concept camera shots.
For lighting, I set a few points of light from HDRI, with very subtle cold and warm lights so as not to lose realism. I adjusted the overall intensity of the HDRI and added a warm light aimed directly at the camera from behind the weapon with a large diameter, creating a subtle rim around the weapon that helps define the silhouette.
It was my first time using this new version of Marmoset and I was very curious to try the new Ray Tracing feature which gave me very good results.
Usually, I don’t like to use Marmoset’s Postprocessing functions, I prefer to geta clean image and treat it to my liking in Photoshop, where I usually add a layer with a very subtle bloom, a soft sharpen or some cloud noise for example. I also make saturation, brightness and contrast adjustments …
Special thanks to the Games Artist team for contacting me for this breakdown, it has been a real pleasure for me to be able to contribute to this fantastic project they are creating.Thanks for reading! If you haven’t already, take a look at the artwork I’m writing this article for: