Breakdown: Sawed-Off Shotgun in Substance & Toolbag
Alexander Sheynin shared a detailed breakdown of his amazing Sawed-Off Shotgun made in 3ds Max, ZBrush, Substance Painter, and Marmoset Toolbag.
Hello! My name is Alexander Sheynin, I’m a self-taught 3D artist from Tula, Russia; in 3D since 2016. Currently, I work for Dekogon Studios, creating assets for games. In this article, I’ll try to describe the process of creating my personal work “Sawed-off shotgun”. I used 3ds Max, Zbrush, Unfold 3D, Substance Painter, Marmoset Toolbag, Adobe Photoshop, and PureRef
The original concept by Ivan Taranenko, I found on his ArtStation page. It is a personal project created for my portfolio and studying Substance Painter, so I made some changes in the design itself. Probably, it was originally supposed that instead of one there were two barrels, but in my opinion, the gun would look more organic with one barrel left, and in its size, it looked more like a grenade launcher than a shotgun. That’s why I added a 40 mm grenade to it.
All the references for my projects, I find on Google, Pinterest, and YouTube. They can be divided into 2 categories: for understanding shapes and material samples. For this project, their count is not too big, cause the project was made for personal purposes. But usually, I spend a lot of time searching for good references, how the material is worn; videos, which represent shapes and how do some mechanisms work.
Main software I used for modeling was 3ds max. It has both a bunch of pros and cons; nevertheless, it works rather stable for me, and in combination with additions, it allows me to get the desired result rather quickly. Here is the list of scripts and add-ons that I use:
- Regularize edge loop – Rearranges loops in regular n-gons.;
- Align Pivot To Selection – quickly sets the pivot position to selection;
- Sub-object pivot – allows you to select a single component on a mesh or poly object and toggle a working pivot onto it. It works similar to a referenced coordinate system, like in Maya or Xsi;
- Vertex Cleaner – cleans polygonal meshes from the useless vertex, for example after the Boolean operations.
There is nothing special about my modeling techniques. I often use symmetry for planar cloning, an array for radial (holes in the barrel jacket). Almost all the edge and polygon actions are bound to hotkeys (extrude, chamfer, bridge, cap hole, connect, weld, quick slice, collapse, set flow, remove loop etc.). Especially, I often use axis alignment. Also, such commands as a center pivot, autosmooth and harden/soften for smoothing groups creation. I use Proboolean in an instance mode, so this way it acts like Live Booleans in Zbrush. To avoid unnecessary vertices, I set the Remove Only Visible option, and remove the rest with the Vertex Cleaner script.
Usually, you should follow the rule “from big shapes to smaller ones”, however, when you have only a side view, it is not always clear how wide the object is. Therefore, since they have 2 equal sides, I prefer to start with cylindrical shapes. All the blockout meshes I place on a separate layer, leaving only the main reference/camera/light (if it is in the scene) on default. The layer list looks like 1) 0-default; 2) blockout; 3) high poly; 4) low poly.
Blockout is one of the most important steps because at this point you define the main shape of your object. Based on your blockout meshes, high poly and low poly will be created. First of all, the topology is important for those objects that will later become the basis for subdiv high poly meshes (grenade). For objects that will be refined in ZBrush, the topology and n-gons are less significant. The main thing here is to convey the silhouette. That’s why I increased the segment’s count in round shapes. The idea is, even from a relatively close distance, the fragment of the mesh should not look angular.
In different cases, such as topology or further mesh editing, I use 3 approaches to create various complex cuts or shape mergings. It could be Proboolean in Max, with “No Edge Removal”; either create a separate mesh for the cutout shape, export it, and perform the boolean operation in ZBrush; or make this mesh completely in a ZBrush, and then subtract it from the main object. In Max, I assign green material to subtract meshes.
In this work, I used the first method in blockout, and the second when creating a high poly.
When the modeling for this stage is done, I position the pivots, make links to separate parts of the object; check if the parts of the object intersect during transformations. And, if everything moves as it should, I come to the next step.
The principle of modeling high poly-parts was determined by the amount of time required to create them. It was easier and faster to make a subdiv grenade because there are no major damages or scratches that would have to be sculpted on it and there is no need to export it from and import back to Max. I duplicated the mesh from the blockout layer, added an Edit Poly modifier on top of the stack, selected the edges, which would be creased. After that, I added a turbosmooth modifier with a couple of iterations and checked for artifacts.
All the other parts were exported to Zbrush. I assigned polygroups by normal, activated dynamesh, then, first masked the edges (mask by feature – groups), after – polished the whole mesh, and inverted the mask and applied polish on the edges (polish, polish by features or polish by crisp edges, depending on the shape of the object). With the trim dynamic, clay, planar, hpolish, orb_slash brushes, I sculpted some wear and cracks. It was easier for me to create a grid pattern in Photoshop, and then use as alpha with the standard brush in Zbrush. After all, I decimated the mesh and imported it back to max. For the naming, I used Rename Objects tool in Max.
It’s pretty simple, even no retopology, I just optimized the blockout meshes, removing the extra vertices and edges, and attached them to a single object. Total polycount is 19806 tris. The only important thing – is the smoothing groups. In some cases, like it was with the round part of the frame, I used a single smoothing group, while with the hard edge, It gave bad shading and visible seam after baking.
Before moving to UVs, detach symmetrical and repeating parts from the model and assign them a new material. These parts will be copied from those on which I will create an unwrap and transferred to the next uv-space to leave more space for the rest. I use Unfold3D Vs 2018, very quickly, it allows you to cut seams, iron your uv-islands and automatically pack them with certain padding value. It’s interface is similar to max/maya, so it is very easy to work with. Square unwrap due to all the islands have filled the square space; uv’s of the unseen parts were scaled down.
After the uv work was done, I sent the model back to Max, cloned the repeating parts, moved their unwrap to nest uv space and attached to the mesh. Then, the model was exploded to several objects, each was named according to highpoly parts. After, I checked for artifacts, overlapping and holes, I made reset xform and export it as fbx for lowpoly and obj for highpoly. Parameters checked for fbx: smoothing groups, tangents and binormals,convert deforming dummies to bones, triangulate (in some areas it’s better to triangulate manually to avoid overlapping), preserve edge orientation.
That was the last time, I baked in painter, marmoset makes it much faster and easy. However, it is also very simple. Texture resolution was 8k; normal,wsm, ID, curvature and position maps were baked first with 2×2 antialiasing, then AO and thickness without antialiasing.
In this work, I had a very dense and uniform grid, so there was no distortion when baking with average normals. In cases, when this happens, I usually combine 2bakes – one I do without average normals (essential cage) for flat edges so that all the details are projected exactly onto the surface, and the second with average normal for the edges to smoothly transform into each other. Then I combine these two by a mask. Also, you can temporarily increase density on the mesh (add tessellate or turbosmooth with the smoothing groups checked), bake maps, and then replace the mesh with the original one. Or, instead of wasting your time, you can use marmoset.)
During AO bake, Ignore backface parameter was disabled, because, without it, the map becomes more contrast, occlusion-areas will be darker. Self occlusion – always, so that the dark traces remain on the contacting objects.
Besides, I have to mention that at the stage of baking and texturing, it is necessary to use both a model with parts exploded in different directions, and an assembled model. Exploded – in order to have access when drawing to the hidden parts (for example – a grenade in the trunk). You can replace the original lowpoly mesh through edit – project configuration without any loss.
Each separate part of the model has its own folder, – a smart material in fact. Such an organization won’t let you get lost in a large number of layers, and also will simplify their manipulation. Adding a color picker allows you to create a mask based on the ID map.
There is also a hierarchical structure within any folder. Mostly, these are “base” and “wear and tear” folders; an empty layer with Sharpen filter goes on top. In the “base” there are layers that define the base material, i.e. almost pure material, without scratches, rust, and other wear. Here I use one main layer – base. This can be a pre-made material (not smart) or manually created from an empty fill layer. Next, come the color variation layers. I have never seen a uniform color in materials, so all channels, except color, are disabled. I masked them with various procedural maps, such as dirt/grunge spots/grunge shavings or with the mask builder generator. The goal here is to create a color variation in accordance with the mask of small dots or small spots. The first layer is a very small noise, then the spots are medium in size, and the last stays for large. You can put histogram scan filter to reduce the mask value. Also, you can make a similar structure for the roughness channel, if needed.
When the base material is done, I start to work on wear and tear. Here I used small scratches, edge wear, rust stains and paint leaks, small holes and so on. The principle here is: put wear where it takes place and remove it from where it should not be. That’s why I often add paint on top of all generators – to mask unwanted areas and manually bring the wear to the desired level. For small scratches or stains, I add a sharpness filter. This makes it a bit more realistic and stand out. The last layer in the wear folder is the dust.
There are so many ways to achieve the same result in Substance Painter. You can use various combinations of generators and filters or hand paint your masks. Best for me was the combination of these methods, and due to the tablet, it all becomes much more convenient. Thus, among other things, paint and blood were drawn in such a way.
Another important thing – is height and roughness. If it is metal, then I add a contrast map to the roughness channel. For everything else – different maps in the height channel. There are some paint leaks on the handle, which have a small positive height, and scuffs on the edges with the negative value. Also, if there is a rubbed corner or area on the model, then this place the bump level could be very low, or absent at all.
The smooth color transition on the barrel – is 3D distance generator. Blood is 2 identical fill layers (with different masks) with burgundy color and a low level of height and roughness. Color variation was created by BnW spots 2 map applied to the layer (add fill) in the overlay blending mode. The first layer – large accumulations of blood on the blade, the second – small splashes on the blade and the grip. Both masks consist of the mask editor generator and the paint on top.
When I was done with the texturing, I checked my model with Iray inside substance painter, with post process and effects on (antialiasing, hi-res shadows). Export config: document channels + normal+ Ao. So, we have a base color, height, metallic, mixed ao, normal, normal DirectX, roughness.
For rendering, I use Marmoset Toolbag 3. Everything is also quite simple, but depending on the camera position, some parameters need to be changed periodically.
Here are the settings that I usually change:
To make the textures look more detailed, disable the mipmaps option. Occlusion strength parameter was picked by eye, as well as brightness and voxel scene fit. Then I start adding light sources to the scene right in the editor window. The main thing is to highlight the silhouette of your model. In the camera settings, I edited the curve, that made the image more contrast, added chromatic aberration with a small value and dof, if necessary.
The final images have png format, the resolution is more than 3000-4000 pixels on the small side. I set sampling at 100x, transparency is on.
I did not do any post-processing in Photoshop, I just added the background and my contacts.
This work took 5 days, blocking and texturing steps were the most time-consuming.