Importing vs calculating normals

I’ve had a lot of problems with importing cylinder shaped items from Blender into Unity. At first I thought it was just the normal maps, but then after looking into it, the problems are the normals of the edges/vertices at the top and bottom of the cylinders. It doesn’t receive lighting correctly from the scene. I can either add an edge loop to correct the problem, or choose “calculate” normals in the import settings. which is the best approach?
Is it acceptable to just have Unity calculate the normals for me?

The blue lines are the directions of the normals.

It’s fine to let Unity calculate the normals based on angle. Another option in Blender instead of the edge loop is to set edges hard/smooth under the shading tab in the tool shelf.

You can also add the Edge Split modifier. This will “separate” the hard edges, technically duplicating the verts, and it generally fixes the easy cases like this. Some more difficult cases require adjusting the angle that counts as a hard edge, and in the most extreme cases you could have to select which edges should be “hard” directly, similar to how you create seams for UV mapping.

Bonus tip.
If hard edges and UV splits happen on the same edge you get one for free. On PC’s today the vertex count is not that important but on mobile it is still relevant.
Simplified example:

  • No Hard edge or UV split = 1 vertex
  • Hard edge = 2 vertices
  • UV split = 2 vertices
  • Hard edge and UV split = 2 vertices

Going back to the original question. Yes it is okay to have Unity calculate the normals but it obviously makes any changes to the normals in Blender irrelevant.

The best way to do this is to use the “Auto Smooth” feature of Blender. The older Edge Split modifier creates extra geometry that doesn’t need to be there, so this is a better way.

So first make your model in Blender. I’ve added this cylinder here as a test. Head over to the Data panel (on the right, looks like a triangle) and enable Auto Smooth. Then set smooth shading on your model. This will, in almost all cases, solve problems like this.

On the off chance that doesn’t work for you model (some models have more complex geometry and this can sharpen edges you don’t want sharp) you can start defining sharp edges by hand. Leave Auto Smooth on but crank the angle up to 180, this will essentially make the entire model smooth, and it should look terrible right now. Select the edges around the end caps and hit Ctrl-E and Mark Sharp. This will tell the auto smoother to split the normals along these edges. The model should look correct now.

1 Like

@UziMonkey Good tip there. I’ve never actually noticed that. It looks like it basically works like the edge split modifier.

The only thing is that I’m not sure how it wouldn’t create the same geometry regardless. To get the hard edge, you have to have the vertices drawn more than once, one time for each normal direction. I don’t see this setting getting around that problem. But I still see it as a useful setting, as you can basically have the edge split without adding a modifier to the list.

No, it doesn’t need to double the geometry. Each face can have different normals for each vertex. So the top face defines upward facing normals for the top face and the side faces define smooth outward facing normals. Further, the side faces will share normals, the right edge of one face will have the same vertex normals as the left edge of the next face and so on.

What an edge split will do is to duplicate vertices along a hard edge. Do the top face as 16 verts with upward facing normals and the side faces have a different 16 vertices in the same positions. It doesn’t really matter on small models like this, adding a few verts isn’t going to hurt anything, but it can be done without duplicating the verts.

Edit: You can actually see this in Blender.

This is both right and wrong. Blender may “pretend” that it is 1 vertex with several normal directions but in reality 1 vertex can never have more than 1 normal direction. The only difference is the workflow. A hard edge is always split but to keep it simple to work with in Blender (or Maya or 3ds Max etc.) they act as if it is still 1 vertex.

Blender, Max and other 3D packages often hide it where all modern game engines expose it. The game engines are in the right. These modelling packages will correctly split things on export though. All Unity does is read it.

It’s correct that you should have multiple verts where edges need different smoothing.

If I make a cube in Blender, set shading to smooth, set auto-smooth and export an FBX, there are only 8 verts in the FBX. There are per-face normals for each vertex, but only 8 verts in the file. If I use an edge split modifier there are 24 verts in the file also with per-face normals. So at least in Blender and the FBX the verts aren’t being duplicated. I’m not sure what happens when it hits Unity though.

It is not a Unity specific thing. In graphics programming each vertex can only store 1 normal vector. If you have a cube set to smooth with no hard edges the normals on the corners are “averaged”. This means that there is only 1 normal and it is pointing in the average direction of all the face normals it is attached to. Therefore you can have a smooth cube with just 8 vertices in total.

Thanks. I tried that out. For a simple cylinder, it works.

3026741--226279--cylinders.jpg

The cylinder on the left is just using the smooth shading. You can see it’s not right. The one on the left was using the “Auto smooth” feature.

I was going crazy for a long time trying to figure out why cylinder shapes were giving me such of a hard time.

In reality, it is technically still doubling the verts. Some file formats don’t duplicate data(OBJ I know for sure), so it has a list of all the verts position, UV, and normals, and then for the definition of the faces, it can index a single position twice, using a different normal each time. In this manner it sort of optimizes the file. But in the end, the vert still gets drawn twice in the game engine, no matter what Blender tells you.