How to bake perfect hard-surface normals in Blender (2022 Tutorial)

Introduction

I've been working on this Cybertruck model for Tesla Simulator. The Cybertruck is a so-called hard-surface object, which is defined (according to Internet) as a modeling technique used to model cars, armor, machines, and generally non-living objects that have smooth, static surfaces. 

The Cybertruck above has way too many triangles to be put into a game (unless you want the game to run at 2 fps) so I have to simplify it. You simplify objects for games by removing triangles and then, to compensate, you bake a so-called normal texture to trick your eyes that the simplified object has more details than it actually has. This simplified object is also known as a low-poly mesh. 

I'm using Blender as modeling software. Baking textures in Blender is always an annoying process if you have a complicated model - especially if you have a hard-surface object. I've earlier baked hard-surface objects and I always had to improve the textures manually because of artifacts. This has always been fine because you can't see the remaining artifacts from far away anyway. But it has always been annoying to manually improve the textures because it's time consuming. I've also been forced to add geometry to make better normals, which is not good either because the more triangles you have the slower the game will be. I remember baking the normals for this Not-A-Flamethrower object was really time consuming - and you can still see some artifacts if you zoom in.

If the tiny weapon was time consuming - then how time consuming will it be to bake normals for the Cybertruck? I shrugged at the very thought of the baking process, so I procrastinated on it instead. But then I told myself to once for all learn how to bake hard-surface normals without struggling. Spoiler: there will always be some struggling because there's no simple solution to the problem. 

By the way, this articles assumes you know how to set up nodes and cages to bake textures, so I will not go through that process as well. If you don't know how, I think this is a good tutorial on the topic: Baking Cavity + Ambient Occlusion Texture Maps | 2019 | Blender 2.8

Cube

If you look for tutorials on the topic how to bake hard-surface normals, there are surprisingly few results. The few you find deal with the simple cube with beveled edges, which is a good start and will teach us the basics. But you will see that the knowledge is not enough when it comes to more complicated objects. So let's start by experimenting with the cube! This is the setup: you want to simulate the soft edges of the right cube on the left cube by using a normal texture:

The naive solution is to unwrap the left cube to get as few uv islands as possible because the fewer the better: 

But if you try to bake the normals (without a cage), you don't get smooth edges because an ugly line is visible on all edges. Right cube is high poly for comparison:

So lets try to bake with a cage. The result is better but you still see an ugly line if you zoom in:

But from the image above you can see that the line is not visible where you added a uv seam. So the solution to all of our problems is to always add a uv seam at each hard-surface edge. Yes you will get more uv islands but there is no other solution. You should also always use a cage. Yes cages are annoying to make because you have to make a high-poly mesh, a low-poly mesh, and now a cage: that's three meshes - but again, there is no other solution. This is the result where each hard-surface edge has an uv seam and a cage is used:

...so the normal texture should look like this:

Cylinder

With knowledge from the cube, I set out to bake hard-surface cylinder normals, thinking the process would be easy. This is the setup: you want to simulate the soft edges of the right cylinder on the left cylinder by using a normal texture:

If you follow what you've learned so far: uv seam along each hard edge and baking with a cage, the result is this:

Depending on how you made your cage, you can see that you get this wave pattern, which is very ugly when you want a smooth edge. You can clearly see this wave pattern if you look at the normal texture you just baked: 

So what is going on? It took a while to find the solution, but according to people on Internet, the problem is my cage. The cage is too far away from the flat part of the cylinder. So to solve the problem you have to push the flat part of the cage closer to the surface - it should be right outside (left white cylinder is bad cage, right white cylinder is good cage):

...and if you bake the normals, the edge is now smooth:

...and you can't anymore see the wave pattern in the normal map:

Cylinder with details

With the knowledge from the cube and the cylinder experiments I set out to bake normals for a Dogecoin asset I made for Tesla Simulator. 

The coin is just a cylinder so I can just use the ideas I've learned so far! The answer is no! I've recreated a simplified version of the coin so you can easily recreate the problem. This is the setup: you want to simulate the soft edges of the right coin on the left coin by using a normal texture:

When you bake the normals texture, the result looks like this: 

...the normals of the cylinders at the edge on the flat side are distorted. You can see this more clearly in the normal map:

The reason this happens is because you increased the size of the cage to be able to capture the geometry on the side. This will result in that the flat side of the cage increases, so the small cylinders will get distorted because the baking fire rays not top-down but top-sideways. So what you actually want is top-down normals baking on the inner side of the flat surface to not get distorted small cylinders, and top-sideways baking on the smooth hard-surface edge to capture the beveled edge. The problem is that you can't get both - unless you add geometry to the low-poly mesh, like this:

...and when you create the new cage, you have to make sure that the inner vertices (the once you added) are only moved upwards (in z direction): 

If you move them in any other direction the normals will again get distorted. Now Blender will fire rays top-down to capture the normals belonging to the small cylinders, and top-sideways to capture the hard-surface edge belonging to the big cylinder. It looks like this from the side (the white arrows are the direction rays will fire to bake the normals):

With the new cage, the normals now look like this:

When you have baked the correct normals you can (at least in this case) remove the extra edge you added because it is no longer needed. So adding and then remove geometry is something you have to plan already when you make the low-poly mesh and when you unwrap it.   

Other tips

Use a larger texture than you need. When making games it's common to use 2k textures. But when baking normals to a 2k texture, the result might be bad because the texture is so small. If that is the case, then you can try to use a larger texture, like a 4k texture, and then scale the texture to a 2k texture in like Photoshop or Unity. This can give you a better result. 

Align the uv seams parallel to the uv grid. This may give you fewer artifacts when baking the texture. The reason is that your texture consists of pixels and the uv-seam is a line. If the line is not going along the u or v axle, you will get a jagged result, like this (left bad, right good):

Example. The naive unwrap of this shape looks like this:

You can't improve the unwrap of the two circles, but you can straighten out the other shape. You can do this manually by selecting a rectangle (pick a rectangle that is sort of aligned along the grid), straighten that out along the uv, and then select that rectangle and unwrap it again by selecting "follow active quads." But this problem is so common that someone has made a free addon which simplifies this process: UvSquares. The result should look like this: 

As a bonus, if you straighten out as many shapes as possible, you will get a more efficient uv pack. The reason is that it's much easier to pack convex shapes than concave shapes!  

Summary

This is a summary of what you should have learned:

  • Add a uv seam along each hard-surface edge.
  • Use a cage, and the cage should be as close as possible to the high poly model but still outside.
  • When making the low-poly model, take into account how you will bake the normals so you can add/remove geometry to get a better bake.
  • Align the unwrapped uvs along the uv grid.
  • Use a larger normal texture than you need - and then rescale it to your needs. 

So have fun and good look with your hard-surface normals bakes! Because I'm gonna need all the luck I can get when baking the Cybertruck normals. 

Comments

  1. Thanks for this, it helped me in my learning process of baking normals!

    ReplyDelete

Post a Comment