Search Unity

Importing vs calculating normals

Discussion in 'Asset Importing & Exporting' started by ArachnidAnimal, Mar 28, 2017.

  1. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,838
    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?

    edgenormals.jpg

    The blue lines are the directions of the normals.
     
  2. _GimbalLock_

    _GimbalLock_

    Joined:
    Feb 26, 2013
    Posts:
    137
    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.
     
  3. kburkhart84

    kburkhart84

    Joined:
    Apr 28, 2012
    Posts:
    910
    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.
     
  4. Pengocat

    Pengocat

    Joined:
    Dec 7, 2016
    Posts:
    140
    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:
    1. No Hard edge or UV split = 1 vertex
    2. Hard edge = 2 vertices
    3. UV split = 2 vertices
    4. 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.
     
  5. UziMonkey

    UziMonkey

    Joined:
    Nov 7, 2012
    Posts:
    206
    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.

     
    Last edited: Apr 9, 2017
    ArachnidAnimal likes this.
  6. kburkhart84

    kburkhart84

    Joined:
    Apr 28, 2012
    Posts:
    910
    @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.
     
  7. UziMonkey

    UziMonkey

    Joined:
    Nov 7, 2012
    Posts:
    206
    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.

     
  8. Pengocat

    Pengocat

    Joined:
    Dec 7, 2016
    Posts:
    140
    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.
     
  9. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    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.
     
  10. UziMonkey

    UziMonkey

    Joined:
    Nov 7, 2012
    Posts:
    206
    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.
     
  11. Pengocat

    Pengocat

    Joined:
    Dec 7, 2016
    Posts:
    140
    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.
     
  12. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,838
    Thanks. I tried that out. For a simple cylinder, it works.

    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.
     
  13. kburkhart84

    kburkhart84

    Joined:
    Apr 28, 2012
    Posts:
    910
    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.