Sins II: Dev Journal 21 - Baking with 'Set'
Published on Wednesday, November 20, 2024 By Unikraken In Sins II Dev Journals
The primary 3D artist on Sins II’s development team, Paul Kiesling (Set), was kind enough to swing through this month to provide a short explanation of the process we go through to get our ships looking so crisp in Sins of a Solar Empire II. This was specifically requested by the fans, so we hope you enjoy!
High-Low Baking
Today we will be covering some of the nuances of our art pipeline and covering the details of our baking process along with some of the tips and tricks we have learned along the way so if you choose you can achieve similar results. By demonstrating this workflow, we hope to encourage the next generation of mods and user generated material for Sins to properly utilize the game engine’s artistic capabilities.
The Basics
Before we get started let’s get down to the basics of what is necessary to generate a good model in quads. This is largely dependent on the tools you have access to and what you are most comfortable with. Since I started doing 3D work, I have been most comfortable in 3DS max but as I understand it a large portion of the community use Blender. This won’t be an issue for what we are doing today as they share a lot of the same features and functions. The most important part here is having a model with good topology in quads to continue further. So let’s get started, I will be using the Coronata as an example to demonstrate the steps.
Let’s take a good look at the model here, pay close attention to the sweeping topology. The shape of the models quads are what we refer to as “globe like” following the silhouette of the ship in smooth sweeping curves. Using Tris isn’t bad but should be minimized as much as possible as having too many tris will not play nicely with later steps. Before we start anything though, your model should look similar in topology to what is shown above. Focus on creating a model that consists mostly of quads, and minimal tris. N-gons (Polygons with more than 4 sides) should be discouraged as well UNLESS you have a firm understanding of how that n-gon will subdivide. It can be useful, and it can be a detriment, that’s on a case-by-case basis.
Let’s assume you have a model with good quadified topology, what’s next? Well, you will then have to set up what is referred to as holding edges. These holding edges are what determine how your model holds up under sub-division. So, this is rarely a one and done type scenario, it often takes a few back and forth attempts to hold the desired shape you’re looking for. Let me demonstrate.
So, let’s examine the model again, you will see important edges highlighted in yellow. All modeling programs have a method of selecting edges that you wish to manipulate. In this scenario you will have to look over your asset and figure out the shape you want it to maintain. Start by selecting where you want your holding edges to be. As shown above the yellow edges are the selected parts I want to maintain their shape with subdivision. Selecting these edges has a two-fold function, first and foremost is to maintain the desired shape of your model, the second is to bevel the edges. The beveling will bake down and rid the model of hard, unrealistic sharp edges. Which you will see in later steps.
Ok, by this step we should have a good quadified model with the holding edges selected. Lets get to the fun part, the actual beveling and subdivision.
In your respective modeling program find a modifier for chamfer/bevel. This will create a 45-degree face along your selected holding edges. The size and placement of these will be entirely up to you as they can change and shift on a case-by-case basis. Shown above is me applying that modifier to my selected edges. I tend to apply the same sized bevel to all edges for consistencies sake but there have been instances where bevels of different sizes could used across a model depending on use case. Just be mindful of how bevels intersect, and if your application has a measure of collision control (this will in most cases prevent your geometry from deforming in a way that is detrimental to a good high poly) make sure it is enabled to prevent broken geometry when using this modifier.
So at this point you should have your quadified mesh, with all your holding edges selected and beveled. During this part of the process, I will export my mesh from whatever program I am using up till this point and importing it into Zbrush. As its subdivision algorithm seems to play better with most models in comparison to 3Dcoat / 3DS Max/ Maya / Blender. Understanding and appreciating that not everyone has access to Zbrush. In your application of choice find your sub-division modifier. This is when the magic happens.
In the image above several subdivisions have been applied. The shapes are rounded, the lines are smoother, and overall appearance is of higher fidelity than the previous image, this will constitute your high poly.
We should now have an original quadified low poly, A proper high poly with its subdivision levels. What's next? Well now we need to use the low and high to make sure we won’t run into bad bakes by using the high poly as a reference mesh for the low. To ensure when we go to bake that the geometry is where it needs to be to capture as much detail as possible. Let me demonstrate. Look at the picture above this is a great example of what happens when the geometry of the low doesn’t quite match the geometry of the high. This is fixed with a couple quick steps.
Start by selecting the faces that don’t quite match, and giving just those faces a single subdivision level.
As you can see the faces more match the geometry of the high poly, that information from the high poly won’t have a hard time baking down now. Let’s continue. You will then have to remove the unneeded edge on the inside of the inset and get rid of those n-gons the subdivision created.
This is a good example of fixed geometry design to better accommodate the high poly geo. At this point of the process you don’t have to worry about triangles on your low poly model. You want to make sure that your low and high poly geometry are in alignment as much as possible. Your mesh will have to be triangulated for the baking process anyways. My recommendation at this point would be to reduce your models tri count as much as possible. Vertices aren’t the most expensive element of rendering a game but Sins will definitely reward you for being smart about where you chose to distribute them.
Here is a larger section of the low poly model, using the high as a reference mesh so you can see how well the two align. This is critical for the next stage.
UVs
Ok the next most important thing here are the UVs, baking can be a picky process so setting up your UVs can actually make the process easier and prevent your cage from collapsing in on itself. Lets start with the basics, padding and margins are important as Sins does MIP textures. Its standard to use a 1-2 ratio for margins and padding so at 1k you will have a margin of 4 pixels and a padding of 8. This will continue up the chain for 8-16 at 2k and for 4k we use a custom of 1-1 so 16-pixel margin AND padding. As capital ships and large structures will un-render before hitting a MIP level where padding/margin bleed between islands become troublesome.
Mipmapping is a pre allocated texture that contains lower resolution versions of itself, its intended to increase rendering speed by allowing the resolution of an object to be shrunk based on its distance or relation to a camera. So just keep that in mind why setting up your uvs that padding and margin matter.
Mip is an acronym in latin “Multum inparvo” Which means “Much in little”
When prepping UVs for baking it’s important to pay attention to the orientation, make sure your UVs are orientated either horizontally or vertically and are straightened as much as possible. Awkwardly placed islands can cause aliasing when baking because the information is being baked from the high to unstraightened edges onto your low. The next thing to pay attention to is the amount of utilized space. In my experience, different applications have different ways of communicating this information. Standard practice is at a minimum 70-80% utilization of your 0-1 space (That’s the box in which your sliced islands are packed into) with more obviously being preferable because better utilization of that space will increase visual fidelity of your materials.
Here is an example of the space utilization on the coronata, take it with a grain of salt. A lot of my UV islands are stacked and that contributes to numbers higher than 100%. We joke internally but there is one Advent ship/structure that has somewhere in the range of 205% efficiency because of how much of it is stacked and it has become a bit of a meme. Just remember you want to aim for the best utilization possible. Good utilization will allow you to make your materials pop more and put less of a strain on texture memory by allowing ships to look better at lower resolutions.
Mesh Normals
Next comes setting up your low poly mesh normals, in this instance there a few different ways to set them up for a bake. I’ll try to walk you through the benefits and draw backs of each.
Maximum Softening
Now when it comes to methods used to bake a high-low the maximum softening is definitely the easiest way to go. This method just removes all the hard edges and hardening on the face normals. It ends up making the model look like playdough, a lot of the defining edges disappear and the mesh becomes a soft mass.
Weighted Normals
Now when it comes to preferred techniques for baking this is definitely my favorite because it simplifies and makes easy a lot of the leg work required for a good bake. You’re probably asking yourself what are weighted normals? Well a normal in technical terms is just anything that perpendicular to a surface. What weighted normals do is force the meshes normals to be perpendicular to the larger faces and this will force the shading of the mesh to concentrate at the edges. That concentration will be useful later on which is why I heavily recommend using weighted normals with a few additional tweaks if you are attempting to bake a low poly mesh. So let see what that looks like visually.
In the instance of the Coronata there isn’t much difference between the standard softening and the use of weighted normal. Something to remember too now is basic rule of thumb for setting up mesh normal for a bake.
“Not all seams have to be sharps, but all sharps have be seams.”
This is important because it should be stressed that your base low poly mesh should be as soft as possible because hard edges can fight the bake but also if you have a hard edge in the middle of an island on your UV sheet, this to can cause edge aliasing and detract from the quality of what you are trying to accomplish. If you do have a sharp edge designated on your mesh it should be where your seams are on your UV sheet.
3DS max’ weighted normal modifier comes with the ability to harden UV island edges; this is a quick and easy way to assure your hard edges are exactly where they should be. Next, we’ll look at a best/worst case scenario for softening/weighted normals.
This is the Radiance with and without weighted normals. The top picture with maximum softening and the bottom with weighted normals. Now I hear a few of your saying “why do I care what my texture normals look like if my ship looks pretty.” That’s a valid question. So let me explain. If you see in the first picture the color banding is loose and more dispersed than the weighted normal. This is an issue because texture normals act as a skew map for your models mesh normals or rather a better term would be an “offset.” Your baker is looking at the mesh normals of your high and low and creates an offset texture that makes low more accurately appear like your high, by using the three color channels red, green, blue. It creates an offset by applying an axis direction to each color red (x), green (y), blue (z). If your color banding is loose and all over the place it may create a desirable looking asset at 4k or 2k texture resolution but when you attempt to lower the resolution there is insufficient color data to create an accurate skew map and because of that you will begin to notice artifacting and the meshes original softened normals bleed through. Which will in fact make your hot ships, less hot.
Now that we have that settled, we need to figure out where we will be baking the mesh maps, you have several options. Blender is the obvious option; however, I will admit to not being familiar with it. Substance painter does have a baker built in but in my experience, it tends to be very fickle and lacks some of the more important controls to perfect a bake. You are more than welcome to bake in what ever application you are most comfortable In but I would recommend marmoset. It makes the easiest to get the best results, but I understand and appreciate not everyone wants to spend the money.
Now when baking meshes it’s good for separate parts both high and low to follow a simple nomenclature as most bakers will use the names of the objects in the scene to decide what’s the high and low poly. Here is an example.
When setting up models for a bake scene they MUST be triangulated, baking in quads is undesirable and without getting too technical could break your assets when trying to put them in game.
You will have to export the high parts as one mesh and low parts as another. This will allow you to have individual cage control over multiple parts in your marmoset scene.
I'm going to walk you through a marmoset tool bag bake to demonstrate the effects, feel free to apply this to what ever respective application you are using. Now when baking in marmoset, you will want to start bake scene. Artists are not without a sense of humor so when you open marmoset look for the bread icon.
This will prompt you to select both your high a low poly meshes. After a few seconds to a minute, it should import them into the scene to start the bake. The time is largely dependent on the tri count of your high poly mesh. Once they are imported into the scene you will need to adjust some settings so the mesh maps that are output will be useful in both substance painter and Sins2.
You want to check the “fixed mirrored tangents” box, make sure you’re baking in the Mikk or MikkT tangent space. As this is the tangent space utilized by Sins. Also make sure your tangent direction is left-handed. Its an odd way of saying it but left-handed simply means DirectX which is the format that Sins 2 expects from normals. I tend to set my samples to 64x. 16-bit channel, with a 4k x 4k bake resolution. From Marmoset I will bake normals, curve, and AO. As the results in marmoset are far better than anything substance painter has put out. After setting all of that let’s adjust the cage to be safe.
You’re going to select top parent element of the low of a mesh, and you will see this slightly inflated version of the low poly mesh that sits above the low poly itself. This is your cage. It acts as area of effect of sorts that the ray tracing happens between the high and low poly. Go wide with it and you get overlapping bake errors from parts of the cage merging into each other awkwardly. Go too tight and your risk losing data because parts of your high poly could potentially fall outside the bounds of the cage. It’s a balancing act. Try it out, experiment and find the sweet spot for your mesh, each one has different needs. Once you have all of that set up and tuned to your liking lets bake and see where we are at. I'm not going to cover the deep and gritty nuances of fixing bake errors here but assuming we had everything go well I will show you the results.
As you can see from the before and after, the difference is quite stark. Creating a carefully crafted high poly with good bevels was important here because just from a quick visual glance edges appear to have a bevel or chamfer which gives the mesh the appearance of having a higher tri count than it actually does. By creating edge highlights and smoothing out mesh normals to make ship looks leagues better.
So we are near the end here and where the truly fun part begins. Assuming you made it to this step without your eyes bleeding or your brain glazing over. Congratulations on your tenacity. Now we get to start the best part, texturing. Your mesh maps are baked let's get them into substance painter and have some bringing our ships to life.
Open up substance painter and import your low-poly into the scene. Once you have it in the scene it should look something like this:
Don’t be discouraged, this is just the bare low poly mesh with its base mesh normals. Locate the folder with your baked mesh maps so your normal/curve/AO and drag them into substance painter and import as textures. Once they are in the scene you will need to apply them in your texture settings window so they can be applied to your low poly.
It will look like this, you have slots for the three you just baked. Next drop them in there respective fields so we can see the difference.
As you can see applying those mesh maps made a world of difference, the mesh looks a lot more defined now. With some crisp texture normals and a clean AO.
This was a basic overview of how our internal process for how ship creation works, this is not an exhaustive break down of every technical detail and nuance of the topic. Baking a good 3D asset is a skill like any other, to get good will take time and practice. However, it is my hope by exposing the larger community to this form of art creation it will allow all of you who chose to try the ability to create some absolutely wonderful art. I started doing this for fun in 2009 and the pursuit of my craft found me a job working on a fantastic game with a talented group of like-minded individuals. It helped me find my wife and I owe a lot of what I have to Sins and by trying to distill some of this information and pass it along it is my hope that what comes next will be worlds better than what has been.
Thank you
~ Set